Skip to content

feat: option to add nitro views #805

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 18 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/workflows/build-templates.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ jobs:
language: kotlin-objc
- name: nitro-module
language: kotlin-swift
- name: nitro-view
language: kotlin-swift
include:
- os: ubuntu-latest
type:
Expand Down Expand Up @@ -140,6 +142,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
Expand Down
2 changes: 1 addition & 1 deletion packages/create-react-native-library/src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export const FALLBACK_BOB_VERSION = '0.40.8';
export const FALLBACK_NITRO_MODULES_VERSION = '0.25.2';
export const FALLBACK_NITRO_MODULES_VERSION = '0.26.2';
export const SUPPORTED_REACT_NATIVE_VERSION = '0.79.2';
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,10 @@ export default async function generateExampleApp({
'react-native-monorepo-config': `^0.1.9`,
};

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.nitro || 'latest'}`,
};
Expand Down
3 changes: 1 addition & 2 deletions packages/create-react-native-library/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,8 @@ async function create(_argv: Args) {
});

const bobVersion = await bobVersionPromise;

const nitroModulesVersion =
answers.type === 'nitro-module'
answers.type === 'nitro-module' || answers.type === 'nitro-view'
? await nitroModulesVersionPromise
: undefined;

Expand Down
9 changes: 8 additions & 1 deletion packages/create-react-native-library/src/input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export type ProjectType =
| 'turbo-module'
| 'fabric-view'
| 'nitro-module'
| 'nitro-view'
| 'library';

const LANGUAGE_CHOICES: {
Expand All @@ -24,7 +25,7 @@ const LANGUAGE_CHOICES: {
{
title: 'Kotlin & Swift',
value: 'kotlin-swift',
types: ['nitro-module'],
types: ['nitro-module', 'nitro-view'],
},
{
title: 'Kotlin & Objective-C',
Expand Down Expand Up @@ -84,6 +85,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: 'JavaScript library',
value: 'library',
Expand Down
12 changes: 11 additions & 1 deletion packages/create-react-native-library/src/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,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
Expand Down Expand Up @@ -76,6 +76,7 @@ const NATIVE_FILES = {
module_new: path.resolve(__dirname, '../templates/native-library-new'),
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 = {
Expand Down Expand Up @@ -155,6 +156,7 @@ function getModuleConfig(projectType: ProjectType): ModuleConfig {
return 'turbo-modules';
case 'fabric-view':
case 'library':
case 'nitro-view':
return null;
}
}
Expand All @@ -163,9 +165,12 @@ function getViewConfig(projectType: ProjectType): ViewConfig {
switch (projectType) {
case 'fabric-view':
return 'fabric-view';
case 'nitro-view':
return 'nitro-view';
case 'nitro-module':
case 'turbo-module':
case 'library':
default:
return null;
}
}
Expand Down Expand Up @@ -208,6 +213,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, NATIVE_FILES[`module_new`], folder);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -123,7 +123,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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,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 --only-version"
Expand Down Expand Up @@ -91,14 +91,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.nitro %>",
<% } -%>
"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.nitro %>",
<% } -%>
"release-it": "^17.10.0",
Expand All @@ -109,7 +109,7 @@
},
"peerDependencies": {
"react": "*",
<% if (project.moduleConfig === 'nitro-modules') { -%>
<% if (project.moduleConfig === 'nitro-modules' || project.viewConfig === 'nitro-view') { -%>
"react-native": "*",
"react-native-nitro-modules": "^<%- versions.nitro %>"
<% } else { -%>
Expand Down Expand Up @@ -164,7 +164,7 @@
"source": "src",
"output": "lib",
"targets": [
<% if (project.moduleConfig === "nitro-modules") { -%>
<% if (project.moduleConfig === "nitro-modules" || project.viewConfig === "nitro-view") { -%>
[
"custom",
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ 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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 -%>';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ buildscript {
}
}

<% if (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"]
Expand All @@ -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'
<% } -%>

Expand All @@ -35,7 +35,7 @@ def getExtOrIntegerDefault(name) {
}

android {
<% 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 -%>"
Expand All @@ -46,7 +46,7 @@ android {
defaultConfig {
minSdkVersion getExtOrIntegerDefault("minSdkVersion")
targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
<% if (project.moduleConfig === 'nitro-modules') { -%>
<% if (project.cpp || project.moduleConfig === 'nitro-modules' || project.viewConfig === 'nitro-view') { -%>

externalNativeBuild {
cmake {
Expand All @@ -66,15 +66,15 @@ android {
}
<% } -%>
}
<% if (project.moduleConfig === 'nitro-modules') { -%>
<% if (project.cpp || project.moduleConfig === 'nitro-modules' || project.viewConfig === 'nitro-view') { -%>

externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
<% } -%>
<% if (project.moduleConfig === 'nitro-modules') { -%>
<% if (project.moduleConfig === 'nitro-modules' || project.viewConfig === 'nitro-view') { -%>

packagingOptions {
excludes = [
Expand All @@ -100,7 +100,7 @@ android {

buildFeatures {
buildConfig true
<% if (project.moduleConfig === 'nitro-modules') { -%>
<% if (project.moduleConfig === 'nitro-modules' || project.viewConfig === 'nitro-view') { -%>
prefab true
<% } -%>
}
Expand Down Expand Up @@ -140,7 +140,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")
<% } -%>
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Pod::Spec.new do |s|
s.platforms = { :ios => min_ios_version_supported }
s.source = { :git => "<%- repo -%>.git", :tag => "#{s.version}" }

<% if (project.moduleConfig !== "nitro-modules") { -%>
<% if (project.moduleConfig !== "nitro-modules" || project.viewConfig === "nitro-view") { -%>
<% if (project.swift) { -%>
s.source_files = "ios/**/*.{h,m,mm,swift}"
<% } else { -%>
Expand All @@ -22,7 +22,7 @@ Pod::Spec.new do |s|
<% } -%>
<% } -%>

<% if (project.moduleConfig === "nitro-modules") { -%>
<% if (project.moduleConfig === "nitro-modules" || project.viewConfig === "nitro-view") { -%>
s.source_files = [
"ios/**/*.{swift}",
"ios/**/*.{m,mm}",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.<%- project.package %>
package com.margelo.nitro.<%- project.package %>

import com.facebook.react.TurboReactPackage
import com.facebook.react.bridge.NativeModule
Expand Down
Original file line number Diff line number Diff line change
@@ -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
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#include <jni.h>
#include "<%- project.package_cpp -%>OnLoad.hpp"

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) {
return margelo::nitro::<%- project.package_cpp -%>::initialize(vm);
}
Original file line number Diff line number Diff line change
@@ -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)
}
}
Loading
Loading