From b0d131e81e371aa69e018171de11970cbee23fb2 Mon Sep 17 00:00:00 2001 From: Hur Ali Date: Fri, 7 Nov 2025 16:47:23 +0500 Subject: [PATCH 1/9] feat: configure reacthost options --- .../callstack/reactnativebrownfield/ReactNativeBrownfield.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/android/src/main/java/com/callstack/reactnativebrownfield/ReactNativeBrownfield.kt b/android/src/main/java/com/callstack/reactnativebrownfield/ReactNativeBrownfield.kt index 5b08f883..0f4bcac1 100644 --- a/android/src/main/java/com/callstack/reactnativebrownfield/ReactNativeBrownfield.kt +++ b/android/src/main/java/com/callstack/reactnativebrownfield/ReactNativeBrownfield.kt @@ -12,6 +12,7 @@ import com.facebook.react.ReactHost import com.facebook.react.ReactInstanceEventListener import com.facebook.react.ReactPackage import com.facebook.react.bridge.ReactContext +import com.facebook.react.common.build.ReactBuildConfig import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost import com.facebook.react.soloader.OpenSourceMergedSoMapping @@ -75,7 +76,8 @@ class ReactNativeBrownfield private constructor(val reactHost: ReactHost) { context = application, packageList = (options["packages"] as? List<*> ?: emptyList()) .filterIsInstance(), - jsRuntimeFactory = null + jsMainModulePath = options["mainModuleName"] as? String ?: "index", + useDevSupport = options["useDevSupport"] as? Boolean ?: ReactBuildConfig.DEBUG ) } From 0d544148a068c7fd0467cf07006f05d00a1c431c Mon Sep 17 00:00:00 2001 From: Hur Ali Date: Fri, 7 Nov 2025 16:56:23 +0500 Subject: [PATCH 2/9] docs: update --- docs/JAVA.md | 2 +- docs/KOTLIN.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/JAVA.md b/docs/JAVA.md index 67367522..92c7af69 100644 --- a/docs/JAVA.md +++ b/docs/JAVA.md @@ -73,7 +73,7 @@ Params: > * - Those fields aren't itself required, but at least one of them is. See examples below. Available options: -- `useDeveloperSupport`: `Boolean` - Flag to use dev support. +- `useDevSupport`: `Boolean` - Flag to use dev support. - `packages`: `List` - List of your React Native Native modules. - `mainModuleName`: `String` - Path to react native entry file. diff --git a/docs/KOTLIN.md b/docs/KOTLIN.md index d30eec9e..c49d43b4 100644 --- a/docs/KOTLIN.md +++ b/docs/KOTLIN.md @@ -56,7 +56,7 @@ Params: > * - Those fields aren't itself required, but at least one of them is. See examples below. Available options: -- `useDeveloperSupport`: `Boolean` - Flag to use dev support. +- `useDevSupport`: `Boolean` - Flag to use dev support. - `packages`: `List` - List of your React Native Native modules. - `mainModuleName`: `String` - Path to react native entry file. From cd4191110f6cca6c9e026a62f2b5f66a9c610da9 Mon Sep 17 00:00:00 2001 From: artus9033 Date: Fri, 7 Nov 2025 12:55:44 +0100 Subject: [PATCH 3/9] chore: rename ReactNativeFragmentPropsNames to ReactNativeFragmentArgNames, use them in example app --- .../reactnativebrownfield/ReactNativeFragment.kt | 10 +++++----- ...ialPropsNames.kt => ReactNativeFragmentArgNames.kt} | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) rename android/src/main/java/com/callstack/reactnativebrownfield/constants/{ReactNativeInitialPropsNames.kt => ReactNativeFragmentArgNames.kt} (89%) diff --git a/android/src/main/java/com/callstack/reactnativebrownfield/ReactNativeFragment.kt b/android/src/main/java/com/callstack/reactnativebrownfield/ReactNativeFragment.kt index 0942da92..5efe9fd9 100644 --- a/android/src/main/java/com/callstack/reactnativebrownfield/ReactNativeFragment.kt +++ b/android/src/main/java/com/callstack/reactnativebrownfield/ReactNativeFragment.kt @@ -5,7 +5,7 @@ import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import com.callstack.reactnativebrownfield.constants.ReactNativeInitialPropsNames +import com.callstack.reactnativebrownfield.constants.ReactNativeFragmentArgNames import com.facebook.react.ReactFragment import com.facebook.react.ReactHost import com.facebook.react.bridge.Callback @@ -36,13 +36,13 @@ class ReactNativeFragment : ReactFragment(), PermissionAwareActivity { ) } - moduleName = arguments?.getString(ReactNativeInitialPropsNames.ARG_MODULE_NAME)!! + moduleName = arguments?.getString(ReactNativeFragmentArgNames.ARG_MODULE_NAME)!! this.reactDelegate = ReactDelegateWrapper( activity, this.reactHost, moduleName, - arguments?.getBundle(ReactNativeInitialPropsNames.ARG_LAUNCH_OPTIONS) + arguments?.getBundle(ReactNativeFragmentArgNames.ARG_LAUNCH_OPTIONS) ) } @@ -113,9 +113,9 @@ class ReactNativeFragment : ReactFragment(), PermissionAwareActivity { ): ReactNativeFragment { val fragment = ReactNativeFragment() val args = Bundle() - args.putString(ReactNativeInitialPropsNames.ARG_MODULE_NAME, moduleName) + args.putString(ReactNativeFragmentArgNames.ARG_MODULE_NAME, moduleName) if (initialProps != null) { - args.putBundle(ReactNativeInitialPropsNames.ARG_LAUNCH_OPTIONS, initialProps) + args.putBundle(ReactNativeFragmentArgNames.ARG_LAUNCH_OPTIONS, initialProps) } fragment.arguments = args return fragment diff --git a/android/src/main/java/com/callstack/reactnativebrownfield/constants/ReactNativeInitialPropsNames.kt b/android/src/main/java/com/callstack/reactnativebrownfield/constants/ReactNativeFragmentArgNames.kt similarity index 89% rename from android/src/main/java/com/callstack/reactnativebrownfield/constants/ReactNativeInitialPropsNames.kt rename to android/src/main/java/com/callstack/reactnativebrownfield/constants/ReactNativeFragmentArgNames.kt index e5c36a13..7a63bcc9 100644 --- a/android/src/main/java/com/callstack/reactnativebrownfield/constants/ReactNativeInitialPropsNames.kt +++ b/android/src/main/java/com/callstack/reactnativebrownfield/constants/ReactNativeFragmentArgNames.kt @@ -5,7 +5,7 @@ import com.facebook.react.ReactFragment /** * Convenience export of arguments that can be used */ -class ReactNativeInitialPropsNames private constructor() : +class ReactNativeFragmentArgNames private constructor() : ReactFragment() // subclass to gain access to protected constants { companion object { From 51f889f714d0dc651a6ecc7c471ac08ee0ee148a Mon Sep 17 00:00:00 2001 From: artus9033 Date: Fri, 7 Nov 2025 13:10:37 +0100 Subject: [PATCH 4/9] docs: updated documentation --- README.md | 22 ++++++++-------- docs/JAVA.md | 56 ++++++++++++++++++++-------------------- docs/KOTLIN.md | 70 ++++++++++++++++++++++++++++++-------------------- 3 files changed, 80 insertions(+), 68 deletions(-) diff --git a/README.md b/README.md index f9517d16..8decdc78 100644 --- a/README.md +++ b/README.md @@ -51,16 +51,16 @@ npm install @callstack/react-native-brownfield First, we need to package our React Native app as an XCFramework or Fat-AAR. -#### With RNEF +#### With Rock -Follow [Integrating with Native Apps](https://www.rnef.dev/docs/brownfield/intro) steps in RNEF docs and run: +Follow [Integrating with Native Apps](https://www.rockjs.dev/docs/brownfield/intro) steps in Rock docs and run: -- `rnef package:ios` for iOS -- `rnef package:aar` for Android +- `rock package:ios` for iOS +- `rock package:aar` for Android #### With custom scripts -Instead of using RNEF, you can create your own custom packaging scripts. Here are base versions for iOS and Android that you'll need to adjust for your project-specific setup: +Instead of using Rock, you can create your own custom packaging scripts. Here are base versions for iOS and Android that you'll need to adjust for your project-specific setup: - [Example iOS script](https://github.com/callstackincubator/modern-brownfield-ref/blob/main/scripts/build-xcframework.sh) - [Example Android script](https://github.com/callstackincubator/modern-brownfield-ref/blob/main/scripts/build-aar.sh) @@ -121,17 +121,13 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment -import com.callstack.rnbrownfield.RNViewFactory // exposed by RN app framework class RNAppFragment : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?, - ): View? = - this.context?.let { - RNViewFactory.createFrameLayout(it) - } + ): View? = ReactNativeBrownfield.shared.createView(activity, "BrownFieldTest") } ``` @@ -166,7 +162,9 @@ class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - ReactNativeHostManager.shared.initialize(this.application) + ReactNativeHostManager.shared.initialize(this.application) { + println("JS bundle loaded") + } showRNAppBtn = findViewById(R.id.show_rn_app_btn) showRNAppBtn.setOnClickListener { @@ -228,7 +226,7 @@ Thanks goes to these wonderful people ([emoji key](https://github.com/kentcdodds | [Michał Chudziak
Michał Chudziak](https://twitter.com/michalchudziak)
[💻](https://github.com/callstack/react-native-brownfield/commits?author=michalchudziak "Code") [📖](https://github.com/callstack/react-native-brownfield/commits?author=michalchudziak "Documentation") [🤔](#ideas-michalchudziak "Ideas, Planning, & Feedback") | [Piotr Drapich
Piotr Drapich](https://twitter.com/dratwas)
[💻](https://github.com/callstack/react-native-brownfield/commits?author=dratwas "Code") [🤔](#ideas-dratwas "Ideas, Planning, & Feedback") | -| :---: | :---: | +| :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | diff --git a/docs/JAVA.md b/docs/JAVA.md index 92c7af69..7754f1c3 100644 --- a/docs/JAVA.md +++ b/docs/JAVA.md @@ -25,13 +25,13 @@ With react-native >= 0.80.0, an auto-generated file was added which is responsib you will have this file `ReactNativeApplicationEntryPoint` available. If you're consuming this library in a RN android library which is backed by `com.callstack.react:brownfield-gradle-plugin`, then this file will also be available. -Below is the code you need to add before you call `RNBrownfield.initialize`: +Below is the code you need to add before you call `ReactNativeBrownfield.initialize`: ```java import com.facebook.react.ReactNativeApplicationEntryPoint.loadReactNative loadReactNative(application); -RNBrownfield.initialize(application, packages); +ReactNativeBrownfield.initialize(application, packages); ```
@@ -62,15 +62,15 @@ A function used to initialize a React Native Brownfield singleton. Keep in mind Params: -| Param | Required | Type | Description | -| ----------------------- | -------- | -------------------- | --------------------------------------------------------- | -| application | Yes | `Application` | Main application. | -| rnHost | No* | `ReactNativeHost` | An instance of [ReactNativeHost](https://bit.ly/2ZnwgnA). | -| packages | No* | `List` | List of your React Native Native modules. | -| options | No* | `HashMap` | Map of initial options. __Options listed below.__ | -| onJSBundleLoaded | No* | `OnJSBundleLoaded` | Callback invoked after JS bundle is fully loaded. | +| Param | Required | Type | Description | +| ---------------- | ------------ | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| application | Yes | `Application` | Main application. | +| reactHost | Exclusively* | `ReactHost` | An instance of [ReactHost](https://github.com/facebook/react-native/blob/main/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactHost.kt). | +| packages | Exclusively* | `List` | List of your React Native Native modules. | +| options | Exclusively* | `HashMap` | Map of initial options. __Options listed below.__ | +| onJSBundleLoaded | Exclusively* | `OnJSBundleLoaded` | Callback invoked after JS bundle is fully loaded. | -> * - Those fields aren't itself required, but at least one of them is. See examples below. +> * - From the marked fields, exactly one must be specified, excluding the others. See examples below. Available options: - `useDevSupport`: `Boolean` - Flag to use dev support. @@ -103,7 +103,7 @@ private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { ReactNativeBrownfield.initialize(this, mReactNativeHost); -OR +// OR ReactNativeBrownfield.initialize(this, mReactNativeHost, initialized -> { // JS bundle loaded @@ -115,7 +115,7 @@ List packages = new PackageList(this).getPackages(); ReactNativeBrownfield.initialize(this, packages); -OR +// OR ReactNativeBrownfield.initialize(this, packages, initialized -> { // JS bundle loaded @@ -130,7 +130,7 @@ options.put("mainModuleName", "example/index"); ReactNativeBrownfield.initialize(this, options); -OR +// OR ReactNativeBrownfield.initialize(this, options, initialized -> { // JS bundle loaded @@ -153,9 +153,9 @@ ReactNativeBrownfield.getShared() **Properties:** -| Property | Type | Default | Description | -| --------------- | --------------- | -------------- | --------------------------------------------------------- | -| reactNativeHost | `ReactNativeHost` | null | An instance of [ReactNativeHost](https://bit.ly/2ZnwgnA). | +| Property | Type | Default | Description | +| --------- | ----------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| reactHost | `ReactHost` | null | An instance of [ReactHost](https://github.com/facebook/react-native/blob/main/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactHost.kt). | --- @@ -163,16 +163,16 @@ ReactNativeBrownfield.getShared() `createView` -Creates a React Native view with a given module name. It automatically uses an instance of React Native created in `startReactNative` method. This is useful when embedding React Native views directly in your native layouts. +Creates a React Native view with a given module name. It automatically uses an instance of React Native created in `initialize` method. This is useful when embedding React Native views directly in your native layouts. Params: -| Param | Required | Type | Description | -| -------------- | -------- | ------------------- | ----------------------------------------------------------- | -| context | Yes | `Context` | Android context to create the view | -| activity | No | `FragmentActivity` | Activity hosting the view, used for lifecycle management | -| moduleName | Yes | `String` | Name of React Native component registered to `AppRegistry` | -| launchOptions | No | `Bundle` | Initial properties to be passed to React Native component | +| Param | Required | Type | Description | +| ------------- | -------- | ------------------ | ---------------------------------------------------------- | +| context | Yes | `Context` | Android context to create the view | +| activity | No | `FragmentActivity` | Activity hosting the view, used for lifecycle management | +| moduleName | Yes | `String` | Name of React Native component registered to `AppRegistry` | +| launchOptions | No | `Bundle` | Initial properties to be passed to React Native component | Returns: `FrameLayout` - A view containing the React Native component. @@ -193,7 +193,7 @@ container.addView(reactView); #### `ReactNativeFragment` -An fragment rendering `ReactRootView` with a given module name. It automatically uses an instance of a React Native created in `startReactNative` method. It works well with exposed JavaScript module. All the lifecycles are proxied to `ReactInstanceManager`. It's the simplest way to embed React Native into your navigation stack. +An fragment rendering `ReactRootView` with a given module name. It automatically uses an instance of a React Native created in `initialize` method. It works well with exposed JavaScript module. All the lifecycles are proxied to `ReactInstanceManager`. It's the simplest way to embed React Native into your navigation stack. ```java import com.callstack.reactnativebrownfield.ReactNativeFragment; @@ -209,10 +209,10 @@ Creates a Fragment with `ReactNativeActivity`, you can use it as a parameter in Params: -| Param | Required | Type | Description | -| ----------------------- | -------- | ------------------------------------------- | ----------------------------------------------------------- | -| moduleName | Yes | `String` | Name of React Native component registered to `AppRegistry`. | -| initialProps | No | `Bundle` \|\| `HashMap` \|\| `ReadableMap` | Initial properties to be passed to React Native component. | +| Param | Required | Type | Description | +| ------------ | -------- | ----------------------------------------------------- | ----------------------------------------------------------- | +| moduleName | Yes | `String` | Name of React Native component registered to `AppRegistry`. | +| initialProps | No | `Bundle` \|\| `HashMap` \|\| `ReadableMap` | Initial properties to be passed to React Native component. | Examples: diff --git a/docs/KOTLIN.md b/docs/KOTLIN.md index c49d43b4..3dd8ecb1 100644 --- a/docs/KOTLIN.md +++ b/docs/KOTLIN.md @@ -8,13 +8,13 @@ With react-native >= 0.80.0, an auto-generated file was added which is responsib you will have this file `ReactNativeApplicationEntryPoint` available. If you're consuming this library in a RN android library which is backed by `com.callstack.react:brownfield-gradle-plugin`, then this file will also be available. -Below is the code you need to add before you call `RNBrownfield.initialize`: +Below is the code you need to add before you call `ReactNativeBrownfield.initialize`: ```kt import com.facebook.react.ReactNativeApplicationEntryPoint.loadReactNative loadReactNative(application) -RNBrownfield.initialize(application, packages) +ReactNativeBrownfield.initialize(application, packages) ```
@@ -45,15 +45,15 @@ A function used to initialize a React Native Brownfield singleton. Keep in mind Params: -| Param | Required | Type | Description | -| ----------------------- | -------- | -------------------- | --------------------------------------------------------- | -| application | Yes | `Application` | Main application. | -| rnHost | No* | `ReactNativeHost` | An instance of [ReactNativeHost](https://bit.ly/2ZnwgnA). | -| packages | No* | `List` | List of your React Native Native modules. | -| options | No* | `HashMap` | Map of initial options. __Options listed below.__ | -| onJSBundleLoaded | No* | `OnJSBundleLoaded` | Callback invoked after JS bundle is fully loaded. | +| Param | Required | Type | Description | +| ---------------- | ------------ | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| application | Yes | `Application` | Main application. | +| reactHost | Exclusively* | `ReactHost` | An instance of [ReactHost](https://github.com/facebook/react-native/blob/main/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactHost.kt). | +| packages | Exclusively* | `List` | List of your React Native Native modules. | +| options | Exclusively* | `HashMap` | Map of initial options. __Options listed below.__ | +| onJSBundleLoaded | Exclusively* | `OnJSBundleLoaded` | Callback invoked after JS bundle is fully loaded. | -> * - Those fields aren't itself required, but at least one of them is. See examples below. +> `*` - From the marked fields, exactly one must be specified, excluding the others. See examples below. Available options: - `useDevSupport`: `Boolean` - Flag to use dev support. @@ -81,7 +81,7 @@ val mReactNativeHost = object : ReactNativeHost(application) { ReactNativeBrownfield.initialize(this, mReactNativeHost) -OR +// OR ReactNativeBrownfield.initialize(this, mReactNativeHost) { // onJSBundleLoaded @@ -93,7 +93,7 @@ val packages = PackageList(this).getPackages() ReactNativeBrownfield.initialize(this, packages) -OR +// OR ReactNativeBrownfield.initialize(this, packages) { // onJSBundleLoaded @@ -109,7 +109,7 @@ val options = hashMapOf( ReactNativeBrownfield.initialize(this, options) -OR +// OR ReactNativeBrownfield.initialize(this, options) { // onJSBundleLoaded @@ -132,9 +132,9 @@ ReactNativeBrownfield.shared **Properties:** -| Property | Type | Default | Description | -| --------------- | --------------- | -------------- | --------------------------------------------------------- | -| reactNativeHost | `ReactNativeHost` | null | An instance of [ReactNativeHost](https://bit.ly/2ZnwgnA). | +| Property | Type | Default | Description | +| --------- | ----------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| reactHost | `ReactHost` | null | An instance of [ReactHost](https://github.com/facebook/react-native/blob/main/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactHost.kt). | --- @@ -142,16 +142,16 @@ ReactNativeBrownfield.shared `createView` -Creates a React Native view with a given module name. It automatically uses an instance of React Native created in `startReactNative` method. This is useful when embedding React Native views directly in your native layouts or Jetpack Compose UI. +Creates a React Native view with a given module name. It automatically uses an instance of React Native created in `initialize` method. This is useful when embedding React Native views directly in your native layouts or Jetpack Compose UI. Params: -| Param | Required | Type | Description | -| -------------- | -------- | ------------------- | ----------------------------------------------------------- | -| context | Yes | `Context` | Android context to create the view | -| activity | No | `FragmentActivity` | Activity hosting the view, used for lifecycle management | -| moduleName | Yes | `String` | Name of React Native component registered to `AppRegistry` | -| launchOptions | No | `Bundle` | Initial properties to be passed to React Native component | +| Param | Required | Type | Description | +| ------------- | -------- | ------------------ | ---------------------------------------------------------- | +| context | Yes | `Context` | Android context to create the view | +| activity | No | `FragmentActivity` | Activity hosting the view, used for lifecycle management | +| moduleName | Yes | `String` | Name of React Native component registered to `AppRegistry` | +| launchOptions | No | `Bundle` | Initial properties to be passed to React Native component | Returns: `FrameLayout` - A view containing the React Native component. @@ -182,7 +182,7 @@ AndroidView( #### `ReactNativeFragment` -An fragment rendering `ReactRootView` with a given module name. It automatically uses a instance of React Native created in `startReactNative` method. It works well with exposed JavaScript module. All the lifecycles are proxied to `ReactInstanceManager`. It's the simplest way to embed React Native into your navigation stack. +An fragment rendering `ReactRootView` with a given module name. It automatically uses a instance of React Native created in `initialize` method. It works well with exposed JavaScript module. All the lifecycles are proxied to `ReactInstanceManager`. It's the simplest way to embed React Native into your navigation stack. ```kotlin import com.callstack.reactnativebrownfield.ReactNativeFragment @@ -198,10 +198,10 @@ Creates a Fragment with `ReactNativeActivity`, you can use it as a parameter in Params: -| Param | Required | Type | Description | -| ----------------------- | -------- | ------------------------------------------- | ----------------------------------------------------------- | -| moduleName | Yes | `String` | Name of React Native component registered to `AppRegistry`. | -| initialProps | No | `Bundle` \|\| `HashMap` \|\| `ReadableMap` | Initial properties to be passed to React Native component. | +| Param | Required | Type | Description | +| ------------ | -------- | ----------------------------------------------------- | ----------------------------------------------------------- | +| moduleName | Yes | `String` | Name of React Native component registered to `AppRegistry`. | +| initialProps | No | `Bundle` \|\| `HashMap` \|\| `ReadableMap` | Initial properties to be passed to React Native component. | Examples: @@ -229,6 +229,20 @@ map.putInt("score", 12) ReactNativeFragment.createReactNativeFragment("ReactNative", map) ``` +### Usage in Jetpack Compose + +You can easily wrap the `ReactNativeFragment` inside a `AndroidFragment` composable to integrate React Native into your Jetpack Compose application: + +```kotlin +import androidx.fragment.compose.AndroidFragment + +import com.callstack.reactnativebrownfield.constants.ReactNativeFragmentArgNames + +AndroidFragment(arguments = Bundle().apply { + putString(ReactNativeFragmentArgNames.ARG_MODULE_NAME, "RnAndroidRockApp") +}, modifier = Modifier.fillMaxSize()) +``` + --- ### Example From 4e3729b369cb2ac668cac6f237bb40465bcd2693 Mon Sep 17 00:00:00 2001 From: Hur Ali Date: Fri, 7 Nov 2025 17:17:24 +0500 Subject: [PATCH 5/9] refactor: use useDeveloperSupport --- .../callstack/reactnativebrownfield/ReactNativeBrownfield.kt | 2 +- docs/JAVA.md | 2 +- docs/KOTLIN.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/android/src/main/java/com/callstack/reactnativebrownfield/ReactNativeBrownfield.kt b/android/src/main/java/com/callstack/reactnativebrownfield/ReactNativeBrownfield.kt index 0f4bcac1..ab6360d5 100644 --- a/android/src/main/java/com/callstack/reactnativebrownfield/ReactNativeBrownfield.kt +++ b/android/src/main/java/com/callstack/reactnativebrownfield/ReactNativeBrownfield.kt @@ -77,7 +77,7 @@ class ReactNativeBrownfield private constructor(val reactHost: ReactHost) { packageList = (options["packages"] as? List<*> ?: emptyList()) .filterIsInstance(), jsMainModulePath = options["mainModuleName"] as? String ?: "index", - useDevSupport = options["useDevSupport"] as? Boolean ?: ReactBuildConfig.DEBUG + useDevSupport = options["useDeveloperSupport"] as? Boolean ?: ReactBuildConfig.DEBUG ) } diff --git a/docs/JAVA.md b/docs/JAVA.md index 7754f1c3..d0443893 100644 --- a/docs/JAVA.md +++ b/docs/JAVA.md @@ -73,7 +73,7 @@ Params: > * - From the marked fields, exactly one must be specified, excluding the others. See examples below. Available options: -- `useDevSupport`: `Boolean` - Flag to use dev support. +- `useDeveloperSupport`: `Boolean` - Flag to use dev support. - `packages`: `List` - List of your React Native Native modules. - `mainModuleName`: `String` - Path to react native entry file. diff --git a/docs/KOTLIN.md b/docs/KOTLIN.md index 3dd8ecb1..96385bea 100644 --- a/docs/KOTLIN.md +++ b/docs/KOTLIN.md @@ -56,7 +56,7 @@ Params: > `*` - From the marked fields, exactly one must be specified, excluding the others. See examples below. Available options: -- `useDevSupport`: `Boolean` - Flag to use dev support. +- `useDeveloperSupport`: `Boolean` - Flag to use dev support. - `packages`: `List` - List of your React Native Native modules. - `mainModuleName`: `String` - Path to react native entry file. From e7b98a83dc54578f674bf05af044ea05ab713563 Mon Sep 17 00:00:00 2001 From: artus9033 Date: Fri, 7 Nov 2025 13:34:15 +0100 Subject: [PATCH 6/9] docs: added docs for Jetpack Compose via AndroidFragment --- docs/KOTLIN.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/KOTLIN.md b/docs/KOTLIN.md index 96385bea..ca6e8dde 100644 --- a/docs/KOTLIN.md +++ b/docs/KOTLIN.md @@ -231,7 +231,11 @@ ReactNativeFragment.createReactNativeFragment("ReactNative", map) ### Usage in Jetpack Compose -You can easily wrap the `ReactNativeFragment` inside a `AndroidFragment` composable to integrate React Native into your Jetpack Compose application: +You can easily wrap the `ReactNativeFragment` inside a `AndroidFragment` composable to integrate React Native into your Jetpack Compose application. Since the AndroidFragment itself acts as a factory for the given Fragment class, you can pass the required arguments using a Bundle. + +The `arguments` passed to the `AndroidFragment` match the ones that can be passed to the `ReactNativeFragment.createReactNativeFragment` factory, yet need to be packed inside a Bundle, as follows: +- ***(required)*** the JS component name, a `String` under the `ReactNativeFragmentArgNames.ARG_MODULE_NAME` (equivalent to `"arg_module_name"`) constant +- *(optional)* the initial properties, a `Bundle` under the `ReactNativeFragmentArgNames.ARG_LAUNCH_OPTIONS` (equivalent to `"arg_launch_options"`) constant ```kotlin import androidx.fragment.compose.AndroidFragment @@ -239,7 +243,8 @@ import androidx.fragment.compose.AndroidFragment import com.callstack.reactnativebrownfield.constants.ReactNativeFragmentArgNames AndroidFragment(arguments = Bundle().apply { - putString(ReactNativeFragmentArgNames.ARG_MODULE_NAME, "RnAndroidRockApp") + putString(ReactNativeFragmentArgNames.ARG_MODULE_NAME, "ReactNative") + putBundle(ReactNativeFragmentArgNames.ARG_LAUNCH_OPTIONS, initialProps) }, modifier = Modifier.fillMaxSize()) ``` From 0b7df16edf21da0e862bfc408e44c11a3ef29cc7 Mon Sep 17 00:00:00 2001 From: artus9033 Date: Fri, 7 Nov 2025 13:44:39 +0100 Subject: [PATCH 7/9] docs: added tested RN version compatibility matrix --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 8decdc78..018267b9 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,13 @@ - Compatible with all native languages **Objective-C**, **Swift**, **Java** and **Kotlin** - Supports UIKit and SwiftUI on iOS and Fragments and Jetpack Compose on Android +## React Native version compatibility matrix + +| Tested React Native Version | React Native Brownfield Version | +| --------------------------- | ------------------------------- | +| 0.81.x, 0.82.x | ^2.0.0-rc.0 | +| 0.78.x | ^1.2.0 | + ## Installation The React Native Brownfield library is intended to be installed in a React Native app that is later consumed as a framework artifact by your native iOS or Android app. From 31dbcd8533f04d4f404697a82870d824e990524e Mon Sep 17 00:00:00 2001 From: artus9033 Date: Fri, 7 Nov 2025 14:12:14 +0100 Subject: [PATCH 8/9] fix: resolve ambiguity in call to getDefaultReactHost --- .../callstack/reactnativebrownfield/ReactNativeBrownfield.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/android/src/main/java/com/callstack/reactnativebrownfield/ReactNativeBrownfield.kt b/android/src/main/java/com/callstack/reactnativebrownfield/ReactNativeBrownfield.kt index ab6360d5..7f599393 100644 --- a/android/src/main/java/com/callstack/reactnativebrownfield/ReactNativeBrownfield.kt +++ b/android/src/main/java/com/callstack/reactnativebrownfield/ReactNativeBrownfield.kt @@ -77,7 +77,9 @@ class ReactNativeBrownfield private constructor(val reactHost: ReactHost) { packageList = (options["packages"] as? List<*> ?: emptyList()) .filterIsInstance(), jsMainModulePath = options["mainModuleName"] as? String ?: "index", - useDevSupport = options["useDeveloperSupport"] as? Boolean ?: ReactBuildConfig.DEBUG + useDevSupport = options["useDeveloperSupport"] as? Boolean + ?: ReactBuildConfig.DEBUG, + jsRuntimeFactory = null ) } From ff4a163cd410ce4186e9197bc320cacf0bba8d60 Mon Sep 17 00:00:00 2001 From: artus9033 Date: Sat, 8 Nov 2025 00:55:38 +0100 Subject: [PATCH 9/9] fix: correct JS entrypoint filename for release example app builds --- example/{index.tsx => App.tsx} | 6 ++---- example/index.js | 5 +++++ 2 files changed, 7 insertions(+), 4 deletions(-) rename example/{index.tsx => App.tsx} (94%) create mode 100644 example/index.js diff --git a/example/index.tsx b/example/App.tsx similarity index 94% rename from example/index.tsx rename to example/App.tsx index c4388644..8c52685f 100644 --- a/example/index.tsx +++ b/example/App.tsx @@ -1,5 +1,5 @@ import React, { useEffect } from 'react'; -import { AppRegistry, StyleSheet, Text, View, Button } from 'react-native'; +import { StyleSheet, Text, View, Button } from 'react-native'; import { createNativeStackNavigator, type NativeStackScreenProps, @@ -71,7 +71,7 @@ type RootStackParamList = { const Stack = createNativeStackNavigator(); -function App() { +export default function App() { return ( @@ -93,5 +93,3 @@ const styles = StyleSheet.create({ margin: 10, }, }); - -AppRegistry.registerComponent('ReactNative', () => App); diff --git a/example/index.js b/example/index.js new file mode 100644 index 00000000..64110690 --- /dev/null +++ b/example/index.js @@ -0,0 +1,5 @@ +import { AppRegistry } from 'react-native'; + +import App from './App'; + +AppRegistry.registerComponent('ReactNative', () => App);