react-native-screens 3.32.0 → 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 (142) hide show
  1. package/README.md +17 -13
  2. package/RNScreens.podspec +10 -52
  3. package/android/CMakeLists.txt +48 -4
  4. package/android/build.gradle +9 -81
  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/java/com/swmansion/rnscreens/CustomSearchView.kt +5 -2
  11. package/android/src/main/java/com/swmansion/rnscreens/CustomToolbar.kt +4 -1
  12. package/android/src/main/java/com/swmansion/rnscreens/FragmentBackPressOverrider.kt +2 -2
  13. package/android/src/main/java/com/swmansion/rnscreens/RNScreensPackage.kt +36 -17
  14. package/android/src/main/java/com/swmansion/rnscreens/Screen.kt +134 -38
  15. package/android/src/main/java/com/swmansion/rnscreens/ScreenContainer.kt +52 -30
  16. package/android/src/main/java/com/swmansion/rnscreens/ScreenContainerViewManager.kt +17 -7
  17. package/android/src/main/java/com/swmansion/rnscreens/ScreenEventDispatcher.kt +10 -2
  18. package/android/src/main/java/com/swmansion/rnscreens/ScreenFragment.kt +56 -27
  19. package/android/src/main/java/com/swmansion/rnscreens/ScreenFragmentWrapper.kt +8 -1
  20. package/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt +50 -19
  21. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragment.kt +60 -37
  22. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragmentWrapper.kt +4 -0
  23. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfig.kt +85 -58
  24. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfigViewManager.kt +128 -37
  25. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubview.kt +19 -4
  26. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubviewManager.kt +16 -10
  27. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackViewManager.kt +28 -25
  28. package/android/src/main/java/com/swmansion/rnscreens/ScreenViewManager.kt +173 -78
  29. package/android/src/main/java/com/swmansion/rnscreens/ScreenWindowTraits.kt +59 -24
  30. package/android/src/main/java/com/swmansion/rnscreens/ScreensModule.kt +30 -8
  31. package/android/src/main/java/com/swmansion/rnscreens/ScreensShadowNode.kt +3 -1
  32. package/android/src/main/java/com/swmansion/rnscreens/SearchBarManager.kt +101 -50
  33. package/android/src/main/java/com/swmansion/rnscreens/SearchBarView.kt +29 -22
  34. package/android/src/main/java/com/swmansion/rnscreens/SearchViewFormatter.kt +7 -2
  35. package/android/src/main/java/com/swmansion/rnscreens/events/HeaderAttachedEvent.kt +4 -1
  36. package/android/src/main/java/com/swmansion/rnscreens/events/HeaderBackButtonClickedEvent.kt +4 -1
  37. package/android/src/main/java/com/swmansion/rnscreens/events/HeaderDetachedEvent.kt +4 -1
  38. package/android/src/main/java/com/swmansion/rnscreens/events/HeaderHeightChangeEvent.kt +5 -5
  39. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenAppearEvent.kt +4 -1
  40. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenDisappearEvent.kt +4 -1
  41. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenDismissedEvent.kt +8 -4
  42. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenTransitionProgressEvent.kt +7 -6
  43. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenWillAppearEvent.kt +4 -1
  44. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenWillDisappearEvent.kt +4 -1
  45. package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarBlurEvent.kt +4 -1
  46. package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarChangeTextEvent.kt +4 -3
  47. package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarCloseEvent.kt +4 -1
  48. package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarFocusEvent.kt +4 -1
  49. package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarOpenEvent.kt +4 -1
  50. package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarSearchButtonPressEvent.kt +9 -4
  51. package/android/src/main/java/com/swmansion/rnscreens/events/StackFinishTransitioningEvent.kt +4 -1
  52. package/android/src/main/java/com/swmansion/rnscreens/utils/DeviceUtils.kt +1 -5
  53. package/android/src/main/java/com/swmansion/rnscreens/utils/ScreenDummyLayoutHelper.kt +214 -0
  54. package/android/src/main/jni/CMakeLists.txt +5 -4
  55. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerDelegate.java +3 -0
  56. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerInterface.java +1 -0
  57. package/android/src/paper/java/com/swmansion/rnscreens/FabricEnabledViewGroup.kt +10 -5
  58. package/android/src/paper/java/com/swmansion/rnscreens/NativeProxy.kt +19 -0
  59. package/android/src/paper/java/com/swmansion/rnscreens/NativeScreensModuleSpec.java +4 -0
  60. package/common/cpp/react/renderer/components/rnscreens/FrameCorrectionModes.h +51 -0
  61. package/common/cpp/react/renderer/components/rnscreens/RNSModalScreenShadowNode.cpp +2 -1
  62. package/common/cpp/react/renderer/components/rnscreens/RNSModalScreenShadowNode.h +1 -1
  63. package/common/cpp/react/renderer/components/rnscreens/RNSScreenComponentDescriptor.h +140 -1
  64. package/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.cpp +51 -1
  65. package/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.h +23 -1
  66. package/common/cpp/react/renderer/components/rnscreens/RNSScreenState.cpp +20 -0
  67. package/common/cpp/react/renderer/components/rnscreens/RNSScreenState.h +23 -1
  68. package/common/cpp/react/renderer/components/rnscreens/utils/RectUtil.h +36 -0
  69. package/cpp/RNSScreenRemovalListener.cpp +25 -0
  70. package/cpp/RNSScreenRemovalListener.h +20 -0
  71. package/ios/RNSConvert.h +1 -0
  72. package/ios/RNSModalScreen.mm +22 -0
  73. package/ios/RNSModule.mm +1 -1
  74. package/ios/RNSScreen.h +2 -1
  75. package/ios/RNSScreen.mm +27 -19
  76. package/ios/RNSScreenStack.mm +24 -77
  77. package/ios/RNSScreenStackAnimator.mm +43 -6
  78. package/ios/RNSScreenStackHeaderConfig.mm +49 -11
  79. package/ios/RNSScreenStackHeaderSubview.mm +8 -0
  80. package/ios/utils/UIView+RNSUtility.h +23 -0
  81. package/ios/utils/UIView+RNSUtility.mm +55 -0
  82. package/lib/commonjs/components/ScreenStack.js +8 -1
  83. package/lib/commonjs/components/ScreenStack.js.map +1 -1
  84. package/lib/commonjs/fabric/ModalScreenNativeComponent.js.map +1 -1
  85. package/lib/commonjs/fabric/ScreenNativeComponent.js.map +1 -1
  86. package/lib/commonjs/native-stack/views/NativeStackView.js +2 -0
  87. package/lib/commonjs/native-stack/views/NativeStackView.js.map +1 -1
  88. package/lib/module/components/ScreenStack.js +8 -1
  89. package/lib/module/components/ScreenStack.js.map +1 -1
  90. package/lib/module/fabric/ModalScreenNativeComponent.js.map +1 -1
  91. package/lib/module/fabric/ScreenNativeComponent.js.map +1 -1
  92. package/lib/module/native-stack/views/NativeStackView.js +2 -0
  93. package/lib/module/native-stack/views/NativeStackView.js.map +1 -1
  94. package/lib/typescript/components/ScreenStack.d.ts.map +1 -1
  95. package/lib/typescript/fabric/ModalScreenNativeComponent.d.ts +1 -0
  96. package/lib/typescript/fabric/ModalScreenNativeComponent.d.ts.map +1 -1
  97. package/lib/typescript/fabric/ScreenNativeComponent.d.ts +1 -0
  98. package/lib/typescript/fabric/ScreenNativeComponent.d.ts.map +1 -1
  99. package/lib/typescript/native-stack/types.d.ts +10 -0
  100. package/lib/typescript/native-stack/types.d.ts.map +1 -1
  101. package/lib/typescript/native-stack/views/NativeStackView.d.ts.map +1 -1
  102. package/lib/typescript/types.d.ts +10 -0
  103. package/lib/typescript/types.d.ts.map +1 -1
  104. package/native-stack/README.md +110 -99
  105. package/package.json +6 -3
  106. package/react-native.config.js +17 -15
  107. package/src/TransitionProgressContext.tsx +1 -1
  108. package/src/components/Screen.tsx +4 -4
  109. package/src/components/ScreenStack.tsx +11 -1
  110. package/src/components/ScreenStackHeaderConfig.tsx +5 -5
  111. package/src/components/ScreenStackHeaderConfig.web.tsx +6 -6
  112. package/src/components/SearchBar.tsx +4 -4
  113. package/src/core.ts +1 -1
  114. package/src/fabric/ModalScreenNativeComponent.ts +1 -0
  115. package/src/fabric/ScreenNativeComponent.ts +1 -0
  116. package/src/fabric/ScreenNavigationContainerNativeComponent.ts +1 -1
  117. package/src/fabric/ScreenStackHeaderConfigNativeComponent.ts +1 -1
  118. package/src/fabric/ScreenStackHeaderSubviewNativeComponent.ts +1 -1
  119. package/src/fabric/SearchBarNativeComponent.ts +1 -1
  120. package/src/gesture-handler/ScreenGestureDetector.tsx +5 -5
  121. package/src/gesture-handler/constraints.ts +5 -5
  122. package/src/gesture-handler/fabricUtils.ts +1 -1
  123. package/src/native-stack/contexts/GHContext.tsx +1 -1
  124. package/src/native-stack/navigators/createNativeStackNavigator.tsx +3 -3
  125. package/src/native-stack/types.tsx +14 -4
  126. package/src/native-stack/utils/getDefaultHeaderHeight.tsx +1 -1
  127. package/src/native-stack/utils/getStatusBarHeight.tsx +1 -1
  128. package/src/native-stack/utils/useAnimatedHeaderHeight.tsx +1 -1
  129. package/src/native-stack/utils/useBackPressSubscription.tsx +1 -1
  130. package/src/native-stack/utils/useHeaderHeight.tsx +1 -1
  131. package/src/native-stack/views/FontProcessor.tsx +1 -1
  132. package/src/native-stack/views/HeaderConfig.tsx +1 -1
  133. package/src/native-stack/views/NativeStackView.tsx +11 -9
  134. package/src/reanimated/ReanimatedHeaderHeightContext.tsx +1 -1
  135. package/src/reanimated/ReanimatedNativeStackScreen.tsx +5 -5
  136. package/src/reanimated/ReanimatedScreen.tsx +2 -2
  137. package/src/reanimated/ReanimatedScreenProvider.tsx +1 -1
  138. package/src/reanimated/useReanimatedHeaderHeight.tsx +1 -1
  139. package/src/reanimated/useReanimatedTransitionProgress.tsx +1 -1
  140. package/src/types.tsx +15 -5
  141. package/src/useTransitionProgress.tsx +1 -1
  142. package/windows/README.md +4 -1
@@ -23,10 +23,12 @@ import com.facebook.react.views.text.ReactTypefaceUtils
23
23
  import com.swmansion.rnscreens.events.HeaderAttachedEvent
24
24
  import com.swmansion.rnscreens.events.HeaderDetachedEvent
25
25
 
26
- class ScreenStackHeaderConfig(context: Context) : ViewGroup(context) {
26
+ class ScreenStackHeaderConfig(
27
+ context: Context,
28
+ ) : ViewGroup(context) {
27
29
  private val configSubviews = ArrayList<ScreenStackHeaderSubview>(3)
28
30
  val toolbar: CustomToolbar
29
- var isHeaderHidden = false // named this way to avoid conflict with platform's isHidden
31
+ var isHeaderHidden = false // named this way to avoid conflict with platform's isHidden
30
32
  var isHeaderTranslucent = false // named this way to avoid conflict with platform's isTranslucent
31
33
  private var headerTopInset: Int? = null
32
34
  private var title: String? = null
@@ -45,29 +47,36 @@ class ScreenStackHeaderConfig(context: Context) : ViewGroup(context) {
45
47
  private var isAttachedToWindow = false
46
48
  private val defaultStartInset: Int
47
49
  private val defaultStartInsetWithNavigation: Int
48
- private val backClickListener = OnClickListener {
49
- screenFragment?.let {
50
- val stack = screenStack
51
- if (stack != null && stack.rootScreen == it.screen) {
52
- val parentFragment = it.parentFragment
53
- if (parentFragment is ScreenStackFragment) {
54
- if (parentFragment.screen.nativeBackButtonDismissalEnabled) {
55
- parentFragment.dismiss()
56
- } else {
57
- parentFragment.dispatchHeaderBackButtonClickedEvent()
50
+ private val backClickListener =
51
+ OnClickListener {
52
+ screenFragment?.let {
53
+ val stack = screenStack
54
+ if (stack != null && stack.rootScreen == it.screen) {
55
+ val parentFragment = it.parentFragment
56
+ if (parentFragment is ScreenStackFragment) {
57
+ if (parentFragment.screen.nativeBackButtonDismissalEnabled) {
58
+ parentFragment.dismiss()
59
+ } else {
60
+ parentFragment.dispatchHeaderBackButtonClickedEvent()
61
+ }
58
62
  }
59
- }
60
- } else {
61
- if (it.screen.nativeBackButtonDismissalEnabled) {
62
- it.dismiss()
63
63
  } else {
64
- it.dispatchHeaderBackButtonClickedEvent()
64
+ if (it.screen.nativeBackButtonDismissalEnabled) {
65
+ it.dismiss()
66
+ } else {
67
+ it.dispatchHeaderBackButtonClickedEvent()
68
+ }
65
69
  }
66
70
  }
67
71
  }
68
- }
69
72
 
70
- override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
73
+ override fun onLayout(
74
+ changed: Boolean,
75
+ l: Int,
76
+ t: Int,
77
+ r: Int,
78
+ b: Int,
79
+ ) {
71
80
  // no-op
72
81
  }
73
82
 
@@ -79,18 +88,21 @@ class ScreenStackHeaderConfig(context: Context) : ViewGroup(context) {
79
88
  super.onAttachedToWindow()
80
89
  isAttachedToWindow = true
81
90
  val surfaceId = UIManagerHelper.getSurfaceId(this)
82
- UIManagerHelper.getEventDispatcherForReactTag(context as ReactContext, id)
91
+ UIManagerHelper
92
+ .getEventDispatcherForReactTag(context as ReactContext, id)
83
93
  ?.dispatchEvent(HeaderAttachedEvent(surfaceId, id))
84
94
  // we want to save the top inset before the status bar can be hidden, which would resolve in
85
95
  // inset being 0
86
96
  if (headerTopInset == null) {
87
- headerTopInset = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
88
- rootWindowInsets.getInsets(WindowInsets.Type.systemBars()).top
89
- else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
90
- rootWindowInsets.systemWindowInsetTop
91
- else
92
- // Hacky fallback for old android. Before Marshmallow, the status bar height was always 25
93
- (25 * resources.displayMetrics.density).toInt()
97
+ headerTopInset =
98
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
99
+ rootWindowInsets.getInsets(WindowInsets.Type.systemBars()).top
100
+ } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
101
+ rootWindowInsets.systemWindowInsetTop
102
+ } else {
103
+ // Hacky fallback for old android. Before Marshmallow, the status bar height was always 25
104
+ (25 * resources.displayMetrics.density).toInt()
105
+ }
94
106
  }
95
107
  onUpdate()
96
108
  }
@@ -99,7 +111,8 @@ class ScreenStackHeaderConfig(context: Context) : ViewGroup(context) {
99
111
  super.onDetachedFromWindow()
100
112
  isAttachedToWindow = false
101
113
  val surfaceId = UIManagerHelper.getSurfaceId(this)
102
- UIManagerHelper.getEventDispatcherForReactTag(context as ReactContext, id)
114
+ UIManagerHelper
115
+ .getEventDispatcherForReactTag(context as ReactContext, id)
103
116
  ?.dispatchEvent(HeaderDetachedEvent(surfaceId, id))
104
117
  }
105
118
 
@@ -144,11 +157,12 @@ class ScreenStackHeaderConfig(context: Context) : ViewGroup(context) {
144
157
  // because sometimes we don't have the Fragment and Activity available then yet, e.g. on the
145
158
  // first setting of props. Similar thing is done for Screens of ScreenContainers, but in
146
159
  // `onContainerUpdate` of their Fragment
147
- val reactContext = if (context is ReactContext) {
148
- context as ReactContext
149
- } else {
150
- it.fragmentWrapper?.tryGetContext()
151
- }
160
+ val reactContext =
161
+ if (context is ReactContext) {
162
+ context as ReactContext
163
+ } else {
164
+ it.fragmentWrapper?.tryGetContext()
165
+ }
152
166
  ScreenWindowTraits.trySetWindowTraits(it, activity, reactContext)
153
167
  }
154
168
 
@@ -187,7 +201,7 @@ class ScreenStackHeaderConfig(context: Context) : ViewGroup(context) {
187
201
 
188
202
  // hide back button
189
203
  actionBar.setDisplayHomeAsUpEnabled(
190
- screenFragment?.canNavigateBack() == true && !isBackButtonHidden
204
+ screenFragment?.canNavigateBack() == true && !isBackButtonHidden,
191
205
  )
192
206
 
193
207
  // when setSupportActionBar is called a toolbar wrapper gets initialized that overwrites
@@ -210,16 +224,21 @@ class ScreenStackHeaderConfig(context: Context) : ViewGroup(context) {
210
224
  toolbar.contentInsetStartWithNavigation = 0
211
225
  }
212
226
 
213
- val titleTextView = titleTextView
227
+ val titleTextView = findTitleTextViewInToolbar(toolbar)
214
228
  if (titleColor != 0) {
215
229
  toolbar.setTitleTextColor(titleColor)
216
230
  }
217
231
 
218
232
  if (titleTextView != null) {
219
233
  if (titleFontFamily != null || titleFontWeight > 0) {
220
- val titleTypeface = ReactTypefaceUtils.applyStyles(
221
- null, 0, titleFontWeight, titleFontFamily, context.assets
222
- )
234
+ val titleTypeface =
235
+ ReactTypefaceUtils.applyStyles(
236
+ null,
237
+ 0,
238
+ titleFontWeight,
239
+ titleFontFamily,
240
+ context.assets,
241
+ )
223
242
  titleTextView.typeface = titleTypeface
224
243
  }
225
244
  if (titleFontSize > 0) {
@@ -250,10 +269,11 @@ class ScreenStackHeaderConfig(context: Context) : ViewGroup(context) {
250
269
  if (type === ScreenStackHeaderSubview.Type.BACK) {
251
270
  // we special case BACK button header config type as we don't add it as a view into toolbar
252
271
  // but instead just copy the drawable from imageview that's added as a first child to it.
253
- val firstChild = view.getChildAt(0) as? ImageView
254
- ?: throw JSApplicationIllegalArgumentException(
255
- "Back button header config view should have Image as first child"
256
- )
272
+ val firstChild =
273
+ view.getChildAt(0) as? ImageView
274
+ ?: throw JSApplicationIllegalArgumentException(
275
+ "Back button header config view should have Image as first child",
276
+ )
257
277
  actionBar.setHomeAsUpIndicator(firstChild.drawable)
258
278
  i++
259
279
  continue
@@ -284,7 +304,7 @@ class ScreenStackHeaderConfig(context: Context) : ViewGroup(context) {
284
304
  }
285
305
 
286
306
  private fun maybeUpdate() {
287
- if (parent != null && !isDestroyed) {
307
+ if (parent != null && !isDestroyed && screen?.isBeingRemoved == false) {
288
308
  onUpdate()
289
309
  }
290
310
  }
@@ -304,24 +324,14 @@ class ScreenStackHeaderConfig(context: Context) : ViewGroup(context) {
304
324
  maybeUpdate()
305
325
  }
306
326
 
307
- fun addConfigSubview(child: ScreenStackHeaderSubview, index: Int) {
327
+ fun addConfigSubview(
328
+ child: ScreenStackHeaderSubview,
329
+ index: Int,
330
+ ) {
308
331
  configSubviews.add(index, child)
309
332
  maybeUpdate()
310
333
  }
311
334
 
312
- private val titleTextView: TextView?
313
- get() {
314
- for (i in 0 until toolbar.childCount) {
315
- val view = toolbar.getChildAt(i)
316
- if (view is TextView) {
317
- if (view.text == toolbar.title) {
318
- return view
319
- }
320
- }
321
- }
322
- return null
323
- }
324
-
325
335
  fun setTitle(title: String?) {
326
336
  this.title = title
327
337
  }
@@ -378,7 +388,10 @@ class ScreenStackHeaderConfig(context: Context) : ViewGroup(context) {
378
388
  this.direction = direction
379
389
  }
380
390
 
381
- private class DebugMenuToolbar(context: Context, config: ScreenStackHeaderConfig) : CustomToolbar(context, config) {
391
+ private class DebugMenuToolbar(
392
+ context: Context,
393
+ config: ScreenStackHeaderConfig,
394
+ ) : CustomToolbar(context, config) {
382
395
  override fun showOverflowMenu(): Boolean {
383
396
  (context.applicationContext as ReactApplication)
384
397
  .reactNativeHost
@@ -401,4 +414,18 @@ class ScreenStackHeaderConfig(context: Context) : ViewGroup(context) {
401
414
  }
402
415
  toolbar.clipChildren = false
403
416
  }
417
+
418
+ companion object {
419
+ fun findTitleTextViewInToolbar(toolbar: Toolbar): TextView? {
420
+ for (i in 0 until toolbar.childCount) {
421
+ val view = toolbar.getChildAt(i)
422
+ if (view is TextView) {
423
+ if (view.text == toolbar.title) {
424
+ return view
425
+ }
426
+ }
427
+ }
428
+ return null
429
+ }
430
+ }
404
431
  }
@@ -16,7 +16,9 @@ import com.swmansion.rnscreens.events.HeaderDetachedEvent
16
16
  import javax.annotation.Nonnull
17
17
 
18
18
  @ReactModule(name = ScreenStackHeaderConfigViewManager.REACT_CLASS)
19
- class ScreenStackHeaderConfigViewManager : ViewGroupManager<ScreenStackHeaderConfig>(), RNSScreenStackHeaderConfigManagerInterface<ScreenStackHeaderConfig> {
19
+ class ScreenStackHeaderConfigViewManager :
20
+ ViewGroupManager<ScreenStackHeaderConfig>(),
21
+ RNSScreenStackHeaderConfigManagerInterface<ScreenStackHeaderConfig> {
20
22
  private val delegate: ViewManagerDelegate<ScreenStackHeaderConfig>
21
23
 
22
24
  init {
@@ -27,16 +29,22 @@ class ScreenStackHeaderConfigViewManager : ViewGroupManager<ScreenStackHeaderCon
27
29
 
28
30
  override fun createViewInstance(reactContext: ThemedReactContext) = ScreenStackHeaderConfig(reactContext)
29
31
 
30
- override fun addView(parent: ScreenStackHeaderConfig, child: View, index: Int) {
32
+ override fun addView(
33
+ parent: ScreenStackHeaderConfig,
34
+ child: View,
35
+ index: Int,
36
+ ) {
31
37
  if (child !is ScreenStackHeaderSubview) {
32
38
  throw JSApplicationCausedNativeException(
33
- "Config children should be of type " + ScreenStackHeaderSubviewManager.REACT_CLASS
39
+ "Config children should be of type " + ScreenStackHeaderSubviewManager.REACT_CLASS,
34
40
  )
35
41
  }
36
42
  parent.addConfigSubview(child, index)
37
43
  }
38
44
 
39
- override fun onDropViewInstance(@Nonnull view: ScreenStackHeaderConfig) {
45
+ override fun onDropViewInstance(
46
+ @Nonnull view: ScreenStackHeaderConfig,
47
+ ) {
40
48
  view.destroy()
41
49
  }
42
50
 
@@ -44,13 +52,19 @@ class ScreenStackHeaderConfigViewManager : ViewGroupManager<ScreenStackHeaderCon
44
52
  parent.removeAllConfigSubviews()
45
53
  }
46
54
 
47
- override fun removeViewAt(parent: ScreenStackHeaderConfig, index: Int) {
55
+ override fun removeViewAt(
56
+ parent: ScreenStackHeaderConfig,
57
+ index: Int,
58
+ ) {
48
59
  parent.removeConfigSubview(index)
49
60
  }
50
61
 
51
62
  override fun getChildCount(parent: ScreenStackHeaderConfig): Int = parent.configSubviewsCount
52
63
 
53
- override fun getChildAt(parent: ScreenStackHeaderConfig, index: Int): View = parent.getConfigSubview(index)
64
+ override fun getChildAt(
65
+ parent: ScreenStackHeaderConfig,
66
+ index: Int,
67
+ ): View = parent.getConfigSubview(index)
54
68
 
55
69
  override fun needsCustomLayoutForChildren() = true
56
70
 
@@ -60,88 +74,126 @@ class ScreenStackHeaderConfigViewManager : ViewGroupManager<ScreenStackHeaderCon
60
74
  }
61
75
 
62
76
  @ReactProp(name = "title")
63
- override fun setTitle(config: ScreenStackHeaderConfig, title: String?) {
77
+ override fun setTitle(
78
+ config: ScreenStackHeaderConfig,
79
+ title: String?,
80
+ ) {
64
81
  config.setTitle(title)
65
82
  }
66
83
 
67
84
  @ReactProp(name = "titleFontFamily")
68
- override fun setTitleFontFamily(config: ScreenStackHeaderConfig, titleFontFamily: String?) {
85
+ override fun setTitleFontFamily(
86
+ config: ScreenStackHeaderConfig,
87
+ titleFontFamily: String?,
88
+ ) {
69
89
  config.setTitleFontFamily(titleFontFamily)
70
90
  }
71
91
 
72
92
  @ReactProp(name = "titleFontSize")
73
- override fun setTitleFontSize(config: ScreenStackHeaderConfig, titleFontSize: Int) {
93
+ override fun setTitleFontSize(
94
+ config: ScreenStackHeaderConfig,
95
+ titleFontSize: Int,
96
+ ) {
74
97
  config.setTitleFontSize(titleFontSize.toFloat())
75
98
  }
76
99
 
77
100
  @ReactProp(name = "titleFontWeight")
78
- override fun setTitleFontWeight(config: ScreenStackHeaderConfig, titleFontWeight: String?) {
101
+ override fun setTitleFontWeight(
102
+ config: ScreenStackHeaderConfig,
103
+ titleFontWeight: String?,
104
+ ) {
79
105
  config.setTitleFontWeight(titleFontWeight)
80
106
  }
81
107
 
82
108
  @ReactProp(name = "titleColor", customType = "Color")
83
- override fun setTitleColor(config: ScreenStackHeaderConfig, titleColor: Int?) {
109
+ override fun setTitleColor(
110
+ config: ScreenStackHeaderConfig,
111
+ titleColor: Int?,
112
+ ) {
84
113
  if (titleColor != null) {
85
114
  config.setTitleColor(titleColor)
86
115
  }
87
116
  }
88
117
 
89
118
  @ReactProp(name = "backgroundColor", customType = "Color")
90
- override fun setBackgroundColor(config: ScreenStackHeaderConfig, backgroundColor: Int?) {
119
+ override fun setBackgroundColor(
120
+ config: ScreenStackHeaderConfig,
121
+ backgroundColor: Int?,
122
+ ) {
91
123
  config.setBackgroundColor(backgroundColor)
92
124
  }
93
125
 
94
126
  @ReactProp(name = "hideShadow")
95
- override fun setHideShadow(config: ScreenStackHeaderConfig, hideShadow: Boolean) {
127
+ override fun setHideShadow(
128
+ config: ScreenStackHeaderConfig,
129
+ hideShadow: Boolean,
130
+ ) {
96
131
  config.setHideShadow(hideShadow)
97
132
  }
98
133
 
99
134
  @ReactProp(name = "hideBackButton")
100
- override fun setHideBackButton(config: ScreenStackHeaderConfig, hideBackButton: Boolean) {
135
+ override fun setHideBackButton(
136
+ config: ScreenStackHeaderConfig,
137
+ hideBackButton: Boolean,
138
+ ) {
101
139
  config.setHideBackButton(hideBackButton)
102
140
  }
103
141
 
104
142
  @ReactProp(name = "topInsetEnabled")
105
- override fun setTopInsetEnabled(config: ScreenStackHeaderConfig, topInsetEnabled: Boolean) {
143
+ override fun setTopInsetEnabled(
144
+ config: ScreenStackHeaderConfig,
145
+ topInsetEnabled: Boolean,
146
+ ) {
106
147
  config.setTopInsetEnabled(topInsetEnabled)
107
148
  }
108
149
 
109
150
  @ReactProp(name = "color", customType = "Color")
110
- override fun setColor(config: ScreenStackHeaderConfig, color: Int?) {
151
+ override fun setColor(
152
+ config: ScreenStackHeaderConfig,
153
+ color: Int?,
154
+ ) {
111
155
  config.setTintColor(color ?: 0)
112
156
  }
113
157
 
114
158
  @ReactProp(name = "hidden")
115
- override fun setHidden(config: ScreenStackHeaderConfig, hidden: Boolean) {
159
+ override fun setHidden(
160
+ config: ScreenStackHeaderConfig,
161
+ hidden: Boolean,
162
+ ) {
116
163
  config.setHidden(hidden)
117
164
  }
118
165
 
119
166
  @ReactProp(name = "translucent")
120
- override fun setTranslucent(config: ScreenStackHeaderConfig, translucent: Boolean) {
167
+ override fun setTranslucent(
168
+ config: ScreenStackHeaderConfig,
169
+ translucent: Boolean,
170
+ ) {
121
171
  config.setTranslucent(translucent)
122
172
  }
123
173
 
124
174
  @ReactProp(name = "backButtonInCustomView")
125
175
  override fun setBackButtonInCustomView(
126
176
  config: ScreenStackHeaderConfig,
127
- backButtonInCustomView: Boolean
177
+ backButtonInCustomView: Boolean,
128
178
  ) {
129
179
  config.setBackButtonInCustomView(backButtonInCustomView)
130
180
  }
131
181
 
132
182
  @ReactProp(name = "direction")
133
- override fun setDirection(config: ScreenStackHeaderConfig, direction: String?) {
183
+ override fun setDirection(
184
+ config: ScreenStackHeaderConfig,
185
+ direction: String?,
186
+ ) {
134
187
  config.setDirection(direction)
135
188
  }
136
189
 
137
- override fun getExportedCustomDirectEventTypeConstants(): Map<String, Any>? {
138
- return MapBuilder.of(
190
+ override fun getExportedCustomDirectEventTypeConstants(): Map<String, Any>? =
191
+ MapBuilder.of(
139
192
  HeaderAttachedEvent.EVENT_NAME,
140
193
  MapBuilder.of("registrationName", "onAttached"),
141
194
  HeaderDetachedEvent.EVENT_NAME,
142
195
  MapBuilder.of("registrationName", "onDetached"),
143
196
  )
144
- }
145
197
 
146
198
  protected override fun getDelegate(): ViewManagerDelegate<ScreenStackHeaderConfig> = delegate
147
199
 
@@ -151,58 +203,97 @@ class ScreenStackHeaderConfigViewManager : ViewGroupManager<ScreenStackHeaderCon
151
203
 
152
204
  // TODO: Find better way to handle platform specific props
153
205
  private fun logNotAvailable(propName: String) {
154
- Log.w("RN SCREENS", "$propName prop is not available on Android")
206
+ Log.w("[RNScreens]", "$propName prop is not available on Android")
155
207
  }
156
208
 
157
- override fun setBackTitle(view: ScreenStackHeaderConfig?, value: String?) {
209
+ override fun setBackTitle(
210
+ view: ScreenStackHeaderConfig?,
211
+ value: String?,
212
+ ) {
158
213
  logNotAvailable("backTitle")
159
214
  }
160
215
 
161
- override fun setBackTitleFontFamily(view: ScreenStackHeaderConfig?, value: String?) {
216
+ override fun setBackTitleFontFamily(
217
+ view: ScreenStackHeaderConfig?,
218
+ value: String?,
219
+ ) {
162
220
  logNotAvailable("backTitleFontFamily")
163
221
  }
164
222
 
165
- override fun setBackTitleFontSize(view: ScreenStackHeaderConfig?, value: Int) {
223
+ override fun setBackTitleFontSize(
224
+ view: ScreenStackHeaderConfig?,
225
+ value: Int,
226
+ ) {
166
227
  logNotAvailable("backTitleFontSize")
167
228
  }
168
229
 
169
- override fun setBackTitleVisible(view: ScreenStackHeaderConfig?, value: Boolean) {
230
+ override fun setBackTitleVisible(
231
+ view: ScreenStackHeaderConfig?,
232
+ value: Boolean,
233
+ ) {
170
234
  logNotAvailable("backTitleVisible")
171
235
  }
172
236
 
173
- override fun setLargeTitle(view: ScreenStackHeaderConfig?, value: Boolean) {
237
+ override fun setLargeTitle(
238
+ view: ScreenStackHeaderConfig?,
239
+ value: Boolean,
240
+ ) {
174
241
  logNotAvailable("largeTitle")
175
242
  }
176
243
 
177
- override fun setLargeTitleFontFamily(view: ScreenStackHeaderConfig?, value: String?) {
244
+ override fun setLargeTitleFontFamily(
245
+ view: ScreenStackHeaderConfig?,
246
+ value: String?,
247
+ ) {
178
248
  logNotAvailable("largeTitleFontFamily")
179
249
  }
180
250
 
181
- override fun setLargeTitleFontSize(view: ScreenStackHeaderConfig?, value: Int) {
251
+ override fun setLargeTitleFontSize(
252
+ view: ScreenStackHeaderConfig?,
253
+ value: Int,
254
+ ) {
182
255
  logNotAvailable("largeTitleFontSize")
183
256
  }
184
257
 
185
- override fun setLargeTitleFontWeight(view: ScreenStackHeaderConfig?, value: String?) {
258
+ override fun setLargeTitleFontWeight(
259
+ view: ScreenStackHeaderConfig?,
260
+ value: String?,
261
+ ) {
186
262
  logNotAvailable("largeTitleFontWeight")
187
263
  }
188
264
 
189
- override fun setLargeTitleBackgroundColor(view: ScreenStackHeaderConfig?, value: Int?) {
265
+ override fun setLargeTitleBackgroundColor(
266
+ view: ScreenStackHeaderConfig?,
267
+ value: Int?,
268
+ ) {
190
269
  logNotAvailable("largeTitleBackgroundColor")
191
270
  }
192
271
 
193
- override fun setLargeTitleHideShadow(view: ScreenStackHeaderConfig?, value: Boolean) {
272
+ override fun setLargeTitleHideShadow(
273
+ view: ScreenStackHeaderConfig?,
274
+ value: Boolean,
275
+ ) {
194
276
  logNotAvailable("largeTitleHideShadow")
195
277
  }
196
278
 
197
- override fun setLargeTitleColor(view: ScreenStackHeaderConfig?, value: Int?) {
279
+ override fun setLargeTitleColor(
280
+ view: ScreenStackHeaderConfig?,
281
+ value: Int?,
282
+ ) {
198
283
  logNotAvailable("largeTitleColor")
199
284
  }
200
285
 
201
- override fun setDisableBackButtonMenu(view: ScreenStackHeaderConfig?, value: Boolean) {
286
+ override fun setDisableBackButtonMenu(
287
+ view: ScreenStackHeaderConfig?,
288
+ value: Boolean,
289
+ ) {
202
290
  logNotAvailable("disableBackButtonMenu")
203
291
  }
204
292
 
205
- override fun setBackButtonDisplayMode(view: ScreenStackHeaderConfig?, value: String?) {
293
+ override fun setBackButtonDisplayMode(
294
+ view: ScreenStackHeaderConfig?,
295
+ value: String?,
296
+ ) {
206
297
  logNotAvailable("backButtonDisplayMode")
207
298
  }
208
299
  }
@@ -6,7 +6,9 @@ import com.facebook.react.bridge.ReactContext
6
6
  import com.facebook.react.views.view.ReactViewGroup
7
7
 
8
8
  @SuppressLint("ViewConstructor")
9
- class ScreenStackHeaderSubview(context: ReactContext?) : ReactViewGroup(context) {
9
+ class ScreenStackHeaderSubview(
10
+ context: ReactContext?,
11
+ ) : ReactViewGroup(context) {
10
12
  private var reactWidth = 0
11
13
  private var reactHeight = 0
12
14
  var type = Type.RIGHT
@@ -14,7 +16,10 @@ class ScreenStackHeaderSubview(context: ReactContext?) : ReactViewGroup(context)
14
16
  val config: ScreenStackHeaderConfig?
15
17
  get() = (parent as? CustomToolbar)?.config
16
18
 
17
- override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
19
+ override fun onMeasure(
20
+ widthMeasureSpec: Int,
21
+ heightMeasureSpec: Int,
22
+ ) {
18
23
  if (MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY &&
19
24
  MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY
20
25
  ) {
@@ -30,9 +35,19 @@ class ScreenStackHeaderSubview(context: ReactContext?) : ReactViewGroup(context)
30
35
  setMeasuredDimension(reactWidth, reactHeight)
31
36
  }
32
37
 
33
- override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) = Unit
38
+ override fun onLayout(
39
+ changed: Boolean,
40
+ left: Int,
41
+ top: Int,
42
+ right: Int,
43
+ bottom: Int,
44
+ ) = Unit
34
45
 
35
46
  enum class Type {
36
- LEFT, CENTER, RIGHT, BACK, SEARCH_BAR
47
+ LEFT,
48
+ CENTER,
49
+ RIGHT,
50
+ BACK,
51
+ SEARCH_BAR,
37
52
  }
38
53
  }
@@ -10,7 +10,9 @@ import com.facebook.react.viewmanagers.RNSScreenStackHeaderSubviewManagerDelegat
10
10
  import com.facebook.react.viewmanagers.RNSScreenStackHeaderSubviewManagerInterface
11
11
 
12
12
  @ReactModule(name = ScreenStackHeaderSubviewManager.REACT_CLASS)
13
- class ScreenStackHeaderSubviewManager : ViewGroupManager<ScreenStackHeaderSubview>(), RNSScreenStackHeaderSubviewManagerInterface<ScreenStackHeaderSubview> {
13
+ class ScreenStackHeaderSubviewManager :
14
+ ViewGroupManager<ScreenStackHeaderSubview>(),
15
+ RNSScreenStackHeaderSubviewManagerInterface<ScreenStackHeaderSubview> {
14
16
  private val delegate: ViewManagerDelegate<ScreenStackHeaderSubview>
15
17
 
16
18
  init {
@@ -22,15 +24,19 @@ class ScreenStackHeaderSubviewManager : ViewGroupManager<ScreenStackHeaderSubvie
22
24
  override fun createViewInstance(context: ThemedReactContext) = ScreenStackHeaderSubview(context)
23
25
 
24
26
  @ReactProp(name = "type")
25
- override fun setType(view: ScreenStackHeaderSubview, type: String?) {
26
- view.type = when (type) {
27
- "left" -> ScreenStackHeaderSubview.Type.LEFT
28
- "center" -> ScreenStackHeaderSubview.Type.CENTER
29
- "right" -> ScreenStackHeaderSubview.Type.RIGHT
30
- "back" -> ScreenStackHeaderSubview.Type.BACK
31
- "searchBar" -> ScreenStackHeaderSubview.Type.SEARCH_BAR
32
- else -> throw JSApplicationIllegalArgumentException("Unknown type $type")
33
- }
27
+ override fun setType(
28
+ view: ScreenStackHeaderSubview,
29
+ type: String?,
30
+ ) {
31
+ view.type =
32
+ when (type) {
33
+ "left" -> ScreenStackHeaderSubview.Type.LEFT
34
+ "center" -> ScreenStackHeaderSubview.Type.CENTER
35
+ "right" -> ScreenStackHeaderSubview.Type.RIGHT
36
+ "back" -> ScreenStackHeaderSubview.Type.BACK
37
+ "searchBar" -> ScreenStackHeaderSubview.Type.SEARCH_BAR
38
+ else -> throw JSApplicationIllegalArgumentException("Unknown type $type")
39
+ }
34
40
  }
35
41
 
36
42
  protected override fun getDelegate(): ViewManagerDelegate<ScreenStackHeaderSubview> = delegate