react-native-screens 3.31.1 → 3.33.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 (203) hide show
  1. package/README.md +21 -11
  2. package/RNScreens.podspec +11 -52
  3. package/android/CMakeLists.txt +48 -4
  4. package/android/build.gradle +16 -9
  5. package/android/src/fabric/java/com/swmansion/rnscreens/FabricEnabledViewGroup.kt +25 -16
  6. package/android/src/fabric/java/com/swmansion/rnscreens/NativeProxy.kt +53 -0
  7. package/android/src/main/cpp/NativeProxy.cpp +51 -0
  8. package/android/src/main/cpp/NativeProxy.h +35 -0
  9. package/android/src/main/cpp/OnLoad.cpp +8 -0
  10. package/android/src/main/cpp/jni-adapter.cpp +86 -93
  11. package/android/src/main/java/com/swmansion/rnscreens/CustomSearchView.kt +7 -2
  12. package/android/src/main/java/com/swmansion/rnscreens/CustomToolbar.kt +6 -1
  13. package/android/src/main/java/com/swmansion/rnscreens/FragmentBackPressOverrider.kt +2 -2
  14. package/android/src/main/java/com/swmansion/rnscreens/RNScreensPackage.kt +36 -17
  15. package/android/src/main/java/com/swmansion/rnscreens/Screen.kt +150 -40
  16. package/android/src/main/java/com/swmansion/rnscreens/ScreenContainer.kt +52 -30
  17. package/android/src/main/java/com/swmansion/rnscreens/ScreenContainerViewManager.kt +27 -4
  18. package/android/src/main/java/com/swmansion/rnscreens/ScreenEventDispatcher.kt +10 -2
  19. package/android/src/main/java/com/swmansion/rnscreens/ScreenFragment.kt +56 -27
  20. package/android/src/main/java/com/swmansion/rnscreens/ScreenFragmentWrapper.kt +8 -1
  21. package/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt +50 -19
  22. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragment.kt +63 -39
  23. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragmentWrapper.kt +4 -0
  24. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfig.kt +88 -57
  25. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfigViewManager.kt +131 -36
  26. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubview.kt +19 -4
  27. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubviewManager.kt +16 -10
  28. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackViewManager.kt +28 -25
  29. package/android/src/main/java/com/swmansion/rnscreens/ScreenViewManager.kt +177 -77
  30. package/android/src/main/java/com/swmansion/rnscreens/ScreenWindowTraits.kt +77 -25
  31. package/android/src/main/java/com/swmansion/rnscreens/ScreensModule.kt +31 -9
  32. package/android/src/main/java/com/swmansion/rnscreens/ScreensShadowNode.kt +3 -1
  33. package/android/src/main/java/com/swmansion/rnscreens/SearchBarManager.kt +160 -54
  34. package/android/src/main/java/com/swmansion/rnscreens/SearchBarView.kt +29 -22
  35. package/android/src/main/java/com/swmansion/rnscreens/SearchViewFormatter.kt +7 -2
  36. package/android/src/main/java/com/swmansion/rnscreens/events/HeaderAttachedEvent.kt +4 -1
  37. package/android/src/main/java/com/swmansion/rnscreens/events/HeaderBackButtonClickedEvent.kt +4 -1
  38. package/android/src/main/java/com/swmansion/rnscreens/events/HeaderDetachedEvent.kt +4 -1
  39. package/android/src/main/java/com/swmansion/rnscreens/events/HeaderHeightChangeEvent.kt +5 -6
  40. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenAppearEvent.kt +4 -1
  41. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenDisappearEvent.kt +4 -1
  42. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenDismissedEvent.kt +8 -4
  43. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenTransitionProgressEvent.kt +7 -6
  44. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenWillAppearEvent.kt +4 -1
  45. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenWillDisappearEvent.kt +4 -1
  46. package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarBlurEvent.kt +5 -2
  47. package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarChangeTextEvent.kt +4 -3
  48. package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarCloseEvent.kt +4 -1
  49. package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarFocusEvent.kt +5 -2
  50. package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarOpenEvent.kt +4 -1
  51. package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarSearchButtonPressEvent.kt +9 -4
  52. package/android/src/main/java/com/swmansion/rnscreens/events/StackFinishTransitioningEvent.kt +4 -1
  53. package/android/src/main/java/com/swmansion/rnscreens/utils/DeviceUtils.kt +1 -5
  54. package/android/src/main/java/com/swmansion/rnscreens/utils/ScreenDummyLayoutHelper.kt +214 -0
  55. package/android/src/main/jni/CMakeLists.txt +5 -4
  56. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenContainerManagerDelegate.java +25 -0
  57. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenContainerManagerInterface.java +16 -0
  58. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerDelegate.java +6 -0
  59. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerInterface.java +2 -0
  60. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderConfigManagerDelegate.java +3 -0
  61. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderConfigManagerInterface.java +1 -0
  62. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSSearchBarManagerDelegate.java +99 -0
  63. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSSearchBarManagerInterface.java +37 -0
  64. package/android/src/paper/java/com/swmansion/rnscreens/FabricEnabledViewGroup.kt +10 -5
  65. package/android/src/paper/java/com/swmansion/rnscreens/NativeProxy.kt +19 -0
  66. package/android/src/paper/java/com/swmansion/rnscreens/NativeScreensModuleSpec.java +4 -0
  67. package/common/cpp/react/renderer/components/rnscreens/FrameCorrectionModes.h +51 -0
  68. package/common/cpp/react/renderer/components/rnscreens/RNSModalScreenComponentDescriptor.h +8 -9
  69. package/common/cpp/react/renderer/components/rnscreens/RNSModalScreenShadowNode.cpp +2 -1
  70. package/common/cpp/react/renderer/components/rnscreens/RNSModalScreenShadowNode.h +9 -8
  71. package/common/cpp/react/renderer/components/rnscreens/RNSScreenComponentDescriptor.h +147 -10
  72. package/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.cpp +51 -1
  73. package/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.h +29 -7
  74. package/common/cpp/react/renderer/components/rnscreens/RNSScreenState.cpp +22 -1
  75. package/common/cpp/react/renderer/components/rnscreens/RNSScreenState.h +30 -10
  76. package/common/cpp/react/renderer/components/rnscreens/utils/RectUtil.h +36 -0
  77. package/cpp/RNSScreenRemovalListener.cpp +25 -0
  78. package/cpp/RNSScreenRemovalListener.h +20 -0
  79. package/cpp/RNScreensTurboModule.cpp +31 -23
  80. package/cpp/RNScreensTurboModule.h +17 -20
  81. package/ios/RNSConvert.h +7 -0
  82. package/ios/RNSConvert.mm +24 -0
  83. package/ios/RNSModalScreen.mm +22 -0
  84. package/ios/RNSModule.mm +2 -3
  85. package/ios/RNSScreen.h +2 -1
  86. package/ios/RNSScreen.mm +35 -19
  87. package/ios/RNSScreenContainer.mm +1 -1
  88. package/ios/RNSScreenStack.mm +59 -54
  89. package/ios/RNSScreenStackAnimator.mm +43 -6
  90. package/ios/RNSScreenStackHeaderConfig.h +2 -0
  91. package/ios/RNSScreenStackHeaderConfig.mm +93 -28
  92. package/ios/RNSScreenStackHeaderSubview.mm +8 -0
  93. package/ios/RNSSearchBar.h +5 -5
  94. package/ios/RNSSearchBar.mm +11 -11
  95. package/ios/utils/RCTSurfaceTouchHandler+RNSUtility.h +15 -0
  96. package/ios/utils/RCTSurfaceTouchHandler+RNSUtility.mm +14 -0
  97. package/ios/utils/RCTTouchHandler+RNSUtility.h +15 -0
  98. package/ios/utils/RCTTouchHandler+RNSUtility.mm +15 -0
  99. package/ios/utils/UIView+RNSUtility.h +23 -0
  100. package/ios/utils/UIView+RNSUtility.mm +55 -0
  101. package/lib/commonjs/components/Screen.js +119 -127
  102. package/lib/commonjs/components/Screen.js.map +1 -1
  103. package/lib/commonjs/components/ScreenStack.js +8 -1
  104. package/lib/commonjs/components/ScreenStack.js.map +1 -1
  105. package/lib/commonjs/components/SearchBar.js +39 -36
  106. package/lib/commonjs/components/SearchBar.js.map +1 -1
  107. package/lib/commonjs/fabric/ModalScreenNativeComponent.js.map +1 -1
  108. package/lib/commonjs/fabric/ScreenNativeComponent.js.map +1 -1
  109. package/lib/commonjs/fabric/ScreenStackHeaderConfigNativeComponent.js.map +1 -1
  110. package/lib/commonjs/native-stack/views/HeaderConfig.js +2 -0
  111. package/lib/commonjs/native-stack/views/HeaderConfig.js.map +1 -1
  112. package/lib/commonjs/native-stack/views/NativeStackView.js +4 -0
  113. package/lib/commonjs/native-stack/views/NativeStackView.js.map +1 -1
  114. package/lib/module/components/Screen.js +118 -126
  115. package/lib/module/components/Screen.js.map +1 -1
  116. package/lib/module/components/ScreenStack.js +8 -1
  117. package/lib/module/components/ScreenStack.js.map +1 -1
  118. package/lib/module/components/SearchBar.js +39 -36
  119. package/lib/module/components/SearchBar.js.map +1 -1
  120. package/lib/module/fabric/ModalScreenNativeComponent.js.map +1 -1
  121. package/lib/module/fabric/ScreenNativeComponent.js.map +1 -1
  122. package/lib/module/fabric/ScreenStackHeaderConfigNativeComponent.js.map +1 -1
  123. package/lib/module/native-stack/views/HeaderConfig.js +2 -0
  124. package/lib/module/native-stack/views/HeaderConfig.js.map +1 -1
  125. package/lib/module/native-stack/views/NativeStackView.js +4 -0
  126. package/lib/module/native-stack/views/NativeStackView.js.map +1 -1
  127. package/lib/typescript/TransitionProgressContext.d.ts +1 -1
  128. package/lib/typescript/TransitionProgressContext.d.ts.map +1 -1
  129. package/lib/typescript/components/Screen.d.ts +3 -14
  130. package/lib/typescript/components/Screen.d.ts.map +1 -1
  131. package/lib/typescript/components/ScreenStack.d.ts.map +1 -1
  132. package/lib/typescript/components/SearchBar.d.ts +14 -21
  133. package/lib/typescript/components/SearchBar.d.ts.map +1 -1
  134. package/lib/typescript/fabric/ModalScreenNativeComponent.d.ts +12 -10
  135. package/lib/typescript/fabric/ModalScreenNativeComponent.d.ts.map +1 -1
  136. package/lib/typescript/fabric/ScreenNativeComponent.d.ts +12 -10
  137. package/lib/typescript/fabric/ScreenNativeComponent.d.ts.map +1 -1
  138. package/lib/typescript/fabric/ScreenStackHeaderConfigNativeComponent.d.ts +5 -3
  139. package/lib/typescript/fabric/ScreenStackHeaderConfigNativeComponent.d.ts.map +1 -1
  140. package/lib/typescript/fabric/ScreenStackHeaderSubviewNativeComponent.d.ts +1 -1
  141. package/lib/typescript/fabric/ScreenStackHeaderSubviewNativeComponent.d.ts.map +1 -1
  142. package/lib/typescript/fabric/ScreenStackNativeComponent.d.ts +1 -1
  143. package/lib/typescript/fabric/ScreenStackNativeComponent.d.ts.map +1 -1
  144. package/lib/typescript/fabric/SearchBarNativeComponent.d.ts +9 -9
  145. package/lib/typescript/fabric/SearchBarNativeComponent.d.ts.map +1 -1
  146. package/lib/typescript/gesture-handler/RNScreensTurboModule.d.ts +1 -1
  147. package/lib/typescript/gesture-handler/RNScreensTurboModule.d.ts.map +1 -1
  148. package/lib/typescript/native-stack/types.d.ts +39 -14
  149. package/lib/typescript/native-stack/types.d.ts.map +1 -1
  150. package/lib/typescript/native-stack/utils/SafeAreaProviderCompat.d.ts +1 -1
  151. package/lib/typescript/native-stack/utils/SafeAreaProviderCompat.d.ts.map +1 -1
  152. package/lib/typescript/native-stack/utils/getDefaultHeaderHeight.d.ts +1 -1
  153. package/lib/typescript/native-stack/utils/getDefaultHeaderHeight.d.ts.map +1 -1
  154. package/lib/typescript/native-stack/utils/useAnimatedHeaderHeight.d.ts +1 -1
  155. package/lib/typescript/native-stack/utils/useAnimatedHeaderHeight.d.ts.map +1 -1
  156. package/lib/typescript/native-stack/views/HeaderConfig.d.ts +2 -2
  157. package/lib/typescript/native-stack/views/HeaderConfig.d.ts.map +1 -1
  158. package/lib/typescript/native-stack/views/NativeStackView.d.ts +1 -1
  159. package/lib/typescript/native-stack/views/NativeStackView.d.ts.map +1 -1
  160. package/lib/typescript/reanimated/ReanimatedTransitionProgressContext.d.ts +1 -1
  161. package/lib/typescript/reanimated/ReanimatedTransitionProgressContext.d.ts.map +1 -1
  162. package/lib/typescript/types.d.ts +39 -13
  163. package/lib/typescript/types.d.ts.map +1 -1
  164. package/lib/typescript/useTransitionProgress.d.ts +3 -3
  165. package/native-stack/README.md +116 -98
  166. package/package.json +16 -7
  167. package/react-native.config.js +17 -15
  168. package/src/TransitionProgressContext.tsx +1 -1
  169. package/src/components/Screen.tsx +31 -37
  170. package/src/components/ScreenStack.tsx +11 -1
  171. package/src/components/ScreenStackHeaderConfig.tsx +5 -5
  172. package/src/components/ScreenStackHeaderConfig.web.tsx +6 -6
  173. package/src/components/SearchBar.tsx +77 -65
  174. package/src/core.ts +1 -1
  175. package/src/fabric/ModalScreenNativeComponent.ts +2 -0
  176. package/src/fabric/ScreenNativeComponent.ts +2 -0
  177. package/src/fabric/ScreenNavigationContainerNativeComponent.ts +1 -1
  178. package/src/fabric/ScreenStackHeaderConfigNativeComponent.ts +4 -1
  179. package/src/fabric/ScreenStackHeaderSubviewNativeComponent.ts +1 -1
  180. package/src/fabric/SearchBarNativeComponent.ts +7 -7
  181. package/src/gesture-handler/ScreenGestureDetector.tsx +5 -5
  182. package/src/gesture-handler/constraints.ts +5 -5
  183. package/src/gesture-handler/fabricUtils.ts +1 -1
  184. package/src/native-stack/contexts/GHContext.tsx +1 -1
  185. package/src/native-stack/navigators/createNativeStackNavigator.tsx +3 -3
  186. package/src/native-stack/types.tsx +29 -4
  187. package/src/native-stack/utils/getDefaultHeaderHeight.tsx +1 -1
  188. package/src/native-stack/utils/getStatusBarHeight.tsx +1 -1
  189. package/src/native-stack/utils/useAnimatedHeaderHeight.tsx +1 -1
  190. package/src/native-stack/utils/useBackPressSubscription.tsx +1 -1
  191. package/src/native-stack/utils/useHeaderHeight.tsx +1 -1
  192. package/src/native-stack/views/FontProcessor.tsx +1 -1
  193. package/src/native-stack/views/HeaderConfig.tsx +3 -1
  194. package/src/native-stack/views/NativeStackView.tsx +13 -9
  195. package/src/reanimated/ReanimatedHeaderHeightContext.tsx +1 -1
  196. package/src/reanimated/ReanimatedNativeStackScreen.tsx +5 -5
  197. package/src/reanimated/ReanimatedScreen.tsx +2 -2
  198. package/src/reanimated/ReanimatedScreenProvider.tsx +1 -1
  199. package/src/reanimated/useReanimatedHeaderHeight.tsx +1 -1
  200. package/src/reanimated/useReanimatedTransitionProgress.tsx +1 -1
  201. package/src/types.tsx +31 -5
  202. package/src/useTransitionProgress.tsx +1 -1
  203. package/windows/README.md +4 -1
@@ -4,7 +4,10 @@ import com.facebook.react.bridge.Arguments
4
4
  import com.facebook.react.bridge.WritableMap
5
5
  import com.facebook.react.uimanager.events.Event
6
6
 
7
- class SearchBarOpenEvent(surfaceId: Int, viewId: Int) : Event<SearchBarOpenEvent>(surfaceId, viewId) {
7
+ class SearchBarOpenEvent(
8
+ surfaceId: Int,
9
+ viewId: Int,
10
+ ) : Event<SearchBarOpenEvent>(surfaceId, viewId) {
8
11
  override fun getEventName(): String = EVENT_NAME
9
12
 
10
13
  // All events for a given view can be coalesced.
@@ -4,15 +4,20 @@ import com.facebook.react.bridge.Arguments
4
4
  import com.facebook.react.bridge.WritableMap
5
5
  import com.facebook.react.uimanager.events.Event
6
6
 
7
- class SearchBarSearchButtonPressEvent(surfaceId: Int, viewId: Int, private val text: String?) : Event<SearchBarSearchButtonPressEvent>(surfaceId, viewId) {
7
+ class SearchBarSearchButtonPressEvent(
8
+ surfaceId: Int,
9
+ viewId: Int,
10
+ private val text: String?,
11
+ ) : Event<SearchBarSearchButtonPressEvent>(surfaceId, viewId) {
8
12
  override fun getEventName(): String = EVENT_NAME
9
13
 
10
14
  // All events for a given view can be coalesced.
11
15
  override fun getCoalescingKey(): Short = 0
12
16
 
13
- override fun getEventData(): WritableMap? = Arguments.createMap().apply {
14
- putString("text", text)
15
- }
17
+ override fun getEventData(): WritableMap? =
18
+ Arguments.createMap().apply {
19
+ putString("text", text)
20
+ }
16
21
 
17
22
  companion object {
18
23
  const val EVENT_NAME = "topSearchButtonPress"
@@ -4,7 +4,10 @@ import com.facebook.react.bridge.Arguments
4
4
  import com.facebook.react.bridge.WritableMap
5
5
  import com.facebook.react.uimanager.events.Event
6
6
 
7
- class StackFinishTransitioningEvent(surfaceId: Int, viewId: Int) : Event<StackFinishTransitioningEvent>(surfaceId, viewId) {
7
+ class StackFinishTransitioningEvent(
8
+ surfaceId: Int,
9
+ viewId: Int,
10
+ ) : Event<StackFinishTransitioningEvent>(surfaceId, viewId) {
8
11
  override fun getEventName() = EVENT_NAME
9
12
 
10
13
  // All events for a given view can be coalesced.
@@ -4,9 +4,5 @@ import android.content.Context
4
4
  import android.content.pm.PackageManager
5
5
 
6
6
  object DeviceUtils {
7
-
8
- fun isPlatformAndroidTV(context: Context?): Boolean {
9
- return context?.packageManager?.hasSystemFeature(PackageManager.FEATURE_LEANBACK) == true
10
- }
11
-
7
+ fun isPlatformAndroidTV(context: Context?): Boolean = context?.packageManager?.hasSystemFeature(PackageManager.FEATURE_LEANBACK) == true
12
8
  }
@@ -0,0 +1,214 @@
1
+ package com.swmansion.rnscreens.utils
2
+
3
+ import android.app.Activity
4
+ import android.util.Log
5
+ import android.view.View
6
+ import androidx.appcompat.widget.Toolbar
7
+ import androidx.coordinatorlayout.widget.CoordinatorLayout
8
+ import com.facebook.react.bridge.ReactApplicationContext
9
+ import com.facebook.react.uimanager.PixelUtil
10
+ import com.google.android.material.appbar.AppBarLayout
11
+ import com.swmansion.rnscreens.ScreenStackHeaderConfig
12
+ import java.lang.ref.WeakReference
13
+
14
+ /**
15
+ * This class provides methods to create dummy layout (that mimics Screen setup), and to compute
16
+ * expected header height. It is meant to be accessed from C++ layer via JNI.
17
+ * See https://github.com/software-mansion/react-native-screens/pull/2169
18
+ * for more detailed description of the issue this code solves.
19
+ */
20
+ internal class ScreenDummyLayoutHelper(
21
+ reactContext: ReactApplicationContext,
22
+ ) {
23
+ // The state required to compute header dimensions. We want this on instance rather than on class
24
+ // for context access & being tied to instance lifetime.
25
+ private lateinit var coordinatorLayout: CoordinatorLayout
26
+ private lateinit var appBarLayout: AppBarLayout
27
+ private lateinit var dummyContentView: View
28
+ private lateinit var toolbar: Toolbar
29
+ private var defaultFontSize: Float = 0f
30
+ private var defaultContentInsetStartWithNavigation: Int = 0
31
+
32
+ // LRU with size 1
33
+ private var cache: CacheEntry = CacheEntry.EMPTY
34
+
35
+ // We do not want to be responsible for the context lifecycle. If it's null, we're fine.
36
+ // This same context is being passed down to our view components so it is destroyed
37
+ // only if our views also are.
38
+ private var reactContextRef: WeakReference<ReactApplicationContext> =
39
+ WeakReference(reactContext)
40
+
41
+ init {
42
+
43
+ // We load the library so that we are able to communicate with our C++ code (descriptor & shadow nodes).
44
+ // Basically we leak this object to C++, as its lifecycle should span throughout whole application
45
+ // lifecycle anyway.
46
+ try {
47
+ System.loadLibrary(LIBRARY_NAME)
48
+ } catch (e: UnsatisfiedLinkError) {
49
+ Log.w(TAG, "Failed to load $LIBRARY_NAME")
50
+ }
51
+
52
+ weakInstance = WeakReference(this)
53
+ ensureDummyLayoutWithHeader(reactContext)
54
+ }
55
+
56
+ /**
57
+ * Initializes dummy view hierarchy with CoordinatorLayout, AppBarLayout and dummy View.
58
+ * We utilize this to compute header height (app bar layout height) from C++ layer when its needed.
59
+ */
60
+ private fun ensureDummyLayoutWithHeader(reactContext: ReactApplicationContext) {
61
+ if (::coordinatorLayout.isInitialized) {
62
+ return
63
+ }
64
+
65
+ // We need to use activity here, as react context does not have theme attributes required by
66
+ // AppBarLayout attached leading to crash.
67
+ val contextWithTheme =
68
+ requireNotNull(reactContext.currentActivity) { "[RNScreens] Attempt to use context detached from activity" }
69
+
70
+ coordinatorLayout = CoordinatorLayout(contextWithTheme)
71
+
72
+ appBarLayout =
73
+ AppBarLayout(contextWithTheme).apply {
74
+ layoutParams =
75
+ CoordinatorLayout.LayoutParams(
76
+ CoordinatorLayout.LayoutParams.MATCH_PARENT,
77
+ CoordinatorLayout.LayoutParams.WRAP_CONTENT,
78
+ )
79
+ }
80
+
81
+ toolbar =
82
+ Toolbar(contextWithTheme).apply {
83
+ title = DEFAULT_HEADER_TITLE
84
+ layoutParams =
85
+ AppBarLayout
86
+ .LayoutParams(
87
+ AppBarLayout.LayoutParams.MATCH_PARENT,
88
+ AppBarLayout.LayoutParams.WRAP_CONTENT,
89
+ ).apply { scrollFlags = 0 }
90
+ }
91
+
92
+ // We know the title text view will be there, cause we've just set title.
93
+ defaultFontSize = ScreenStackHeaderConfig.findTitleTextViewInToolbar(toolbar)!!.textSize
94
+ defaultContentInsetStartWithNavigation = toolbar.contentInsetStartWithNavigation
95
+
96
+ appBarLayout.addView(toolbar)
97
+
98
+ dummyContentView =
99
+ View(contextWithTheme).apply {
100
+ layoutParams =
101
+ CoordinatorLayout.LayoutParams(
102
+ CoordinatorLayout.LayoutParams.MATCH_PARENT,
103
+ CoordinatorLayout.LayoutParams.MATCH_PARENT,
104
+ )
105
+ }
106
+
107
+ coordinatorLayout.apply {
108
+ addView(appBarLayout)
109
+ addView(dummyContentView)
110
+ }
111
+ }
112
+
113
+ /**
114
+ * Triggers layout pass on dummy view hierarchy, taking into consideration selected
115
+ * ScreenStackHeaderConfig props that might have impact on final header height.
116
+ *
117
+ * @param fontSize font size value as passed from JS
118
+ * @return header height in dp as consumed by Yoga
119
+ */
120
+ private fun computeDummyLayout(
121
+ fontSize: Int,
122
+ isTitleEmpty: Boolean,
123
+ ): Float {
124
+ if (!::coordinatorLayout.isInitialized) {
125
+ Log.e(
126
+ TAG,
127
+ "[RNScreens] Attempt to access dummy view hierarchy before it is initialized",
128
+ )
129
+ return 0.0f
130
+ }
131
+
132
+ if (cache.hasKey(CacheKey(fontSize, isTitleEmpty))) {
133
+ return cache.headerHeight
134
+ }
135
+
136
+ val topLevelDecorView = requireActivity().window.decorView
137
+
138
+ // These dimensions are not accurate, as they do include status bar & navigation bar, however
139
+ // it is ok for our purposes.
140
+ val decorViewWidth = topLevelDecorView.width
141
+ val decorViewHeight = topLevelDecorView.height
142
+
143
+ val widthMeasureSpec =
144
+ View.MeasureSpec.makeMeasureSpec(decorViewWidth, View.MeasureSpec.EXACTLY)
145
+ val heightMeasureSpec =
146
+ View.MeasureSpec.makeMeasureSpec(decorViewHeight, View.MeasureSpec.EXACTLY)
147
+
148
+ if (isTitleEmpty) {
149
+ toolbar.title = ""
150
+ toolbar.contentInsetStartWithNavigation = 0
151
+ } else {
152
+ toolbar.title = DEFAULT_HEADER_TITLE
153
+ toolbar.contentInsetStartWithNavigation = defaultContentInsetStartWithNavigation
154
+ }
155
+
156
+ val textView = ScreenStackHeaderConfig.findTitleTextViewInToolbar(toolbar)
157
+ textView?.textSize =
158
+ if (fontSize != FONT_SIZE_UNSET) fontSize.toFloat() else defaultFontSize
159
+
160
+ coordinatorLayout.measure(widthMeasureSpec, heightMeasureSpec)
161
+
162
+ // It seems that measure pass would be enough, however I'm not certain whether there are no
163
+ // scenarios when layout violates measured dimensions.
164
+ coordinatorLayout.layout(0, 0, decorViewWidth, decorViewHeight)
165
+
166
+ val headerHeight = PixelUtil.toDIPFromPixel(appBarLayout.height.toFloat())
167
+ cache = CacheEntry(CacheKey(fontSize, isTitleEmpty), headerHeight)
168
+ return headerHeight
169
+ }
170
+
171
+ private fun requireReactContext(): ReactApplicationContext =
172
+ requireNotNull(reactContextRef.get()) {
173
+ "[RNScreens] Attempt to require missing react context"
174
+ }
175
+
176
+ private fun requireActivity(): Activity =
177
+ requireNotNull(requireReactContext().currentActivity) {
178
+ "[RNScreens] Attempt to use context detached from activity"
179
+ }
180
+
181
+ companion object {
182
+ const val TAG = "ScreenDummyLayoutHelper"
183
+
184
+ const val LIBRARY_NAME = "react_codegen_rnscreens"
185
+
186
+ const val FONT_SIZE_UNSET = -1
187
+
188
+ private const val DEFAULT_HEADER_TITLE: String = "FontSize123!#$"
189
+
190
+ // We access this field from C++ layer, through `getInstance` method.
191
+ // We don't care what instance we get access to as long as it has initialized
192
+ // dummy view hierarchy.
193
+ private var weakInstance = WeakReference<ScreenDummyLayoutHelper>(null)
194
+
195
+ @JvmStatic
196
+ fun getInstance(): ScreenDummyLayoutHelper? = weakInstance.get()
197
+ }
198
+ }
199
+
200
+ private data class CacheKey(
201
+ val fontSize: Int,
202
+ val isTitleEmpty: Boolean,
203
+ )
204
+
205
+ private class CacheEntry(
206
+ val cacheKey: CacheKey,
207
+ val headerHeight: Float,
208
+ ) {
209
+ fun hasKey(key: CacheKey) = cacheKey.fontSize != Int.MIN_VALUE && cacheKey == key
210
+
211
+ companion object {
212
+ val EMPTY = CacheEntry(CacheKey(Int.MIN_VALUE, false), 0f)
213
+ }
214
+ }
@@ -6,6 +6,7 @@ set(LIB_TARGET_NAME react_codegen_${LIB_LITERAL})
6
6
 
7
7
  set(LIB_ANDROID_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../..)
8
8
  set(LIB_COMMON_DIR ${LIB_ANDROID_DIR}/../common/cpp)
9
+ set(LIB_COMMON_COMPONENTS_DIR ${LIB_COMMON_DIR}/react/renderer/components/${LIB_LITERAL})
9
10
  set(LIB_ANDROID_GENERATED_JNI_DIR ${LIB_ANDROID_DIR}/build/generated/source/codegen/jni)
10
11
  set(LIB_ANDROID_GENERATED_COMPONENTS_DIR ${LIB_ANDROID_GENERATED_JNI_DIR}/react/renderer/components/${LIB_LITERAL})
11
12
 
@@ -18,20 +19,20 @@ add_compile_options(
18
19
  -Wno-gnu-zero-variadic-macro-arguments
19
20
  )
20
21
 
21
- file(GLOB LIB_CUSTOM_SRCS CONFIGURE_DEPENDS *.cpp ${LIB_COMMON_DIR}/react/renderer/components/${LIB_LITERAL}/*.cpp)
22
+ file(GLOB LIB_CUSTOM_SRCS CONFIGURE_DEPENDS *.cpp ${LIB_COMMON_COMPONENTS_DIR}/*.cpp ${LIB_COMMON_COMPONENTS_DIR}/utils/*.cpp)
22
23
  file(GLOB LIB_CODEGEN_SRCS CONFIGURE_DEPENDS ${LIB_ANDROID_GENERATED_COMPONENTS_DIR}/*.cpp)
23
24
 
24
25
  add_library(
25
26
  ${LIB_TARGET_NAME}
26
- SHARED
27
+ SHARED
27
28
  ${LIB_CUSTOM_SRCS}
28
29
  ${LIB_CODEGEN_SRCS}
29
30
  )
30
31
 
31
32
  target_include_directories(
32
33
  ${LIB_TARGET_NAME}
33
- PUBLIC
34
- .
34
+ PUBLIC
35
+ .
35
36
  ${LIB_COMMON_DIR}
36
37
  ${LIB_ANDROID_GENERATED_JNI_DIR}
37
38
  ${LIB_ANDROID_GENERATED_COMPONENTS_DIR}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
3
+ *
4
+ * Do not edit this file as changes may cause incorrect behavior and will be lost
5
+ * once the code is regenerated.
6
+ *
7
+ * @generated by codegen project: GeneratePropsJavaDelegate.js
8
+ */
9
+
10
+ package com.facebook.react.viewmanagers;
11
+
12
+ import android.view.View;
13
+ import androidx.annotation.Nullable;
14
+ import com.facebook.react.uimanager.BaseViewManagerDelegate;
15
+ import com.facebook.react.uimanager.BaseViewManagerInterface;
16
+
17
+ public class RNSScreenContainerManagerDelegate<T extends View, U extends BaseViewManagerInterface<T> & RNSScreenContainerManagerInterface<T>> extends BaseViewManagerDelegate<T, U> {
18
+ public RNSScreenContainerManagerDelegate(U viewManager) {
19
+ super(viewManager);
20
+ }
21
+ @Override
22
+ public void setProperty(T view, String propName, @Nullable Object value) {
23
+ super.setProperty(view, propName, value);
24
+ }
25
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
3
+ *
4
+ * Do not edit this file as changes may cause incorrect behavior and will be lost
5
+ * once the code is regenerated.
6
+ *
7
+ * @generated by codegen project: GeneratePropsJavaInterface.js
8
+ */
9
+
10
+ package com.facebook.react.viewmanagers;
11
+
12
+ import android.view.View;
13
+
14
+ public interface RNSScreenContainerManagerInterface<T extends View> {
15
+ // No props
16
+ }
@@ -44,6 +44,9 @@ public class RNSScreenManagerDelegate<T extends View, U extends BaseViewManagerI
44
44
  case "fullScreenSwipeEnabled":
45
45
  mViewManager.setFullScreenSwipeEnabled(view, value == null ? false : (boolean) value);
46
46
  break;
47
+ case "fullScreenSwipeShadowEnabled":
48
+ mViewManager.setFullScreenSwipeShadowEnabled(view, value == null ? false : (boolean) value);
49
+ break;
47
50
  case "homeIndicatorHidden":
48
51
  mViewManager.setHomeIndicatorHidden(view, value == null ? false : (boolean) value);
49
52
  break;
@@ -98,6 +101,9 @@ public class RNSScreenManagerDelegate<T extends View, U extends BaseViewManagerI
98
101
  case "navigationBarColor":
99
102
  mViewManager.setNavigationBarColor(view, ColorPropConverter.getColor(value, view.getContext()));
100
103
  break;
104
+ case "navigationBarTranslucent":
105
+ mViewManager.setNavigationBarTranslucent(view, value == null ? false : (boolean) value);
106
+ break;
101
107
  case "navigationBarHidden":
102
108
  mViewManager.setNavigationBarHidden(view, value == null ? false : (boolean) value);
103
109
  break;
@@ -21,6 +21,7 @@ public interface RNSScreenManagerInterface<T extends View> {
21
21
  void setSheetExpandsWhenScrolledToEdge(T view, boolean value);
22
22
  void setCustomAnimationOnSwipe(T view, boolean value);
23
23
  void setFullScreenSwipeEnabled(T view, boolean value);
24
+ void setFullScreenSwipeShadowEnabled(T view, boolean value);
24
25
  void setHomeIndicatorHidden(T view, boolean value);
25
26
  void setPreventNativeDismiss(T view, boolean value);
26
27
  void setGestureEnabled(T view, boolean value);
@@ -39,6 +40,7 @@ public interface RNSScreenManagerInterface<T extends View> {
39
40
  void setHideKeyboardOnSwipe(T view, boolean value);
40
41
  void setActivityState(T view, float value);
41
42
  void setNavigationBarColor(T view, @Nullable Integer value);
43
+ void setNavigationBarTranslucent(T view, boolean value);
42
44
  void setNavigationBarHidden(T view, boolean value);
43
45
  void setNativeBackButtonDismissalEnabled(T view, boolean value);
44
46
  }
@@ -91,6 +91,9 @@ public class RNSScreenStackHeaderConfigManagerDelegate<T extends View, U extends
91
91
  case "disableBackButtonMenu":
92
92
  mViewManager.setDisableBackButtonMenu(view, value == null ? false : (boolean) value);
93
93
  break;
94
+ case "backButtonDisplayMode":
95
+ mViewManager.setBackButtonDisplayMode(view, (String) value);
96
+ break;
94
97
  case "hideBackButton":
95
98
  mViewManager.setHideBackButton(view, value == null ? false : (boolean) value);
96
99
  break;
@@ -36,6 +36,7 @@ public interface RNSScreenStackHeaderConfigManagerInterface<T extends View> {
36
36
  void setTitleFontWeight(T view, @Nullable String value);
37
37
  void setTitleColor(T view, @Nullable Integer value);
38
38
  void setDisableBackButtonMenu(T view, boolean value);
39
+ void setBackButtonDisplayMode(T view, @Nullable String value);
39
40
  void setHideBackButton(T view, boolean value);
40
41
  void setBackButtonInCustomView(T view, boolean value);
41
42
  void setTopInsetEnabled(T view, boolean value);
@@ -0,0 +1,99 @@
1
+ /**
2
+ * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
3
+ *
4
+ * Do not edit this file as changes may cause incorrect behavior and will be lost
5
+ * once the code is regenerated.
6
+ *
7
+ * @generated by codegen project: GeneratePropsJavaDelegate.js
8
+ */
9
+
10
+ package com.facebook.react.viewmanagers;
11
+
12
+ import android.view.View;
13
+ import androidx.annotation.Nullable;
14
+ import com.facebook.react.bridge.ColorPropConverter;
15
+ import com.facebook.react.bridge.ReadableArray;
16
+ import com.facebook.react.uimanager.BaseViewManagerDelegate;
17
+ import com.facebook.react.uimanager.BaseViewManagerInterface;
18
+
19
+ public class RNSSearchBarManagerDelegate<T extends View, U extends BaseViewManagerInterface<T> & RNSSearchBarManagerInterface<T>> extends BaseViewManagerDelegate<T, U> {
20
+ public RNSSearchBarManagerDelegate(U viewManager) {
21
+ super(viewManager);
22
+ }
23
+ @Override
24
+ public void setProperty(T view, String propName, @Nullable Object value) {
25
+ switch (propName) {
26
+ case "hideWhenScrolling":
27
+ mViewManager.setHideWhenScrolling(view, value == null ? false : (boolean) value);
28
+ break;
29
+ case "autoCapitalize":
30
+ mViewManager.setAutoCapitalize(view, (String) value);
31
+ break;
32
+ case "placeholder":
33
+ mViewManager.setPlaceholder(view, value == null ? null : (String) value);
34
+ break;
35
+ case "placement":
36
+ mViewManager.setPlacement(view, (String) value);
37
+ break;
38
+ case "obscureBackground":
39
+ mViewManager.setObscureBackground(view, value == null ? false : (boolean) value);
40
+ break;
41
+ case "hideNavigationBar":
42
+ mViewManager.setHideNavigationBar(view, value == null ? false : (boolean) value);
43
+ break;
44
+ case "cancelButtonText":
45
+ mViewManager.setCancelButtonText(view, value == null ? null : (String) value);
46
+ break;
47
+ case "barTintColor":
48
+ mViewManager.setBarTintColor(view, ColorPropConverter.getColor(value, view.getContext()));
49
+ break;
50
+ case "tintColor":
51
+ mViewManager.setTintColor(view, ColorPropConverter.getColor(value, view.getContext()));
52
+ break;
53
+ case "textColor":
54
+ mViewManager.setTextColor(view, ColorPropConverter.getColor(value, view.getContext()));
55
+ break;
56
+ case "disableBackButtonOverride":
57
+ mViewManager.setDisableBackButtonOverride(view, value == null ? false : (boolean) value);
58
+ break;
59
+ case "inputType":
60
+ mViewManager.setInputType(view, value == null ? null : (String) value);
61
+ break;
62
+ case "hintTextColor":
63
+ mViewManager.setHintTextColor(view, ColorPropConverter.getColor(value, view.getContext()));
64
+ break;
65
+ case "headerIconColor":
66
+ mViewManager.setHeaderIconColor(view, ColorPropConverter.getColor(value, view.getContext()));
67
+ break;
68
+ case "shouldShowHintSearchIcon":
69
+ mViewManager.setShouldShowHintSearchIcon(view, value == null ? true : (boolean) value);
70
+ break;
71
+ default:
72
+ super.setProperty(view, propName, value);
73
+ }
74
+ }
75
+
76
+ @Override
77
+ public void receiveCommand(T view, String commandName, ReadableArray args) {
78
+ switch (commandName) {
79
+ case "blur":
80
+ mViewManager.blur(view);
81
+ break;
82
+ case "focus":
83
+ mViewManager.focus(view);
84
+ break;
85
+ case "clearText":
86
+ mViewManager.clearText(view);
87
+ break;
88
+ case "toggleCancelButton":
89
+ mViewManager.toggleCancelButton(view, args.getBoolean(0));
90
+ break;
91
+ case "setText":
92
+ mViewManager.setText(view, args.getString(0));
93
+ break;
94
+ case "cancelSearch":
95
+ mViewManager.cancelSearch(view);
96
+ break;
97
+ }
98
+ }
99
+ }
@@ -0,0 +1,37 @@
1
+ /**
2
+ * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
3
+ *
4
+ * Do not edit this file as changes may cause incorrect behavior and will be lost
5
+ * once the code is regenerated.
6
+ *
7
+ * @generated by codegen project: GeneratePropsJavaInterface.js
8
+ */
9
+
10
+ package com.facebook.react.viewmanagers;
11
+
12
+ import android.view.View;
13
+ import androidx.annotation.Nullable;
14
+
15
+ public interface RNSSearchBarManagerInterface<T extends View> {
16
+ void setHideWhenScrolling(T view, boolean value);
17
+ void setAutoCapitalize(T view, @Nullable String value);
18
+ void setPlaceholder(T view, @Nullable String value);
19
+ void setPlacement(T view, @Nullable String value);
20
+ void setObscureBackground(T view, boolean value);
21
+ void setHideNavigationBar(T view, boolean value);
22
+ void setCancelButtonText(T view, @Nullable String value);
23
+ void setBarTintColor(T view, @Nullable Integer value);
24
+ void setTintColor(T view, @Nullable Integer value);
25
+ void setTextColor(T view, @Nullable Integer value);
26
+ void setDisableBackButtonOverride(T view, boolean value);
27
+ void setInputType(T view, @Nullable String value);
28
+ void setHintTextColor(T view, @Nullable Integer value);
29
+ void setHeaderIconColor(T view, @Nullable Integer value);
30
+ void setShouldShowHintSearchIcon(T view, boolean value);
31
+ void blur(T view);
32
+ void focus(T view);
33
+ void clearText(T view);
34
+ void toggleCancelButton(T view, boolean flag);
35
+ void setText(T view, String text);
36
+ void cancelSearch(T view);
37
+ }
@@ -2,13 +2,18 @@ package com.swmansion.rnscreens
2
2
 
3
3
  import android.view.ViewGroup
4
4
  import com.facebook.react.bridge.ReactContext
5
- import com.facebook.react.uimanager.FabricViewStateManager
5
+ import com.facebook.react.uimanager.StateWrapper
6
6
 
7
- abstract class FabricEnabledViewGroup constructor(context: ReactContext?) : ViewGroup(context) {
7
+ abstract class FabricEnabledViewGroup(
8
+ context: ReactContext?,
9
+ ) : ViewGroup(context) {
10
+ fun setStateWrapper(wrapper: StateWrapper?) = Unit
8
11
 
9
- val fabricViewStateManager get() = null as FabricViewStateManager?
10
-
11
- protected fun updateScreenSizeFabric(width: Int, height: Int, headerHeight: Double) {
12
+ protected fun updateScreenSizeFabric(
13
+ width: Int,
14
+ height: Int,
15
+ headerHeight: Double,
16
+ ) {
12
17
  // do nothing
13
18
  }
14
19
  }
@@ -0,0 +1,19 @@
1
+ package com.swmansion.rnscreens
2
+
3
+ import com.facebook.react.fabric.FabricUIManager
4
+
5
+ class NativeProxy {
6
+ // do nothing on Paper
7
+ fun nativeAddMutationsListener(fabricUIManager: FabricUIManager) = Unit
8
+
9
+ companion object {
10
+ fun addScreenToMap(
11
+ tag: Int,
12
+ view: Screen,
13
+ ) = Unit
14
+
15
+ fun removeScreenFromMap(tag: Int) = Unit
16
+
17
+ fun clearMapOnInvalidate() = Unit
18
+ }
19
+ }
@@ -12,8 +12,10 @@
12
12
 
13
13
  package com.swmansion.rnscreens;
14
14
 
15
+ import com.facebook.proguard.annotations.DoNotStrip;
15
16
  import com.facebook.react.bridge.ReactApplicationContext;
16
17
  import com.facebook.react.bridge.ReactContextBaseJavaModule;
18
+ import com.facebook.react.bridge.ReactMethod;
17
19
  import com.facebook.react.bridge.ReactModuleWithSpec;
18
20
  import com.facebook.react.turbomodule.core.interfaces.TurboModule;
19
21
  import javax.annotation.Nonnull;
@@ -29,4 +31,6 @@ public abstract class NativeScreensModuleSpec extends ReactContextBaseJavaModule
29
31
  public @Nonnull String getName() {
30
32
  return NAME;
31
33
  }
34
+
35
+
32
36
  }
@@ -0,0 +1,51 @@
1
+ #pragma once
2
+
3
+ #include <cstdint>
4
+
5
+ namespace rnscreens {
6
+
7
+ /**
8
+ * Flags describing types of corrections to apply to Screen frame
9
+ * after layout process.
10
+ */
11
+ class FrameCorrectionModes final {
12
+ public:
13
+ enum Mode : std::uint8_t {
14
+ /**
15
+ * No correction should be applied to layout metrics of Screen
16
+ */
17
+ None = 0,
18
+
19
+ /**
20
+ * Screen's frame height should be corrected
21
+ */
22
+ FrameHeightCorrection = 1 << 0,
23
+
24
+ /**
25
+ * Screen's frame origin should be corrected
26
+ */
27
+ FrameOriginCorrection = 1 << 1,
28
+ };
29
+
30
+ inline void set(Mode mode) {
31
+ modes_ = Mode(modes_ | mode);
32
+ }
33
+
34
+ inline void unset(Mode mode) {
35
+ modes_ = Mode(modes_ & ~mode);
36
+ }
37
+
38
+ // Check whether current set of flags contains all flags set in argument.
39
+ inline bool check(Mode mode) const {
40
+ return Mode(modes_ & mode) == mode;
41
+ }
42
+
43
+ inline Mode getAll() const {
44
+ return modes_;
45
+ }
46
+
47
+ private:
48
+ Mode modes_{Mode::None};
49
+ };
50
+
51
+ } // namespace rnscreens