react-native-screens 4.0.0-beta.0 → 4.0.0-beta.10

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 (216) hide show
  1. package/README.md +1 -1
  2. package/android/build.gradle +26 -6
  3. package/android/src/fabric/java/com/swmansion/rnscreens/FabricEnabledHeaderConfigViewGroup.kt +61 -0
  4. package/android/src/fabric/java/com/swmansion/rnscreens/FabricEnabledViewGroup.kt +4 -3
  5. package/android/src/main/java/com/swmansion/rnscreens/CustomToolbar.kt +54 -1
  6. package/android/src/main/java/com/swmansion/rnscreens/InsetsObserverProxy.kt +2 -4
  7. package/android/src/main/java/com/swmansion/rnscreens/Screen.kt +59 -36
  8. package/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt +26 -5
  9. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragment.kt +37 -17
  10. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfig.kt +1 -2
  11. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfigShadowNode.kt +25 -0
  12. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfigViewManager.kt +18 -0
  13. package/android/src/main/java/com/swmansion/rnscreens/ScreenViewManager.kt +8 -2
  14. package/android/src/main/java/com/swmansion/rnscreens/ScreenWindowTraits.kt +2 -1
  15. package/android/src/main/java/com/swmansion/rnscreens/events/HeaderHeightChangeEvent.kt +3 -3
  16. package/android/src/main/java/com/swmansion/rnscreens/ext/ViewExt.kt +17 -0
  17. package/android/src/main/java/com/swmansion/rnscreens/utils/PaddingBundle.kt +8 -0
  18. package/android/src/main/jni/rnscreens.h +2 -0
  19. package/android/src/main/res/base/anim/rns_ios_from_left_background_close.xml +5 -0
  20. package/android/src/main/res/base/anim/{rns_slide_out_to_left_ios.xml → rns_ios_from_left_background_open.xml} +1 -1
  21. package/android/src/main/res/base/anim/rns_ios_from_left_foreground_close.xml +6 -0
  22. package/android/src/main/res/base/anim/rns_ios_from_left_foreground_open.xml +6 -0
  23. package/android/src/main/res/base/anim/rns_ios_from_right_background_open.xml +5 -0
  24. package/android/src/paper/java/com/swmansion/rnscreens/FabricEnabledHeaderConfigViewGroup.kt +39 -0
  25. package/android/src/paper/java/com/swmansion/rnscreens/FabricEnabledViewGroup.kt +1 -1
  26. package/common/cpp/react/renderer/components/rnscreens/RNSScreenComponentDescriptor.h +5 -99
  27. package/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.cpp +101 -0
  28. package/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.h +2 -0
  29. package/common/cpp/react/renderer/components/rnscreens/RNSScreenStackHeaderConfigComponentDescriptor.h +44 -0
  30. package/common/cpp/react/renderer/components/rnscreens/RNSScreenStackHeaderConfigShadowNode.cpp +8 -0
  31. package/common/cpp/react/renderer/components/rnscreens/RNSScreenStackHeaderConfigShadowNode.h +32 -0
  32. package/common/cpp/react/renderer/components/rnscreens/RNSScreenStackHeaderConfigState.cpp +23 -0
  33. package/common/cpp/react/renderer/components/rnscreens/RNSScreenStackHeaderConfigState.h +50 -0
  34. package/common/cpp/react/renderer/components/rnscreens/RNSScreenStackHeaderSubviewComponentDescriptor.h +27 -0
  35. package/common/cpp/react/renderer/components/rnscreens/RNSScreenStackHeaderSubviewShadowNode.cpp +8 -0
  36. package/common/cpp/react/renderer/components/rnscreens/RNSScreenStackHeaderSubviewShadowNode.h +32 -0
  37. package/common/cpp/react/renderer/components/rnscreens/RNSScreenStackHeaderSubviewState.cpp +15 -0
  38. package/common/cpp/react/renderer/components/rnscreens/RNSScreenStackHeaderSubviewState.h +40 -0
  39. package/ios/RNSConvert.mm +4 -2
  40. package/ios/RNSFullWindowOverlay.mm +6 -0
  41. package/ios/RNSModalScreen.mm +7 -0
  42. package/ios/RNSScreen.h +9 -0
  43. package/ios/RNSScreen.mm +46 -8
  44. package/ios/RNSScreenContainer.mm +6 -0
  45. package/ios/RNSScreenContentWrapper.mm +6 -0
  46. package/ios/RNSScreenFooter.mm +6 -0
  47. package/ios/RNSScreenNavigationContainer.mm +7 -0
  48. package/ios/RNSScreenStack.mm +86 -8
  49. package/ios/RNSScreenStackHeaderConfig.h +63 -0
  50. package/ios/RNSScreenStackHeaderConfig.mm +133 -6
  51. package/ios/RNSScreenStackHeaderSubview.mm +32 -3
  52. package/ios/RNSSearchBar.mm +7 -0
  53. package/ios/utils/UINavigationBar+RNSUtility.h +37 -0
  54. package/ios/utils/UINavigationBar+RNSUtility.mm +44 -0
  55. package/ios/utils/UIView+RNSUtility.mm +0 -1
  56. package/lib/commonjs/TransitionProgressContext.js +1 -0
  57. package/lib/commonjs/TransitionProgressContext.js.map +1 -1
  58. package/lib/commonjs/components/Screen.js +111 -5
  59. package/lib/commonjs/components/Screen.js.map +1 -1
  60. package/lib/commonjs/components/Screen.web.js +2 -0
  61. package/lib/commonjs/components/Screen.web.js.map +1 -1
  62. package/lib/commonjs/components/ScreenContainer.js +1 -0
  63. package/lib/commonjs/components/ScreenContainer.js.map +1 -1
  64. package/lib/commonjs/components/ScreenContentWrapper.web.js +11 -0
  65. package/lib/commonjs/components/ScreenContentWrapper.web.js.map +1 -0
  66. package/lib/commonjs/components/ScreenFooter.web.js +11 -0
  67. package/lib/commonjs/components/ScreenFooter.web.js.map +1 -0
  68. package/lib/commonjs/components/ScreenStack.js +1 -0
  69. package/lib/commonjs/components/ScreenStack.js.map +1 -1
  70. package/lib/commonjs/components/ScreenStackHeaderConfig.js +54 -17
  71. package/lib/commonjs/components/ScreenStackHeaderConfig.js.map +1 -1
  72. package/lib/commonjs/components/SearchBar.js +1 -0
  73. package/lib/commonjs/components/SearchBar.js.map +1 -1
  74. package/lib/commonjs/components/helpers/usePrevious.js +15 -0
  75. package/lib/commonjs/components/helpers/usePrevious.js.map +1 -0
  76. package/lib/commonjs/core.js +1 -0
  77. package/lib/commonjs/core.js.map +1 -1
  78. package/lib/commonjs/fabric/FullWindowOverlayNativeComponent.js +1 -0
  79. package/lib/commonjs/fabric/FullWindowOverlayNativeComponent.js.map +1 -1
  80. package/lib/commonjs/fabric/ModalScreenNativeComponent.js +1 -0
  81. package/lib/commonjs/fabric/ModalScreenNativeComponent.js.map +1 -1
  82. package/lib/commonjs/fabric/NativeScreensModule.js +2 -1
  83. package/lib/commonjs/fabric/NativeScreensModule.js.map +1 -1
  84. package/lib/commonjs/fabric/ScreenContainerNativeComponent.js +1 -0
  85. package/lib/commonjs/fabric/ScreenContainerNativeComponent.js.map +1 -1
  86. package/lib/commonjs/fabric/ScreenNativeComponent.js +1 -0
  87. package/lib/commonjs/fabric/ScreenNativeComponent.js.map +1 -1
  88. package/lib/commonjs/fabric/ScreenNavigationContainerNativeComponent.js +1 -0
  89. package/lib/commonjs/fabric/ScreenNavigationContainerNativeComponent.js.map +1 -1
  90. package/lib/commonjs/fabric/ScreenStackHeaderConfigNativeComponent.js +4 -1
  91. package/lib/commonjs/fabric/ScreenStackHeaderConfigNativeComponent.js.map +1 -1
  92. package/lib/commonjs/fabric/ScreenStackHeaderSubviewNativeComponent.js +4 -1
  93. package/lib/commonjs/fabric/ScreenStackHeaderSubviewNativeComponent.js.map +1 -1
  94. package/lib/commonjs/fabric/ScreenStackNativeComponent.js +1 -0
  95. package/lib/commonjs/fabric/ScreenStackNativeComponent.js.map +1 -1
  96. package/lib/commonjs/fabric/SearchBarNativeComponent.js +2 -2
  97. package/lib/commonjs/fabric/SearchBarNativeComponent.js.map +1 -1
  98. package/lib/commonjs/native-stack/contexts/GHContext.js +1 -0
  99. package/lib/commonjs/native-stack/contexts/GHContext.js.map +1 -1
  100. package/lib/commonjs/native-stack/views/NativeStackView.js +7 -13
  101. package/lib/commonjs/native-stack/views/NativeStackView.js.map +1 -1
  102. package/lib/module/TransitionProgressContext.js +2 -0
  103. package/lib/module/TransitionProgressContext.js.map +1 -1
  104. package/lib/module/components/Screen.js +112 -5
  105. package/lib/module/components/Screen.js.map +1 -1
  106. package/lib/module/components/Screen.web.js +3 -0
  107. package/lib/module/components/Screen.web.js.map +1 -1
  108. package/lib/module/components/ScreenContainer.js +2 -0
  109. package/lib/module/components/ScreenContainer.js.map +1 -1
  110. package/lib/module/components/ScreenContentWrapper.web.js +5 -0
  111. package/lib/module/components/ScreenContentWrapper.web.js.map +1 -0
  112. package/lib/module/components/ScreenFooter.web.js +5 -0
  113. package/lib/module/components/ScreenFooter.web.js.map +1 -0
  114. package/lib/module/components/ScreenStack.js +2 -0
  115. package/lib/module/components/ScreenStack.js.map +1 -1
  116. package/lib/module/components/ScreenStackHeaderConfig.js +52 -16
  117. package/lib/module/components/ScreenStackHeaderConfig.js.map +1 -1
  118. package/lib/module/components/SearchBar.js +2 -0
  119. package/lib/module/components/SearchBar.js.map +1 -1
  120. package/lib/module/components/helpers/usePrevious.js +9 -0
  121. package/lib/module/components/helpers/usePrevious.js.map +1 -0
  122. package/lib/module/core.js +2 -0
  123. package/lib/module/core.js.map +1 -1
  124. package/lib/module/fabric/FullWindowOverlayNativeComponent.js +2 -0
  125. package/lib/module/fabric/FullWindowOverlayNativeComponent.js.map +1 -1
  126. package/lib/module/fabric/ModalScreenNativeComponent.js +2 -0
  127. package/lib/module/fabric/ModalScreenNativeComponent.js.map +1 -1
  128. package/lib/module/fabric/NativeScreensModule.js +2 -1
  129. package/lib/module/fabric/NativeScreensModule.js.map +1 -1
  130. package/lib/module/fabric/ScreenContainerNativeComponent.js +2 -0
  131. package/lib/module/fabric/ScreenContainerNativeComponent.js.map +1 -1
  132. package/lib/module/fabric/ScreenNativeComponent.js +2 -0
  133. package/lib/module/fabric/ScreenNativeComponent.js.map +1 -1
  134. package/lib/module/fabric/ScreenNavigationContainerNativeComponent.js +2 -0
  135. package/lib/module/fabric/ScreenNavigationContainerNativeComponent.js.map +1 -1
  136. package/lib/module/fabric/ScreenStackHeaderConfigNativeComponent.js +5 -1
  137. package/lib/module/fabric/ScreenStackHeaderConfigNativeComponent.js.map +1 -1
  138. package/lib/module/fabric/ScreenStackHeaderSubviewNativeComponent.js +5 -1
  139. package/lib/module/fabric/ScreenStackHeaderSubviewNativeComponent.js.map +1 -1
  140. package/lib/module/fabric/ScreenStackNativeComponent.js +2 -0
  141. package/lib/module/fabric/ScreenStackNativeComponent.js.map +1 -1
  142. package/lib/module/fabric/SearchBarNativeComponent.js +2 -0
  143. package/lib/module/fabric/SearchBarNativeComponent.js.map +1 -1
  144. package/lib/module/index.js +6 -6
  145. package/lib/module/native-stack/contexts/GHContext.js +2 -0
  146. package/lib/module/native-stack/contexts/GHContext.js.map +1 -1
  147. package/lib/module/native-stack/views/NativeStackView.js +7 -13
  148. package/lib/module/native-stack/views/NativeStackView.js.map +1 -1
  149. package/lib/typescript/TransitionProgressContext.d.ts.map +1 -1
  150. package/lib/typescript/components/Screen.d.ts +5 -1
  151. package/lib/typescript/components/Screen.d.ts.map +1 -1
  152. package/lib/typescript/components/Screen.web.d.ts.map +1 -1
  153. package/lib/typescript/components/ScreenContainer.d.ts.map +1 -1
  154. package/lib/typescript/components/ScreenContentWrapper.web.d.ts +5 -0
  155. package/lib/typescript/components/ScreenContentWrapper.web.d.ts.map +1 -0
  156. package/lib/typescript/components/ScreenFooter.web.d.ts +5 -0
  157. package/lib/typescript/components/ScreenFooter.web.d.ts.map +1 -0
  158. package/lib/typescript/components/ScreenStack.d.ts.map +1 -1
  159. package/lib/typescript/components/ScreenStackHeaderConfig.d.ts +1 -1
  160. package/lib/typescript/components/ScreenStackHeaderConfig.d.ts.map +1 -1
  161. package/lib/typescript/components/SearchBar.d.ts.map +1 -1
  162. package/lib/typescript/components/helpers/usePrevious.d.ts +2 -0
  163. package/lib/typescript/components/helpers/usePrevious.d.ts.map +1 -0
  164. package/lib/typescript/core.d.ts.map +1 -1
  165. package/lib/typescript/fabric/FullWindowOverlayNativeComponent.d.ts.map +1 -1
  166. package/lib/typescript/fabric/ModalScreenNativeComponent.d.ts +1 -0
  167. package/lib/typescript/fabric/ModalScreenNativeComponent.d.ts.map +1 -1
  168. package/lib/typescript/fabric/NativeScreensModule.d.ts.map +1 -1
  169. package/lib/typescript/fabric/ScreenContainerNativeComponent.d.ts.map +1 -1
  170. package/lib/typescript/fabric/ScreenNativeComponent.d.ts +1 -1
  171. package/lib/typescript/fabric/ScreenNativeComponent.d.ts.map +1 -1
  172. package/lib/typescript/fabric/ScreenNavigationContainerNativeComponent.d.ts.map +1 -1
  173. package/lib/typescript/fabric/ScreenStackHeaderConfigNativeComponent.d.ts.map +1 -1
  174. package/lib/typescript/fabric/ScreenStackHeaderSubviewNativeComponent.d.ts.map +1 -1
  175. package/lib/typescript/fabric/ScreenStackNativeComponent.d.ts.map +1 -1
  176. package/lib/typescript/fabric/SearchBarNativeComponent.d.ts.map +1 -1
  177. package/lib/typescript/index.d.ts +18 -0
  178. package/lib/typescript/index.d.ts.map +1 -1
  179. package/lib/typescript/native-stack/contexts/GHContext.d.ts.map +1 -1
  180. package/lib/typescript/native-stack/types.d.ts +14 -5
  181. package/lib/typescript/native-stack/types.d.ts.map +1 -1
  182. package/lib/typescript/native-stack/views/NativeStackView.d.ts.map +1 -1
  183. package/lib/typescript/types.d.ts +56 -11
  184. package/lib/typescript/types.d.ts.map +1 -1
  185. package/native-stack/README.md +30 -5
  186. package/package.json +1 -1
  187. package/src/TransitionProgressContext.tsx +2 -0
  188. package/src/components/Screen.tsx +161 -8
  189. package/src/components/Screen.web.tsx +3 -0
  190. package/src/components/ScreenContainer.tsx +2 -0
  191. package/src/components/ScreenContentWrapper.web.tsx +6 -0
  192. package/src/components/ScreenFooter.web.tsx +6 -0
  193. package/src/components/ScreenStack.tsx +2 -0
  194. package/src/components/ScreenStackHeaderConfig.tsx +61 -26
  195. package/src/components/SearchBar.tsx +2 -0
  196. package/src/components/helpers/usePrevious.tsx +11 -0
  197. package/src/core.ts +2 -0
  198. package/src/fabric/FullWindowOverlayNativeComponent.ts +2 -0
  199. package/src/fabric/ModalScreenNativeComponent.ts +3 -0
  200. package/src/fabric/NativeScreensModule.ts +2 -0
  201. package/src/fabric/ScreenContainerNativeComponent.ts +2 -0
  202. package/src/fabric/ScreenNativeComponent.ts +4 -1
  203. package/src/fabric/ScreenNavigationContainerNativeComponent.ts +2 -0
  204. package/src/fabric/ScreenStackHeaderConfigNativeComponent.ts +5 -1
  205. package/src/fabric/ScreenStackHeaderSubviewNativeComponent.ts +5 -1
  206. package/src/fabric/ScreenStackNativeComponent.ts +2 -0
  207. package/src/fabric/SearchBarNativeComponent.ts +2 -0
  208. package/src/index.tsx +6 -6
  209. package/src/native-stack/contexts/GHContext.tsx +2 -0
  210. package/src/native-stack/types.tsx +14 -5
  211. package/src/native-stack/views/NativeStackView.tsx +11 -16
  212. package/src/types.tsx +63 -11
  213. package/windows/RNScreens/Screen.h +2 -1
  214. /package/android/src/main/res/base/anim/{rns_slide_in_from_left_ios.xml → rns_ios_from_right_background_close.xml} +0 -0
  215. /package/android/src/main/res/base/anim/{rns_slide_out_to_right_ios.xml → rns_ios_from_right_foreground_close.xml} +0 -0
  216. /package/android/src/main/res/base/anim/{rns_slide_in_from_right_ios.xml → rns_ios_from_right_foreground_open.xml} +0 -0
@@ -3,8 +3,12 @@ package com.swmansion.rnscreens
3
3
  import android.util.Log
4
4
  import android.view.View
5
5
  import com.facebook.react.bridge.JSApplicationCausedNativeException
6
+ import com.facebook.react.bridge.ReactApplicationContext
6
7
  import com.facebook.react.common.MapBuilder
7
8
  import com.facebook.react.module.annotations.ReactModule
9
+ import com.facebook.react.uimanager.LayoutShadowNode
10
+ import com.facebook.react.uimanager.ReactStylesDiffMap
11
+ import com.facebook.react.uimanager.StateWrapper
8
12
  import com.facebook.react.uimanager.ThemedReactContext
9
13
  import com.facebook.react.uimanager.ViewGroupManager
10
14
  import com.facebook.react.uimanager.ViewManagerDelegate
@@ -29,6 +33,9 @@ class ScreenStackHeaderConfigViewManager :
29
33
 
30
34
  override fun createViewInstance(reactContext: ThemedReactContext) = ScreenStackHeaderConfig(reactContext)
31
35
 
36
+ // This works only on Paper. On Fabric the shadow node is implemented in C++ layer.
37
+ override fun createShadowNodeInstance(context: ReactApplicationContext): LayoutShadowNode = ScreenStackHeaderConfigShadowNode(context)
38
+
32
39
  override fun addView(
33
40
  parent: ScreenStackHeaderConfig,
34
41
  child: View,
@@ -42,6 +49,17 @@ class ScreenStackHeaderConfigViewManager :
42
49
  parent.addConfigSubview(child, index)
43
50
  }
44
51
 
52
+ override fun updateState(
53
+ view: ScreenStackHeaderConfig,
54
+ props: ReactStylesDiffMap?,
55
+ stateWrapper: StateWrapper?,
56
+ ): Any? {
57
+ if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
58
+ view.setStateWrapper(stateWrapper)
59
+ }
60
+ return super.updateState(view, props, stateWrapper)
61
+ }
62
+
45
63
  override fun onDropViewInstance(
46
64
  @Nonnull view: ScreenStackHeaderConfig,
47
65
  ) {
@@ -87,12 +87,17 @@ open class ScreenViewManager :
87
87
  stateWrapper: StateWrapper?,
88
88
  ): Any? {
89
89
  if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
90
- // fabricViewStateManager should never be null in Fabric. The null check is only for Paper's empty impl.
91
90
  view.setStateWrapper(stateWrapper)
92
91
  }
93
92
  return super.updateState(view, props, stateWrapper)
94
93
  }
95
94
 
95
+ // Called after all props are updated for given view
96
+ override fun onAfterUpdateTransaction(view: Screen) {
97
+ super.onAfterUpdateTransaction(view)
98
+ view.onFinalizePropsUpdate()
99
+ }
100
+
96
101
  @ReactProp(name = "activityState")
97
102
  fun setActivityState(
98
103
  view: Screen,
@@ -143,7 +148,8 @@ open class ScreenViewManager :
143
148
  "slide_from_left" -> Screen.StackAnimation.SLIDE_FROM_LEFT
144
149
  "slide_from_bottom" -> Screen.StackAnimation.SLIDE_FROM_BOTTOM
145
150
  "fade_from_bottom" -> Screen.StackAnimation.FADE_FROM_BOTTOM
146
- "ios" -> Screen.StackAnimation.IOS
151
+ "ios_from_right" -> Screen.StackAnimation.IOS_FROM_RIGHT
152
+ "ios_from_left" -> Screen.StackAnimation.IOS_FROM_LEFT
147
153
  else -> throw JSApplicationIllegalArgumentException("Unknown animation type $animation")
148
154
  }
149
155
  }
@@ -163,6 +163,7 @@ object ScreenWindowTraits {
163
163
  InsetsObserverProxy.registerOnView(decorView)
164
164
  InsetsObserverProxy.addOnApplyWindowInsetsListener(windowInsetsListener)
165
165
  } else {
166
+ InsetsObserverProxy.unregisterOnView(decorView)
166
167
  InsetsObserverProxy.removeOnApplyWindowInsetsListener(windowInsetsListener)
167
168
  }
168
169
  ViewCompat.requestApplyInsets(decorView)
@@ -225,7 +226,7 @@ object ScreenWindowTraits {
225
226
  val window = activity.window
226
227
 
227
228
  val screenForNavBarTranslucent = findScreenForTrait(screen, WindowTraits.NAVIGATION_BAR_TRANSLUCENT)
228
- val translucent = screenForNavBarTranslucent?.isNavigationBarTranslucent ?: false
229
+ val translucent = screenForNavBarTranslucent?.isNavigationBarTranslucent ?: return
229
230
 
230
231
  // Following method controls whether to display edge-to-edge content that draws behind the navigation bar
231
232
  WindowCompat.setDecorFitsSystemWindows(window, !translucent)
@@ -7,16 +7,16 @@ import com.facebook.react.uimanager.events.Event
7
7
  class HeaderHeightChangeEvent(
8
8
  surfaceId: Int,
9
9
  viewId: Int,
10
- private val headerHeight: Double,
10
+ private val headerHeight: Int,
11
11
  ) : Event<HeaderHeightChangeEvent>(surfaceId, viewId) {
12
12
  override fun getEventName() = EVENT_NAME
13
13
 
14
14
  // As the same header height could appear twice, use header height as a coalescing key.
15
- override fun getCoalescingKey(): Short = headerHeight.toInt().toShort()
15
+ override fun getCoalescingKey(): Short = headerHeight.toShort()
16
16
 
17
17
  override fun getEventData(): WritableMap? =
18
18
  Arguments.createMap().apply {
19
- putDouble("headerHeight", headerHeight)
19
+ putDouble("headerHeight", headerHeight.toDouble())
20
20
  }
21
21
 
22
22
  companion object {
@@ -3,6 +3,9 @@ package com.swmansion.rnscreens.ext
3
3
  import android.graphics.drawable.ColorDrawable
4
4
  import android.view.View
5
5
  import android.view.ViewGroup
6
+ import com.facebook.react.views.scroll.ReactHorizontalScrollView
7
+ import com.facebook.react.views.scroll.ReactScrollView
8
+ import com.swmansion.rnscreens.ScreenStack
6
9
 
7
10
  internal fun View.parentAsView() = this.parent as? View
8
11
 
@@ -30,3 +33,17 @@ internal fun View.maybeBgColor(): Int? {
30
33
  }
31
34
  return null
32
35
  }
36
+
37
+ internal fun View.isInsideScrollViewWithRemoveClippedSubviews(): Boolean {
38
+ if (this is ReactHorizontalScrollView || this is ReactScrollView) {
39
+ return false
40
+ }
41
+ var parentView = this.parent
42
+ while (parentView is ViewGroup && parentView !is ScreenStack) {
43
+ if (parentView is ReactScrollView) {
44
+ return parentView.removeClippedSubviews
45
+ }
46
+ parentView = parentView.parent
47
+ }
48
+ return false
49
+ }
@@ -0,0 +1,8 @@
1
+ package com.swmansion.rnscreens.utils
2
+
3
+ // Used only on Paper together with `setLocalData` mechanism to pass
4
+ // the information on header paddings to shadow node.
5
+ data class PaddingBundle(
6
+ val paddingStart: Float,
7
+ val paddingEnd: Float,
8
+ )
@@ -18,6 +18,8 @@
18
18
  */
19
19
  #include <react/renderer/components/rnscreens/RNSScreenComponentDescriptor.h>
20
20
  #include <react/renderer/components/rnscreens/RNSModalScreenComponentDescriptor.h>
21
+ #include <react/renderer/components/rnscreens/RNSScreenStackHeaderSubviewComponentDescriptor.h>
22
+ #include <react/renderer/components/rnscreens/RNSScreenStackHeaderConfigComponentDescriptor.h>
21
23
 
22
24
  namespace facebook {
23
25
  namespace react {
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <translate xmlns:android="http://schemas.android.com/apk/res/android"
3
+ android:duration="@android:integer/config_shortAnimTime"
4
+ android:fromXDelta="30%"
5
+ android:toXDelta="0%" />
@@ -2,4 +2,4 @@
2
2
  <translate xmlns:android="http://schemas.android.com/apk/res/android"
3
3
  android:duration="@android:integer/config_shortAnimTime"
4
4
  android:fromXDelta="0%"
5
- android:toXDelta="-30%"/>
5
+ android:toXDelta="30%" />
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <translate xmlns:android="http://schemas.android.com/apk/res/android"
3
+ android:duration="@android:integer/config_shortAnimTime"
4
+ android:interpolator="@android:interpolator/accelerate_decelerate"
5
+ android:fromXDelta="0%"
6
+ android:toXDelta="-100%" />
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <translate xmlns:android="http://schemas.android.com/apk/res/android"
3
+ android:duration="@android:integer/config_shortAnimTime"
4
+ android:interpolator="@android:interpolator/accelerate_decelerate"
5
+ android:fromXDelta="-100%"
6
+ android:toXDelta="0%" />
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <translate xmlns:android="http://schemas.android.com/apk/res/android"
3
+ android:duration="@android:integer/config_shortAnimTime"
4
+ android:fromXDelta="0%"
5
+ android:toXDelta="-30%" />
@@ -0,0 +1,39 @@
1
+ package com.swmansion.rnscreens
2
+
3
+ import android.content.Context
4
+ import android.view.ViewGroup
5
+ import com.facebook.react.bridge.ReactContext
6
+ import com.facebook.react.uimanager.StateWrapper
7
+ import com.facebook.react.uimanager.UIManagerModule
8
+ import com.swmansion.rnscreens.utils.PaddingBundle
9
+ import kotlin.math.abs
10
+
11
+ abstract class FabricEnabledHeaderConfigViewGroup(
12
+ context: Context,
13
+ ) : ViewGroup(context) {
14
+ private var lastPaddingStart = 0
15
+ private var lastPaddingEnd = 0
16
+
17
+ fun setStateWrapper(wrapper: StateWrapper?) = Unit
18
+
19
+ fun updatePaddingsFabric(
20
+ paddingStart: Int,
21
+ paddingEnd: Int,
22
+ ) {
23
+ // Note that on Paper we do not convert these props from px to dip. This is done internally by RN.
24
+ if (abs(lastPaddingStart - paddingStart) < DELTA && abs(lastPaddingEnd - paddingEnd) < DELTA) {
25
+ return
26
+ }
27
+
28
+ lastPaddingStart = paddingStart
29
+ lastPaddingEnd = paddingEnd
30
+
31
+ val reactContext = context as? ReactContext
32
+ val uiManagerModule = reactContext?.getNativeModule(UIManagerModule::class.java)
33
+ uiManagerModule?.setViewLocalData(this.id, PaddingBundle(paddingStart.toFloat(), paddingEnd.toFloat()))
34
+ }
35
+
36
+ companion object {
37
+ private const val DELTA = 0.9
38
+ }
39
+ }
@@ -12,7 +12,7 @@ abstract class FabricEnabledViewGroup(
12
12
  protected fun updateScreenSizeFabric(
13
13
  width: Int,
14
14
  height: Int,
15
- headerHeight: Double,
15
+ headerHeight: Int,
16
16
  ) {
17
17
  // do nothing
18
18
  }
@@ -5,9 +5,9 @@
5
5
  #endif
6
6
  #include <react/debug/react_native_assert.h>
7
7
  #include <react/renderer/components/rnscreens/Props.h>
8
+ #include <react/renderer/components/rnscreens/utils/RectUtil.h>
8
9
  #include <react/renderer/core/ConcreteComponentDescriptor.h>
9
10
  #include "RNSScreenShadowNode.h"
10
- #include "utils/RectUtil.h"
11
11
 
12
12
  namespace facebook {
13
13
  namespace react {
@@ -19,9 +19,6 @@ class RNSScreenComponentDescriptor final
19
19
  public:
20
20
  using ConcreteComponentDescriptor::ConcreteComponentDescriptor;
21
21
 
22
- static constexpr const char *kScreenDummyLayoutHelperClass =
23
- "com/swmansion/rnscreens/utils/ScreenDummyLayoutHelper";
24
-
25
22
  void adopt(ShadowNode &shadowNode) const override {
26
23
  react_native_assert(dynamic_cast<RNSScreenShadowNode *>(&shadowNode));
27
24
  auto &screenShadowNode = static_cast<RNSScreenShadowNode &>(shadowNode);
@@ -39,8 +36,8 @@ class RNSScreenComponentDescriptor final
39
36
  #ifdef ANDROID
40
37
  if (stateData.frameSize.width != 0 && stateData.frameSize.height != 0) {
41
38
  // When we receive dimensions from JVM side we can remove padding used for
42
- // correction, and we can stop applying height correction for the frame.
43
- // We want to leave top offset correction though intact.
39
+ // correction, and we can stop applying height and offset corrections for
40
+ // the frame.
44
41
  // TODO: In future, when we have dynamic header height we might want to
45
42
  // update Y offset correction here.
46
43
 
@@ -67,36 +64,11 @@ class RNSScreenComponentDescriptor final
67
64
  screenShadowNode.setPadding({0, 0, 0, 0});
68
65
  screenShadowNode.getFrameCorrectionModes().unset(
69
66
  FrameCorrectionModes::Mode::FrameHeightCorrection);
67
+ screenShadowNode.getFrameCorrectionModes().unset(
68
+ FrameCorrectionModes::Mode::FrameOriginCorrection);
70
69
 
71
70
  layoutableShadowNode.setSize(
72
71
  Size{stateData.frameSize.width, stateData.frameSize.height});
73
- } else {
74
- // This code path should be executed only on the very first (few)
75
- // layout(s), when we haven't received state update from JVM side yet.
76
-
77
- auto headerConfigChildOpt = findHeaderConfigChild(layoutableShadowNode);
78
-
79
- // During creation of the shadow node children are not attached yet.
80
- // We also do not want to set any padding in case.
81
- if (headerConfigChildOpt) {
82
- const auto &headerConfigChild = headerConfigChildOpt->get();
83
- const auto &headerProps =
84
- *std::static_pointer_cast<const RNSScreenStackHeaderConfigProps>(
85
- headerConfigChild->getProps());
86
-
87
- const auto headerHeight = headerProps.hidden
88
- ? 0.f
89
- : findHeaderHeight(
90
- headerProps.titleFontSize, headerProps.title.empty())
91
- .value_or(0.f);
92
-
93
- screenShadowNode.setPadding({0, 0, 0, headerHeight});
94
- screenShadowNode.setHeaderHeight(headerHeight);
95
- screenShadowNode.getFrameCorrectionModes().set(
96
- FrameCorrectionModes::Mode(
97
- FrameCorrectionModes::Mode::FrameHeightCorrection |
98
- FrameCorrectionModes::Mode::FrameOriginCorrection));
99
- }
100
72
  }
101
73
  #else
102
74
  if (stateData.frameSize.width != 0 && stateData.frameSize.height != 0) {
@@ -106,72 +78,6 @@ class RNSScreenComponentDescriptor final
106
78
  #endif // ANDROID
107
79
  ConcreteComponentDescriptor::adopt(shadowNode);
108
80
  }
109
-
110
- std::optional<std::reference_wrapper<const ShadowNode::Shared>>
111
- findHeaderConfigChild(
112
- const YogaLayoutableShadowNode &screenShadowNode) const {
113
- for (const ShadowNode::Shared &child : screenShadowNode.getChildren()) {
114
- if (std::strcmp(
115
- child->getComponentName(), "RNSScreenStackHeaderConfig") == 0) {
116
- return {std::cref(child)};
117
- }
118
- }
119
- return {};
120
- }
121
-
122
- #ifdef ANDROID
123
- std::optional<float> findHeaderHeight(
124
- const int fontSize,
125
- const bool isTitleEmpty) const {
126
- JNIEnv *env = facebook::jni::Environment::current();
127
-
128
- if (env == nullptr) {
129
- LOG(ERROR) << "[RNScreens] Failed to retrieve env\n";
130
- return {};
131
- }
132
-
133
- jclass layoutHelperClass = env->FindClass(kScreenDummyLayoutHelperClass);
134
-
135
- if (layoutHelperClass == nullptr) {
136
- LOG(ERROR) << "[RNScreens] Failed to find class with id "
137
- << kScreenDummyLayoutHelperClass;
138
- return {};
139
- }
140
-
141
- jmethodID computeDummyLayoutID =
142
- env->GetMethodID(layoutHelperClass, "computeDummyLayout", "(IZ)F");
143
-
144
- if (computeDummyLayoutID == nullptr) {
145
- LOG(ERROR)
146
- << "[RNScreens] Failed to retrieve computeDummyLayout method ID";
147
- return {};
148
- }
149
-
150
- jmethodID getInstanceMethodID = env->GetStaticMethodID(
151
- layoutHelperClass,
152
- "getInstance",
153
- "()Lcom/swmansion/rnscreens/utils/ScreenDummyLayoutHelper;");
154
-
155
- if (getInstanceMethodID == nullptr) {
156
- LOG(ERROR) << "[RNScreens] Failed to retrieve getInstanceMethodID";
157
- return {};
158
- }
159
-
160
- jobject packageInstance =
161
- env->CallStaticObjectMethod(layoutHelperClass, getInstanceMethodID);
162
-
163
- if (packageInstance == nullptr) {
164
- LOG(ERROR)
165
- << "[RNScreens] Failed to retrieve packageInstance or the package instance was null on JVM side";
166
- return {};
167
- }
168
-
169
- jfloat headerHeight = env->CallFloatMethod(
170
- packageInstance, computeDummyLayoutID, fontSize, isTitleEmpty);
171
-
172
- return {headerHeight};
173
- }
174
- #endif // ANDROID
175
81
  };
176
82
 
177
83
  } // namespace react
@@ -15,6 +15,107 @@ Point RNSScreenShadowNode::getContentOriginOffset(
15
15
  return {contentOffset.x, contentOffset.y};
16
16
  }
17
17
 
18
+ std::optional<std::reference_wrapper<const ShadowNode::Shared>>
19
+ findHeaderConfigChild(const YogaLayoutableShadowNode &screenShadowNode) {
20
+ for (const ShadowNode::Shared &child : screenShadowNode.getChildren()) {
21
+ if (std::strcmp(child->getComponentName(), "RNSScreenStackHeaderConfig") ==
22
+ 0) {
23
+ return {std::cref(child)};
24
+ }
25
+ }
26
+ return {};
27
+ }
28
+
29
+ static constexpr const char *kScreenDummyLayoutHelperClass =
30
+ "com/swmansion/rnscreens/utils/ScreenDummyLayoutHelper";
31
+
32
+ #ifdef ANDROID
33
+ std::optional<float> findHeaderHeight(
34
+ const int fontSize,
35
+ const bool isTitleEmpty) {
36
+ JNIEnv *env = facebook::jni::Environment::current();
37
+
38
+ if (env == nullptr) {
39
+ LOG(ERROR) << "[RNScreens] Failed to retrieve env\n";
40
+ return {};
41
+ }
42
+
43
+ jclass layoutHelperClass = env->FindClass(kScreenDummyLayoutHelperClass);
44
+
45
+ if (layoutHelperClass == nullptr) {
46
+ LOG(ERROR) << "[RNScreens] Failed to find class with id "
47
+ << kScreenDummyLayoutHelperClass;
48
+ return {};
49
+ }
50
+
51
+ jmethodID computeDummyLayoutID =
52
+ env->GetMethodID(layoutHelperClass, "computeDummyLayout", "(IZ)F");
53
+
54
+ if (computeDummyLayoutID == nullptr) {
55
+ LOG(ERROR) << "[RNScreens] Failed to retrieve computeDummyLayout method ID";
56
+ return {};
57
+ }
58
+
59
+ jmethodID getInstanceMethodID = env->GetStaticMethodID(
60
+ layoutHelperClass,
61
+ "getInstance",
62
+ "()Lcom/swmansion/rnscreens/utils/ScreenDummyLayoutHelper;");
63
+
64
+ if (getInstanceMethodID == nullptr) {
65
+ LOG(ERROR) << "[RNScreens] Failed to retrieve getInstanceMethodID";
66
+ return {};
67
+ }
68
+
69
+ jobject packageInstance =
70
+ env->CallStaticObjectMethod(layoutHelperClass, getInstanceMethodID);
71
+
72
+ if (packageInstance == nullptr) {
73
+ LOG(ERROR)
74
+ << "[RNScreens] Failed to retrieve packageInstance or the package instance was null on JVM side";
75
+ return {};
76
+ }
77
+
78
+ jfloat headerHeight = env->CallFloatMethod(
79
+ packageInstance, computeDummyLayoutID, fontSize, isTitleEmpty);
80
+
81
+ return {headerHeight};
82
+ }
83
+ #endif // ANDROID
84
+
85
+ void RNSScreenShadowNode::appendChild(const ShadowNode::Shared &child) {
86
+ YogaLayoutableShadowNode::appendChild(child);
87
+ #ifdef ANDROID
88
+ const auto &stateData = getStateData();
89
+ if (stateData.frameSize.width == 0 || stateData.frameSize.height == 0) {
90
+ // This code path should be executed only on the very first (few)
91
+ // layout(s), when we haven't received state update from JVM side yet.
92
+ auto headerConfigChildOpt = findHeaderConfigChild(*this);
93
+ auto &screenShadowNode = static_cast<RNSScreenShadowNode &>(*this);
94
+
95
+ // During creation of the shadow node children are not attached yet.
96
+ // We also do not want to set any padding in case.
97
+ if (headerConfigChildOpt) {
98
+ const auto &headerConfigChild = headerConfigChildOpt->get();
99
+ const auto &headerProps =
100
+ *std::static_pointer_cast<const RNSScreenStackHeaderConfigProps>(
101
+ headerConfigChild->getProps());
102
+
103
+ const auto headerHeight = headerProps.hidden
104
+ ? 0.f
105
+ : findHeaderHeight(
106
+ headerProps.titleFontSize, headerProps.title.empty())
107
+ .value_or(0.f);
108
+
109
+ screenShadowNode.setPadding({0, 0, 0, headerHeight});
110
+ screenShadowNode.setHeaderHeight(headerHeight);
111
+ screenShadowNode.getFrameCorrectionModes().set(FrameCorrectionModes::Mode(
112
+ FrameCorrectionModes::Mode::FrameHeightCorrection |
113
+ FrameCorrectionModes::Mode::FrameOriginCorrection));
114
+ }
115
+ }
116
+ #endif // ANDROID
117
+ }
118
+
18
119
  void RNSScreenShadowNode::layout(facebook::react::LayoutContext layoutContext) {
19
120
  YogaLayoutableShadowNode::layout(layoutContext);
20
121
 
@@ -28,6 +28,8 @@ class JSI_EXPORT RNSScreenShadowNode final : public ConcreteViewShadowNode<
28
28
 
29
29
  Point getContentOriginOffset(bool includeTransform) const override;
30
30
 
31
+ void appendChild(const ShadowNode::Shared &child) override;
32
+
31
33
  void layout(LayoutContext layoutContext) override;
32
34
 
33
35
  #pragma mark - Custom interface
@@ -0,0 +1,44 @@
1
+ #pragma once
2
+
3
+ #ifdef ANDROID
4
+ #include <fbjni/fbjni.h>
5
+ #endif
6
+ #include <react/debug/react_native_assert.h>
7
+ #include <react/renderer/components/rnscreens/Props.h>
8
+ #include <react/renderer/components/rnscreens/utils/RectUtil.h>
9
+ #include <react/renderer/core/ConcreteComponentDescriptor.h>
10
+ #include "RNSScreenStackHeaderConfigShadowNode.h"
11
+
12
+ namespace facebook::react {
13
+
14
+ using namespace rnscreens;
15
+
16
+ class RNSScreenStackHeaderConfigComponentDescriptor final
17
+ : public ConcreteComponentDescriptor<RNSScreenStackHeaderConfigShadowNode> {
18
+ public:
19
+ using ConcreteComponentDescriptor::ConcreteComponentDescriptor;
20
+
21
+ void adopt(ShadowNode &shadowNode) const override {
22
+ react_native_assert(
23
+ dynamic_cast<RNSScreenStackHeaderConfigShadowNode *>(&shadowNode));
24
+ auto &configShadowNode =
25
+ static_cast<RNSScreenStackHeaderConfigShadowNode &>(shadowNode);
26
+
27
+ react_native_assert(
28
+ dynamic_cast<YogaLayoutableShadowNode *>(&configShadowNode));
29
+ auto &layoutableShadowNode =
30
+ dynamic_cast<YogaLayoutableShadowNode &>(configShadowNode);
31
+
32
+ auto state = std::static_pointer_cast<
33
+ const RNSScreenStackHeaderConfigShadowNode::ConcreteState>(
34
+ shadowNode.getState());
35
+ auto stateData = state->getData();
36
+
37
+ layoutableShadowNode.setPadding(
38
+ {stateData.getPaddingStart(), 0, stateData.getPaddingEnd(), 0});
39
+
40
+ ConcreteComponentDescriptor::adopt(shadowNode);
41
+ }
42
+ };
43
+
44
+ } // namespace facebook::react
@@ -0,0 +1,8 @@
1
+ #include "RNSScreenStackHeaderConfigShadowNode.h"
2
+
3
+ namespace facebook::react {
4
+
5
+ extern const char RNSScreenStackHeaderConfigComponentName[] =
6
+ "RNSScreenStackHeaderConfig";
7
+
8
+ }
@@ -0,0 +1,32 @@
1
+ #pragma once
2
+
3
+ #include <jsi/jsi.h>
4
+ #include <react/renderer/components/rnscreens/EventEmitters.h>
5
+ #include <react/renderer/components/rnscreens/Props.h>
6
+ #include <react/renderer/components/view/ConcreteViewShadowNode.h>
7
+ #include <react/renderer/core/LayoutContext.h>
8
+ #include "FrameCorrectionModes.h"
9
+ #include "RNSScreenStackHeaderConfigState.h"
10
+
11
+ namespace facebook::react {
12
+
13
+ using namespace rnscreens;
14
+
15
+ JSI_EXPORT extern const char RNSScreenStackHeaderConfigComponentName[];
16
+
17
+ class JSI_EXPORT RNSScreenStackHeaderConfigShadowNode final
18
+ : public ConcreteViewShadowNode<
19
+ RNSScreenStackHeaderConfigComponentName,
20
+ RNSScreenStackHeaderConfigProps,
21
+ RNSScreenStackHeaderConfigEventEmitter,
22
+ RNSScreenStackHeaderConfigState> {
23
+ public:
24
+ using ConcreteViewShadowNode::ConcreteViewShadowNode;
25
+ using StateData = ConcreteViewShadowNode::ConcreteStateData;
26
+
27
+ #pragma mark - ShadowNode overrides
28
+
29
+ #pragma mark - Custom interface
30
+ };
31
+
32
+ } // namespace facebook::react
@@ -0,0 +1,23 @@
1
+ #include "RNSScreenStackHeaderConfigState.h"
2
+
3
+ namespace facebook {
4
+ namespace react {
5
+
6
+ #ifdef ANDROID
7
+ folly::dynamic RNSScreenStackHeaderConfigState::getDynamic() const {
8
+ return folly::dynamic::object("paddingStart", paddingStart_)(
9
+ "paddingEnd_", paddingEnd_);
10
+ }
11
+
12
+ #endif
13
+
14
+ Float RNSScreenStackHeaderConfigState::getPaddingStart() const noexcept {
15
+ return paddingStart_;
16
+ }
17
+
18
+ Float RNSScreenStackHeaderConfigState::getPaddingEnd() const noexcept {
19
+ return paddingEnd_;
20
+ }
21
+
22
+ } // namespace react
23
+ } // namespace facebook
@@ -0,0 +1,50 @@
1
+ #pragma once
2
+
3
+ #include <react/renderer/core/graphicsConversions.h>
4
+ #include <react/renderer/graphics/Float.h>
5
+
6
+ #ifdef ANDROID
7
+ #include <folly/dynamic.h>
8
+ #include <react/renderer/mapbuffer/MapBuffer.h>
9
+ #include <react/renderer/mapbuffer/MapBufferBuilder.h>
10
+ #endif
11
+
12
+ namespace facebook::react {
13
+
14
+ class JSI_EXPORT RNSScreenStackHeaderConfigState final {
15
+ public:
16
+ using Shared = std::shared_ptr<const RNSScreenStackHeaderConfigState>;
17
+
18
+ RNSScreenStackHeaderConfigState() = default;
19
+
20
+ RNSScreenStackHeaderConfigState(Float paddingStart, Float paddingEnd)
21
+ : paddingStart_{paddingStart}, paddingEnd_{paddingEnd} {}
22
+
23
+ #ifdef ANDROID
24
+ RNSScreenStackHeaderConfigState(
25
+ RNSScreenStackHeaderConfigState const &previousState,
26
+ folly::dynamic data)
27
+ : paddingStart_{static_cast<Float>(data["paddingStart"].getDouble())},
28
+ paddingEnd_{static_cast<Float>(data["paddingEnd"].getDouble())} {}
29
+ #endif
30
+
31
+ #ifdef ANDROID
32
+ folly::dynamic getDynamic() const;
33
+ MapBuffer getMapBuffer() const {
34
+ return MapBufferBuilder::EMPTY();
35
+ };
36
+
37
+ #endif
38
+
39
+ #pragma mark - Getters
40
+
41
+ [[nodiscard]] Float getPaddingStart() const noexcept;
42
+
43
+ [[nodiscard]] Float getPaddingEnd() const noexcept;
44
+
45
+ private:
46
+ Float paddingStart_{0.f};
47
+ Float paddingEnd_{0.f};
48
+ };
49
+
50
+ } // namespace facebook::react