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
@@ -22,7 +22,9 @@ import com.swmansion.rnscreens.events.ScreenWillAppearEvent
22
22
  import com.swmansion.rnscreens.events.ScreenWillDisappearEvent
23
23
 
24
24
  @ReactModule(name = ScreenViewManager.REACT_CLASS)
25
- open class ScreenViewManager : ViewGroupManager<Screen>(), RNSScreenManagerInterface<Screen> {
25
+ open class ScreenViewManager :
26
+ ViewGroupManager<Screen>(),
27
+ RNSScreenManagerInterface<Screen> {
26
28
  private val delegate: ViewManagerDelegate<Screen>
27
29
 
28
30
  init {
@@ -33,24 +35,30 @@ open class ScreenViewManager : ViewGroupManager<Screen>(), RNSScreenManagerInter
33
35
 
34
36
  override fun createViewInstance(reactContext: ThemedReactContext) = Screen(reactContext)
35
37
 
36
- override fun setActivityState(view: Screen, activityState: Float) {
38
+ override fun setActivityState(
39
+ view: Screen,
40
+ activityState: Float,
41
+ ) {
37
42
  setActivityState(view, activityState.toInt())
38
43
  }
39
44
 
40
45
  override fun updateState(
41
46
  view: Screen,
42
47
  props: ReactStylesDiffMap?,
43
- stateWrapper: StateWrapper?
48
+ stateWrapper: StateWrapper?,
44
49
  ): Any? {
45
50
  if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
46
51
  // fabricViewStateManager should never be null in Fabric. The null check is only for Paper's empty impl.
47
- view.fabricViewStateManager?.setStateWrapper(stateWrapper)
52
+ view.setStateWrapper(stateWrapper)
48
53
  }
49
54
  return super.updateState(view, props, stateWrapper)
50
55
  }
51
56
 
52
57
  @ReactProp(name = "activityState")
53
- fun setActivityState(view: Screen, activityState: Int) {
58
+ fun setActivityState(
59
+ view: Screen,
60
+ activityState: Int,
61
+ ) {
54
62
  if (activityState == -1) {
55
63
  // Null will be provided when activityState is set as an animated value and we change
56
64
  // it from JS to be a plain value (non animated).
@@ -66,132 +74,224 @@ open class ScreenViewManager : ViewGroupManager<Screen>(), RNSScreenManagerInter
66
74
  }
67
75
 
68
76
  @ReactProp(name = "stackPresentation")
69
- override fun setStackPresentation(view: Screen, presentation: String?) {
70
- view.stackPresentation = when (presentation) {
71
- "push" -> Screen.StackPresentation.PUSH
72
- "modal", "containedModal", "fullScreenModal", "formSheet" ->
73
- Screen.StackPresentation.MODAL
74
- "transparentModal", "containedTransparentModal" ->
75
- Screen.StackPresentation.TRANSPARENT_MODAL
76
- else -> throw JSApplicationIllegalArgumentException("Unknown presentation type $presentation")
77
- }
77
+ override fun setStackPresentation(
78
+ view: Screen,
79
+ presentation: String?,
80
+ ) {
81
+ view.stackPresentation =
82
+ when (presentation) {
83
+ "push" -> Screen.StackPresentation.PUSH
84
+ "modal", "containedModal", "fullScreenModal", "formSheet" ->
85
+ Screen.StackPresentation.MODAL
86
+ "transparentModal", "containedTransparentModal" ->
87
+ Screen.StackPresentation.TRANSPARENT_MODAL
88
+ else -> throw JSApplicationIllegalArgumentException("Unknown presentation type $presentation")
89
+ }
78
90
  }
79
91
 
80
92
  @ReactProp(name = "stackAnimation")
81
- override fun setStackAnimation(view: Screen, animation: String?) {
82
- view.stackAnimation = when (animation) {
83
- null, "default", "flip", "simple_push" -> Screen.StackAnimation.DEFAULT
84
- "none" -> Screen.StackAnimation.NONE
85
- "fade" -> Screen.StackAnimation.FADE
86
- "slide_from_right" -> Screen.StackAnimation.SLIDE_FROM_RIGHT
87
- "slide_from_left" -> Screen.StackAnimation.SLIDE_FROM_LEFT
88
- "slide_from_bottom" -> Screen.StackAnimation.SLIDE_FROM_BOTTOM
89
- "fade_from_bottom" -> Screen.StackAnimation.FADE_FROM_BOTTOM
90
- "ios" -> Screen.StackAnimation.IOS
91
- else -> throw JSApplicationIllegalArgumentException("Unknown animation type $animation")
92
- }
93
+ override fun setStackAnimation(
94
+ view: Screen,
95
+ animation: String?,
96
+ ) {
97
+ view.stackAnimation =
98
+ when (animation) {
99
+ null, "default", "flip", "simple_push" -> Screen.StackAnimation.DEFAULT
100
+ "none" -> Screen.StackAnimation.NONE
101
+ "fade" -> Screen.StackAnimation.FADE
102
+ "slide_from_right" -> Screen.StackAnimation.SLIDE_FROM_RIGHT
103
+ "slide_from_left" -> Screen.StackAnimation.SLIDE_FROM_LEFT
104
+ "slide_from_bottom" -> Screen.StackAnimation.SLIDE_FROM_BOTTOM
105
+ "fade_from_bottom" -> Screen.StackAnimation.FADE_FROM_BOTTOM
106
+ "ios" -> Screen.StackAnimation.IOS
107
+ else -> throw JSApplicationIllegalArgumentException("Unknown animation type $animation")
108
+ }
93
109
  }
94
110
 
95
111
  @ReactProp(name = "gestureEnabled", defaultBoolean = true)
96
- override fun setGestureEnabled(view: Screen, gestureEnabled: Boolean) {
112
+ override fun setGestureEnabled(
113
+ view: Screen,
114
+ gestureEnabled: Boolean,
115
+ ) {
97
116
  view.isGestureEnabled = gestureEnabled
98
117
  }
99
118
 
100
119
  @ReactProp(name = "replaceAnimation")
101
- override fun setReplaceAnimation(view: Screen, animation: String?) {
102
- view.replaceAnimation = when (animation) {
103
- null, "pop" -> Screen.ReplaceAnimation.POP
104
- "push" -> Screen.ReplaceAnimation.PUSH
105
- else -> throw JSApplicationIllegalArgumentException("Unknown replace animation type $animation")
106
- }
120
+ override fun setReplaceAnimation(
121
+ view: Screen,
122
+ animation: String?,
123
+ ) {
124
+ view.replaceAnimation =
125
+ when (animation) {
126
+ null, "pop" -> Screen.ReplaceAnimation.POP
127
+ "push" -> Screen.ReplaceAnimation.PUSH
128
+ else -> throw JSApplicationIllegalArgumentException("Unknown replace animation type $animation")
129
+ }
107
130
  }
108
131
 
109
132
  @ReactProp(name = "screenOrientation")
110
- override fun setScreenOrientation(view: Screen, screenOrientation: String?) {
133
+ override fun setScreenOrientation(
134
+ view: Screen,
135
+ screenOrientation: String?,
136
+ ) {
111
137
  view.setScreenOrientation(screenOrientation)
112
138
  }
113
139
 
114
140
  @ReactProp(name = "statusBarAnimation")
115
- override fun setStatusBarAnimation(view: Screen, statusBarAnimation: String?) {
141
+ override fun setStatusBarAnimation(
142
+ view: Screen,
143
+ statusBarAnimation: String?,
144
+ ) {
116
145
  val animated = statusBarAnimation != null && "none" != statusBarAnimation
117
146
  view.isStatusBarAnimated = animated
118
147
  }
119
148
 
120
149
  @ReactProp(name = "statusBarColor", customType = "Color")
121
- override fun setStatusBarColor(view: Screen, statusBarColor: Int?) {
150
+ override fun setStatusBarColor(
151
+ view: Screen,
152
+ statusBarColor: Int?,
153
+ ) {
122
154
  view.statusBarColor = statusBarColor
123
155
  }
124
156
 
125
157
  @ReactProp(name = "statusBarStyle")
126
- override fun setStatusBarStyle(view: Screen, statusBarStyle: String?) {
158
+ override fun setStatusBarStyle(
159
+ view: Screen,
160
+ statusBarStyle: String?,
161
+ ) {
127
162
  view.statusBarStyle = statusBarStyle
128
163
  }
129
164
 
130
165
  @ReactProp(name = "statusBarTranslucent")
131
- override fun setStatusBarTranslucent(view: Screen, statusBarTranslucent: Boolean) {
166
+ override fun setStatusBarTranslucent(
167
+ view: Screen,
168
+ statusBarTranslucent: Boolean,
169
+ ) {
132
170
  view.isStatusBarTranslucent = statusBarTranslucent
133
171
  }
134
172
 
135
173
  @ReactProp(name = "statusBarHidden")
136
- override fun setStatusBarHidden(view: Screen, statusBarHidden: Boolean) {
174
+ override fun setStatusBarHidden(
175
+ view: Screen,
176
+ statusBarHidden: Boolean,
177
+ ) {
137
178
  view.isStatusBarHidden = statusBarHidden
138
179
  }
139
180
 
140
181
  @ReactProp(name = "navigationBarColor", customType = "Color")
141
- override fun setNavigationBarColor(view: Screen, navigationBarColor: Int?) {
182
+ override fun setNavigationBarColor(
183
+ view: Screen,
184
+ navigationBarColor: Int?,
185
+ ) {
142
186
  view.navigationBarColor = navigationBarColor
143
187
  }
144
188
 
189
+ @ReactProp(name = "navigationBarTranslucent")
190
+ override fun setNavigationBarTranslucent(
191
+ view: Screen,
192
+ navigationBarTranslucent: Boolean,
193
+ ) {
194
+ view.isNavigationBarTranslucent = navigationBarTranslucent
195
+ }
196
+
145
197
  @ReactProp(name = "navigationBarHidden")
146
- override fun setNavigationBarHidden(view: Screen, navigationBarHidden: Boolean) {
198
+ override fun setNavigationBarHidden(
199
+ view: Screen,
200
+ navigationBarHidden: Boolean,
201
+ ) {
147
202
  view.isNavigationBarHidden = navigationBarHidden
148
203
  }
149
204
 
150
205
  @ReactProp(name = "nativeBackButtonDismissalEnabled")
151
206
  override fun setNativeBackButtonDismissalEnabled(
152
207
  view: Screen,
153
- nativeBackButtonDismissalEnabled: Boolean
208
+ nativeBackButtonDismissalEnabled: Boolean,
154
209
  ) {
155
210
  view.nativeBackButtonDismissalEnabled = nativeBackButtonDismissalEnabled
156
211
  }
157
212
 
158
213
  // these props are not available on Android, however we must override their setters
159
- override fun setFullScreenSwipeEnabled(view: Screen?, value: Boolean) = Unit
160
-
161
- override fun setTransitionDuration(view: Screen?, value: Int) = Unit
162
-
163
- override fun setHideKeyboardOnSwipe(view: Screen?, value: Boolean) = Unit
164
-
165
- override fun setCustomAnimationOnSwipe(view: Screen?, value: Boolean) = Unit
166
-
167
- override fun setGestureResponseDistance(view: Screen?, value: ReadableMap?) = Unit
168
-
169
- override fun setHomeIndicatorHidden(view: Screen?, value: Boolean) = Unit
170
-
171
- override fun setPreventNativeDismiss(view: Screen?, value: Boolean) = Unit
172
-
173
- override fun setSwipeDirection(view: Screen?, value: String?) = Unit
174
-
175
- override fun setSheetAllowedDetents(view: Screen, value: String?) = Unit
176
-
177
- override fun setSheetLargestUndimmedDetent(view: Screen, value: String?) = Unit
178
-
179
- override fun setSheetGrabberVisible(view: Screen?, value: Boolean) = Unit
180
-
181
- override fun setSheetCornerRadius(view: Screen?, value: Float) = Unit
182
-
183
- override fun setSheetExpandsWhenScrolledToEdge(view: Screen?, value: Boolean) = Unit
214
+ override fun setFullScreenSwipeEnabled(
215
+ view: Screen?,
216
+ value: Boolean,
217
+ ) = Unit
218
+
219
+ override fun setFullScreenSwipeShadowEnabled(
220
+ view: Screen?,
221
+ value: Boolean,
222
+ ) = Unit
223
+
224
+ override fun setTransitionDuration(
225
+ view: Screen?,
226
+ value: Int,
227
+ ) = Unit
228
+
229
+ override fun setHideKeyboardOnSwipe(
230
+ view: Screen?,
231
+ value: Boolean,
232
+ ) = Unit
233
+
234
+ override fun setCustomAnimationOnSwipe(
235
+ view: Screen?,
236
+ value: Boolean,
237
+ ) = Unit
238
+
239
+ override fun setGestureResponseDistance(
240
+ view: Screen?,
241
+ value: ReadableMap?,
242
+ ) = Unit
243
+
244
+ override fun setHomeIndicatorHidden(
245
+ view: Screen?,
246
+ value: Boolean,
247
+ ) = Unit
248
+
249
+ override fun setPreventNativeDismiss(
250
+ view: Screen?,
251
+ value: Boolean,
252
+ ) = Unit
253
+
254
+ override fun setSwipeDirection(
255
+ view: Screen?,
256
+ value: String?,
257
+ ) = Unit
258
+
259
+ override fun setSheetAllowedDetents(
260
+ view: Screen,
261
+ value: String?,
262
+ ) = Unit
184
263
 
185
- override fun getExportedCustomDirectEventTypeConstants(): MutableMap<String, Any> = mutableMapOf(
186
- ScreenDismissedEvent.EVENT_NAME to MapBuilder.of("registrationName", "onDismissed"),
187
- ScreenWillAppearEvent.EVENT_NAME to MapBuilder.of("registrationName", "onWillAppear"),
188
- ScreenAppearEvent.EVENT_NAME to MapBuilder.of("registrationName", "onAppear"),
189
- ScreenWillDisappearEvent.EVENT_NAME to MapBuilder.of("registrationName", "onWillDisappear"),
190
- ScreenDisappearEvent.EVENT_NAME to MapBuilder.of("registrationName", "onDisappear"),
191
- HeaderHeightChangeEvent.EVENT_NAME to MapBuilder.of("registrationName", "onHeaderHeightChange"),
192
- HeaderBackButtonClickedEvent.EVENT_NAME to MapBuilder.of("registrationName", "onHeaderBackButtonClicked"),
193
- ScreenTransitionProgressEvent.EVENT_NAME to MapBuilder.of("registrationName", "onTransitionProgress")
194
- )
264
+ override fun setSheetLargestUndimmedDetent(
265
+ view: Screen,
266
+ value: String?,
267
+ ) = Unit
268
+
269
+ override fun setSheetGrabberVisible(
270
+ view: Screen?,
271
+ value: Boolean,
272
+ ) = Unit
273
+
274
+ override fun setSheetCornerRadius(
275
+ view: Screen?,
276
+ value: Float,
277
+ ) = Unit
278
+
279
+ override fun setSheetExpandsWhenScrolledToEdge(
280
+ view: Screen?,
281
+ value: Boolean,
282
+ ) = Unit
283
+
284
+ override fun getExportedCustomDirectEventTypeConstants(): MutableMap<String, Any> =
285
+ mutableMapOf(
286
+ ScreenDismissedEvent.EVENT_NAME to MapBuilder.of("registrationName", "onDismissed"),
287
+ ScreenWillAppearEvent.EVENT_NAME to MapBuilder.of("registrationName", "onWillAppear"),
288
+ ScreenAppearEvent.EVENT_NAME to MapBuilder.of("registrationName", "onAppear"),
289
+ ScreenWillDisappearEvent.EVENT_NAME to MapBuilder.of("registrationName", "onWillDisappear"),
290
+ ScreenDisappearEvent.EVENT_NAME to MapBuilder.of("registrationName", "onDisappear"),
291
+ HeaderHeightChangeEvent.EVENT_NAME to MapBuilder.of("registrationName", "onHeaderHeightChange"),
292
+ HeaderBackButtonClickedEvent.EVENT_NAME to MapBuilder.of("registrationName", "onHeaderBackButtonClicked"),
293
+ ScreenTransitionProgressEvent.EVENT_NAME to MapBuilder.of("registrationName", "onTransitionProgress"),
294
+ )
195
295
 
196
296
  protected override fun getDelegate(): ViewManagerDelegate<Screen> = delegate
197
297
 
@@ -2,7 +2,6 @@ package com.swmansion.rnscreens
2
2
 
3
3
  import android.animation.ArgbEvaluator
4
4
  import android.animation.ValueAnimator
5
- import android.annotation.SuppressLint
6
5
  import android.annotation.TargetApi
7
6
  import android.app.Activity
8
7
  import android.content.pm.ActivityInfo
@@ -11,6 +10,7 @@ import android.os.Build
11
10
  import android.view.ViewParent
12
11
  import androidx.core.graphics.Insets
13
12
  import androidx.core.view.ViewCompat
13
+ import androidx.core.view.WindowCompat
14
14
  import androidx.core.view.WindowInsetsCompat
15
15
  import androidx.core.view.WindowInsetsControllerCompat
16
16
  import com.facebook.react.bridge.GuardedRunnable
@@ -38,7 +38,10 @@ object ScreenWindowTraits {
38
38
  didSetNavigationBarAppearance = true
39
39
  }
40
40
 
41
- internal fun setOrientation(screen: Screen, activity: Activity?) {
41
+ internal fun setOrientation(
42
+ screen: Screen,
43
+ activity: Activity?,
44
+ ) {
42
45
  if (activity == null) {
43
46
  return
44
47
  }
@@ -47,7 +50,11 @@ object ScreenWindowTraits {
47
50
  activity.requestedOrientation = orientation
48
51
  }
49
52
 
50
- internal fun setColor(screen: Screen, activity: Activity?, context: ReactContext?) {
53
+ internal fun setColor(
54
+ screen: Screen,
55
+ activity: Activity?,
56
+ context: ReactContext?,
57
+ ) {
51
58
  if (activity == null || context == null) {
52
59
  return
53
60
  }
@@ -60,7 +67,7 @@ object ScreenWindowTraits {
60
67
  val animated = screenForAnimated?.isStatusBarAnimated ?: false
61
68
 
62
69
  UiThreadUtil.runOnUiThread(
63
- object : GuardedRunnable(context) {
70
+ object : GuardedRunnable(context.exceptionHandler) {
64
71
  override fun runGuarded() {
65
72
  val window = activity.window
66
73
  val curColor: Int = window.statusBarColor
@@ -75,10 +82,15 @@ object ScreenWindowTraits {
75
82
  }
76
83
  colorAnimation.start()
77
84
  }
78
- })
85
+ },
86
+ )
79
87
  }
80
88
 
81
- internal fun setStyle(screen: Screen, activity: Activity?, context: ReactContext?) {
89
+ internal fun setStyle(
90
+ screen: Screen,
91
+ activity: Activity?,
92
+ context: ReactContext?,
93
+ ) {
82
94
  if (activity == null || context == null || Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
83
95
  return
84
96
  }
@@ -97,7 +109,7 @@ object ScreenWindowTraits {
97
109
  internal fun setTranslucent(
98
110
  screen: Screen,
99
111
  activity: Activity?,
100
- context: ReactContext?
112
+ context: ReactContext?,
101
113
  ) {
102
114
  if (activity == null || context == null) {
103
115
  return
@@ -105,7 +117,7 @@ object ScreenWindowTraits {
105
117
  val screenForTranslucent = findScreenForTrait(screen, WindowTraits.TRANSLUCENT)
106
118
  val translucent = screenForTranslucent?.isStatusBarTranslucent ?: false
107
119
  UiThreadUtil.runOnUiThread(
108
- object : GuardedRunnable(context) {
120
+ object : GuardedRunnable(context.exceptionHandler) {
109
121
  @TargetApi(Build.VERSION_CODES.LOLLIPOP)
110
122
  override fun runGuarded() {
111
123
  // If the status bar is translucent hook into the window insets calculations
@@ -127,16 +139,15 @@ object ScreenWindowTraits {
127
139
  windowInsets.left,
128
140
  0,
129
141
  windowInsets.right,
130
- windowInsets.bottom
131
- )
132
- )
133
- .build()
142
+ windowInsets.bottom,
143
+ ),
144
+ ).build()
134
145
  } else {
135
146
  defaultInsets.replaceSystemWindowInsets(
136
147
  defaultInsets.systemWindowInsetLeft,
137
148
  0,
138
149
  defaultInsets.systemWindowInsetRight,
139
- defaultInsets.systemWindowInsetBottom
150
+ defaultInsets.systemWindowInsetBottom,
140
151
  )
141
152
  }
142
153
  }
@@ -145,10 +156,14 @@ object ScreenWindowTraits {
145
156
  }
146
157
  ViewCompat.requestApplyInsets(decorView)
147
158
  }
148
- })
159
+ },
160
+ )
149
161
  }
150
162
 
151
- internal fun setHidden(screen: Screen, activity: Activity?) {
163
+ internal fun setHidden(
164
+ screen: Screen,
165
+ activity: Activity?,
166
+ ) {
152
167
  if (activity == null) {
153
168
  return
154
169
  }
@@ -168,7 +183,10 @@ object ScreenWindowTraits {
168
183
 
169
184
  // Methods concerning navigationBar management were taken from `react-native-navigation`'s repo:
170
185
  // https://github.com/wix/react-native-navigation/blob/9bb70d81700692141a2c505c081c2d86c7f9c66e/lib/android/app/src/main/java/com/reactnativenavigation/utils/SystemUiUtils.kt
171
- internal fun setNavigationBarColor(screen: Screen, activity: Activity?) {
186
+ internal fun setNavigationBarColor(
187
+ screen: Screen,
188
+ activity: Activity?,
189
+ ) {
172
190
  if (activity == null) {
173
191
  return
174
192
  }
@@ -185,7 +203,27 @@ object ScreenWindowTraits {
185
203
  window.navigationBarColor = color
186
204
  }
187
205
 
188
- internal fun setNavigationBarHidden(screen: Screen, activity: Activity?) {
206
+ internal fun setNavigationBarTranslucent(
207
+ screen: Screen,
208
+ activity: Activity?,
209
+ ) {
210
+ if (activity == null) {
211
+ return
212
+ }
213
+
214
+ val window = activity.window
215
+
216
+ val screenForNavBarTranslucent = findScreenForTrait(screen, WindowTraits.NAVIGATION_BAR_TRANSLUCENT)
217
+ val translucent = screenForNavBarTranslucent?.isNavigationBarTranslucent ?: false
218
+
219
+ // Following method controls whether to display edge-to-edge content that draws behind the navigation bar
220
+ WindowCompat.setDecorFitsSystemWindows(window, !translucent)
221
+ }
222
+
223
+ internal fun setNavigationBarHidden(
224
+ screen: Screen,
225
+ activity: Activity?,
226
+ ) {
189
227
  if (activity == null) {
190
228
  return
191
229
  }
@@ -204,12 +242,16 @@ object ScreenWindowTraits {
204
242
  } else {
205
243
  WindowInsetsControllerCompat(
206
244
  window,
207
- window.decorView
245
+ window.decorView,
208
246
  ).show(WindowInsetsCompat.Type.navigationBars())
209
247
  }
210
248
  }
211
249
 
212
- internal fun trySetWindowTraits(screen: Screen, activity: Activity?, context: ReactContext?) {
250
+ internal fun trySetWindowTraits(
251
+ screen: Screen,
252
+ activity: Activity?,
253
+ context: ReactContext?,
254
+ ) {
213
255
  if (didSetOrientation) {
214
256
  setOrientation(screen, activity)
215
257
  }
@@ -221,11 +263,15 @@ object ScreenWindowTraits {
221
263
  }
222
264
  if (didSetNavigationBarAppearance) {
223
265
  setNavigationBarColor(screen, activity)
266
+ setNavigationBarTranslucent(screen, activity)
224
267
  setNavigationBarHidden(screen, activity)
225
268
  }
226
269
  }
227
270
 
228
- private fun findScreenForTrait(screen: Screen, trait: WindowTraits): Screen? {
271
+ private fun findScreenForTrait(
272
+ screen: Screen,
273
+ trait: WindowTraits,
274
+ ): Screen? {
229
275
  val childWithTrait = childScreenWithTraitSet(screen, trait)
230
276
  if (childWithTrait != null) {
231
277
  return childWithTrait
@@ -239,7 +285,10 @@ object ScreenWindowTraits {
239
285
  }
240
286
  }
241
287
 
242
- private fun findParentWithTraitSet(screen: Screen, trait: WindowTraits): Screen? {
288
+ private fun findParentWithTraitSet(
289
+ screen: Screen,
290
+ trait: WindowTraits,
291
+ ): Screen? {
243
292
  var parent: ViewParent? = screen.container
244
293
  while (parent != null) {
245
294
  if (parent is Screen) {
@@ -254,7 +303,7 @@ object ScreenWindowTraits {
254
303
 
255
304
  private fun childScreenWithTraitSet(
256
305
  screen: Screen?,
257
- trait: WindowTraits
306
+ trait: WindowTraits,
258
307
  ): Screen? {
259
308
  screen?.fragmentWrapper?.let {
260
309
  for (sc in it.childScreenContainers) {
@@ -272,8 +321,11 @@ object ScreenWindowTraits {
272
321
  return null
273
322
  }
274
323
 
275
- private fun checkTraitForScreen(screen: Screen, trait: WindowTraits): Boolean {
276
- return when (trait) {
324
+ private fun checkTraitForScreen(
325
+ screen: Screen,
326
+ trait: WindowTraits,
327
+ ): Boolean =
328
+ when (trait) {
277
329
  WindowTraits.ORIENTATION -> screen.screenOrientation != null
278
330
  WindowTraits.COLOR -> screen.statusBarColor != null
279
331
  WindowTraits.STYLE -> screen.statusBarStyle != null
@@ -281,9 +333,9 @@ object ScreenWindowTraits {
281
333
  WindowTraits.HIDDEN -> screen.isStatusBarHidden != null
282
334
  WindowTraits.ANIMATED -> screen.isStatusBarAnimated != null
283
335
  WindowTraits.NAVIGATION_BAR_COLOR -> screen.navigationBarColor != null
336
+ WindowTraits.NAVIGATION_BAR_TRANSLUCENT -> screen.isNavigationBarTranslucent != null
284
337
  WindowTraits.NAVIGATION_BAR_HIDDEN -> screen.isNavigationBarHidden != null
285
338
  }
286
- }
287
339
 
288
340
  private fun isColorLight(color: Int): Boolean {
289
341
  val darkness: Double =
@@ -4,17 +4,20 @@ import android.util.Log
4
4
  import com.facebook.proguard.annotations.DoNotStrip
5
5
  import com.facebook.react.bridge.ReactApplicationContext
6
6
  import com.facebook.react.bridge.UiThreadUtil
7
+ import com.facebook.react.fabric.FabricUIManager
7
8
  import com.facebook.react.module.annotations.ReactModule
8
9
  import com.facebook.react.uimanager.UIManagerHelper
10
+ import com.facebook.react.uimanager.common.UIManagerType
9
11
  import com.swmansion.rnscreens.events.ScreenTransitionProgressEvent
10
12
  import java.util.concurrent.atomic.AtomicBoolean
11
13
 
12
14
  @ReactModule(name = ScreensModule.NAME)
13
- class ScreensModule(private val reactContext: ReactApplicationContext)
14
- : NativeScreensModuleSpec(reactContext)
15
- {
15
+ class ScreensModule(
16
+ private val reactContext: ReactApplicationContext,
17
+ ) : NativeScreensModuleSpec(reactContext) {
16
18
  private var topScreenId: Int = -1
17
19
  private val isActiveTransition = AtomicBoolean(false)
20
+ private var proxy: NativeProxy? = null
18
21
 
19
22
  init {
20
23
  try {
@@ -25,13 +28,25 @@ class ScreensModule(private val reactContext: ReactApplicationContext)
25
28
  } else {
26
29
  Log.e("[RNScreens]", "Could not install JSI bindings.")
27
30
  }
28
- } catch (exception: Exception) {
31
+ } catch (exception: UnsatisfiedLinkError) {
29
32
  Log.w("[RNScreens]", "Could not load RNScreens module.")
30
33
  }
31
34
  }
32
35
 
33
36
  private external fun nativeInstall(jsiPtr: Long)
34
37
 
38
+ override fun initialize() {
39
+ super.initialize()
40
+ if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
41
+ val fabricUIManager =
42
+ UIManagerHelper.getUIManager(reactContext, UIManagerType.FABRIC) as FabricUIManager
43
+ proxy =
44
+ NativeProxy().apply {
45
+ nativeAddMutationsListener(fabricUIManager)
46
+ }
47
+ }
48
+ }
49
+
35
50
  override fun getName(): String = NAME
36
51
 
37
52
  @DoNotStrip
@@ -64,25 +79,32 @@ class ScreensModule(private val reactContext: ReactApplicationContext)
64
79
  if (topScreenId == -1) {
65
80
  return
66
81
  }
67
- val progressFloat = progress.toFloat();
82
+ val progressFloat = progress.toFloat()
68
83
  val coalescingKey = ScreenFragment.getCoalescingKey(progressFloat)
69
84
  UIManagerHelper
70
85
  .getEventDispatcherForReactTag(reactContext, topScreenId)
71
86
  ?.dispatchEvent(
72
87
  ScreenTransitionProgressEvent(
73
88
  UIManagerHelper.getSurfaceId(reactContext),
74
- topScreenId, progressFloat, true, true, coalescingKey
75
- )
89
+ topScreenId,
90
+ progressFloat,
91
+ true,
92
+ true,
93
+ coalescingKey,
94
+ ),
76
95
  )
77
96
  }
78
97
 
79
98
  @DoNotStrip
80
- private fun finishTransition(reactTag: Int?, canceled: Boolean) {
99
+ private fun finishTransition(
100
+ reactTag: Int?,
101
+ canceled: Boolean,
102
+ ) {
81
103
  UiThreadUtil.assertOnUiThread()
82
104
  if (!isActiveTransition.get() || reactTag == null) {
83
105
  Log.e(
84
106
  "[RNScreens]",
85
- "Unable to call `finishTransition` method before transition start."
107
+ "Unable to call `finishTransition` method before transition start.",
86
108
  )
87
109
  return
88
110
  }