react-native-screens 3.7.1 → 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 (85) hide show
  1. package/README.md +69 -3
  2. package/android/build.gradle +8 -7
  3. package/android/src/main/java/com/swmansion/rnscreens/CustomSearchView.kt +71 -0
  4. package/android/src/main/java/com/swmansion/rnscreens/CustomToolbar.kt +7 -0
  5. package/android/src/main/java/com/swmansion/rnscreens/FragmentBackPressOverrider.kt +29 -0
  6. package/android/src/main/java/com/swmansion/rnscreens/RNScreensPackage.kt +2 -1
  7. package/android/src/main/java/com/swmansion/rnscreens/Screen.kt +7 -41
  8. package/android/src/main/java/com/swmansion/rnscreens/ScreenContainer.kt +55 -40
  9. package/android/src/main/java/com/swmansion/rnscreens/ScreenFragment.kt +19 -1
  10. package/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt +30 -101
  11. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragment.kt +75 -14
  12. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfig.kt +13 -4
  13. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfigViewManager.kt +8 -0
  14. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubview.kt +7 -1
  15. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubviewManager.kt +1 -0
  16. package/android/src/main/java/com/swmansion/rnscreens/SearchBarManager.kt +90 -0
  17. package/android/src/main/java/com/swmansion/rnscreens/SearchBarView.kt +150 -0
  18. package/android/src/main/java/com/swmansion/rnscreens/SearchViewFormatter.kt +40 -0
  19. package/createNativeStackNavigator/README.md +33 -9
  20. package/ios/RNSScreen.h +1 -0
  21. package/ios/RNSScreen.m +35 -0
  22. package/ios/RNSScreenContainer.h +2 -0
  23. package/ios/RNSScreenStack.m +24 -6
  24. package/ios/RNSScreenStackHeaderConfig.m +45 -2
  25. package/ios/RNSScreenWindowTraits.h +5 -0
  26. package/ios/RNSScreenWindowTraits.m +29 -0
  27. package/lib/commonjs/index.js +24 -1
  28. package/lib/commonjs/index.js.map +1 -1
  29. package/lib/commonjs/index.native.js +103 -17
  30. package/lib/commonjs/index.native.js.map +1 -1
  31. package/lib/commonjs/native-stack/utils/useBackPressSubscription.js +67 -0
  32. package/lib/commonjs/native-stack/utils/useBackPressSubscription.js.map +1 -0
  33. package/lib/commonjs/native-stack/views/HeaderConfig.js +46 -4
  34. package/lib/commonjs/native-stack/views/HeaderConfig.js.map +1 -1
  35. package/lib/commonjs/reanimated/ReanimatedNativeStackScreen.js +60 -0
  36. package/lib/commonjs/reanimated/ReanimatedNativeStackScreen.js.map +1 -0
  37. package/lib/commonjs/reanimated/ReanimatedScreen.js +7 -79
  38. package/lib/commonjs/reanimated/ReanimatedScreen.js.map +1 -1
  39. package/lib/commonjs/reanimated/ReanimatedScreenProvider.js +61 -0
  40. package/lib/commonjs/reanimated/ReanimatedScreenProvider.js.map +1 -0
  41. package/lib/commonjs/reanimated/index.js +2 -2
  42. package/lib/commonjs/reanimated/index.js.map +1 -1
  43. package/lib/commonjs/utils.js +20 -0
  44. package/lib/commonjs/utils.js.map +1 -0
  45. package/lib/module/index.js +5 -0
  46. package/lib/module/index.js.map +1 -1
  47. package/lib/module/index.native.js +99 -19
  48. package/lib/module/index.native.js.map +1 -1
  49. package/lib/module/native-stack/utils/useBackPressSubscription.js +50 -0
  50. package/lib/module/native-stack/utils/useBackPressSubscription.js.map +1 -0
  51. package/lib/module/native-stack/views/HeaderConfig.js +46 -5
  52. package/lib/module/native-stack/views/HeaderConfig.js.map +1 -1
  53. package/lib/module/reanimated/ReanimatedNativeStackScreen.js +40 -0
  54. package/lib/module/reanimated/ReanimatedNativeStackScreen.js.map +1 -0
  55. package/lib/module/reanimated/ReanimatedScreen.js +6 -73
  56. package/lib/module/reanimated/ReanimatedScreen.js.map +1 -1
  57. package/lib/module/reanimated/ReanimatedScreenProvider.js +49 -0
  58. package/lib/module/reanimated/ReanimatedScreenProvider.js.map +1 -0
  59. package/lib/module/reanimated/index.js +1 -1
  60. package/lib/module/reanimated/index.js.map +1 -1
  61. package/lib/module/utils.js +8 -0
  62. package/lib/module/utils.js.map +1 -0
  63. package/lib/typescript/index.d.ts +2 -0
  64. package/lib/typescript/native-stack/types.d.ts +0 -2
  65. package/lib/typescript/native-stack/utils/useBackPressSubscription.d.ts +16 -0
  66. package/lib/typescript/reanimated/ReanimatedNativeStackScreen.d.ts +5 -0
  67. package/lib/typescript/reanimated/ReanimatedScreen.d.ts +5 -2
  68. package/lib/typescript/reanimated/ReanimatedScreenProvider.d.ts +2 -0
  69. package/lib/typescript/reanimated/index.d.ts +1 -1
  70. package/lib/typescript/types.d.ts +46 -1
  71. package/lib/typescript/utils.d.ts +2 -0
  72. package/native-stack/README.md +35 -7
  73. package/package.json +5 -2
  74. package/src/index.native.tsx +138 -43
  75. package/src/index.tsx +10 -0
  76. package/src/native-stack/types.tsx +0 -2
  77. package/src/native-stack/utils/useBackPressSubscription.tsx +66 -0
  78. package/src/native-stack/views/HeaderConfig.tsx +46 -3
  79. package/src/reanimated/ReanimatedNativeStackScreen.tsx +61 -0
  80. package/src/reanimated/ReanimatedScreen.tsx +6 -84
  81. package/src/reanimated/ReanimatedScreenProvider.tsx +42 -0
  82. package/src/reanimated/index.tsx +1 -1
  83. package/src/types.tsx +46 -1
  84. package/src/utils.ts +12 -0
  85. package/windows/.gitignore +0 -92
@@ -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.h CHANGED
@@ -65,6 +65,7 @@ typedef NS_ENUM(NSInteger, RNSWindowTrait) {
65
65
 
66
66
  - (instancetype)initWithView:(UIView *)view;
67
67
  - (void)notifyFinishTransitioning;
68
+ - (UIViewController *)findChildVCForConfigAndTrait:(RNSWindowTrait)trait includingModals:(BOOL)includingModals;
68
69
 
69
70
  @end
70
71
 
package/ios/RNSScreen.m CHANGED
@@ -564,6 +564,8 @@
564
564
  _shouldNotify = NO;
565
565
  }
566
566
 
567
+ [self hideHeaderIfNecessary];
568
+
567
569
  // as per documentation of these methods
568
570
  _goingForward = [self isBeingPresented] || [self isMovingToParentViewController];
569
571
 
@@ -575,6 +577,35 @@
575
577
  }
576
578
  }
577
579
 
580
+ - (void)hideHeaderIfNecessary
581
+ {
582
+ #if !TARGET_OS_TV
583
+ // On iOS >=13, there is a bug when user transitions from screen with active search bar to screen without header
584
+ // In that case default iOS header will be shown. To fix this we hide header when the screens that appears has header
585
+ // hidden and search bar was active on previous screen. We need to do it asynchronously, because default header is
586
+ // added after viewWillAppear.
587
+ if (@available(iOS 13.0, *)) {
588
+ NSUInteger currentIndex = [self.navigationController.viewControllers indexOfObject:self];
589
+
590
+ if (currentIndex > 0 && [self.view.reactSubviews[0] isKindOfClass:[RNSScreenStackHeaderConfig class]]) {
591
+ UINavigationItem *prevNavigationItem =
592
+ [self.navigationController.viewControllers objectAtIndex:currentIndex - 1].navigationItem;
593
+ RNSScreenStackHeaderConfig *config = ((RNSScreenStackHeaderConfig *)self.view.reactSubviews[0]);
594
+
595
+ BOOL wasSearchBarActive = prevNavigationItem.searchController.active;
596
+ BOOL shouldHideHeader = config.hide;
597
+
598
+ if (wasSearchBarActive && shouldHideHeader) {
599
+ dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 0);
600
+ dispatch_after(popTime, dispatch_get_main_queue(), ^(void) {
601
+ [self.navigationController setNavigationBarHidden:YES animated:NO];
602
+ });
603
+ }
604
+ }
605
+ }
606
+ #endif
607
+ }
608
+
578
609
  - (void)viewWillDisappear:(BOOL)animated
579
610
  {
580
611
  [super viewWillDisappear:animated];
@@ -657,6 +688,10 @@
657
688
 
658
689
  - (void)traverseForScrollView:(UIView *)view
659
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
+ }
660
695
  if ([view isKindOfClass:[UIScrollView class]] &&
661
696
  ([[(UIScrollView *)view delegate] respondsToSelector:@selector(scrollViewDidEndDecelerating:)])) {
662
697
  [[(UIScrollView *)view delegate] scrollViewDidEndDecelerating:(id)view];
@@ -13,6 +13,8 @@
13
13
 
14
14
  @interface RNScreensViewController : UIViewController <RNScreensViewControllerDelegate>
15
15
 
16
+ - (UIViewController *)findActiveChildVC;
17
+
16
18
  @end
17
19
 
18
20
  @interface RNSScreenContainerManager : RCTViewManager
@@ -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.
@@ -489,6 +489,23 @@
489
489
  [self setModalViewControllers:modalControllers];
490
490
  }
491
491
 
492
+ // By default, the header buttons that are not inside the native hit area
493
+ // cannot be clicked, so we check it by ourselves
494
+ - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
495
+ {
496
+ if (CGRectContainsPoint(_controller.navigationBar.frame, point)) {
497
+ // headerConfig should be the first subview of the topmost screen
498
+ UIView *headerConfig = [[_reactSubviews.lastObject reactSubviews] firstObject];
499
+ if ([headerConfig isKindOfClass:[RNSScreenStackHeaderConfig class]]) {
500
+ UIView *headerHitTestResult = [headerConfig hitTest:point withEvent:event];
501
+ if (headerHitTestResult != nil) {
502
+ return headerHitTestResult;
503
+ }
504
+ }
505
+ }
506
+ return [super hitTest:point withEvent:event];
507
+ }
508
+
492
509
  - (void)layoutSubviews
493
510
  {
494
511
  [super layoutSubviews];
@@ -555,7 +572,8 @@
555
572
  {
556
573
  RNSScreenView *topScreen = (RNSScreenView *)_controller.viewControllers.lastObject.view;
557
574
 
558
- if (!topScreen.gestureEnabled || _controller.viewControllers.count < 2) {
575
+ if (![topScreen isKindOfClass:[RNSScreenView class]] || !topScreen.gestureEnabled ||
576
+ _controller.viewControllers.count < 2) {
559
577
  return NO;
560
578
  }
561
579
 
@@ -118,6 +118,27 @@
118
118
  _screenView = nil;
119
119
  }
120
120
 
121
+ // this method is never invoked by the system since this view
122
+ // is not added to native view hierarchy so we can apply our logic
123
+ - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
124
+ {
125
+ for (RNSScreenStackHeaderSubview *subview in _reactSubviews) {
126
+ if (subview.type == RNSScreenStackHeaderSubviewTypeLeft || subview.type == RNSScreenStackHeaderSubviewTypeRight) {
127
+ // we wrap the headerLeft/Right component in a UIBarButtonItem
128
+ // so we need to use the only subview of it to retrieve the correct view
129
+ UIView *headerComponent = subview.subviews.firstObject;
130
+ // we convert the point to RNSScreenStackView since it always contains the header inside it
131
+ CGPoint convertedPoint = [_screenView.reactSuperview convertPoint:point toView:headerComponent];
132
+
133
+ UIView *hitTestResult = [headerComponent hitTest:convertedPoint withEvent:event];
134
+ if (hitTestResult != nil) {
135
+ return hitTestResult;
136
+ }
137
+ }
138
+ }
139
+ return nil;
140
+ }
141
+
121
142
  - (void)updateViewControllerIfNeeded
122
143
  {
123
144
  UIViewController *vc = _screenView.controller;
@@ -138,10 +159,23 @@
138
159
  }
139
160
  }
140
161
 
162
+ - (void)layoutNavigationControllerView
163
+ {
164
+ UIViewController *vc = _screenView.controller;
165
+ UINavigationController *navctr = vc.navigationController;
166
+ [navctr.view setNeedsLayout];
167
+ }
168
+
141
169
  - (void)didSetProps:(NSArray<NSString *> *)changedProps
142
170
  {
143
171
  [super didSetProps:changedProps];
144
172
  [self updateViewControllerIfNeeded];
173
+ // We need to layout navigation controller view after translucent prop changes, because otherwise
174
+ // frame of RNSScreen will not be changed and screen content will remain the same size.
175
+ // For more details look at https://github.com/software-mansion/react-native-screens/issues/1158
176
+ if ([changedProps containsObject:@"translucent"]) {
177
+ [self layoutNavigationControllerView];
178
+ }
145
179
  }
146
180
 
147
181
  - (void)didUpdateReactSubviews
@@ -444,8 +478,10 @@
444
478
 
445
479
  [navctr setNavigationBarHidden:shouldHide animated:animated];
446
480
 
447
- if (config.direction == UISemanticContentAttributeForceLeftToRight ||
448
- config.direction == UISemanticContentAttributeForceRightToLeft) {
481
+ if ((config.direction == UISemanticContentAttributeForceLeftToRight ||
482
+ config.direction == UISemanticContentAttributeForceRightToLeft) &&
483
+ // iOS 12 cancels swipe gesture when direction is changed. See #1091
484
+ navctr.view.semanticContentAttribute != config.direction) {
449
485
  navctr.view.semanticContentAttribute = config.direction;
450
486
  navctr.navigationBar.semanticContentAttribute = config.direction;
451
487
  }
@@ -554,6 +590,13 @@
554
590
  break;
555
591
  }
556
592
  case RNSScreenStackHeaderSubviewTypeSearchBar: {
593
+ if (subview.subviews == nil || [subview.subviews count] == 0) {
594
+ RCTLogWarn(
595
+ @"Failed to attach search bar to the header. We recommend using `useLayoutEffect` when managing "
596
+ "searchBar properties dynamically. \n\nSee: github.com/software-mansion/react-native-screens/issues/1188");
597
+ break;
598
+ }
599
+
557
600
  if ([subview.subviews[0] isKindOfClass:[RNSSearchBar class]]) {
558
601
  #if !TARGET_OS_TV
559
602
  if (@available(iOS 11.0, *)) {
@@ -17,4 +17,9 @@
17
17
  + (UIInterfaceOrientationMask)maskFromOrientation:(UIInterfaceOrientation)orientation;
18
18
  #endif
19
19
 
20
+ + (BOOL)shouldAskScreensForTrait:(RNSWindowTrait)trait
21
+ includingModals:(BOOL)includingModals
22
+ inViewController:(UIViewController *)vc;
23
+ + (BOOL)shouldAskScreensForScreenOrientationInViewController:(UIViewController *)vc;
24
+
20
25
  @end
@@ -1,5 +1,7 @@
1
1
  #import "RNSScreenWindowTraits.h"
2
2
  #import "RNSScreen.h"
3
+ #import "RNSScreenContainer.h"
4
+ #import "RNSScreenStack.h"
3
5
 
4
6
  @implementation RNSScreenWindowTraits
5
7
 
@@ -190,4 +192,31 @@
190
192
  }
191
193
  #endif
192
194
 
195
+ // method to be used in Expo for checking if RNScreens have trait set
196
+ + (BOOL)shouldAskScreensForTrait:(RNSWindowTrait)trait
197
+ includingModals:(BOOL)includingModals
198
+ inViewController:(UIViewController *)vc
199
+ {
200
+ UIViewController *lastViewController = [[vc childViewControllers] lastObject];
201
+ if ([lastViewController conformsToProtocol:@protocol(RNScreensViewControllerDelegate)]) {
202
+ UIViewController *vc = nil;
203
+ if ([lastViewController isKindOfClass:[RNScreensViewController class]]) {
204
+ vc = [(RNScreensViewController *)lastViewController findActiveChildVC];
205
+ } else if ([lastViewController isKindOfClass:[RNScreensNavigationController class]]) {
206
+ vc = [(RNScreensNavigationController *)lastViewController topViewController];
207
+ }
208
+ return [vc isKindOfClass:[RNSScreen class]] &&
209
+ [(RNSScreen *)vc findChildVCForConfigAndTrait:trait includingModals:includingModals] != nil;
210
+ }
211
+ return NO;
212
+ }
213
+
214
+ // same method as above, but directly for orientation
215
+ + (BOOL)shouldAskScreensForScreenOrientationInViewController:(UIViewController *)vc
216
+ {
217
+ return [RNSScreenWindowTraits shouldAskScreensForTrait:RNSWindowTraitOrientation
218
+ includingModals:YES
219
+ inViewController:vc];
220
+ }
221
+
193
222
  @end
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  var _exportNames = {
7
7
  enableScreens: true,
8
8
  screensEnabled: true,
9
+ enableFreeze: true,
9
10
  NativeScreen: true,
10
11
  Screen: true,
11
12
  ScreenContext: true,
@@ -23,16 +24,31 @@ var _exportNames = {
23
24
  SearchBar: true,
24
25
  ScreenStackHeaderSubview: true,
25
26
  shouldUseActivityState: true,
26
- useTransitionProgress: true
27
+ useTransitionProgress: true,
28
+ isSearchBarAvailableForCurrentPlatform: true,
29
+ executeNativeBackPress: true
27
30
  };
28
31
  exports.enableScreens = enableScreens;
29
32
  exports.screensEnabled = screensEnabled;
33
+ exports.enableFreeze = enableFreeze;
30
34
  Object.defineProperty(exports, "useTransitionProgress", {
31
35
  enumerable: true,
32
36
  get: function () {
33
37
  return _useTransitionProgress.default;
34
38
  }
35
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
+ });
36
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;
37
53
 
38
54
  var _react = _interopRequireDefault(require("react"));
@@ -55,6 +71,8 @@ Object.keys(_types).forEach(function (key) {
55
71
 
56
72
  var _useTransitionProgress = _interopRequireDefault(require("./useTransitionProgress"));
57
73
 
74
+ var _utils = require("./utils");
75
+
58
76
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
59
77
 
60
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); }
@@ -67,6 +85,11 @@ function enableScreens(shouldEnableScreens = true) {
67
85
 
68
86
  function screensEnabled() {
69
87
  return ENABLE_SCREENS;
88
+ } // @ts-ignore function stub, freezing logic is located in index.native.tsx
89
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
90
+
91
+
92
+ function enableFreeze(shouldEnableReactFreeze = true) {// noop
70
93
  }
71
94
 
72
95
  class NativeScreen extends _react.default.Component {
@@ -1 +1 @@
1
- {"version":3,"sources":["index.tsx"],"names":["ENABLE_SCREENS","enableScreens","shouldEnableScreens","screensEnabled","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;;AAEM,MAAMI,YAAN,SAA2BC,eAAMC,SAAjC,CAAwD;AAC7DC,EAAAA,MAAM,GAAgB;AACpB,QAAI;AACFC,MAAAA,MADE;AAEFC,MAAAA,aAFE;AAGFC,MAAAA,KAHE;AAIFC,MAAAA,OAAO,GAAGX,cAJR;AAKF,SAAGY;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\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"]}