@callstack/react-native-brownfield 0.0.3 → 1.0.0-rc.0

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 (65) hide show
  1. package/README.md +26 -1
  2. package/ReactNativeBrownfield.podspec +10 -3
  3. package/android/build.gradle +89 -16
  4. package/android/gradle.properties +5 -0
  5. package/android/src/main/java/com/callstack/reactnativebrownfield/ReactNativeBrownfield.kt +90 -18
  6. package/android/src/main/java/com/callstack/reactnativebrownfield/ReactNativeBrownfieldModule.kt +22 -21
  7. package/android/src/main/java/com/callstack/reactnativebrownfield/ReactNativeBrownfieldPackage.kt +9 -9
  8. package/android/src/main/java/com/callstack/reactnativebrownfield/ReactNativeFragment.kt +139 -143
  9. package/ios/ReactNativeBrownfield.swift +119 -0
  10. package/ios/ReactNativeBrownfieldModule.m +8 -11
  11. package/ios/ReactNativeBrownfieldModule.swift +18 -0
  12. package/ios/ReactNativeView.swift +42 -0
  13. package/ios/ReactNativeViewController.swift +66 -0
  14. package/lib/commonjs/RNBrownfieldSpec.js +9 -0
  15. package/lib/commonjs/RNBrownfieldSpec.js.map +1 -0
  16. package/lib/commonjs/index.js +31 -0
  17. package/lib/commonjs/index.js.map +1 -0
  18. package/lib/commonjs/package.json +1 -0
  19. package/lib/module/RNBrownfieldSpec.js +5 -0
  20. package/lib/module/RNBrownfieldSpec.js.map +1 -0
  21. package/lib/module/index.js +26 -0
  22. package/lib/module/index.js.map +1 -0
  23. package/lib/module/package.json +1 -0
  24. package/lib/typescript/src/RNBrownfieldSpec.d.ts +20 -0
  25. package/lib/typescript/src/RNBrownfieldSpec.d.ts.map +1 -0
  26. package/lib/typescript/src/index.d.ts +6 -0
  27. package/lib/typescript/src/index.d.ts.map +1 -0
  28. package/package.json +126 -18
  29. package/src/RNBrownfieldSpec.ts +23 -0
  30. package/src/{index.js → index.ts} +9 -9
  31. package/.eslintrc.js +0 -6
  32. package/.flowconfig +0 -100
  33. package/CODE_OF_CONDUCT.md +0 -73
  34. package/android/.gradle/4.10/fileChanges/last-build.bin +0 -0
  35. package/android/.gradle/4.10/fileHashes/fileHashes.bin +0 -0
  36. package/android/.gradle/4.10/fileHashes/fileHashes.lock +0 -0
  37. package/android/.gradle/4.10/gc.properties +0 -0
  38. package/android/.gradle/5.1.1/fileChanges/last-build.bin +0 -0
  39. package/android/.gradle/5.1.1/fileHashes/fileHashes.lock +0 -0
  40. package/android/.gradle/5.1.1/gc.properties +0 -0
  41. package/android/.gradle/vcs-1/gc.properties +0 -0
  42. package/android/.idea/encodings.xml +0 -4
  43. package/android/.idea/gradle.xml +0 -12
  44. package/android/.idea/misc.xml +0 -14
  45. package/android/.idea/runConfigurations.xml +0 -12
  46. package/android/.idea/vcs.xml +0 -6
  47. package/android/.idea/workspace.xml +0 -126
  48. package/android/android.iml +0 -16
  49. package/android/local.properties +0 -8
  50. package/android/react-native-brownfield.iml +0 -201
  51. package/android/src/main/java/com/callstack/reactnativebrownfield/ReactNativeActivity.kt +0 -170
  52. package/babel.config.js +0 -13
  53. package/docs/JAVA.md +0 -305
  54. package/docs/KOTLIN.md +0 -274
  55. package/docs/OBJECTIVE_C.md +0 -150
  56. package/docs/SWIFT.md +0 -164
  57. package/ios/ReactNativeBrownfield.h +0 -24
  58. package/ios/ReactNativeBrownfield.m +0 -82
  59. package/ios/ReactNativeBrownfieldNotifications.h +0 -4
  60. package/ios/ReactNativeBrownfieldNotifications.m +0 -4
  61. package/ios/ReactNativeViewController.h +0 -15
  62. package/ios/ReactNativeViewController.m +0 -64
  63. package/prettier.config.js +0 -7
  64. package/react-native.config.js +0 -9
  65. package/types/index.d.ts +0 -11
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,10 +101,13 @@ 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!
85
108
 
109
+ Like the project? ⚛️ [Join the team](https://callstack.com/careers/?utm_campaign=Senior_RN&utm_source=github&utm_medium=readme) who does amazing stuff for clients and drives React Native Open Source! 🔥
110
+
86
111
  ## Contributors
87
112
 
88
113
  Thanks goes to these wonderful people ([emoji key](https://github.com/kentcdodds/all-contributors#emoji-key)):
@@ -1,5 +1,9 @@
1
1
  require 'json'
2
2
 
3
+ is_new_arch_enabled = ENV['RCT_NEW_ARCH_ENABLED'] == '1'
4
+ new_arch_enabled_flag = (is_new_arch_enabled ? " -DRCT_NEW_ARCH_ENABLED" : "")
5
+ other_cflags = "$(inherited)" + new_arch_enabled_flag
6
+
3
7
  package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
4
8
 
5
9
  Pod::Spec.new do |spec|
@@ -14,7 +18,10 @@ Pod::Spec.new do |spec|
14
18
 
15
19
  # s.source = { :git => "git@github.com/michalchudziak/react-native-brownfield.git", :tag => "v#{s.version}" }
16
20
  spec.source = { :path => "." }
17
- spec.source_files = "ios/**/*.{h,m}"
21
+ spec.source_files = "ios/**/*.{h,m,mm,swift}"
22
+ spec.compiler_flags = new_arch_enabled_flag
23
+ spec.pod_target_xcconfig = { 'OTHER_CPLUSPLUSFLAGS' => other_cflags, 'DEFINES_MODULE' => 'YES' }
18
24
 
19
- spec.dependency 'React'
20
- end
25
+ install_modules_dependencies(spec)
26
+ spec.dependency 'ReactAppDependencyProvider'
27
+ end
@@ -1,29 +1,102 @@
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"
14
52
 
15
- defaultConfig {
16
- minSdkVersion safeExtGet('minSdkVersion', 21)
17
- targetSdkVersion safeExtGet('targetSdkVersion', 28)
18
- }
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
+ }
19
72
 
20
- lintOptions {
21
- abortOnError false
73
+ buildTypes {
74
+ release {
75
+ minifyEnabled false
22
76
  }
77
+ }
23
78
 
79
+ lintOptions {
80
+ disable "GradleCompatible"
81
+ }
82
+
83
+ compileOptions {
84
+ sourceCompatibility JavaVersion.VERSION_1_8
85
+ targetCompatibility JavaVersion.VERSION_1_8
86
+ }
87
+ }
88
+
89
+ repositories {
90
+ mavenCentral()
91
+ google()
24
92
  }
25
93
 
94
+ def kotlin_version = getExtOrDefault("kotlinVersion")
95
+
26
96
  dependencies {
27
- implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${safeExtGet('kotlinVersion', '1.3.40')}"
28
- implementation "com.facebook.react:react-native:+"
29
- }
97
+ // For < 0.71, this will be from the local maven repo
98
+ // For > 0.71, this will be replaced by `com.facebook.react:react-android:$version` by react gradle plugin
99
+ //noinspection GradleDynamicVersion
100
+ implementation "com.facebook.react:react-native:+"
101
+ implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
102
+ }
@@ -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,10 +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
11
+ import com.facebook.react.ReactInstanceEventListener
12
+ import com.facebook.react.ReactInstanceManager
4
13
  import com.facebook.react.ReactNativeHost
5
14
  import com.facebook.react.ReactPackage
15
+ import com.facebook.react.ReactRootView
16
+ import com.facebook.react.bridge.ReactContext
17
+ import com.facebook.react.defaults.DefaultReactNativeHost
18
+ import com.facebook.react.soloader.OpenSourceMergedSoMapping
6
19
  import com.facebook.soloader.SoLoader
7
20
  import java.util.concurrent.atomic.AtomicBoolean
21
+ import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
22
+ import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
8
23
 
9
24
  interface InitializedCallback {
10
25
  operator fun invoke(initialized: Boolean)
@@ -20,30 +35,33 @@ class ReactNativeBrownfield private constructor(val reactNativeHost: ReactNative
20
35
 
21
36
  @JvmStatic
22
37
  fun initialize(application: Application, rnHost: ReactNativeHost) {
23
- if(!initialized.getAndSet(true)) {
38
+ if (!initialized.getAndSet(true)) {
24
39
  instance = ReactNativeBrownfield(rnHost)
25
- SoLoader.init(application.applicationContext,false)
40
+ SoLoader.init(application.applicationContext, OpenSourceMergedSoMapping)
26
41
  }
27
42
  }
28
43
 
29
44
  @JvmStatic
30
45
  fun initialize(application: Application, options: HashMap<String, Any>) {
31
- val rnHost = object : ReactNativeHost(application) {
32
- override fun getUseDeveloperSupport(): Boolean {
33
- return options["useDeveloperSupport"] as? Boolean ?: BuildConfig.DEBUG
34
- }
46
+ val reactNativeHost: ReactNativeHost =
47
+ object : DefaultReactNativeHost(application) {
35
48
 
36
- override fun getPackages(): List<ReactPackage> {
37
- return (options["packages"] as? List<*> ?: emptyList<ReactPackage>())
38
- .filterIsInstance<ReactPackage>()
39
- }
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
+ }
40
57
 
41
- override fun getJSMainModuleName(): String {
42
- 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
43
62
  }
44
- }
45
63
 
46
- initialize(application, rnHost)
64
+ initialize(application, reactNativeHost)
47
65
  }
48
66
 
49
67
  @JvmStatic
@@ -52,6 +70,8 @@ class ReactNativeBrownfield private constructor(val reactNativeHost: ReactNative
52
70
 
53
71
  initialize(application, options)
54
72
  }
73
+
74
+
55
75
  }
56
76
 
57
77
  fun startReactNative(callback: InitializedCallback?) {
@@ -60,10 +80,62 @@ class ReactNativeBrownfield private constructor(val reactNativeHost: ReactNative
60
80
 
61
81
  @JvmName("startReactNativeKotlin")
62
82
  fun startReactNative(callback: ((initialized: Boolean) -> Unit)?) {
63
- if (callback != null) {
64
- reactNativeHost.reactInstanceManager?.addReactInstanceEventListener { callback(true) }
83
+ reactNativeHost.reactInstanceManager.addReactInstanceEventListener(object :
84
+ ReactInstanceEventListener {
85
+ override fun onReactContextInitialized(reactContext: ReactContext) {
86
+ callback?.let { it(true) }
87
+ reactNativeHost.reactInstanceManager.removeReactInstanceEventListener(this)
88
+ }
89
+ })
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()
65
95
  }
96
+ }
66
97
 
67
- reactNativeHost.reactInstanceManager?.createReactContextInBackground()
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
68
139
  }
69
- }
140
+ }
141
+
@@ -4,29 +4,30 @@ import com.facebook.react.bridge.ReactApplicationContext
4
4
  import com.facebook.react.bridge.ReactContextBaseJavaModule
5
5
  import com.facebook.react.bridge.ReactMethod
6
6
 
7
- class ReactNativeBrownfieldModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
8
- companion object {
9
- var shouldPopToNative: Boolean = false
10
- }
7
+ class ReactNativeBrownfieldModule(reactContext: ReactApplicationContext) :
8
+ ReactContextBaseJavaModule(reactContext) {
9
+ companion object {
10
+ var shouldPopToNative: Boolean = false
11
+ }
11
12
 
12
- @ReactMethod
13
- fun popToNative() {
14
- shouldPopToNative = true
15
- onBackPressed()
16
- }
13
+ @ReactMethod
14
+ fun popToNative() {
15
+ shouldPopToNative = true
16
+ onBackPressed()
17
+ }
17
18
 
18
- @ReactMethod
19
- fun setHardwareBackButtonEnabled(isFirstRoute: Boolean) {
20
- shouldPopToNative = isFirstRoute
21
- }
19
+ @ReactMethod
20
+ fun setHardwareBackButtonEnabled(isFirstRoute: Boolean) {
21
+ shouldPopToNative = isFirstRoute
22
+ }
22
23
 
23
- private fun onBackPressed() {
24
- reactApplicationContext.currentActivity?.runOnUiThread {
25
- reactApplicationContext.currentActivity?.onBackPressed()
26
- }
24
+ private fun onBackPressed() {
25
+ reactApplicationContext.currentActivity?.runOnUiThread {
26
+ reactApplicationContext.currentActivity?.onBackPressed()
27
27
  }
28
+ }
28
29
 
29
- override fun getName(): String {
30
- return "ReactNativeBrownfield"
31
- }
32
- }
30
+ override fun getName(): String {
31
+ return "ReactNativeBrownfield"
32
+ }
33
+ }
@@ -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
+ }