diff --git a/.github/workflows/build-templates.yml b/.github/workflows/build-templates.yml index 73d5df0b9..53d1e1ced 100644 --- a/.github/workflows/build-templates.yml +++ b/.github/workflows/build-templates.yml @@ -35,6 +35,7 @@ jobs: - legacy-module - legacy-view - nitro-module + - nitro-view language: - kotlin-objc - kotlin-swift @@ -52,6 +53,10 @@ jobs: language: kotlin-objc - type: nitro-module language: cpp + - type: nitro-view + language: kotlin-objc + - type: nitro-view + language: cpp include: - os: ubuntu type: library @@ -147,6 +152,11 @@ jobs: fi fi + - name: Generate nitrogen code + if: matrix.type == 'nitro-view' || matrix.type == 'nitro-module' + working-directory: ${{ env.work_dir }} + run: yarn nitrogen + - name: Cache turborepo if: env.android_build == 1 || env.ios_build == 1 uses: actions/cache@v4 diff --git a/packages/create-react-native-library/src/exampleApp/generateExampleApp.ts b/packages/create-react-native-library/src/exampleApp/generateExampleApp.ts index 79295b051..eb8bfda8e 100644 --- a/packages/create-react-native-library/src/exampleApp/generateExampleApp.ts +++ b/packages/create-react-native-library/src/exampleApp/generateExampleApp.ts @@ -180,7 +180,10 @@ export default async function generateExampleApp({ 'react-native-builder-bob': `^${config.versions.bob}`, }; - if (config.project.moduleConfig === 'nitro-modules') { + if ( + config.project.moduleConfig === 'nitro-modules' || + config.project.viewConfig === 'nitro-view' + ) { const packagesToAddNitro = { 'react-native-nitro-modules': `^${config.versions.nitroModules}`, }; @@ -296,6 +299,76 @@ export default async function generateExampleApp({ } } + // nitro modules on xcode 16.2 requires ios 16 version because of the bug https://github.com/swiftlang/swift/issues/77909 + // full thread in https://github.com/mrousavy/nitro/issues/422 + if ( + config.project.viewConfig === 'nitro-view' || + config.project.moduleConfig === 'nitro-modules' + ) { + const newTargetVersion = 16.0; + + const podfile = await fs.readFile( + path.join(directory, 'ios', 'Podfile'), + 'utf8' + ); + + const postInstallLine = 'post_install do |installer|'; + // set pods deployement min version + const podVersionOverride = ` + installer.pods_project.targets.each do |target| + target.build_configurations.each do |config| + config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '${newTargetVersion}' + end + end + `; + + const insertionIndex = podfile.indexOf(postInstallLine); + + if (insertionIndex !== -1) { + const endOfMarkerLineIndex = podfile.indexOf('\n', insertionIndex); + + if (endOfMarkerLineIndex !== -1) { + const updatedPodfileContent = + podfile.slice(0, endOfMarkerLineIndex) + + podVersionOverride + + podfile.slice(endOfMarkerLineIndex); + + await fs.writeFile( + path.join(directory, 'ios', 'Podfile'), + updatedPodfileContent + ); + } + } + + // set project deployement min version + const project = await fs.readFile( + path.join( + directory, + `ios/${config.project.name}Example.xcodeproj`, + 'project.pbxproj' + ), + 'utf8' + ); + + // match whole IPHONEOS_DEPLOYMENT_TARGET line + const deployementLineRegex = + /^(\s*)IPHONEOS_DEPLOYMENT_TARGET\s*=\s*[^;]+;$/gm; + const replacementPattern = `$1IPHONEOS_DEPLOYMENT_TARGET = ${newTargetVersion};`; + const updatedContent = project.replace( + deployementLineRegex, + replacementPattern + ); + + await fs.writeFile( + path.join( + directory, + `ios/${config.project.name}Example.xcodeproj`, + 'project.pbxproj' + ), + updatedContent + ); + } + await fs.writeFile( path.join(directory, 'android', 'gradle.properties'), gradleProperties diff --git a/packages/create-react-native-library/src/index.ts b/packages/create-react-native-library/src/index.ts index ca03b407c..1437e934a 100644 --- a/packages/create-react-native-library/src/index.ts +++ b/packages/create-react-native-library/src/index.ts @@ -21,7 +21,7 @@ import { prompt } from './utils/prompt'; import { resolveNpmPackageVersion } from './utils/resolveNpmPackageVersion'; const FALLBACK_BOB_VERSION = '0.38.3'; -const FALLBACK_NITRO_MODULES_VERSION = '0.22.1'; +const FALLBACK_NITRO_MODULES_VERSION = '0.25.2'; // eslint-disable-next-line @typescript-eslint/no-unused-expressions yargs @@ -75,9 +75,8 @@ async function create(_argv: yargs.Arguments) { assertUserInput(questions, answers); const bobVersion = await bobVersionPromise; - const nitroModulesVersion = - answers.type === 'nitro-module' + answers.type === 'nitro-module' || answers.type === 'nitro-view' ? await nitroModulesVersionPromise : undefined; diff --git a/packages/create-react-native-library/src/input.ts b/packages/create-react-native-library/src/input.ts index 23620d1a1..4051316aa 100644 --- a/packages/create-react-native-library/src/input.ts +++ b/packages/create-react-native-library/src/input.ts @@ -26,6 +26,7 @@ export type ProjectType = | 'legacy-module' | 'legacy-view' | 'nitro-module' + | 'nitro-view' | 'library'; const LANGUAGE_CHOICES: { @@ -36,7 +37,7 @@ const LANGUAGE_CHOICES: { { title: 'Kotlin & Swift', value: 'kotlin-swift', - types: ['nitro-module', 'legacy-module', 'legacy-view'], + types: ['nitro-view', 'nitro-module', 'legacy-module', 'legacy-view'], }, { title: 'Kotlin & Objective-C', @@ -101,6 +102,12 @@ const TYPE_CHOICES: { description: 'type-safe, fast integration for native APIs to JS (experimental)', }, + { + title: 'Nitro view', + value: 'nitro-view', + description: + 'integration for native views to JS using nitro for prop parsing (experimental)', + }, { title: 'Legacy Native module', value: 'legacy-module', diff --git a/packages/create-react-native-library/src/template.ts b/packages/create-react-native-library/src/template.ts index c003891c1..b70fd75b0 100644 --- a/packages/create-react-native-library/src/template.ts +++ b/packages/create-react-native-library/src/template.ts @@ -20,7 +20,7 @@ export type ModuleConfig = | 'nitro-modules' | null; -export type ViewConfig = 'paper-view' | 'fabric-view' | null; +export type ViewConfig = 'paper-view' | 'fabric-view' | 'nitro-view' | null; // Please think at least 5 times before introducing a new config key // You can just reuse the existing ones most of the time @@ -90,6 +90,7 @@ const NATIVE_FILES = { view_legacy: path.resolve(__dirname, '../templates/native-view-legacy'), view_new: path.resolve(__dirname, '../templates/native-view-new'), module_nitro: path.resolve(__dirname, '../templates/nitro-module'), + view_nitro: path.resolve(__dirname, '../templates/nitro-view'), } as const; const OBJC_FILES = { @@ -195,6 +196,8 @@ function getViewConfig(projectType: ProjectType): ViewConfig { return 'paper-view'; case 'fabric-view': return 'fabric-view'; + case 'nitro-view': + return 'nitro-view'; default: return null; } @@ -241,6 +244,11 @@ export async function applyTemplates( return; } + if (config.project.viewConfig === 'nitro-view') { + await applyTemplate(config, NATIVE_FILES['view_nitro'], folder); + return; + } + if (config.project.moduleConfig !== null) { await applyTemplate( config, diff --git a/packages/create-react-native-library/templates/common/$.github/workflows/ci.yml b/packages/create-react-native-library/templates/common/$.github/workflows/ci.yml index 3cba52f1d..9e7919727 100644 --- a/packages/create-react-native-library/templates/common/$.github/workflows/ci.yml +++ b/packages/create-react-native-library/templates/common/$.github/workflows/ci.yml @@ -61,7 +61,7 @@ jobs: - name: Setup uses: ./.github/actions/setup -<% if (project.moduleConfig === 'nitro-modules') { -%> +<% if (project.moduleConfig === 'nitro-modules' || project.viewConfig === 'nitro-view') { -%> - name: Generate nitrogen code run: yarn nitrogen @@ -122,7 +122,7 @@ jobs: - name: Setup uses: ./.github/actions/setup -<% if (project.moduleConfig === 'nitro-modules') { -%> +<% if (project.moduleConfig === 'nitro-modules' || project.viewConfig === 'nitro-view') { -%> - name: Generate nitrogen code run: yarn nitrogen diff --git a/packages/create-react-native-library/templates/common/$package.json b/packages/create-react-native-library/templates/common/$package.json index 1473eebba..42178317d 100644 --- a/packages/create-react-native-library/templates/common/$package.json +++ b/packages/create-react-native-library/templates/common/$package.json @@ -53,7 +53,7 @@ "clean": "del-cli lib", <% } -%> "prepare": "bob build", -<% if (project.moduleConfig === 'nitro-modules') { -%> +<% if (project.moduleConfig === 'nitro-modules' || project.viewConfig === 'nitro-view') { -%> "nitrogen": "nitro-codegen", <% } -%> "release": "release-it" @@ -95,14 +95,14 @@ "eslint-config-prettier": "^10.1.1", "eslint-plugin-prettier": "^5.2.3", "jest": "^29.7.0", -<% if (project.moduleConfig === 'nitro-modules') { -%> +<% if (project.moduleConfig === 'nitro-modules' || project.viewConfig === 'nitro-view') { -%> "nitro-codegen": "^<%- versions.nitroCodegen %>", <% } -%> "prettier": "^3.0.3", "react": "19.0.0", "react-native": "0.78.1", "react-native-builder-bob": "^<%- versions.bob %>", -<% if (project.moduleConfig === 'nitro-modules') { -%> +<% if (project.moduleConfig === 'nitro-modules' || project.viewConfig === 'nitro-view') { -%> "react-native-nitro-modules": "^<%- versions.nitroModules %>", <% } -%> "release-it": "^17.10.0", @@ -113,7 +113,7 @@ }, "peerDependencies": { "react": "*", -<% if (project.moduleConfig === 'nitro-modules') { -%> +<% if (project.moduleConfig === 'nitro-modules' || project.viewConfig === 'nitro-view') { -%> "react-native": "*", "react-native-nitro-modules": "^<%- versions.nitroModules %>" <% } else { -%> @@ -168,7 +168,7 @@ "source": "src", "output": "lib", "targets": [ -<% if (project.moduleConfig === "nitro-modules") { -%> +<% if (project.moduleConfig === "nitro-modules" || project.viewConfig === "nitro-view") { -%> [ "custom", { diff --git a/packages/create-react-native-library/templates/common/CONTRIBUTING.md b/packages/create-react-native-library/templates/common/CONTRIBUTING.md index fa78e872c..85cdcf56d 100644 --- a/packages/create-react-native-library/templates/common/CONTRIBUTING.md +++ b/packages/create-react-native-library/templates/common/CONTRIBUTING.md @@ -18,13 +18,14 @@ yarn ``` > Since the project relies on Yarn workspaces, you cannot use [`npm`](https://github.com/npm/cli) for development. -<% if (project.moduleConfig === 'nitro-modules') { -%> +> <% if (project.moduleConfig === 'nitro-modules' || project.viewConfig === 'nitro-view') { -%> This project uses Nitro Modules. If you're not familiar with how Nitro works, make sure to check the [Nitro Modules Docs](https://nitro.margelo.com/). You need to run [Nitrogen](https://nitro.margelo.com/docs/nitrogen) to generate the boilerplate code required for this project. The example app will not build without this step. Run **Nitrogen** in following cases: + - When you make changes to any `*.nitro.ts` files. - When running the project for the first time (since the generated files are not committed to the repository). @@ -33,6 +34,7 @@ To invoke **Nitrogen**, use the following command: ```sh yarn nitrogen ``` + <% } -%> The [example app](/example/) demonstrates usage of the library. You need to run it to test any changes you make. diff --git a/packages/create-react-native-library/templates/common/README.md b/packages/create-react-native-library/templates/common/README.md index 5b34c58f1..aacb0cf34 100644 --- a/packages/create-react-native-library/templates/common/README.md +++ b/packages/create-react-native-library/templates/common/README.md @@ -4,16 +4,20 @@ ## Installation -<% if (project.moduleConfig === 'nitro-modules') { -%> +<% if (project.moduleConfig === 'nitro-modules' || project.viewConfig === 'nitro-view') { -%> + ```sh npm install <%- project.slug %> react-native-nitro-modules > `react-native-nitro-modules` is required as this library relies on [Nitro Modules](https://nitro.margelo.com/). ``` + <% } else { -%> + ```sh npm install <%- project.slug %> ``` + <% } -%> ## Usage @@ -28,7 +32,7 @@ import { <%- project.name -%>View } from "<%- project.slug -%>"; <<%- project.name -%>View color="tomato" /> ``` -<% } else if (project.moduleConfig === 'nitro-modules' || project.moduleConfig === 'turbo-modules') { -%> +<% } else if (project.moduleConfig === 'nitro-modules' || project.viewConfig === 'nitro-view' || project.moduleConfig === 'turbo-modules') { -%> ```js import { multiply } from '<%- project.slug -%>'; diff --git a/packages/create-react-native-library/templates/native-common/android/build.gradle b/packages/create-react-native-library/templates/native-common/android/build.gradle index d7925a44d..fa3912ca0 100644 --- a/packages/create-react-native-library/templates/native-common/android/build.gradle +++ b/packages/create-react-native-library/templates/native-common/android/build.gradle @@ -15,7 +15,7 @@ buildscript { } } -<% if (project.cpp || project.moduleConfig === 'nitro-modules') { -%> +<% if (project.cpp || project.moduleConfig === 'nitro-modules' || project.viewConfig === 'nitro-view') { -%> def reactNativeArchitectures() { def value = rootProject.getProperties().get("reactNativeArchitectures") return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"] @@ -24,7 +24,7 @@ def reactNativeArchitectures() { apply plugin: "com.android.library" apply plugin: "kotlin-android" -<% if (project.moduleConfig === 'nitro-modules') { -%> +<% if (project.moduleConfig === 'nitro-modules' || project.viewConfig === 'nitro-view') { -%> apply from: '../nitrogen/generated/android/<%- project.package_cpp -%>+autolinking.gradle' <% } -%> @@ -47,7 +47,7 @@ def supportsNamespace() { android { if (supportsNamespace()) { -<% if (project.moduleConfig === 'nitro-modules') { -%> +<% if (project.moduleConfig === 'nitro-modules' || project.viewConfig === 'nitro-view') { -%> namespace "com.margelo.nitro.<%- project.package -%>" <% } else { -%> namespace "com.<%- project.package -%>" @@ -68,7 +68,7 @@ android { defaultConfig { minSdkVersion getExtOrIntegerDefault("minSdkVersion") targetSdkVersion getExtOrIntegerDefault("targetSdkVersion") -<% if (project.cpp || project.moduleConfig === 'nitro-modules') { -%> +<% if (project.cpp || project.moduleConfig === 'nitro-modules' || project.viewConfig === 'nitro-view') { -%> externalNativeBuild { cmake { @@ -88,7 +88,7 @@ android { } <% } -%> } -<% if (project.cpp || project.moduleConfig === 'nitro-modules') { -%> +<% if (project.cpp || project.moduleConfig === 'nitro-modules' || project.viewConfig === 'nitro-view') { -%> externalNativeBuild { cmake { @@ -96,7 +96,7 @@ android { } } <% } -%> -<% if (project.moduleConfig === 'nitro-modules') { -%> +<% if (project.moduleConfig === 'nitro-modules' || project.viewConfig === 'nitro-view') { -%> packagingOptions { excludes = [ @@ -123,7 +123,7 @@ android { buildFeatures { buildConfig true -<% if (project.moduleConfig === 'nitro-modules') { -%> +<% if (project.moduleConfig === 'nitro-modules' || project.viewConfig === 'nitro-view') { -%> prefab true <% } -%> } @@ -166,7 +166,7 @@ def kotlin_version = getExtOrDefault("kotlinVersion") dependencies { implementation "com.facebook.react:react-android" implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" -<% if (project.moduleConfig === 'nitro-modules') { -%> +<% if (project.moduleConfig === 'nitro-modules' || project.viewConfig === 'nitro-view') { -%> implementation project(":react-native-nitro-modules") <% } -%> } diff --git a/packages/create-react-native-library/templates/native-common/{%- project.name %}.podspec b/packages/create-react-native-library/templates/native-common/{%- project.name %}.podspec index ec8f8785c..b71f7c629 100644 --- a/packages/create-react-native-library/templates/native-common/{%- project.name %}.podspec +++ b/packages/create-react-native-library/templates/native-common/{%- project.name %}.podspec @@ -23,7 +23,7 @@ Pod::Spec.new do |s| <% } else { -%> s.source_files = "ios/**/*.{h,m,mm}" <% } -%> -<% if (project.moduleConfig === "nitro-modules") { -%> +<% if (project.moduleConfig === "nitro-modules" || project.viewConfig === "nitro-view") { -%> load 'nitrogen/generated/ios/<%- project.name -%>+autolinking.rb' add_nitrogen_files(s) diff --git a/packages/create-react-native-library/templates/nitro-view/android/CMakeLists.txt b/packages/create-react-native-library/templates/nitro-view/android/CMakeLists.txt new file mode 100644 index 000000000..1fa9ed39d --- /dev/null +++ b/packages/create-react-native-library/templates/nitro-view/android/CMakeLists.txt @@ -0,0 +1,24 @@ +project(<%- project.package_cpp -%>) +cmake_minimum_required(VERSION 3.9.0) + +set(PACKAGE_NAME <%- project.package_cpp -%>) +set(CMAKE_VERBOSE_MAKEFILE ON) +set(CMAKE_CXX_STANDARD 20) + +# Define C++ library and add all sources +add_library(${PACKAGE_NAME} SHARED src/main/cpp/cpp-adapter.cpp) + +# Add Nitrogen specs :) +include(${CMAKE_SOURCE_DIR}/../nitrogen/generated/android/<%- project.package_cpp -%>+autolinking.cmake) + +# Set up local includes +include_directories("src/main/cpp" "../cpp") + +find_library(LOG_LIB log) + +# Link all libraries together +target_link_libraries( + ${PACKAGE_NAME} + ${LOG_LIB} + android # <-- Android core +) diff --git a/packages/create-react-native-library/templates/nitro-view/android/src/main/cpp/cpp-adapter.cpp b/packages/create-react-native-library/templates/nitro-view/android/src/main/cpp/cpp-adapter.cpp new file mode 100644 index 000000000..8e1f6123b --- /dev/null +++ b/packages/create-react-native-library/templates/nitro-view/android/src/main/cpp/cpp-adapter.cpp @@ -0,0 +1,6 @@ +#include +#include "<%- project.package_cpp -%>OnLoad.hpp" + +JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) { + return margelo::nitro::<%- project.package_cpp -%>::initialize(vm); +} diff --git a/packages/create-react-native-library/templates/nitro-view/android/src/main/java/com/margelo/nitro/{%- project.package_dir %}/{%- project.name %}.kt b/packages/create-react-native-library/templates/nitro-view/android/src/main/java/com/margelo/nitro/{%- project.package_dir %}/{%- project.name %}.kt new file mode 100644 index 000000000..9634f8d57 --- /dev/null +++ b/packages/create-react-native-library/templates/nitro-view/android/src/main/java/com/margelo/nitro/{%- project.package_dir %}/{%- project.name %}.kt @@ -0,0 +1,23 @@ +package com.margelo.nitro.<%- project.package %> + +import android.view.View +import com.facebook.proguard.annotations.DoNotStrip +import com.facebook.react.uimanager.ThemedReactContext +import androidx.core.graphics.toColorInt + +@DoNotStrip +class Hybrid<%- project.name %>(val context: ThemedReactContext) : Hybrid<%- project.name %>Spec() { + + // View + override val view: View = View(context) + + // Props + private var _color = "#000" + override var color: String + get() = _color + set(value) { + _color = value + val color = value.toColorInt() + view.setBackgroundColor(color) + } +} diff --git a/packages/create-react-native-library/templates/nitro-view/android/src/main/java/com/{%- project.package_dir %}/{%- project.name %}Package.kt b/packages/create-react-native-library/templates/nitro-view/android/src/main/java/com/{%- project.package_dir %}/{%- project.name %}Package.kt new file mode 100644 index 000000000..c2ceba5af --- /dev/null +++ b/packages/create-react-native-library/templates/nitro-view/android/src/main/java/com/{%- project.package_dir %}/{%- project.name %}Package.kt @@ -0,0 +1,28 @@ +package com.<%- project.package %> + +import com.facebook.react.TurboReactPackage +import com.facebook.react.bridge.NativeModule +import com.facebook.react.bridge.ReactApplicationContext +import com.facebook.react.module.model.ReactModuleInfoProvider +import com.facebook.react.uimanager.ViewManager +import com.margelo.nitro.<%- project.package_cpp -%>.views.Hybrid<%- project.name -%>Manager + +class <%- project.name -%>Package : TurboReactPackage() { + override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? { + return null + } + + override fun getReactModuleInfoProvider(): ReactModuleInfoProvider { + return ReactModuleInfoProvider { HashMap() } + } + + override fun createViewManagers(reactContext: ReactApplicationContext): List> { + return listOf(Hybrid<%- project.name -%>Manager()) + } + + companion object { + init { + System.loadLibrary("<%- project.package_cpp -%>") + } + } +} diff --git a/packages/create-react-native-library/templates/nitro-view/ios/{%- project.name %}.swift b/packages/create-react-native-library/templates/nitro-view/ios/{%- project.name %}.swift new file mode 100644 index 000000000..0e4c8ef3c --- /dev/null +++ b/packages/create-react-native-library/templates/nitro-view/ios/{%- project.name %}.swift @@ -0,0 +1,28 @@ +class Hybrid<%- project.name -%> : Hybrid<%- project.name -%>Spec { + + // UIView + var view: UIView = UIView() + + // props + var color: String = "#000" { + didSet { + view.backgroundColor = hexStringToUIColor(hexColor: color) + } + } + + func hexStringToUIColor(hexColor: String) -> UIColor { + let stringScanner = Scanner(string: hexColor) + + if(hexColor.hasPrefix("#")) { + stringScanner.scanLocation = 1 + } + var color: UInt32 = 0 + stringScanner.scanHexInt32(&color) + + let r = CGFloat(Int(color >> 16) & 0x000000FF) + let g = CGFloat(Int(color >> 8) & 0x000000FF) + let b = CGFloat(Int(color) & 0x000000FF) + + return UIColor(red: r / 255.0, green: g / 255.0, blue: b / 255.0, alpha: 1) + } +} diff --git a/packages/create-react-native-library/templates/nitro-view/nitro.json b/packages/create-react-native-library/templates/nitro-view/nitro.json new file mode 100644 index 000000000..78941a518 --- /dev/null +++ b/packages/create-react-native-library/templates/nitro-view/nitro.json @@ -0,0 +1,17 @@ +{ + "cxxNamespace": ["<%- project.package_cpp -%>"], + "ios": { + "iosModuleName": "<%- project.name -%>" + }, + "android": { + "androidNamespace": <%- JSON.stringify(project.package.split('.')) -%>, + "androidCxxLibName": "<%- project.package_cpp -%>" + }, + "autolinking": { + "<%- project.name -%>": { + "swift": "Hybrid<%- project.name -%>", + "kotlin": "Hybrid<%- project.name -%>" + } + }, + "ignorePaths": ["node_modules"] +} diff --git a/packages/create-react-native-library/templates/nitro-view/src/index.tsx b/packages/create-react-native-library/templates/nitro-view/src/index.tsx new file mode 100644 index 000000000..2f1c95268 --- /dev/null +++ b/packages/create-react-native-library/templates/nitro-view/src/index.tsx @@ -0,0 +1,11 @@ +import { getHostComponent } from 'react-native-nitro-modules'; +const <%- project.name %>Config = require('../nitrogen/generated/shared/json/<%- project.name %>Config.json'); +import type { + <%- project.name %>Methods, + <%- project.name %>Props, +} from './<%- project.name %>.nitro'; + +export const <%- project.name %>View = getHostComponent< + <%- project.name %>Props, + <%- project.name %>Methods +>('<%- project.name %>', () => <%- project.name %>Config); diff --git a/packages/create-react-native-library/templates/nitro-view/src/{%- project.name %}.nitro.ts b/packages/create-react-native-library/templates/nitro-view/src/{%- project.name %}.nitro.ts new file mode 100644 index 000000000..194477f98 --- /dev/null +++ b/packages/create-react-native-library/templates/nitro-view/src/{%- project.name %}.nitro.ts @@ -0,0 +1,15 @@ +import type { + HybridView, + HybridViewMethods, + HybridViewProps, +} from 'react-native-nitro-modules'; + +export interface <%- project.name %>Props extends HybridViewProps { + color: string; +} +export interface <%- project.name %>Methods extends HybridViewMethods {} + +export type <%- project.name %> = HybridView< + <%- project.name %>Props, + <%- project.name %>Methods +>;