@callstack/react-native-brownfield 0.1.0 → 1.0.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/README.md +24 -1
  2. package/ReactBrownfield.podspec +22 -0
  3. package/android/build.gradle +103 -15
  4. package/android/gradle.properties +5 -0
  5. package/android/src/main/java/com/callstack/reactnativebrownfield/ReactNativeBrownfield.kt +82 -15
  6. package/android/src/main/java/com/callstack/reactnativebrownfield/ReactNativeBrownfieldPackage.kt +9 -9
  7. package/android/src/main/java/com/callstack/reactnativebrownfield/ReactNativeFragment.kt +139 -145
  8. package/android/src/newarch/ReactNativeBrownfieldModule.kt +37 -0
  9. package/android/src/oldarch/ReactNativeBrownfieldModule.kt +38 -0
  10. package/ios/ReactNativeBrownfield.swift +119 -0
  11. package/ios/ReactNativeBrownfieldModule.h +7 -2
  12. package/ios/ReactNativeBrownfieldModule.mm +25 -0
  13. package/ios/ReactNativeBrownfieldModule.swift +18 -0
  14. package/ios/ReactNativeView.swift +43 -0
  15. package/ios/ReactNativeViewController.swift +66 -0
  16. package/lib/commonjs/NativeReactNativeBrownfieldModule.js +2 -0
  17. package/lib/commonjs/NativeReactNativeBrownfieldModule.js.map +1 -0
  18. package/lib/commonjs/index.js +1 -28
  19. package/lib/commonjs/index.js.map +1 -1
  20. package/lib/module/NativeReactNativeBrownfieldModule.js +2 -0
  21. package/lib/module/NativeReactNativeBrownfieldModule.js.map +1 -0
  22. package/lib/module/index.js +1 -22
  23. package/lib/module/index.js.map +1 -1
  24. package/lib/typescript/commonjs/package.json +1 -0
  25. package/lib/typescript/commonjs/src/NativeReactNativeBrownfieldModule.d.ts +20 -0
  26. package/lib/typescript/commonjs/src/NativeReactNativeBrownfieldModule.d.ts.map +1 -0
  27. package/lib/typescript/commonjs/src/index.d.ts.map +1 -0
  28. package/lib/typescript/module/package.json +1 -0
  29. package/lib/typescript/module/src/NativeReactNativeBrownfieldModule.d.ts +20 -0
  30. package/lib/typescript/module/src/NativeReactNativeBrownfieldModule.d.ts.map +1 -0
  31. package/lib/typescript/module/src/index.d.ts +6 -0
  32. package/lib/typescript/module/src/index.d.ts.map +1 -0
  33. package/package.json +62 -31
  34. package/src/NativeReactNativeBrownfieldModule.ts +23 -0
  35. package/src/index.ts +6 -7
  36. package/ReactNativeBrownfield.podspec +0 -20
  37. package/android/src/main/java/com/callstack/reactnativebrownfield/ReactNativeActivity.kt +0 -188
  38. package/android/src/main/java/com/callstack/reactnativebrownfield/ReactNativeBrownfieldModule.kt +0 -32
  39. package/ios/ReactNativeBrownfield.h +0 -24
  40. package/ios/ReactNativeBrownfield.m +0 -82
  41. package/ios/ReactNativeBrownfieldModule.m +0 -24
  42. package/ios/ReactNativeBrownfieldNotifications.h +0 -4
  43. package/ios/ReactNativeBrownfieldNotifications.m +0 -4
  44. package/ios/ReactNativeViewController.h +0 -15
  45. package/ios/ReactNativeViewController.m +0 -66
  46. package/lib/typescript/src/index.d.ts.map +0 -1
  47. /package/lib/typescript/{src → commonjs/src}/index.d.ts +0 -0
package/README.md CHANGED
@@ -23,11 +23,13 @@
23
23
 
24
24
  - **Easily integrate** React Native with existing native app
25
25
  - Start React Native with **one method** and invoke code as soon as it's loaded
26
- - Reuse the same instance of React Native **bridge** between different components
26
+ - Compatible with **both old and new React Native architecture**!
27
+ - Reuse the same instance of React Native between different components
27
28
  - Use predefined **native building blocks** - crafted for React Native
28
29
  - Disable and enable **native gestures and hardware buttons** from JavaScript
29
30
  - Works well with **any native navigation** pattern, as well as every React Native JavaScript based navigation
30
31
  - Compatible with all native languages **Objective-C**, **Swift**, **Java** and **Kotlin**
32
+ - Supports UIKit and SwiftUI on iOS and Fragments and Jetpack Compose on Android
31
33
 
32
34
 
33
35
  ## Installation
@@ -42,6 +44,26 @@ or
42
44
  yarn add @callstack/react-native-brownfield
43
45
  ```
44
46
 
47
+ ## Enabling New Architecture
48
+
49
+ ### Android
50
+ Add the following to your `android/gradle.properties`:
51
+
52
+ ```
53
+ # Enable new architecture
54
+ newArchEnabled=true
55
+ ```
56
+
57
+ ### iOS
58
+ Install cocoapods with the flag:
59
+
60
+ ```
61
+ RCT_NEW_ARCH_ENABLED=1 pod install
62
+ ```
63
+
64
+ > [!NOTE]
65
+ > New Architecture is enabled by default from React Native 0.76
66
+
45
67
  ## Usage
46
68
 
47
69
  React Native Brownfield library works with all major native programming languages. Majority of its API is exposed on the native side. Click on the logo to choose the one that interests you:
@@ -79,6 +101,7 @@ ReactNativeBrownfield.popToNative(true);
79
101
 
80
102
  > NOTE: Those methods works only with native components provided by this library.
81
103
 
104
+
82
105
  ## Made with ❤️ at Callstack
83
106
 
84
107
  React Native Brownfield is an open source project and will always remain free to use. If you think it's cool, please star it 🌟. [Callstack](https://callstack.com) is a group of React and React Native geeks, contact us at [hello@callstack.com](mailto:hello@callstack.com) if you need any help with these or just want to say hi!
@@ -0,0 +1,22 @@
1
+ require 'json'
2
+
3
+ package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
4
+
5
+ Pod::Spec.new do |spec|
6
+ spec.name = "ReactBrownfield"
7
+ spec.version = package['version']
8
+ spec.summary = package['description']
9
+ spec.license = package['license']
10
+
11
+ spec.authors = package['author']
12
+ spec.homepage = package['homepage']
13
+ spec.platform = :ios, "14.0"
14
+
15
+ spec.module_name = "ReactBrownfield"
16
+ spec.source = { :git => "git@github.com:callstack/react-native-brownfield.git", :tag => "#{spec.version}" }
17
+ spec.source_files = "ios/**/*.{h,m,mm,swift}"
18
+ spec.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' }
19
+
20
+ spec.dependency 'ReactAppDependencyProvider'
21
+ install_modules_dependencies(spec)
22
+ end
@@ -1,29 +1,117 @@
1
- apply plugin: 'com.android.library'
2
- apply plugin: 'kotlin-android'
1
+ buildscript {
2
+ // Buildscript is evaluated before everything else so we can't use getExtOrDefault
3
+ def kotlin_version = rootProject.ext.has("kotlinVersion") ? rootProject.ext.get("kotlinVersion") : project.properties["RNBrownfield_kotlinVersion"]
3
4
 
4
- def safeExtGet(prop, fallback) {
5
- rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
5
+ repositories {
6
+ google()
7
+ mavenCentral()
8
+ }
9
+
10
+ dependencies {
11
+ classpath "com.android.tools.build:gradle:7.2.1"
12
+ // noinspection DifferentKotlinGradleVersion
13
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
14
+ }
6
15
  }
7
16
 
8
- repositories {
9
- google()
17
+ def isNewArchitectureEnabled() {
18
+ return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
19
+ }
20
+
21
+ def isHermesEnabled() {
22
+ return rootProject.hasProperty("hermesEnabled") && rootProject.getProperty("hermesEnabled") == "true"
23
+ }
24
+
25
+ apply plugin: "com.android.library"
26
+ apply plugin: "kotlin-android"
27
+
28
+ if (isNewArchitectureEnabled()) {
29
+ apply plugin: "com.facebook.react"
30
+ }
31
+
32
+ def getExtOrDefault(name) {
33
+ return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties["RNBrownfield_" + name]
34
+ }
35
+
36
+ def getExtOrIntegerDefault(name) {
37
+ return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["RNBrownfield_" + name]).toInteger()
38
+ }
39
+
40
+ def supportsNamespace() {
41
+ def parsed = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION.tokenize('.')
42
+ def major = parsed[0].toInteger()
43
+ def minor = parsed[1].toInteger()
44
+
45
+ // Namespace support was added in 7.3.0
46
+ return (major == 7 && minor >= 3) || major >= 8
10
47
  }
11
48
 
12
49
  android {
13
- compileSdkVersion safeExtGet('compileSdkVersion', 28)
50
+ if (supportsNamespace()) {
51
+ namespace "com.callstack.reactnativebrownfield"
52
+
53
+ sourceSets {
54
+ main {
55
+ manifest.srcFile "src/main/AndroidManifest.xml"
56
+ }
57
+ }
58
+ }
59
+
60
+ compileSdkVersion getExtOrIntegerDefault("compileSdkVersion")
61
+
62
+ defaultConfig {
63
+ minSdkVersion getExtOrIntegerDefault("minSdkVersion")
64
+ targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
65
+ buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
66
+ buildConfigField "boolean", "IS_HERMES_ENABLED", isHermesEnabled().toString()
67
+ }
68
+
69
+ buildFeatures {
70
+ buildConfig true
71
+ }
14
72
 
15
- defaultConfig {
16
- minSdkVersion safeExtGet('minSdkVersion', 21)
17
- targetSdkVersion safeExtGet('targetSdkVersion', 28)
73
+ buildTypes {
74
+ release {
75
+ minifyEnabled false
18
76
  }
77
+ }
19
78
 
20
- lintOptions {
21
- abortOnError false
79
+ lintOptions {
80
+ disable "GradleCompatible"
81
+ }
82
+
83
+ compileOptions {
84
+ sourceCompatibility JavaVersion.VERSION_1_8
85
+ targetCompatibility JavaVersion.VERSION_1_8
86
+ }
87
+
88
+ sourceSets {
89
+ main {
90
+ if (isNewArchitectureEnabled()) {
91
+ java.srcDirs += [
92
+ "src/newarch",
93
+ // Codegen specs
94
+ "generated/java",
95
+ "generated/jni"
96
+ ]
97
+ } else {
98
+ java.srcDirs += ["src/oldarch"]
99
+ }
22
100
  }
101
+ }
102
+ }
23
103
 
104
+ repositories {
105
+ mavenCentral()
106
+ google()
24
107
  }
25
108
 
109
+ def kotlin_version = getExtOrDefault("kotlinVersion")
110
+
26
111
  dependencies {
27
- implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${safeExtGet('kotlinVersion', '1.3.40')}"
28
- implementation "com.facebook.react:react-native:+"
29
- }
112
+ // For < 0.71, this will be from the local maven repo
113
+ // For > 0.71, this will be replaced by `com.facebook.react:react-android:$version` by react gradle plugin
114
+ //noinspection GradleDynamicVersion
115
+ implementation "com.facebook.react:react-native:+"
116
+ implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
117
+ }
@@ -0,0 +1,5 @@
1
+ RNBrownfield_kotlinVersion=1.7.0
2
+ RNBrownfield_minSdkVersion=21
3
+ RNBrownfield_targetSdkVersion=31
4
+ RNBrownfield_compileSdkVersion=31
5
+ RNBrownfield_ndkversion=21.4.7075529
@@ -1,12 +1,25 @@
1
1
  package com.callstack.reactnativebrownfield
2
2
 
3
3
  import android.app.Application
4
+ import android.content.Context
5
+ import android.os.Bundle
6
+ import android.widget.FrameLayout
7
+ import androidx.fragment.app.FragmentActivity
8
+ import androidx.lifecycle.DefaultLifecycleObserver
9
+ import androidx.lifecycle.LifecycleOwner
10
+ import com.facebook.react.ReactDelegate
4
11
  import com.facebook.react.ReactInstanceEventListener
12
+ import com.facebook.react.ReactInstanceManager
5
13
  import com.facebook.react.ReactNativeHost
6
14
  import com.facebook.react.ReactPackage
15
+ import com.facebook.react.ReactRootView
7
16
  import com.facebook.react.bridge.ReactContext
17
+ import com.facebook.react.defaults.DefaultReactNativeHost
18
+ import com.facebook.react.soloader.OpenSourceMergedSoMapping
8
19
  import com.facebook.soloader.SoLoader
9
20
  import java.util.concurrent.atomic.AtomicBoolean
21
+ import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
22
+ import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
10
23
 
11
24
  interface InitializedCallback {
12
25
  operator fun invoke(initialized: Boolean)
@@ -22,30 +35,33 @@ class ReactNativeBrownfield private constructor(val reactNativeHost: ReactNative
22
35
 
23
36
  @JvmStatic
24
37
  fun initialize(application: Application, rnHost: ReactNativeHost) {
25
- if(!initialized.getAndSet(true)) {
38
+ if (!initialized.getAndSet(true)) {
26
39
  instance = ReactNativeBrownfield(rnHost)
27
- SoLoader.init(application.applicationContext,false)
40
+ SoLoader.init(application.applicationContext, OpenSourceMergedSoMapping)
28
41
  }
29
42
  }
30
43
 
31
44
  @JvmStatic
32
45
  fun initialize(application: Application, options: HashMap<String, Any>) {
33
- val rnHost = object : ReactNativeHost(application) {
34
- override fun getUseDeveloperSupport(): Boolean {
35
- return options["useDeveloperSupport"] as? Boolean ?: BuildConfig.DEBUG
36
- }
46
+ val reactNativeHost: ReactNativeHost =
47
+ object : DefaultReactNativeHost(application) {
37
48
 
38
- override fun getPackages(): List<ReactPackage> {
39
- return (options["packages"] as? List<*> ?: emptyList<ReactPackage>())
40
- .filterIsInstance<ReactPackage>()
41
- }
49
+ override fun getJSMainModuleName(): String {
50
+ return options["mainModuleName"] as? String ?: super.getJSMainModuleName()
51
+ }
52
+
53
+ override fun getPackages(): List<ReactPackage> {
54
+ return (options["packages"] as? List<*> ?: emptyList<ReactPackage>())
55
+ .filterIsInstance<ReactPackage>()
56
+ }
42
57
 
43
- override fun getJSMainModuleName(): String {
44
- return options["mainModuleName"] as? String ?: super.getJSMainModuleName()
58
+ override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG
59
+
60
+ override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
61
+ override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
45
62
  }
46
- }
47
63
 
48
- initialize(application, rnHost)
64
+ initialize(application, reactNativeHost)
49
65
  }
50
66
 
51
67
  @JvmStatic
@@ -54,6 +70,8 @@ class ReactNativeBrownfield private constructor(val reactNativeHost: ReactNative
54
70
 
55
71
  initialize(application, options)
56
72
  }
73
+
74
+
57
75
  }
58
76
 
59
77
  fun startReactNative(callback: InitializedCallback?) {
@@ -62,13 +80,62 @@ class ReactNativeBrownfield private constructor(val reactNativeHost: ReactNative
62
80
 
63
81
  @JvmName("startReactNativeKotlin")
64
82
  fun startReactNative(callback: ((initialized: Boolean) -> Unit)?) {
65
- reactNativeHost.reactInstanceManager.addReactInstanceEventListener(object : ReactInstanceEventListener {
83
+ reactNativeHost.reactInstanceManager.addReactInstanceEventListener(object :
84
+ ReactInstanceEventListener {
66
85
  override fun onReactContextInitialized(reactContext: ReactContext) {
67
86
  callback?.let { it(true) }
68
87
  reactNativeHost.reactInstanceManager.removeReactInstanceEventListener(this)
69
88
  }
70
89
  })
71
90
  reactNativeHost.reactInstanceManager?.createReactContextInBackground()
91
+
92
+ if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
93
+ // If you opted-in for the New Architecture, we load the native entry point for this app.
94
+ load()
95
+ }
96
+ }
97
+
98
+ fun createView(
99
+ context: Context,
100
+ activity: FragmentActivity?,
101
+ moduleName: String,
102
+ launchOptions: Bundle? = null,
103
+ ): FrameLayout {
104
+ if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
105
+ val reactHost = getDefaultReactHost(
106
+ context,
107
+ shared.reactNativeHost
108
+ )
109
+ val reactDelegate = ReactDelegate(activity, reactHost, moduleName, launchOptions)
110
+
111
+ activity?.lifecycle?.addObserver(object : DefaultLifecycleObserver {
112
+ override fun onResume(owner: LifecycleOwner) {
113
+ reactDelegate.onHostResume()
114
+ }
115
+
116
+ override fun onPause(owner: LifecycleOwner) {
117
+ reactDelegate.onHostPause()
118
+ }
119
+
120
+ override fun onDestroy(owner: LifecycleOwner) {
121
+ reactDelegate.onHostDestroy()
122
+ owner.lifecycle.removeObserver(this) // Cleanup to avoid leaks
123
+ }
124
+ })
125
+
126
+ reactDelegate.loadApp()
127
+ return reactDelegate.reactRootView!!
128
+ }
129
+
130
+ val instanceManager: ReactInstanceManager? = shared.reactNativeHost?.reactInstanceManager
131
+ val reactView = ReactRootView(context)
132
+ reactView.startReactApplication(
133
+ instanceManager,
134
+ moduleName,
135
+ launchOptions,
136
+ )
137
+
138
+ return reactView
72
139
  }
73
140
  }
74
141
 
@@ -11,13 +11,13 @@ import com.facebook.react.uimanager.ReactShadowNode
11
11
 
12
12
 
13
13
  class ReactNativeBrownfieldPackage : ReactPackage {
14
- override fun createViewManagers(reactContext: ReactApplicationContext): MutableList<ViewManager<View, ReactShadowNode<*>>> {
15
- return Collections.emptyList()
16
- }
14
+ override fun createViewManagers(reactContext: ReactApplicationContext): MutableList<ViewManager<View, ReactShadowNode<*>>> {
15
+ return Collections.emptyList()
16
+ }
17
17
 
18
- override fun createNativeModules(reactContext: ReactApplicationContext): MutableList<NativeModule> {
19
- val modules = ArrayList<NativeModule>()
20
- modules.add(ReactNativeBrownfieldModule(reactContext))
21
- return modules
22
- }
23
- }
18
+ override fun createNativeModules(reactContext: ReactApplicationContext): MutableList<NativeModule> {
19
+ val modules = ArrayList<NativeModule>()
20
+ modules.add(ReactNativeBrownfieldModule(reactContext))
21
+ return modules
22
+ }
23
+ }