react-native-screens 3.9.0 → 3.10.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 (77) hide show
  1. package/README.md +38 -0
  2. package/android/src/main/java/com/swmansion/rnscreens/CustomSearchView.kt +71 -0
  3. package/android/src/main/java/com/swmansion/rnscreens/CustomToolbar.kt +7 -0
  4. package/android/src/main/java/com/swmansion/rnscreens/FragmentBackPressOverrider.kt +29 -0
  5. package/android/src/main/java/com/swmansion/rnscreens/RNScreensPackage.kt +2 -1
  6. package/android/src/main/java/com/swmansion/rnscreens/Screen.kt +7 -41
  7. package/android/src/main/java/com/swmansion/rnscreens/ScreenFragment.kt +19 -1
  8. package/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt +29 -2
  9. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragment.kt +76 -12
  10. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfig.kt +13 -4
  11. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfigViewManager.kt +8 -0
  12. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubview.kt +7 -1
  13. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubviewManager.kt +1 -0
  14. package/android/src/main/java/com/swmansion/rnscreens/SearchBarManager.kt +90 -0
  15. package/android/src/main/java/com/swmansion/rnscreens/SearchBarView.kt +150 -0
  16. package/android/src/main/java/com/swmansion/rnscreens/SearchViewFormatter.kt +40 -0
  17. package/createNativeStackNavigator/README.md +33 -9
  18. package/ios/RNSScreen.m +4 -0
  19. package/ios/RNSScreenStack.m +7 -6
  20. package/lib/commonjs/index.js +17 -1
  21. package/lib/commonjs/index.js.map +1 -1
  22. package/lib/commonjs/index.native.js +66 -18
  23. package/lib/commonjs/index.native.js.map +1 -1
  24. package/lib/commonjs/native-stack/utils/useBackPressSubscription.js +67 -0
  25. package/lib/commonjs/native-stack/utils/useBackPressSubscription.js.map +1 -0
  26. package/lib/commonjs/native-stack/views/HeaderConfig.js +46 -4
  27. package/lib/commonjs/native-stack/views/HeaderConfig.js.map +1 -1
  28. package/lib/commonjs/reanimated/ReanimatedNativeStackScreen.js +60 -0
  29. package/lib/commonjs/reanimated/ReanimatedNativeStackScreen.js.map +1 -0
  30. package/lib/commonjs/reanimated/ReanimatedScreen.js +7 -79
  31. package/lib/commonjs/reanimated/ReanimatedScreen.js.map +1 -1
  32. package/lib/commonjs/reanimated/ReanimatedScreenProvider.js +61 -0
  33. package/lib/commonjs/reanimated/ReanimatedScreenProvider.js.map +1 -0
  34. package/lib/commonjs/reanimated/index.js +2 -2
  35. package/lib/commonjs/reanimated/index.js.map +1 -1
  36. package/lib/commonjs/utils.js +20 -0
  37. package/lib/commonjs/utils.js.map +1 -0
  38. package/lib/module/index.js +1 -0
  39. package/lib/module/index.js.map +1 -1
  40. package/lib/module/index.native.js +65 -19
  41. package/lib/module/index.native.js.map +1 -1
  42. package/lib/module/native-stack/utils/useBackPressSubscription.js +50 -0
  43. package/lib/module/native-stack/utils/useBackPressSubscription.js.map +1 -0
  44. package/lib/module/native-stack/views/HeaderConfig.js +46 -5
  45. package/lib/module/native-stack/views/HeaderConfig.js.map +1 -1
  46. package/lib/module/reanimated/ReanimatedNativeStackScreen.js +40 -0
  47. package/lib/module/reanimated/ReanimatedNativeStackScreen.js.map +1 -0
  48. package/lib/module/reanimated/ReanimatedScreen.js +6 -73
  49. package/lib/module/reanimated/ReanimatedScreen.js.map +1 -1
  50. package/lib/module/reanimated/ReanimatedScreenProvider.js +49 -0
  51. package/lib/module/reanimated/ReanimatedScreenProvider.js.map +1 -0
  52. package/lib/module/reanimated/index.js +1 -1
  53. package/lib/module/reanimated/index.js.map +1 -1
  54. package/lib/module/utils.js +8 -0
  55. package/lib/module/utils.js.map +1 -0
  56. package/lib/typescript/index.d.ts +1 -0
  57. package/lib/typescript/native-stack/types.d.ts +0 -2
  58. package/lib/typescript/native-stack/utils/useBackPressSubscription.d.ts +16 -0
  59. package/lib/typescript/reanimated/ReanimatedNativeStackScreen.d.ts +5 -0
  60. package/lib/typescript/reanimated/ReanimatedScreen.d.ts +5 -2
  61. package/lib/typescript/reanimated/ReanimatedScreenProvider.d.ts +2 -0
  62. package/lib/typescript/reanimated/index.d.ts +1 -1
  63. package/lib/typescript/types.d.ts +46 -1
  64. package/lib/typescript/utils.d.ts +2 -0
  65. package/native-stack/README.md +31 -5
  66. package/package.json +2 -1
  67. package/src/index.native.tsx +94 -36
  68. package/src/index.tsx +4 -0
  69. package/src/native-stack/types.tsx +0 -2
  70. package/src/native-stack/utils/useBackPressSubscription.tsx +66 -0
  71. package/src/native-stack/views/HeaderConfig.tsx +46 -3
  72. package/src/reanimated/ReanimatedNativeStackScreen.tsx +61 -0
  73. package/src/reanimated/ReanimatedScreen.tsx +6 -84
  74. package/src/reanimated/ReanimatedScreenProvider.tsx +42 -0
  75. package/src/reanimated/index.tsx +1 -1
  76. package/src/types.tsx +46 -1
  77. package/src/utils.ts +12 -0
@@ -0,0 +1,90 @@
1
+ package com.swmansion.rnscreens
2
+
3
+ import com.facebook.react.bridge.JSApplicationIllegalArgumentException
4
+ import com.facebook.react.common.MapBuilder
5
+ import com.facebook.react.module.annotations.ReactModule
6
+ import com.facebook.react.uimanager.ThemedReactContext
7
+ import com.facebook.react.uimanager.ViewGroupManager
8
+ import com.facebook.react.uimanager.annotations.ReactProp
9
+
10
+ @ReactModule(name = SearchBarManager.REACT_CLASS)
11
+ class SearchBarManager : ViewGroupManager<SearchBarView>() {
12
+ override fun getName(): String {
13
+ return REACT_CLASS
14
+ }
15
+
16
+ override fun createViewInstance(context: ThemedReactContext): SearchBarView {
17
+ return SearchBarView(context)
18
+ }
19
+
20
+ override fun onAfterUpdateTransaction(view: SearchBarView) {
21
+ super.onAfterUpdateTransaction(view)
22
+ view.onUpdate()
23
+ }
24
+
25
+ @ReactProp(name = "autoCapitalize")
26
+ fun setAutoCapitalize(view: SearchBarView, autoCapitalize: String?) {
27
+ view.autoCapitalize = when (autoCapitalize) {
28
+ null, "none" -> SearchBarView.SearchBarAutoCapitalize.NONE
29
+ "words" -> SearchBarView.SearchBarAutoCapitalize.WORDS
30
+ "sentences" -> SearchBarView.SearchBarAutoCapitalize.SENTENCES
31
+ "characters" -> SearchBarView.SearchBarAutoCapitalize.CHARACTERS
32
+ else -> throw JSApplicationIllegalArgumentException(
33
+ "Forbidden auto capitalize value passed"
34
+ )
35
+ }
36
+ }
37
+
38
+ @ReactProp(name = "autoFocus")
39
+ fun setAutoFocus(view: SearchBarView, autoFocus: Boolean?) {
40
+ view.autoFocus = autoFocus ?: false
41
+ }
42
+
43
+ @ReactProp(name = "barTintColor", customType = "Color")
44
+ fun setTintColor(view: SearchBarView, color: Int?) {
45
+ view.tintColor = color
46
+ }
47
+
48
+ @ReactProp(name = "disableBackButtonOverride")
49
+ fun setDisableBackButtonOverride(view: SearchBarView, disableBackButtonOverride: Boolean?) {
50
+ view.shouldOverrideBackButton = disableBackButtonOverride != true
51
+ }
52
+
53
+ @ReactProp(name = "inputType")
54
+ fun setInputType(view: SearchBarView, inputType: String?) {
55
+ view.inputType = when (inputType) {
56
+ null, "text" -> SearchBarView.SearchBarInputTypes.TEXT
57
+ "phone" -> SearchBarView.SearchBarInputTypes.PHONE
58
+ "number" -> SearchBarView.SearchBarInputTypes.NUMBER
59
+ "email" -> SearchBarView.SearchBarInputTypes.EMAIL
60
+ else -> throw JSApplicationIllegalArgumentException(
61
+ "Forbidden input type value"
62
+ )
63
+ }
64
+ }
65
+
66
+ @ReactProp(name = "placeholder")
67
+ fun setPlaceholder(view: SearchBarView, placeholder: String?) {
68
+ view.placeholder = placeholder
69
+ }
70
+
71
+ @ReactProp(name = "textColor", customType = "Color")
72
+ fun setTextColor(view: SearchBarView, color: Int?) {
73
+ view.textColor = color
74
+ }
75
+
76
+ override fun getExportedCustomDirectEventTypeConstants(): Map<String, Any>? {
77
+ return MapBuilder.builder<String, Any>()
78
+ .put("onChangeText", MapBuilder.of("registrationName", "onChangeText"))
79
+ .put("onSearchButtonPress", MapBuilder.of("registrationName", "onSearchButtonPress"))
80
+ .put("onFocus", MapBuilder.of("registrationName", "onFocus"))
81
+ .put("onBlur", MapBuilder.of("registrationName", "onBlur"))
82
+ .put("onClose", MapBuilder.of("registrationName", "onClose"))
83
+ .put("onOpen", MapBuilder.of("registrationName", "onOpen"))
84
+ .build()
85
+ }
86
+
87
+ companion object {
88
+ const val REACT_CLASS = "RNSSearchBar"
89
+ }
90
+ }
@@ -0,0 +1,150 @@
1
+ package com.swmansion.rnscreens
2
+
3
+ import android.annotation.SuppressLint
4
+ import android.text.InputType
5
+ import androidx.appcompat.widget.SearchView
6
+ import com.facebook.react.bridge.Arguments
7
+ import com.facebook.react.bridge.ReactContext
8
+ import com.facebook.react.bridge.WritableMap
9
+ import com.facebook.react.uimanager.events.RCTEventEmitter
10
+ import com.facebook.react.views.view.ReactViewGroup
11
+
12
+ @SuppressLint("ViewConstructor")
13
+ class SearchBarView(reactContext: ReactContext?) : ReactViewGroup(reactContext) {
14
+ var inputType: SearchBarInputTypes = SearchBarInputTypes.TEXT
15
+ var autoCapitalize: SearchBarAutoCapitalize = SearchBarAutoCapitalize.NONE
16
+ var textColor: Int? = null
17
+ var tintColor: Int? = null
18
+ var placeholder: String? = null
19
+ var shouldOverrideBackButton: Boolean = true
20
+ var autoFocus: Boolean = false
21
+
22
+ private var mSearchViewFormatter: SearchViewFormatter? = null
23
+
24
+ private var mAreListenersSet: Boolean = false
25
+
26
+ private val screenStackFragment: ScreenStackFragment?
27
+ get() {
28
+ val currentParent = parent
29
+ if (currentParent is ScreenStackHeaderSubview) {
30
+ return currentParent.config?.screenFragment
31
+ }
32
+ return null
33
+ }
34
+
35
+ fun onUpdate() {
36
+ setSearchViewProps()
37
+ }
38
+
39
+ private fun setSearchViewProps() {
40
+ val searchView = screenStackFragment?.searchView
41
+ if (searchView != null) {
42
+ if (!mAreListenersSet) {
43
+ setSearchViewListeners(searchView)
44
+ mAreListenersSet = true
45
+ }
46
+
47
+ searchView.inputType = inputType.toAndroidInputType(autoCapitalize)
48
+ searchView.queryHint = placeholder
49
+ mSearchViewFormatter?.setTextColor(textColor)
50
+ mSearchViewFormatter?.setTintColor(tintColor)
51
+ searchView.overrideBackAction = shouldOverrideBackButton
52
+ }
53
+ }
54
+
55
+ override fun onAttachedToWindow() {
56
+ super.onAttachedToWindow()
57
+
58
+ screenStackFragment?.onSearchViewCreate = { newSearchView ->
59
+ if (mSearchViewFormatter == null) mSearchViewFormatter =
60
+ SearchViewFormatter(newSearchView)
61
+ setSearchViewProps()
62
+ if (autoFocus) {
63
+ screenStackFragment?.searchView?.focus()
64
+ }
65
+ }
66
+ }
67
+
68
+ private fun setSearchViewListeners(searchView: SearchView) {
69
+ searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
70
+ override fun onQueryTextChange(newText: String?): Boolean {
71
+ handleTextChange(newText)
72
+ return true
73
+ }
74
+
75
+ override fun onQueryTextSubmit(query: String?): Boolean {
76
+ handleTextSubmit(query)
77
+ return true
78
+ }
79
+ })
80
+ searchView.setOnQueryTextFocusChangeListener { _, hasFocus ->
81
+ handleFocusChange(hasFocus)
82
+ }
83
+ searchView.setOnCloseListener {
84
+ handleClose()
85
+ false
86
+ }
87
+ searchView.setOnSearchClickListener {
88
+ handleOpen()
89
+ }
90
+ }
91
+
92
+ private fun handleTextChange(newText: String?) {
93
+ val event = Arguments.createMap()
94
+ event.putString("text", newText)
95
+ sendEvent("onChangeText", event)
96
+ }
97
+
98
+ private fun handleFocusChange(hasFocus: Boolean) {
99
+ sendEvent(if (hasFocus) "onFocus" else "onBlur", null)
100
+ }
101
+
102
+ private fun handleClose() {
103
+ sendEvent("onClose", null)
104
+ }
105
+
106
+ private fun handleOpen() {
107
+ sendEvent("onOpen", null)
108
+ }
109
+
110
+ private fun handleTextSubmit(newText: String?) {
111
+ val event = Arguments.createMap()
112
+ event.putString("text", newText)
113
+ sendEvent("onSearchButtonPress", event)
114
+ }
115
+
116
+ private fun sendEvent(eventName: String, eventContent: WritableMap?) {
117
+ (context as ReactContext).getJSModule(RCTEventEmitter::class.java)
118
+ ?.receiveEvent(id, eventName, eventContent)
119
+ }
120
+
121
+ enum class SearchBarAutoCapitalize {
122
+ NONE, WORDS, SENTENCES, CHARACTERS
123
+ }
124
+
125
+ enum class SearchBarInputTypes {
126
+ TEXT {
127
+ override fun toAndroidInputType(capitalize: SearchBarAutoCapitalize) =
128
+ when (capitalize) {
129
+ SearchBarAutoCapitalize.NONE -> InputType.TYPE_CLASS_TEXT
130
+ SearchBarAutoCapitalize.WORDS -> InputType.TYPE_TEXT_FLAG_CAP_WORDS
131
+ SearchBarAutoCapitalize.SENTENCES -> InputType.TYPE_TEXT_FLAG_CAP_SENTENCES
132
+ SearchBarAutoCapitalize.CHARACTERS -> InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
133
+ }
134
+ },
135
+ PHONE {
136
+ override fun toAndroidInputType(capitalize: SearchBarAutoCapitalize) =
137
+ InputType.TYPE_CLASS_PHONE
138
+ },
139
+ NUMBER {
140
+ override fun toAndroidInputType(capitalize: SearchBarAutoCapitalize) =
141
+ InputType.TYPE_CLASS_NUMBER
142
+ },
143
+ EMAIL {
144
+ override fun toAndroidInputType(capitalize: SearchBarAutoCapitalize) =
145
+ InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS
146
+ };
147
+
148
+ abstract fun toAndroidInputType(capitalize: SearchBarAutoCapitalize): Int
149
+ }
150
+ }
@@ -0,0 +1,40 @@
1
+ package com.swmansion.rnscreens
2
+
3
+ import android.graphics.drawable.Drawable
4
+ import android.view.View
5
+ import android.widget.EditText
6
+ import androidx.appcompat.widget.SearchView
7
+
8
+ class SearchViewFormatter(var searchView: SearchView) {
9
+ private var mDefaultTextColor: Int? = null
10
+ private var mDefaultTintBackground: Drawable? = null
11
+
12
+ private val searchEditText
13
+ get() = searchView.findViewById<View>(androidx.appcompat.R.id.search_src_text) as? EditText
14
+ private val searchTextPlate
15
+ get() = searchView.findViewById<View>(androidx.appcompat.R.id.search_plate)
16
+
17
+ fun setTextColor(textColor: Int?) {
18
+ val currentDefaultTextColor = mDefaultTextColor
19
+ if (textColor != null) {
20
+ if (mDefaultTextColor == null) {
21
+ mDefaultTextColor = searchEditText?.textColors?.defaultColor
22
+ }
23
+ searchEditText?.setTextColor(textColor)
24
+ } else if (currentDefaultTextColor != null) {
25
+ searchEditText?.setTextColor(currentDefaultTextColor)
26
+ }
27
+ }
28
+
29
+ fun setTintColor(tintColor: Int?) {
30
+ val currentDefaultTintColor = mDefaultTintBackground
31
+ if (tintColor != null) {
32
+ if (mDefaultTintBackground == null) {
33
+ mDefaultTintBackground = searchTextPlate.background
34
+ }
35
+ searchTextPlate.setBackgroundColor(tintColor)
36
+ } else if (currentDefaultTintColor != null) {
37
+ searchTextPlate.background = currentDefaultTintColor
38
+ }
39
+ }
40
+ }
@@ -360,12 +360,10 @@ Defaults to `auto`.
360
360
 
361
361
  Sets the translucency of the status bar (similar to the `StatusBar` component). Defaults to `false`.
362
362
 
363
- ### Search bar (iOS only)
363
+ ### Search bar
364
364
 
365
365
  The search bar is just a `searchBar` property that can be specified in the navigator's `defaultNavigationOptions` prop or an individual screen's `navigationOptions`. Search bars are rarely static so normally it is controlled by passing an object to `searchBar` navigation option in the component's body.
366
366
 
367
- Search bar is only supported on iOS.
368
-
369
367
  Example:
370
368
 
371
369
  ```js
@@ -390,7 +388,11 @@ Possible values:
390
388
  - `sentences`
391
389
  - `characters`
392
390
 
393
- Defaults to `sentences`.
391
+ Defaults to `sentences` on iOS and `'none'` on Android.
392
+
393
+ #### `autoFocus` (Android only)
394
+
395
+ When set to `true` focuses search bar automatically when screen is appearing. Default value is `false`.
394
396
 
395
397
  #### `barTintColor`
396
398
 
@@ -398,23 +400,37 @@ The search field background color.
398
400
 
399
401
  By default bar tint color is translucent.
400
402
 
401
- #### `cancelButtonText`
403
+ #### `cancelButtonText` (iOS only)
402
404
 
403
405
  The text to be used instead of default `Cancel` button text.
404
406
 
405
- #### `hideNavigationBar`
407
+ #### `disableBackButtonOverride` (Android only)
408
+
409
+ Default behavior is to prevent screen from going back when search bar is open (`disableBackButtonOverride: false`). If you don't want this to happen set `disableBackButtonOverride` to `true`
410
+
411
+ #### `hideNavigationBar` (iOS only)
406
412
 
407
413
  Boolean indicating whether to hide the navigation bar during searching.
408
414
 
409
415
  Defaults to `true`.
410
416
 
411
- #### `hideWhenScrolling`
417
+ #### `hideWhenScrolling` (iOS only)
412
418
 
413
419
  Boolean indicating whether to hide the search bar when scrolling.
414
420
 
415
421
  Defaults to `true`.
416
422
 
417
- #### `obscureBackground`
423
+ #### `inputType` (Android only)
424
+
425
+ This prop is used to change type of the input and keyboard. Default value is `'text'`.
426
+
427
+ All values:
428
+ - `'text'` - normal text input
429
+ - `'number'` - number input
430
+ - `'email'` - email input
431
+ - `'phone'` - phone input
432
+
433
+ #### `obscureBackground` (iOS only)
418
434
 
419
435
  Boolean indicating whether to obscure the underlying content with semi-transparent overlay.
420
436
 
@@ -424,7 +440,7 @@ Defaults to `true`.
424
440
 
425
441
  A callback that gets called when search bar has lost focus.
426
442
 
427
- #### `onCancelButtonPress`
443
+ #### `onCancelButtonPress` (iOS only)
428
444
 
429
445
  A callback that gets called when the cancel button is pressed.
430
446
 
@@ -446,10 +462,18 @@ static navigationOptions = ({navigation}) => {
446
462
  };
447
463
  ```
448
464
 
465
+ #### `onClose` (Android only)
466
+
467
+ A callback that gets called when search bar is closing
468
+
449
469
  #### `onFocus`
450
470
 
451
471
  A callback that gets called when search bar has received focus.
452
472
 
473
+ #### `onOpen` (Android only)
474
+
475
+ A callback that gets called when search bar is expanding
476
+
453
477
  #### `onSearchButtonPress`
454
478
 
455
479
  A callback that gets called when the search button is pressed. It receives the current text value of the search bar.
package/ios/RNSScreen.m CHANGED
@@ -688,6 +688,10 @@
688
688
 
689
689
  - (void)traverseForScrollView:(UIView *)view
690
690
  {
691
+ if (![[self.view valueForKey:@"_bridge"] valueForKey:@"_jsThread"]) {
692
+ // we don't want to send `scrollViewDidEndDecelerating` event to JS before the JS thread is ready
693
+ return;
694
+ }
691
695
  if ([view isKindOfClass:[UIScrollView class]] &&
692
696
  ([[(UIScrollView *)view delegate] respondsToSelector:@selector(scrollViewDidEndDecelerating:)])) {
693
697
  [[(UIScrollView *)view delegate] scrollViewDidEndDecelerating:(id)view];
@@ -425,12 +425,12 @@
425
425
  // controller is still there
426
426
  BOOL firstTimePush = ![lastTop isKindOfClass:[RNSScreen class]];
427
427
 
428
- BOOL shouldAnimate = !firstTimePush && ((RNSScreenView *)lastTop.view).stackAnimation != RNSScreenStackAnimationNone;
429
-
430
428
  if (firstTimePush) {
431
429
  // nothing pushed yet
432
430
  [_controller setViewControllers:controllers animated:NO];
433
431
  } else if (top != lastTop) {
432
+ // we always provide `animated:YES` since, if the user does not want the animation, he will provide
433
+ // `stackAnimation: 'none'`, which will resolve in no animation anyways.
434
434
  if (![controllers containsObject:lastTop]) {
435
435
  // if the previous top screen does not exist anymore and the new top was not on the stack before, probably replace
436
436
  // was called, so we check the animation
@@ -445,7 +445,7 @@
445
445
  NSMutableArray *newControllers = [NSMutableArray arrayWithArray:controllers];
446
446
  [newControllers addObject:lastTop];
447
447
  [_controller setViewControllers:newControllers animated:NO];
448
- [_controller popViewControllerAnimated:shouldAnimate];
448
+ [_controller popViewControllerAnimated:YES];
449
449
  }
450
450
  } else if (![_controller.viewControllers containsObject:top]) {
451
451
  // new top controller is not on the stack
@@ -454,11 +454,11 @@
454
454
  NSMutableArray *newControllers = [NSMutableArray arrayWithArray:controllers];
455
455
  [newControllers removeLastObject];
456
456
  [_controller setViewControllers:newControllers animated:NO];
457
- [_controller pushViewController:top animated:shouldAnimate];
457
+ [_controller pushViewController:top animated:YES];
458
458
  } else {
459
459
  // don't really know what this case could be, but may need to handle it
460
460
  // somehow
461
- [_controller setViewControllers:controllers animated:shouldAnimate];
461
+ [_controller setViewControllers:controllers animated:NO];
462
462
  }
463
463
  } else {
464
464
  // change wasn't on the top of the stack. We don't need animation.
@@ -572,7 +572,8 @@
572
572
  {
573
573
  RNSScreenView *topScreen = (RNSScreenView *)_controller.viewControllers.lastObject.view;
574
574
 
575
- if (!topScreen.gestureEnabled || _controller.viewControllers.count < 2) {
575
+ if (![topScreen isKindOfClass:[RNSScreenView class]] || !topScreen.gestureEnabled ||
576
+ _controller.viewControllers.count < 2) {
576
577
  return NO;
577
578
  }
578
579
 
@@ -24,7 +24,9 @@ var _exportNames = {
24
24
  SearchBar: true,
25
25
  ScreenStackHeaderSubview: true,
26
26
  shouldUseActivityState: true,
27
- useTransitionProgress: true
27
+ useTransitionProgress: true,
28
+ isSearchBarAvailableForCurrentPlatform: true,
29
+ executeNativeBackPress: true
28
30
  };
29
31
  exports.enableScreens = enableScreens;
30
32
  exports.screensEnabled = screensEnabled;
@@ -35,6 +37,18 @@ Object.defineProperty(exports, "useTransitionProgress", {
35
37
  return _useTransitionProgress.default;
36
38
  }
37
39
  });
40
+ Object.defineProperty(exports, "isSearchBarAvailableForCurrentPlatform", {
41
+ enumerable: true,
42
+ get: function () {
43
+ return _utils.isSearchBarAvailableForCurrentPlatform;
44
+ }
45
+ });
46
+ Object.defineProperty(exports, "executeNativeBackPress", {
47
+ enumerable: true,
48
+ get: function () {
49
+ return _utils.executeNativeBackPress;
50
+ }
51
+ });
38
52
  exports.shouldUseActivityState = exports.ScreenStackHeaderSubview = exports.SearchBar = exports.ScreenStackHeaderConfig = exports.ScreenStackHeaderSearchBarView = exports.ScreenStackHeaderCenterView = exports.ScreenStackHeaderLeftView = exports.ScreenStackHeaderRightView = exports.ScreenStackHeaderBackButtonImage = exports.FullWindowOverlay = exports.ScreenStack = exports.NativeScreenNavigationContainer = exports.NativeScreenContainer = exports.ScreenContainer = exports.ScreenContext = exports.Screen = exports.NativeScreen = void 0;
39
53
 
40
54
  var _react = _interopRequireDefault(require("react"));
@@ -57,6 +71,8 @@ Object.keys(_types).forEach(function (key) {
57
71
 
58
72
  var _useTransitionProgress = _interopRequireDefault(require("./useTransitionProgress"));
59
73
 
74
+ var _utils = require("./utils");
75
+
60
76
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
61
77
 
62
78
  function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
@@ -1 +1 @@
1
- {"version":3,"sources":["index.tsx"],"names":["ENABLE_SCREENS","enableScreens","shouldEnableScreens","screensEnabled","enableFreeze","shouldEnableReactFreeze","NativeScreen","React","Component","render","active","activityState","style","enabled","rest","props","undefined","display","Screen","Animated","createAnimatedComponent","ScreenContext","createContext","ScreenContainer","View","NativeScreenContainer","NativeScreenNavigationContainer","ScreenStack","FullWindowOverlay","ScreenStackHeaderBackButtonImage","ScreenStackHeaderRightView","ScreenStackHeaderLeftView","ScreenStackHeaderCenterView","ScreenStackHeaderSearchBarView","ScreenStackHeaderConfig","SearchBar","ScreenStackHeaderSubview","shouldUseActivityState"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;AACA;;AAUA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;;;;;;AAEA,IAAIA,cAAc,GAAG,IAArB;;AAEO,SAASC,aAAT,CAAuBC,mBAAmB,GAAG,IAA7C,EAAyD;AAC9DF,EAAAA,cAAc,GAAGE,mBAAjB;AACD;;AAEM,SAASC,cAAT,GAAmC;AACxC,SAAOH,cAAP;AACD,C,CAED;AACA;;;AACO,SAASI,YAAT,CAAsBC,uBAAuB,GAAG,IAAhD,EAA4D,CACjE;AACD;;AAEM,MAAMC,YAAN,SAA2BC,eAAMC,SAAjC,CAAwD;AAC7DC,EAAAA,MAAM,GAAgB;AACpB,QAAI;AACFC,MAAAA,MADE;AAEFC,MAAAA,aAFE;AAGFC,MAAAA,KAHE;AAIFC,MAAAA,OAAO,GAAGb,cAJR;AAKF,SAAGc;AALD,QAMA,KAAKC,KANT;;AAQA,QAAIF,OAAJ,EAAa;AACX,UAAIH,MAAM,KAAKM,SAAX,IAAwBL,aAAa,KAAKK,SAA9C,EAAyD;AACvDL,QAAAA,aAAa,GAAGD,MAAM,KAAK,CAAX,GAAe,CAAf,GAAmB,CAAnC,CADuD,CACjB;AACvC;;AACD,0BACE,6BAAC,iBAAD,CACE;AADF;AAEE,QAAA,MAAM,EAAEC,aAAa,KAAK,CAF5B;AAGE,QAAA,KAAK,EAAE,CAACC,KAAD,EAAQ;AAAEK,UAAAA,OAAO,EAAEN,aAAa,KAAK,CAAlB,GAAsB,MAAtB,GAA+B;AAA1C,SAAR;AAHT,SAIMG,IAJN,EADF;AAQD;;AAED,wBAAO,6BAAC,iBAAD,EAAUA,IAAV,CAAP;AACD;;AAzB4D;;;;AA4BxD,MAAMI,MAAM,GAAGC,sBAASC,uBAAT,CAAiCd,YAAjC,CAAf;;;;AAEA,MAAMe,aAAa,gBAAGd,eAAMe,aAAN,CAAoBJ,MAApB,CAAtB;;;AAEA,MAAMK,eAA0D,GAAGC,iBAAnE;;AAEA,MAAMC,qBAAgE,GAAGD,iBAAzE;;AAEA,MAAME,+BAA0E,GAAGF,iBAAnF;;AAEA,MAAMG,WAAkD,GAAGH,iBAA3D;;AAEA,MAAMI,iBAAiB,GAAGJ,iBAA1B;;;AAEA,MAAMK,gCAAgC,GAC3Cd,KAD8C,iBAG9C,6BAAC,iBAAD,qBACE,6BAAC,kBAAD;AAAO,EAAA,UAAU,EAAC,QAAlB;AAA2B,EAAA,YAAY,EAAE;AAAzC,GAAgDA,KAAhD,EADF,CAHK;;;;AAQA,MAAMe,0BAA0B,GACrCf,KADwC,iBAExB,6BAAC,iBAAD,EAAUA,KAAV,CAFX;;;;AAIA,MAAMgB,yBAAyB,GACpChB,KADuC,iBAEvB,6BAAC,iBAAD,EAAUA,KAAV,CAFX;;;;AAIA,MAAMiB,2BAA2B,GACtCjB,KADyC,iBAEzB,6BAAC,iBAAD,EAAUA,KAAV,CAFX;;;;AAIA,MAAMkB,8BAA8B,GACzClB,KAD4C,iBAE5B,6BAAC,iBAAD,EAAUA,KAAV,CAFX;;;AAIA,MAAMmB,uBAA0E,GAAGV,iBAAnF,C,CAEP;;;AACO,MAAMW,SAA8C,GAAGX,iBAAvD;;AAEA,MAAMY,wBAEX,GAAGZ,iBAFE;;AAIA,MAAMa,sBAAsB,GAAG,IAA/B","sourcesContent":["import React from 'react';\nimport { Animated, View, ViewProps, ImageProps, Image } from 'react-native';\nimport {\n ScreenProps,\n ScreenContainerProps,\n ScreenStackProps,\n ScreenStackHeaderConfigProps,\n HeaderSubviewTypes,\n SearchBarProps,\n} from './types';\n\nexport * from './types';\nexport { default as useTransitionProgress } from './useTransitionProgress';\n\nlet ENABLE_SCREENS = true;\n\nexport function enableScreens(shouldEnableScreens = true): void {\n ENABLE_SCREENS = shouldEnableScreens;\n}\n\nexport function screensEnabled(): boolean {\n return ENABLE_SCREENS;\n}\n\n// @ts-ignore function stub, freezing logic is located in index.native.tsx\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport function enableFreeze(shouldEnableReactFreeze = true): void {\n // noop\n}\n\nexport class NativeScreen extends React.Component<ScreenProps> {\n render(): JSX.Element {\n let {\n active,\n activityState,\n style,\n enabled = ENABLE_SCREENS,\n ...rest\n } = this.props;\n\n if (enabled) {\n if (active !== undefined && activityState === undefined) {\n activityState = active !== 0 ? 2 : 0; // change taken from index.native.tsx\n }\n return (\n <View\n // @ts-expect-error: hidden exists on web, but not in React Native\n hidden={activityState === 0}\n style={[style, { display: activityState !== 0 ? 'flex' : 'none' }]}\n {...rest}\n />\n );\n }\n\n return <View {...rest} />;\n }\n}\n\nexport const Screen = Animated.createAnimatedComponent(NativeScreen);\n\nexport const ScreenContext = React.createContext(Screen);\n\nexport const ScreenContainer: React.ComponentType<ScreenContainerProps> = View;\n\nexport const NativeScreenContainer: React.ComponentType<ScreenContainerProps> = View;\n\nexport const NativeScreenNavigationContainer: React.ComponentType<ScreenContainerProps> = View;\n\nexport const ScreenStack: React.ComponentType<ScreenStackProps> = View;\n\nexport const FullWindowOverlay = View;\n\nexport const ScreenStackHeaderBackButtonImage = (\n props: ImageProps\n): JSX.Element => (\n <View>\n <Image resizeMode=\"center\" fadeDuration={0} {...props} />\n </View>\n);\n\nexport const ScreenStackHeaderRightView = (\n props: React.PropsWithChildren<ViewProps>\n): JSX.Element => <View {...props} />;\n\nexport const ScreenStackHeaderLeftView = (\n props: React.PropsWithChildren<ViewProps>\n): JSX.Element => <View {...props} />;\n\nexport const ScreenStackHeaderCenterView = (\n props: React.PropsWithChildren<ViewProps>\n): JSX.Element => <View {...props} />;\n\nexport const ScreenStackHeaderSearchBarView = (\n props: React.PropsWithChildren<SearchBarProps>\n): JSX.Element => <View {...props} />;\n\nexport const ScreenStackHeaderConfig: React.ComponentType<ScreenStackHeaderConfigProps> = View;\n\n// @ts-expect-error: search bar props have no common props with View\nexport const SearchBar: React.ComponentType<SearchBarProps> = View;\n\nexport const ScreenStackHeaderSubview: React.ComponentType<React.PropsWithChildren<\n ViewProps & { type?: HeaderSubviewTypes }\n>> = View;\n\nexport const shouldUseActivityState = true;\n"]}
1
+ {"version":3,"sources":["index.tsx"],"names":["ENABLE_SCREENS","enableScreens","shouldEnableScreens","screensEnabled","enableFreeze","shouldEnableReactFreeze","NativeScreen","React","Component","render","active","activityState","style","enabled","rest","props","undefined","display","Screen","Animated","createAnimatedComponent","ScreenContext","createContext","ScreenContainer","View","NativeScreenContainer","NativeScreenNavigationContainer","ScreenStack","FullWindowOverlay","ScreenStackHeaderBackButtonImage","ScreenStackHeaderRightView","ScreenStackHeaderLeftView","ScreenStackHeaderCenterView","ScreenStackHeaderSearchBarView","ScreenStackHeaderConfig","SearchBar","ScreenStackHeaderSubview","shouldUseActivityState"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;AACA;;AAUA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;;AACA;;;;;;AAKA,IAAIA,cAAc,GAAG,IAArB;;AAEO,SAASC,aAAT,CAAuBC,mBAAmB,GAAG,IAA7C,EAAyD;AAC9DF,EAAAA,cAAc,GAAGE,mBAAjB;AACD;;AAEM,SAASC,cAAT,GAAmC;AACxC,SAAOH,cAAP;AACD,C,CAED;AACA;;;AACO,SAASI,YAAT,CAAsBC,uBAAuB,GAAG,IAAhD,EAA4D,CACjE;AACD;;AAEM,MAAMC,YAAN,SAA2BC,eAAMC,SAAjC,CAAwD;AAC7DC,EAAAA,MAAM,GAAgB;AACpB,QAAI;AACFC,MAAAA,MADE;AAEFC,MAAAA,aAFE;AAGFC,MAAAA,KAHE;AAIFC,MAAAA,OAAO,GAAGb,cAJR;AAKF,SAAGc;AALD,QAMA,KAAKC,KANT;;AAQA,QAAIF,OAAJ,EAAa;AACX,UAAIH,MAAM,KAAKM,SAAX,IAAwBL,aAAa,KAAKK,SAA9C,EAAyD;AACvDL,QAAAA,aAAa,GAAGD,MAAM,KAAK,CAAX,GAAe,CAAf,GAAmB,CAAnC,CADuD,CACjB;AACvC;;AACD,0BACE,6BAAC,iBAAD,CACE;AADF;AAEE,QAAA,MAAM,EAAEC,aAAa,KAAK,CAF5B;AAGE,QAAA,KAAK,EAAE,CAACC,KAAD,EAAQ;AAAEK,UAAAA,OAAO,EAAEN,aAAa,KAAK,CAAlB,GAAsB,MAAtB,GAA+B;AAA1C,SAAR;AAHT,SAIMG,IAJN,EADF;AAQD;;AAED,wBAAO,6BAAC,iBAAD,EAAUA,IAAV,CAAP;AACD;;AAzB4D;;;;AA4BxD,MAAMI,MAAM,GAAGC,sBAASC,uBAAT,CAAiCd,YAAjC,CAAf;;;;AAEA,MAAMe,aAAa,gBAAGd,eAAMe,aAAN,CAAoBJ,MAApB,CAAtB;;;AAEA,MAAMK,eAA0D,GAAGC,iBAAnE;;AAEA,MAAMC,qBAAgE,GAAGD,iBAAzE;;AAEA,MAAME,+BAA0E,GAAGF,iBAAnF;;AAEA,MAAMG,WAAkD,GAAGH,iBAA3D;;AAEA,MAAMI,iBAAiB,GAAGJ,iBAA1B;;;AAEA,MAAMK,gCAAgC,GAC3Cd,KAD8C,iBAG9C,6BAAC,iBAAD,qBACE,6BAAC,kBAAD;AAAO,EAAA,UAAU,EAAC,QAAlB;AAA2B,EAAA,YAAY,EAAE;AAAzC,GAAgDA,KAAhD,EADF,CAHK;;;;AAQA,MAAMe,0BAA0B,GACrCf,KADwC,iBAExB,6BAAC,iBAAD,EAAUA,KAAV,CAFX;;;;AAIA,MAAMgB,yBAAyB,GACpChB,KADuC,iBAEvB,6BAAC,iBAAD,EAAUA,KAAV,CAFX;;;;AAIA,MAAMiB,2BAA2B,GACtCjB,KADyC,iBAEzB,6BAAC,iBAAD,EAAUA,KAAV,CAFX;;;;AAIA,MAAMkB,8BAA8B,GACzClB,KAD4C,iBAE5B,6BAAC,iBAAD,EAAUA,KAAV,CAFX;;;AAIA,MAAMmB,uBAA0E,GAAGV,iBAAnF,C,CAEP;;;AACO,MAAMW,SAA8C,GAAGX,iBAAvD;;AAEA,MAAMY,wBAEX,GAAGZ,iBAFE;;AAIA,MAAMa,sBAAsB,GAAG,IAA/B","sourcesContent":["import React from 'react';\nimport { Animated, View, ViewProps, ImageProps, Image } from 'react-native';\nimport {\n ScreenProps,\n ScreenContainerProps,\n ScreenStackProps,\n ScreenStackHeaderConfigProps,\n HeaderSubviewTypes,\n SearchBarProps,\n} from './types';\n\nexport * from './types';\nexport { default as useTransitionProgress } from './useTransitionProgress';\nexport {\n isSearchBarAvailableForCurrentPlatform,\n executeNativeBackPress,\n} from './utils';\n\nlet ENABLE_SCREENS = true;\n\nexport function enableScreens(shouldEnableScreens = true): void {\n ENABLE_SCREENS = shouldEnableScreens;\n}\n\nexport function screensEnabled(): boolean {\n return ENABLE_SCREENS;\n}\n\n// @ts-ignore function stub, freezing logic is located in index.native.tsx\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport function enableFreeze(shouldEnableReactFreeze = true): void {\n // noop\n}\n\nexport class NativeScreen extends React.Component<ScreenProps> {\n render(): JSX.Element {\n let {\n active,\n activityState,\n style,\n enabled = ENABLE_SCREENS,\n ...rest\n } = this.props;\n\n if (enabled) {\n if (active !== undefined && activityState === undefined) {\n activityState = active !== 0 ? 2 : 0; // change taken from index.native.tsx\n }\n return (\n <View\n // @ts-expect-error: hidden exists on web, but not in React Native\n hidden={activityState === 0}\n style={[style, { display: activityState !== 0 ? 'flex' : 'none' }]}\n {...rest}\n />\n );\n }\n\n return <View {...rest} />;\n }\n}\n\nexport const Screen = Animated.createAnimatedComponent(NativeScreen);\n\nexport const ScreenContext = React.createContext(Screen);\n\nexport const ScreenContainer: React.ComponentType<ScreenContainerProps> = View;\n\nexport const NativeScreenContainer: React.ComponentType<ScreenContainerProps> = View;\n\nexport const NativeScreenNavigationContainer: React.ComponentType<ScreenContainerProps> = View;\n\nexport const ScreenStack: React.ComponentType<ScreenStackProps> = View;\n\nexport const FullWindowOverlay = View;\n\nexport const ScreenStackHeaderBackButtonImage = (\n props: ImageProps\n): JSX.Element => (\n <View>\n <Image resizeMode=\"center\" fadeDuration={0} {...props} />\n </View>\n);\n\nexport const ScreenStackHeaderRightView = (\n props: React.PropsWithChildren<ViewProps>\n): JSX.Element => <View {...props} />;\n\nexport const ScreenStackHeaderLeftView = (\n props: React.PropsWithChildren<ViewProps>\n): JSX.Element => <View {...props} />;\n\nexport const ScreenStackHeaderCenterView = (\n props: React.PropsWithChildren<ViewProps>\n): JSX.Element => <View {...props} />;\n\nexport const ScreenStackHeaderSearchBarView = (\n props: React.PropsWithChildren<SearchBarProps>\n): JSX.Element => <View {...props} />;\n\nexport const ScreenStackHeaderConfig: React.ComponentType<ScreenStackHeaderConfigProps> = View;\n\n// @ts-expect-error: search bar props have no common props with View\nexport const SearchBar: React.ComponentType<SearchBarProps> = View;\n\nexport const ScreenStackHeaderSubview: React.ComponentType<React.PropsWithChildren<\n ViewProps & { type?: HeaderSubviewTypes }\n>> = View;\n\nexport const shouldUseActivityState = true;\n"]}
@@ -8,10 +8,14 @@ var _reactFreeze = require("react-freeze");
8
8
 
9
9
  var _processColor = _interopRequireDefault(require("react-native/Libraries/StyleSheet/processColor"));
10
10
 
11
+ var _package = require("react-native/package.json");
12
+
11
13
  var _TransitionProgressContext = _interopRequireDefault(require("./TransitionProgressContext"));
12
14
 
13
15
  var _useTransitionProgress = _interopRequireDefault(require("./useTransitionProgress"));
14
16
 
17
+ var _utils = require("./utils");
18
+
15
19
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
16
20
 
17
21
  function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
@@ -33,6 +37,13 @@ function enableScreens(shouldEnableScreens = true) {
33
37
  let ENABLE_FREEZE = false;
34
38
 
35
39
  function enableFreeze(shouldEnableReactFreeze = true) {
40
+ const minor = parseInt(_package.version.split('.')[1]); // eg. takes 66 from '0.66.0'
41
+ // react-freeze requires react-native >=0.64, react-native from main is 0.0.0
42
+
43
+ if (!(minor === 0 || minor >= 64) && shouldEnableReactFreeze) {
44
+ console.warn('react-freeze library requires at least react-native 0.64. Please upgrade your react-native version in order to use this feature.');
45
+ }
46
+
36
47
  ENABLE_FREEZE = shouldEnableReactFreeze;
37
48
  } // const that tells if the library should use new implementation, will be undefined for older versions
38
49
 
@@ -97,12 +108,34 @@ const ScreensNativeModules = {
97
108
 
98
109
  };
99
110
 
111
+ // This component allows one more render before freezing the screen.
112
+ // Allows activityState to reach the native side and useIsFocused to work correctly.
113
+ function DelayedFreeze({
114
+ freeze,
115
+ children
116
+ }) {
117
+ // flag used for determining whether freeze should be enabled
118
+ const [freezeState, setFreezeState] = _react.default.useState(false);
119
+
120
+ if (freeze !== freezeState) {
121
+ // setImmediate is executed at the end of the JS execution block.
122
+ // Used here for changing the state right after the render.
123
+ setImmediate(() => {
124
+ setFreezeState(freeze);
125
+ });
126
+ }
127
+
128
+ return /*#__PURE__*/_react.default.createElement(_reactFreeze.Freeze, {
129
+ freeze: freeze ? freezeState : false
130
+ }, children);
131
+ }
132
+
100
133
  function MaybeFreeze({
101
134
  freeze,
102
135
  children
103
136
  }) {
104
137
  if (ENABLE_FREEZE) {
105
- return /*#__PURE__*/_react.default.createElement(_reactFreeze.Freeze, {
138
+ return /*#__PURE__*/_react.default.createElement(DelayedFreeze, {
106
139
  freeze: freeze
107
140
  }, children);
108
141
  } else {
@@ -117,19 +150,20 @@ function ScreenStack(props) {
117
150
  ...rest
118
151
  } = props;
119
152
 
120
- const count = _react.default.Children.count(children);
153
+ const size = _react.default.Children.count(children); // freezes all screens except the top one
121
154
 
122
- const childrenWithProps = _react.default.Children.map(children, (child, index) => {
123
- return /*#__PURE__*/_react.default.createElement(_reactFreeze.Freeze, {
124
- freeze: count - index > 2
125
- }, child);
126
- });
127
155
 
128
- return /*#__PURE__*/_react.default.createElement(ScreensNativeModules.NativeScreenStack, rest, childrenWithProps);
156
+ const childrenWithFreeze = _react.default.Children.map(children, (child, index) => /*#__PURE__*/_react.default.createElement(DelayedFreeze, {
157
+ freeze: size - index > 1
158
+ }, child));
159
+
160
+ return /*#__PURE__*/_react.default.createElement(ScreensNativeModules.NativeScreenStack, rest, childrenWithFreeze);
129
161
  }
130
162
 
131
163
  return /*#__PURE__*/_react.default.createElement(ScreensNativeModules.NativeScreenStack, props);
132
- }
164
+ } // Incomplete type, all accessible properties available at:
165
+ // react-native/Libraries/Components/View/ReactNativeViewViewConfig.js
166
+
133
167
 
134
168
  class Screen extends _react.default.Component {
135
169
  constructor(...args) {
@@ -183,10 +217,24 @@ class Screen extends _react.default.Component {
183
217
  }
184
218
 
185
219
  const processedColor = (0, _processColor.default)(statusBarColor);
186
- return /*#__PURE__*/_react.default.createElement(AnimatedNativeScreen, _extends({}, props, {
220
+ return /*#__PURE__*/_react.default.createElement(MaybeFreeze, {
221
+ freeze: activityState === 0
222
+ }, /*#__PURE__*/_react.default.createElement(AnimatedNativeScreen, _extends({}, props, {
187
223
  statusBarColor: processedColor,
188
- activityState: activityState,
189
- ref: this.setRef,
224
+ activityState: activityState // This prevents showing blank screen when navigating between multiple screens with freezing
225
+ // https://github.com/software-mansion/react-native-screens/pull/1208
226
+ ,
227
+ ref: ref => {
228
+ var _ref$viewConfig, _ref$viewConfig$valid;
229
+
230
+ if (ref !== null && ref !== void 0 && (_ref$viewConfig = ref.viewConfig) !== null && _ref$viewConfig !== void 0 && (_ref$viewConfig$valid = _ref$viewConfig.validAttributes) !== null && _ref$viewConfig$valid !== void 0 && _ref$viewConfig$valid.style) {
231
+ ref.viewConfig.validAttributes.style = { ...ref.viewConfig.validAttributes.style,
232
+ display: false
233
+ };
234
+ }
235
+
236
+ this.setRef(ref);
237
+ },
190
238
  onTransitionProgress: !isNativeStack ? undefined : _reactNative.Animated.event([{
191
239
  nativeEvent: {
192
240
  progress: this.progress,
@@ -196,9 +244,7 @@ class Screen extends _react.default.Component {
196
244
  }], {
197
245
  useNativeDriver: true
198
246
  })
199
- }), /*#__PURE__*/_react.default.createElement(MaybeFreeze, {
200
- freeze: activityState === 0
201
- }, !isNativeStack ? // see comment of this prop in types.tsx for information why it is needed
247
+ }), !isNativeStack ? // see comment of this prop in types.tsx for information why it is needed
202
248
  children : /*#__PURE__*/_react.default.createElement(_TransitionProgressContext.default.Provider, {
203
249
  value: {
204
250
  progress: this.progress,
@@ -322,8 +368,8 @@ module.exports = {
322
368
  },
323
369
 
324
370
  get SearchBar() {
325
- if (_reactNative.Platform.OS !== 'ios') {
326
- console.warn('Importing SearchBar is only valid on iOS devices.');
371
+ if (!_utils.isSearchBarAvailableForCurrentPlatform) {
372
+ console.warn('Importing SearchBar is only valid on iOS and Android devices.');
327
373
  return _reactNative.View;
328
374
  }
329
375
 
@@ -350,6 +396,8 @@ module.exports = {
350
396
  enableFreeze,
351
397
  screensEnabled,
352
398
  shouldUseActivityState,
353
- useTransitionProgress: _useTransitionProgress.default
399
+ useTransitionProgress: _useTransitionProgress.default,
400
+ isSearchBarAvailableForCurrentPlatform: _utils.isSearchBarAvailableForCurrentPlatform,
401
+ executeNativeBackPress: _utils.executeNativeBackPress
354
402
  };
355
403
  //# sourceMappingURL=index.native.js.map