react-native-screens 3.31.1 → 3.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (203) hide show
  1. package/README.md +21 -11
  2. package/RNScreens.podspec +11 -52
  3. package/android/CMakeLists.txt +48 -4
  4. package/android/build.gradle +16 -9
  5. package/android/src/fabric/java/com/swmansion/rnscreens/FabricEnabledViewGroup.kt +25 -16
  6. package/android/src/fabric/java/com/swmansion/rnscreens/NativeProxy.kt +53 -0
  7. package/android/src/main/cpp/NativeProxy.cpp +51 -0
  8. package/android/src/main/cpp/NativeProxy.h +35 -0
  9. package/android/src/main/cpp/OnLoad.cpp +8 -0
  10. package/android/src/main/cpp/jni-adapter.cpp +86 -93
  11. package/android/src/main/java/com/swmansion/rnscreens/CustomSearchView.kt +7 -2
  12. package/android/src/main/java/com/swmansion/rnscreens/CustomToolbar.kt +6 -1
  13. package/android/src/main/java/com/swmansion/rnscreens/FragmentBackPressOverrider.kt +2 -2
  14. package/android/src/main/java/com/swmansion/rnscreens/RNScreensPackage.kt +36 -17
  15. package/android/src/main/java/com/swmansion/rnscreens/Screen.kt +150 -40
  16. package/android/src/main/java/com/swmansion/rnscreens/ScreenContainer.kt +52 -30
  17. package/android/src/main/java/com/swmansion/rnscreens/ScreenContainerViewManager.kt +27 -4
  18. package/android/src/main/java/com/swmansion/rnscreens/ScreenEventDispatcher.kt +10 -2
  19. package/android/src/main/java/com/swmansion/rnscreens/ScreenFragment.kt +56 -27
  20. package/android/src/main/java/com/swmansion/rnscreens/ScreenFragmentWrapper.kt +8 -1
  21. package/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt +50 -19
  22. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragment.kt +63 -39
  23. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragmentWrapper.kt +4 -0
  24. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfig.kt +88 -57
  25. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfigViewManager.kt +131 -36
  26. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubview.kt +19 -4
  27. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubviewManager.kt +16 -10
  28. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackViewManager.kt +28 -25
  29. package/android/src/main/java/com/swmansion/rnscreens/ScreenViewManager.kt +177 -77
  30. package/android/src/main/java/com/swmansion/rnscreens/ScreenWindowTraits.kt +77 -25
  31. package/android/src/main/java/com/swmansion/rnscreens/ScreensModule.kt +31 -9
  32. package/android/src/main/java/com/swmansion/rnscreens/ScreensShadowNode.kt +3 -1
  33. package/android/src/main/java/com/swmansion/rnscreens/SearchBarManager.kt +160 -54
  34. package/android/src/main/java/com/swmansion/rnscreens/SearchBarView.kt +29 -22
  35. package/android/src/main/java/com/swmansion/rnscreens/SearchViewFormatter.kt +7 -2
  36. package/android/src/main/java/com/swmansion/rnscreens/events/HeaderAttachedEvent.kt +4 -1
  37. package/android/src/main/java/com/swmansion/rnscreens/events/HeaderBackButtonClickedEvent.kt +4 -1
  38. package/android/src/main/java/com/swmansion/rnscreens/events/HeaderDetachedEvent.kt +4 -1
  39. package/android/src/main/java/com/swmansion/rnscreens/events/HeaderHeightChangeEvent.kt +5 -6
  40. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenAppearEvent.kt +4 -1
  41. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenDisappearEvent.kt +4 -1
  42. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenDismissedEvent.kt +8 -4
  43. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenTransitionProgressEvent.kt +7 -6
  44. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenWillAppearEvent.kt +4 -1
  45. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenWillDisappearEvent.kt +4 -1
  46. package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarBlurEvent.kt +5 -2
  47. package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarChangeTextEvent.kt +4 -3
  48. package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarCloseEvent.kt +4 -1
  49. package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarFocusEvent.kt +5 -2
  50. package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarOpenEvent.kt +4 -1
  51. package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarSearchButtonPressEvent.kt +9 -4
  52. package/android/src/main/java/com/swmansion/rnscreens/events/StackFinishTransitioningEvent.kt +4 -1
  53. package/android/src/main/java/com/swmansion/rnscreens/utils/DeviceUtils.kt +1 -5
  54. package/android/src/main/java/com/swmansion/rnscreens/utils/ScreenDummyLayoutHelper.kt +214 -0
  55. package/android/src/main/jni/CMakeLists.txt +5 -4
  56. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenContainerManagerDelegate.java +25 -0
  57. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenContainerManagerInterface.java +16 -0
  58. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerDelegate.java +6 -0
  59. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerInterface.java +2 -0
  60. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderConfigManagerDelegate.java +3 -0
  61. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderConfigManagerInterface.java +1 -0
  62. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSSearchBarManagerDelegate.java +99 -0
  63. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSSearchBarManagerInterface.java +37 -0
  64. package/android/src/paper/java/com/swmansion/rnscreens/FabricEnabledViewGroup.kt +10 -5
  65. package/android/src/paper/java/com/swmansion/rnscreens/NativeProxy.kt +19 -0
  66. package/android/src/paper/java/com/swmansion/rnscreens/NativeScreensModuleSpec.java +4 -0
  67. package/common/cpp/react/renderer/components/rnscreens/FrameCorrectionModes.h +51 -0
  68. package/common/cpp/react/renderer/components/rnscreens/RNSModalScreenComponentDescriptor.h +8 -9
  69. package/common/cpp/react/renderer/components/rnscreens/RNSModalScreenShadowNode.cpp +2 -1
  70. package/common/cpp/react/renderer/components/rnscreens/RNSModalScreenShadowNode.h +9 -8
  71. package/common/cpp/react/renderer/components/rnscreens/RNSScreenComponentDescriptor.h +147 -10
  72. package/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.cpp +51 -1
  73. package/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.h +29 -7
  74. package/common/cpp/react/renderer/components/rnscreens/RNSScreenState.cpp +22 -1
  75. package/common/cpp/react/renderer/components/rnscreens/RNSScreenState.h +30 -10
  76. package/common/cpp/react/renderer/components/rnscreens/utils/RectUtil.h +36 -0
  77. package/cpp/RNSScreenRemovalListener.cpp +25 -0
  78. package/cpp/RNSScreenRemovalListener.h +20 -0
  79. package/cpp/RNScreensTurboModule.cpp +31 -23
  80. package/cpp/RNScreensTurboModule.h +17 -20
  81. package/ios/RNSConvert.h +7 -0
  82. package/ios/RNSConvert.mm +24 -0
  83. package/ios/RNSModalScreen.mm +22 -0
  84. package/ios/RNSModule.mm +2 -3
  85. package/ios/RNSScreen.h +2 -1
  86. package/ios/RNSScreen.mm +35 -19
  87. package/ios/RNSScreenContainer.mm +1 -1
  88. package/ios/RNSScreenStack.mm +59 -54
  89. package/ios/RNSScreenStackAnimator.mm +43 -6
  90. package/ios/RNSScreenStackHeaderConfig.h +2 -0
  91. package/ios/RNSScreenStackHeaderConfig.mm +93 -28
  92. package/ios/RNSScreenStackHeaderSubview.mm +8 -0
  93. package/ios/RNSSearchBar.h +5 -5
  94. package/ios/RNSSearchBar.mm +11 -11
  95. package/ios/utils/RCTSurfaceTouchHandler+RNSUtility.h +15 -0
  96. package/ios/utils/RCTSurfaceTouchHandler+RNSUtility.mm +14 -0
  97. package/ios/utils/RCTTouchHandler+RNSUtility.h +15 -0
  98. package/ios/utils/RCTTouchHandler+RNSUtility.mm +15 -0
  99. package/ios/utils/UIView+RNSUtility.h +23 -0
  100. package/ios/utils/UIView+RNSUtility.mm +55 -0
  101. package/lib/commonjs/components/Screen.js +119 -127
  102. package/lib/commonjs/components/Screen.js.map +1 -1
  103. package/lib/commonjs/components/ScreenStack.js +8 -1
  104. package/lib/commonjs/components/ScreenStack.js.map +1 -1
  105. package/lib/commonjs/components/SearchBar.js +39 -36
  106. package/lib/commonjs/components/SearchBar.js.map +1 -1
  107. package/lib/commonjs/fabric/ModalScreenNativeComponent.js.map +1 -1
  108. package/lib/commonjs/fabric/ScreenNativeComponent.js.map +1 -1
  109. package/lib/commonjs/fabric/ScreenStackHeaderConfigNativeComponent.js.map +1 -1
  110. package/lib/commonjs/native-stack/views/HeaderConfig.js +2 -0
  111. package/lib/commonjs/native-stack/views/HeaderConfig.js.map +1 -1
  112. package/lib/commonjs/native-stack/views/NativeStackView.js +4 -0
  113. package/lib/commonjs/native-stack/views/NativeStackView.js.map +1 -1
  114. package/lib/module/components/Screen.js +118 -126
  115. package/lib/module/components/Screen.js.map +1 -1
  116. package/lib/module/components/ScreenStack.js +8 -1
  117. package/lib/module/components/ScreenStack.js.map +1 -1
  118. package/lib/module/components/SearchBar.js +39 -36
  119. package/lib/module/components/SearchBar.js.map +1 -1
  120. package/lib/module/fabric/ModalScreenNativeComponent.js.map +1 -1
  121. package/lib/module/fabric/ScreenNativeComponent.js.map +1 -1
  122. package/lib/module/fabric/ScreenStackHeaderConfigNativeComponent.js.map +1 -1
  123. package/lib/module/native-stack/views/HeaderConfig.js +2 -0
  124. package/lib/module/native-stack/views/HeaderConfig.js.map +1 -1
  125. package/lib/module/native-stack/views/NativeStackView.js +4 -0
  126. package/lib/module/native-stack/views/NativeStackView.js.map +1 -1
  127. package/lib/typescript/TransitionProgressContext.d.ts +1 -1
  128. package/lib/typescript/TransitionProgressContext.d.ts.map +1 -1
  129. package/lib/typescript/components/Screen.d.ts +3 -14
  130. package/lib/typescript/components/Screen.d.ts.map +1 -1
  131. package/lib/typescript/components/ScreenStack.d.ts.map +1 -1
  132. package/lib/typescript/components/SearchBar.d.ts +14 -21
  133. package/lib/typescript/components/SearchBar.d.ts.map +1 -1
  134. package/lib/typescript/fabric/ModalScreenNativeComponent.d.ts +12 -10
  135. package/lib/typescript/fabric/ModalScreenNativeComponent.d.ts.map +1 -1
  136. package/lib/typescript/fabric/ScreenNativeComponent.d.ts +12 -10
  137. package/lib/typescript/fabric/ScreenNativeComponent.d.ts.map +1 -1
  138. package/lib/typescript/fabric/ScreenStackHeaderConfigNativeComponent.d.ts +5 -3
  139. package/lib/typescript/fabric/ScreenStackHeaderConfigNativeComponent.d.ts.map +1 -1
  140. package/lib/typescript/fabric/ScreenStackHeaderSubviewNativeComponent.d.ts +1 -1
  141. package/lib/typescript/fabric/ScreenStackHeaderSubviewNativeComponent.d.ts.map +1 -1
  142. package/lib/typescript/fabric/ScreenStackNativeComponent.d.ts +1 -1
  143. package/lib/typescript/fabric/ScreenStackNativeComponent.d.ts.map +1 -1
  144. package/lib/typescript/fabric/SearchBarNativeComponent.d.ts +9 -9
  145. package/lib/typescript/fabric/SearchBarNativeComponent.d.ts.map +1 -1
  146. package/lib/typescript/gesture-handler/RNScreensTurboModule.d.ts +1 -1
  147. package/lib/typescript/gesture-handler/RNScreensTurboModule.d.ts.map +1 -1
  148. package/lib/typescript/native-stack/types.d.ts +39 -14
  149. package/lib/typescript/native-stack/types.d.ts.map +1 -1
  150. package/lib/typescript/native-stack/utils/SafeAreaProviderCompat.d.ts +1 -1
  151. package/lib/typescript/native-stack/utils/SafeAreaProviderCompat.d.ts.map +1 -1
  152. package/lib/typescript/native-stack/utils/getDefaultHeaderHeight.d.ts +1 -1
  153. package/lib/typescript/native-stack/utils/getDefaultHeaderHeight.d.ts.map +1 -1
  154. package/lib/typescript/native-stack/utils/useAnimatedHeaderHeight.d.ts +1 -1
  155. package/lib/typescript/native-stack/utils/useAnimatedHeaderHeight.d.ts.map +1 -1
  156. package/lib/typescript/native-stack/views/HeaderConfig.d.ts +2 -2
  157. package/lib/typescript/native-stack/views/HeaderConfig.d.ts.map +1 -1
  158. package/lib/typescript/native-stack/views/NativeStackView.d.ts +1 -1
  159. package/lib/typescript/native-stack/views/NativeStackView.d.ts.map +1 -1
  160. package/lib/typescript/reanimated/ReanimatedTransitionProgressContext.d.ts +1 -1
  161. package/lib/typescript/reanimated/ReanimatedTransitionProgressContext.d.ts.map +1 -1
  162. package/lib/typescript/types.d.ts +39 -13
  163. package/lib/typescript/types.d.ts.map +1 -1
  164. package/lib/typescript/useTransitionProgress.d.ts +3 -3
  165. package/native-stack/README.md +116 -98
  166. package/package.json +16 -7
  167. package/react-native.config.js +17 -15
  168. package/src/TransitionProgressContext.tsx +1 -1
  169. package/src/components/Screen.tsx +31 -37
  170. package/src/components/ScreenStack.tsx +11 -1
  171. package/src/components/ScreenStackHeaderConfig.tsx +5 -5
  172. package/src/components/ScreenStackHeaderConfig.web.tsx +6 -6
  173. package/src/components/SearchBar.tsx +77 -65
  174. package/src/core.ts +1 -1
  175. package/src/fabric/ModalScreenNativeComponent.ts +2 -0
  176. package/src/fabric/ScreenNativeComponent.ts +2 -0
  177. package/src/fabric/ScreenNavigationContainerNativeComponent.ts +1 -1
  178. package/src/fabric/ScreenStackHeaderConfigNativeComponent.ts +4 -1
  179. package/src/fabric/ScreenStackHeaderSubviewNativeComponent.ts +1 -1
  180. package/src/fabric/SearchBarNativeComponent.ts +7 -7
  181. package/src/gesture-handler/ScreenGestureDetector.tsx +5 -5
  182. package/src/gesture-handler/constraints.ts +5 -5
  183. package/src/gesture-handler/fabricUtils.ts +1 -1
  184. package/src/native-stack/contexts/GHContext.tsx +1 -1
  185. package/src/native-stack/navigators/createNativeStackNavigator.tsx +3 -3
  186. package/src/native-stack/types.tsx +29 -4
  187. package/src/native-stack/utils/getDefaultHeaderHeight.tsx +1 -1
  188. package/src/native-stack/utils/getStatusBarHeight.tsx +1 -1
  189. package/src/native-stack/utils/useAnimatedHeaderHeight.tsx +1 -1
  190. package/src/native-stack/utils/useBackPressSubscription.tsx +1 -1
  191. package/src/native-stack/utils/useHeaderHeight.tsx +1 -1
  192. package/src/native-stack/views/FontProcessor.tsx +1 -1
  193. package/src/native-stack/views/HeaderConfig.tsx +3 -1
  194. package/src/native-stack/views/NativeStackView.tsx +13 -9
  195. package/src/reanimated/ReanimatedHeaderHeightContext.tsx +1 -1
  196. package/src/reanimated/ReanimatedNativeStackScreen.tsx +5 -5
  197. package/src/reanimated/ReanimatedScreen.tsx +2 -2
  198. package/src/reanimated/ReanimatedScreenProvider.tsx +1 -1
  199. package/src/reanimated/useReanimatedHeaderHeight.tsx +1 -1
  200. package/src/reanimated/useReanimatedTransitionProgress.tsx +1 -1
  201. package/src/types.tsx +31 -5
  202. package/src/useTransitionProgress.tsx +1 -1
  203. package/windows/README.md +4 -1
@@ -1,4 +1,3 @@
1
- /* eslint-disable @typescript-eslint/no-var-requires */
2
1
  import React from 'react';
3
2
  import { Animated, View, Platform } from 'react-native';
4
3
 
@@ -17,10 +16,10 @@ import ScreenNativeComponent from '../fabric/ScreenNativeComponent';
17
16
  import ModalScreenNativeComponent from '../fabric/ModalScreenNativeComponent';
18
17
 
19
18
  export const NativeScreen: React.ComponentType<ScreenProps> =
20
- ScreenNativeComponent as any;
19
+ ScreenNativeComponent as React.ComponentType<ScreenProps>;
21
20
  const AnimatedNativeScreen = Animated.createAnimatedComponent(NativeScreen);
22
21
  const AnimatedNativeModalScreen = Animated.createAnimatedComponent(
23
- ModalScreenNativeComponent as React.ComponentType<ScreenProps>
22
+ ModalScreenNativeComponent as React.ComponentType<ScreenProps>,
24
23
  );
25
24
 
26
25
  // Incomplete type, all accessible properties available at:
@@ -42,27 +41,25 @@ interface ViewConfig extends View {
42
41
  };
43
42
  }
44
43
 
45
- export class InnerScreen extends React.Component<ScreenProps> {
46
- private ref: React.ElementRef<typeof View> | null = null;
47
- private closing = new Animated.Value(0);
48
- private progress = new Animated.Value(0);
49
- private goingForward = new Animated.Value(0);
44
+ export const InnerScreen = React.forwardRef<View, ScreenProps>(
45
+ function InnerScreen(props, ref) {
46
+ const innerRef = React.useRef<ViewConfig | null>(null);
47
+ React.useImperativeHandle(ref, () => innerRef.current!, []);
50
48
 
51
- setNativeProps(props: ScreenProps): void {
52
- this.ref?.setNativeProps(props);
53
- }
49
+ const setRef = (ref: ViewConfig) => {
50
+ innerRef.current = ref;
51
+ props.onComponentRef?.(ref);
52
+ };
54
53
 
55
- setRef = (ref: React.ElementRef<typeof View> | null): void => {
56
- this.ref = ref;
57
- this.props.onComponentRef?.(ref);
58
- };
54
+ const closing = React.useRef(new Animated.Value(0)).current;
55
+ const progress = React.useRef(new Animated.Value(0)).current;
56
+ const goingForward = React.useRef(new Animated.Value(0)).current;
59
57
 
60
- render() {
61
58
  const {
62
59
  enabled = screensEnabled(),
63
60
  freezeOnBlur = freezeEnabled(),
64
61
  ...rest
65
- } = this.props;
62
+ } = props;
66
63
 
67
64
  // To maintain default behavior of formSheet stack presentation style and to have reasonable
68
65
  // defaults for new medium-detent iOS API we need to set defaults here
@@ -101,7 +98,7 @@ export class InnerScreen extends React.Component<ScreenProps> {
101
98
 
102
99
  if (active !== undefined && activityState === undefined) {
103
100
  console.warn(
104
- 'It appears that you are using old version of react-navigation library. Please update @react-navigation/bottom-tabs, @react-navigation/stack and @react-navigation/drawer to version 5.10.0 or above to take full advantage of new functionality added to react-native-screens'
101
+ 'It appears that you are using old version of react-navigation library. Please update @react-navigation/bottom-tabs, @react-navigation/stack and @react-navigation/drawer to version 5.10.0 or above to take full advantage of new functionality added to react-native-screens',
105
102
  );
106
103
  activityState = active !== 0 ? 2 : 0; // in the new version, we need one of the screens to have value of 2 after the transition
107
104
  }
@@ -112,13 +109,13 @@ export class InnerScreen extends React.Component<ScreenProps> {
112
109
  ...ref.viewConfig.validAttributes.style,
113
110
  display: false,
114
111
  };
115
- this.setRef(ref);
112
+ setRef(ref);
116
113
  } else if (ref?._viewConfig?.validAttributes?.style) {
117
114
  ref._viewConfig.validAttributes.style = {
118
115
  ...ref._viewConfig.validAttributes.style,
119
116
  display: false,
120
117
  };
121
- this.setRef(ref);
118
+ setRef(ref);
122
119
  }
123
120
  };
124
121
 
@@ -148,13 +145,13 @@ export class InnerScreen extends React.Component<ScreenProps> {
148
145
  [
149
146
  {
150
147
  nativeEvent: {
151
- progress: this.progress,
152
- closing: this.closing,
153
- goingForward: this.goingForward,
148
+ progress,
149
+ closing,
150
+ goingForward,
154
151
  },
155
152
  },
156
153
  ],
157
- { useNativeDriver: true }
154
+ { useNativeDriver: true },
158
155
  )
159
156
  }
160
157
  onGestureCancel={
@@ -168,9 +165,9 @@ export class InnerScreen extends React.Component<ScreenProps> {
168
165
  ) : (
169
166
  <TransitionProgressContext.Provider
170
167
  value={{
171
- progress: this.progress,
172
- closing: this.closing,
173
- goingForward: this.goingForward,
168
+ progress,
169
+ closing,
170
+ goingForward,
174
171
  }}>
175
172
  {children}
176
173
  </TransitionProgressContext.Provider>
@@ -195,25 +192,22 @@ export class InnerScreen extends React.Component<ScreenProps> {
195
192
  return (
196
193
  <Animated.View
197
194
  style={[style, { display: activityState !== 0 ? 'flex' : 'none' }]}
198
- ref={this.setRef}
195
+ ref={setRef}
199
196
  {...props}
200
197
  />
201
198
  );
202
199
  }
203
- }
204
- }
200
+ },
201
+ );
205
202
 
206
203
  // context to be used when the user wants to use enhanced implementation
207
204
  // e.g. to use `useReanimatedTransitionProgress` (see `reanimated` folder in repo)
208
205
  export const ScreenContext = React.createContext(InnerScreen);
209
206
 
210
- class Screen extends React.Component<ScreenProps> {
211
- static contextType = ScreenContext;
207
+ const Screen: React.FC<ScreenProps> = props => {
208
+ const ScreenWrapper = React.useContext(ScreenContext) || InnerScreen;
212
209
 
213
- render() {
214
- const ScreenWrapper = (this.context || InnerScreen) as React.ElementType;
215
- return <ScreenWrapper {...this.props} />;
216
- }
217
- }
210
+ return <ScreenWrapper {...props} />;
211
+ };
218
212
 
219
213
  export default Screen;
@@ -7,6 +7,10 @@ import ScreenStackNativeComponent from '../fabric/ScreenStackNativeComponent';
7
7
  const NativeScreenStack: React.ComponentType<ScreenStackProps> =
8
8
  ScreenStackNativeComponent as any;
9
9
 
10
+ function isFabric() {
11
+ return 'nativeFabricUIManager' in global;
12
+ }
13
+
10
14
  function ScreenStack(props: ScreenStackProps) {
11
15
  const { children, gestureDetectorBridge, ...rest } = props;
12
16
  const ref = React.useRef(null);
@@ -19,8 +23,14 @@ function ScreenStack(props: ScreenStackProps) {
19
23
  const isFreezeEnabled =
20
24
  descriptor?.options?.freezeOnBlur ?? freezeEnabled();
21
25
 
26
+ // On Fabric, when screen is frozen, animated and reanimated values are not updated
27
+ // due to component being unmounted. To avoid this, we don't freeze the previous screen there
28
+ const freezePreviousScreen = isFabric()
29
+ ? size - index > 2
30
+ : size - index > 1;
31
+
22
32
  return (
23
- <DelayedFreeze freeze={isFreezeEnabled && size - index > 1}>
33
+ <DelayedFreeze freeze={isFreezeEnabled && freezePreviousScreen}>
24
34
  {child}
25
35
  </DelayedFreeze>
26
36
  );
@@ -17,7 +17,7 @@ export const ScreenStackHeaderSubview: React.ComponentType<
17
17
  > = ScreenStackHeaderSubviewNativeComponent as any;
18
18
 
19
19
  export const ScreenStackHeaderBackButtonImage = (
20
- props: ImageProps
20
+ props: ImageProps,
21
21
  ): JSX.Element => (
22
22
  <ScreenStackHeaderSubview type="back" style={styles.headerSubview}>
23
23
  <Image resizeMode="center" fadeDuration={0} {...props} />
@@ -25,7 +25,7 @@ export const ScreenStackHeaderBackButtonImage = (
25
25
  );
26
26
 
27
27
  export const ScreenStackHeaderRightView = (
28
- props: React.PropsWithChildren<ViewProps>
28
+ props: React.PropsWithChildren<ViewProps>,
29
29
  ): JSX.Element => (
30
30
  <ScreenStackHeaderSubview
31
31
  {...props}
@@ -35,7 +35,7 @@ export const ScreenStackHeaderRightView = (
35
35
  );
36
36
 
37
37
  export const ScreenStackHeaderLeftView = (
38
- props: React.PropsWithChildren<ViewProps>
38
+ props: React.PropsWithChildren<ViewProps>,
39
39
  ): JSX.Element => (
40
40
  <ScreenStackHeaderSubview
41
41
  {...props}
@@ -45,7 +45,7 @@ export const ScreenStackHeaderLeftView = (
45
45
  );
46
46
 
47
47
  export const ScreenStackHeaderCenterView = (
48
- props: React.PropsWithChildren<ViewProps>
48
+ props: React.PropsWithChildren<ViewProps>,
49
49
  ): JSX.Element => (
50
50
  <ScreenStackHeaderSubview
51
51
  {...props}
@@ -55,7 +55,7 @@ export const ScreenStackHeaderCenterView = (
55
55
  );
56
56
 
57
57
  export const ScreenStackHeaderSearchBarView = (
58
- props: React.PropsWithChildren<SearchBarProps>
58
+ props: React.PropsWithChildren<SearchBarProps>,
59
59
  ): JSX.Element => (
60
60
  <ScreenStackHeaderSubview
61
61
  {...props}
@@ -7,7 +7,7 @@ import {
7
7
  } from 'react-native-screens';
8
8
 
9
9
  export const ScreenStackHeaderBackButtonImage = (
10
- props: ImageProps
10
+ props: ImageProps,
11
11
  ): JSX.Element => (
12
12
  <View>
13
13
  <Image resizeMode="center" fadeDuration={0} {...props} />
@@ -15,23 +15,23 @@ export const ScreenStackHeaderBackButtonImage = (
15
15
  );
16
16
 
17
17
  export const ScreenStackHeaderRightView = (
18
- props: React.PropsWithChildren<ViewProps>
18
+ props: React.PropsWithChildren<ViewProps>,
19
19
  ): JSX.Element => <View {...props} />;
20
20
 
21
21
  export const ScreenStackHeaderLeftView = (
22
- props: React.PropsWithChildren<ViewProps>
22
+ props: React.PropsWithChildren<ViewProps>,
23
23
  ): JSX.Element => <View {...props} />;
24
24
 
25
25
  export const ScreenStackHeaderCenterView = (
26
- props: React.PropsWithChildren<ViewProps>
26
+ props: React.PropsWithChildren<ViewProps>,
27
27
  ): JSX.Element => <View {...props} />;
28
28
 
29
29
  export const ScreenStackHeaderSearchBarView = (
30
- props: React.PropsWithChildren<Omit<SearchBarProps, 'ref'>>
30
+ props: React.PropsWithChildren<Omit<SearchBarProps, 'ref'>>,
31
31
  ): JSX.Element => <View {...props} />;
32
32
 
33
33
  export const ScreenStackHeaderConfig = (
34
- props: React.PropsWithChildren<ScreenStackHeaderConfigProps>
34
+ props: React.PropsWithChildren<ScreenStackHeaderConfigProps>,
35
35
  ): JSX.Element => <View {...props} />;
36
36
 
37
37
  export const ScreenStackHeaderSubview: React.ComponentType<
@@ -1,4 +1,4 @@
1
- import React, { ReactNode } from 'react';
1
+ import React from 'react';
2
2
  import {
3
3
  isSearchBarAvailableForCurrentPlatform,
4
4
  SearchBarCommands,
@@ -9,83 +9,95 @@ import { View } from 'react-native';
9
9
  // Native components
10
10
  import SearchBarNativeComponent, {
11
11
  Commands as SearchBarNativeCommands,
12
+ NativeProps as SearchBarNativeProps,
13
+ SearchBarEvent,
14
+ SearchButtonPressedEvent,
15
+ ChangeTextEvent,
12
16
  } from '../fabric/SearchBarNativeComponent';
17
+ import { DirectEventHandler } from 'react-native/Libraries/Types/CodegenTypes';
13
18
 
14
- export const NativeSearchBar: React.ComponentType<SearchBarProps> &
15
- typeof NativeSearchBarCommands = SearchBarNativeComponent as any;
19
+ export const NativeSearchBar: React.ComponentType<
20
+ SearchBarNativeProps & { ref?: React.RefObject<SearchBarCommands> }
21
+ > &
22
+ typeof NativeSearchBarCommands =
23
+ SearchBarNativeComponent as unknown as React.ComponentType<SearchBarNativeProps> &
24
+ SearchBarCommandsType;
16
25
  export const NativeSearchBarCommands: SearchBarCommandsType =
17
- SearchBarNativeCommands as any;
26
+ SearchBarNativeCommands as SearchBarCommandsType;
27
+
28
+ type NativeSearchBarRef = React.ElementRef<typeof NativeSearchBar>;
18
29
 
19
30
  type SearchBarCommandsType = {
20
- blur: (viewRef: React.ElementRef<typeof NativeSearchBar>) => void;
21
- focus: (viewRef: React.ElementRef<typeof NativeSearchBar>) => void;
22
- clearText: (viewRef: React.ElementRef<typeof NativeSearchBar>) => void;
23
- toggleCancelButton: (
24
- viewRef: React.ElementRef<typeof NativeSearchBar>,
25
- flag: boolean
26
- ) => void;
27
- setText: (
28
- viewRef: React.ElementRef<typeof NativeSearchBar>,
29
- text: string
30
- ) => void;
31
- cancelSearch: (viewRef: React.ElementRef<typeof NativeSearchBar>) => void;
31
+ blur: (viewRef: NativeSearchBarRef) => void;
32
+ focus: (viewRef: NativeSearchBarRef) => void;
33
+ clearText: (viewRef: NativeSearchBarRef) => void;
34
+ toggleCancelButton: (viewRef: NativeSearchBarRef, flag: boolean) => void;
35
+ setText: (viewRef: NativeSearchBarRef, text: string) => void;
36
+ cancelSearch: (viewRef: NativeSearchBarRef) => void;
32
37
  };
33
38
 
34
- class SearchBar extends React.Component<SearchBarProps> {
35
- nativeSearchBarRef: React.RefObject<SearchBarCommands>;
36
-
37
- constructor(props: SearchBarProps) {
38
- super(props);
39
- this.nativeSearchBarRef = React.createRef();
40
- }
39
+ function SearchBar(props: SearchBarProps, ref: React.Ref<SearchBarCommands>) {
40
+ const searchBarRef = React.useRef<SearchBarCommands | null>(null);
41
41
 
42
- _callMethodWithRef(method: (ref: SearchBarCommands) => void) {
43
- const ref = this.nativeSearchBarRef.current;
44
- if (ref) {
45
- method(ref);
46
- } else {
47
- console.warn(
48
- 'Reference to native search bar component has not been updated yet'
42
+ React.useImperativeHandle(ref, () => ({
43
+ blur: () => {
44
+ _callMethodWithRef(ref => NativeSearchBarCommands.blur(ref));
45
+ },
46
+ focus: () => {
47
+ _callMethodWithRef(ref => NativeSearchBarCommands.focus(ref));
48
+ },
49
+ toggleCancelButton: (flag: boolean) => {
50
+ _callMethodWithRef(ref =>
51
+ NativeSearchBarCommands.toggleCancelButton(ref, flag),
49
52
  );
50
- }
51
- }
53
+ },
54
+ clearText: () => {
55
+ _callMethodWithRef(ref => NativeSearchBarCommands.clearText(ref));
56
+ },
57
+ setText: (text: string) => {
58
+ _callMethodWithRef(ref => NativeSearchBarCommands.setText(ref, text));
59
+ },
60
+ cancelSearch: () => {
61
+ _callMethodWithRef(ref => NativeSearchBarCommands.cancelSearch(ref));
62
+ },
63
+ }));
52
64
 
53
- blur() {
54
- this._callMethodWithRef(ref => NativeSearchBarCommands.blur(ref));
55
- }
56
-
57
- focus() {
58
- this._callMethodWithRef(ref => NativeSearchBarCommands.focus(ref));
59
- }
65
+ const _callMethodWithRef = React.useCallback(
66
+ (method: (ref: SearchBarCommands) => void) => {
67
+ const ref = searchBarRef.current;
68
+ if (ref) {
69
+ method(ref);
70
+ } else {
71
+ console.warn(
72
+ 'Reference to native search bar component has not been updated yet',
73
+ );
74
+ }
75
+ },
76
+ [searchBarRef],
77
+ );
60
78
 
61
- toggleCancelButton(flag: boolean) {
62
- this._callMethodWithRef(ref =>
63
- NativeSearchBarCommands.toggleCancelButton(ref, flag)
79
+ if (!isSearchBarAvailableForCurrentPlatform) {
80
+ console.warn(
81
+ 'Importing SearchBar is only valid on iOS and Android devices.',
64
82
  );
83
+ return View as unknown as React.ReactNode;
65
84
  }
66
85
 
67
- clearText() {
68
- this._callMethodWithRef(ref => NativeSearchBarCommands.clearText(ref));
69
- }
70
-
71
- setText(text: string) {
72
- this._callMethodWithRef(ref => NativeSearchBarCommands.setText(ref, text));
73
- }
74
-
75
- cancelSearch() {
76
- this._callMethodWithRef(ref => NativeSearchBarCommands.cancelSearch(ref));
77
- }
78
-
79
- render() {
80
- if (!isSearchBarAvailableForCurrentPlatform) {
81
- console.warn(
82
- 'Importing SearchBar is only valid on iOS and Android devices.'
83
- );
84
- return View as any as ReactNode;
85
- }
86
-
87
- return <NativeSearchBar {...this.props} ref={this.nativeSearchBarRef} />;
88
- }
86
+ return (
87
+ <NativeSearchBar
88
+ ref={searchBarRef}
89
+ {...props}
90
+ onSearchFocus={props.onFocus as DirectEventHandler<SearchBarEvent>}
91
+ onSearchBlur={props.onBlur as DirectEventHandler<SearchBarEvent>}
92
+ onSearchButtonPress={
93
+ props.onSearchButtonPress as DirectEventHandler<SearchButtonPressedEvent>
94
+ }
95
+ onCancelButtonPress={
96
+ props.onCancelButtonPress as DirectEventHandler<SearchBarEvent>
97
+ }
98
+ onChangeText={props.onChangeText as DirectEventHandler<ChangeTextEvent>}
99
+ />
100
+ );
89
101
  }
90
102
 
91
- export default SearchBar;
103
+ export default React.forwardRef<SearchBarCommands, SearchBarProps>(SearchBar);
package/src/core.ts CHANGED
@@ -19,7 +19,7 @@ export function enableScreens(shouldEnableScreens = true) {
19
19
 
20
20
  if (ENABLE_SCREENS && !UIManager.getViewManagerConfig('RNSScreen')) {
21
21
  console.error(
22
- `Screen native module hasn't been linked. Please check the react-native-screens README for more details`
22
+ `Screen native module hasn't been linked. Please check the react-native-screens README for more details`,
23
23
  );
24
24
  }
25
25
  }
@@ -77,6 +77,7 @@ export interface NativeProps extends ViewProps {
77
77
  sheetExpandsWhenScrolledToEdge?: WithDefault<boolean, false>;
78
78
  customAnimationOnSwipe?: boolean;
79
79
  fullScreenSwipeEnabled?: boolean;
80
+ fullScreenSwipeShadowEnabled?: boolean;
80
81
  homeIndicatorHidden?: boolean;
81
82
  preventNativeDismiss?: boolean;
82
83
  gestureEnabled?: WithDefault<boolean, true>;
@@ -95,6 +96,7 @@ export interface NativeProps extends ViewProps {
95
96
  hideKeyboardOnSwipe?: boolean;
96
97
  activityState?: WithDefault<Float, -1.0>;
97
98
  navigationBarColor?: ColorValue;
99
+ navigationBarTranslucent?: boolean;
98
100
  navigationBarHidden?: boolean;
99
101
  nativeBackButtonDismissalEnabled?: boolean;
100
102
  }
@@ -77,6 +77,7 @@ export interface NativeProps extends ViewProps {
77
77
  sheetExpandsWhenScrolledToEdge?: WithDefault<boolean, false>;
78
78
  customAnimationOnSwipe?: boolean;
79
79
  fullScreenSwipeEnabled?: boolean;
80
+ fullScreenSwipeShadowEnabled?: boolean;
80
81
  homeIndicatorHidden?: boolean;
81
82
  preventNativeDismiss?: boolean;
82
83
  gestureEnabled?: WithDefault<boolean, true>;
@@ -95,6 +96,7 @@ export interface NativeProps extends ViewProps {
95
96
  hideKeyboardOnSwipe?: boolean;
96
97
  activityState?: WithDefault<Float, -1.0>;
97
98
  navigationBarColor?: ColorValue;
99
+ navigationBarTranslucent?: boolean;
98
100
  navigationBarHidden?: boolean;
99
101
  nativeBackButtonDismissalEnabled?: boolean;
100
102
  }
@@ -5,5 +5,5 @@ interface NativeProps extends ViewProps {}
5
5
 
6
6
  export default codegenNativeComponent<NativeProps>(
7
7
  'RNSScreenNavigationContainer',
8
- {}
8
+ {},
9
9
  );
@@ -13,6 +13,8 @@ type OnAttachedEvent = Readonly<{}>;
13
13
  // eslint-disable-next-line @typescript-eslint/ban-types
14
14
  type OnDetachedEvent = Readonly<{}>;
15
15
 
16
+ type BackButtonDisplayMode = 'minimal' | 'default' | 'generic';
17
+
16
18
  export interface NativeProps extends ViewProps {
17
19
  onAttached?: DirectEventHandler<OnAttachedEvent>;
18
20
  onDetached?: DirectEventHandler<OnDetachedEvent>;
@@ -39,6 +41,7 @@ export interface NativeProps extends ViewProps {
39
41
  titleFontWeight?: string;
40
42
  titleColor?: ColorValue;
41
43
  disableBackButtonMenu?: boolean;
44
+ backButtonDisplayMode?: WithDefault<BackButtonDisplayMode, 'default'>;
42
45
  hideBackButton?: boolean;
43
46
  backButtonInCustomView?: boolean;
44
47
  // TODO: implement this props on iOS
@@ -47,5 +50,5 @@ export interface NativeProps extends ViewProps {
47
50
 
48
51
  export default codegenNativeComponent<NativeProps>(
49
52
  'RNSScreenStackHeaderConfig',
50
- {}
53
+ {},
51
54
  );
@@ -16,5 +16,5 @@ export interface NativeProps extends ViewProps {
16
16
 
17
17
  export default codegenNativeComponent<NativeProps>(
18
18
  'RNSScreenStackHeaderSubview',
19
- {}
19
+ {},
20
20
  );
@@ -7,13 +7,13 @@ import type {
7
7
  } from 'react-native/Libraries/Types/CodegenTypes';
8
8
  import codegenNativeCommands from 'react-native/Libraries/Utilities/codegenNativeCommands';
9
9
 
10
- type SearchBarEvent = Readonly<{}>;
10
+ export type SearchBarEvent = Readonly<{}>;
11
11
 
12
- type SearchButtonPressedEvent = Readonly<{
12
+ export type SearchButtonPressedEvent = Readonly<{
13
13
  text?: string;
14
14
  }>;
15
15
 
16
- type ChangeTextEvent = Readonly<{
16
+ export type ChangeTextEvent = Readonly<{
17
17
  text?: string;
18
18
  }>;
19
19
 
@@ -21,9 +21,9 @@ type SearchBarPlacement = 'automatic' | 'inline' | 'stacked';
21
21
 
22
22
  type AutoCapitalizeType = 'none' | 'words' | 'sentences' | 'characters';
23
23
 
24
- interface NativeProps extends ViewProps {
25
- onFocus?: DirectEventHandler<SearchBarEvent> | null;
26
- onBlur?: DirectEventHandler<SearchBarEvent> | null;
24
+ export interface NativeProps extends ViewProps {
25
+ onSearchFocus?: DirectEventHandler<SearchBarEvent> | null;
26
+ onSearchBlur?: DirectEventHandler<SearchBarEvent> | null;
27
27
  onSearchButtonPress?: DirectEventHandler<SearchButtonPressedEvent> | null;
28
28
  onCancelButtonPress?: DirectEventHandler<SearchBarEvent> | null;
29
29
  onChangeText?: DirectEventHandler<ChangeTextEvent> | null;
@@ -58,7 +58,7 @@ interface NativeCommands {
58
58
  clearText: (viewRef: React.ElementRef<ComponentType>) => void;
59
59
  toggleCancelButton: (
60
60
  viewRef: React.ElementRef<ComponentType>,
61
- flag: boolean
61
+ flag: boolean,
62
62
  ) => void;
63
63
  setText: (viewRef: React.ElementRef<ComponentType>, text: string) => void;
64
64
  cancelSearch: (viewRef: React.ElementRef<ComponentType>) => void;
@@ -40,7 +40,7 @@ const ScreenGestureDetector = ({
40
40
  const canPerformUpdates = makeMutable(false);
41
41
  const transitionAnimation = getAnimationForTransition(
42
42
  goBackGesture,
43
- customTransitionAnimation
43
+ customTransitionAnimation,
44
44
  );
45
45
  const screenTransitionConfig = makeMutable({
46
46
  stackTag: -1,
@@ -90,7 +90,7 @@ const ScreenGestureDetector = ({
90
90
  }, [currentRouteKey]);
91
91
 
92
92
  function computeProgress(
93
- event: GestureUpdateEvent<PanGestureHandlerEventPayload>
93
+ event: GestureUpdateEvent<PanGestureHandlerEventPayload>,
94
94
  ) {
95
95
  'worklet';
96
96
  let progress = 0;
@@ -114,10 +114,10 @@ const ScreenGestureDetector = ({
114
114
  progress = Math.abs(event.translationY / screenDimensions.height / 2);
115
115
  } else if (goBackGesture === 'twoDimensionalSwipe') {
116
116
  const progressX = Math.abs(
117
- event.translationX / screenDimensions.width / 2
117
+ event.translationX / screenDimensions.width / 2,
118
118
  );
119
119
  const progressY = Math.abs(
120
- event.translationY / screenDimensions.height / 2
120
+ event.translationY / screenDimensions.height / 2,
121
121
  );
122
122
  progress = Math.max(progressX, progressY);
123
123
  }
@@ -194,7 +194,7 @@ const ScreenGestureDetector = ({
194
194
  distanceX,
195
195
  requiredXDistance,
196
196
  distanceY,
197
- requiredYDistance
197
+ requiredYDistance,
198
198
  );
199
199
  const stackTag = screenTransitionConfig.value.stackTag;
200
200
  screenTransitionConfig.value.onFinishAnimation = () => {
@@ -19,14 +19,14 @@ const SupportedGestures = [
19
19
 
20
20
  export function getAnimationForTransition(
21
21
  goBackGesture: GoBackGesture | undefined,
22
- customTransitionAnimation: AnimatedScreenTransition | undefined
22
+ customTransitionAnimation: AnimatedScreenTransition | undefined,
23
23
  ) {
24
24
  let transitionAnimation = ScreenTransition.SwipeRight;
25
25
  if (customTransitionAnimation) {
26
26
  transitionAnimation = customTransitionAnimation;
27
27
  if (!goBackGesture) {
28
28
  throw new Error(
29
- '[RNScreens] You have to specify `goBackGesture` when using `transitionAnimation`.'
29
+ '[RNScreens] You have to specify `goBackGesture` when using `transitionAnimation`.',
30
30
  );
31
31
  }
32
32
  } else {
@@ -34,7 +34,7 @@ export function getAnimationForTransition(
34
34
  transitionAnimation = AnimationForGesture[goBackGesture];
35
35
  } else if (goBackGesture !== undefined) {
36
36
  throw new Error(
37
- `[RNScreens] Unknown goBackGesture parameter has been specified: ${goBackGesture}.`
37
+ `[RNScreens] Unknown goBackGesture parameter has been specified: ${goBackGesture}.`,
38
38
  );
39
39
  }
40
40
  }
@@ -43,7 +43,7 @@ export function getAnimationForTransition(
43
43
 
44
44
  export function checkBoundaries(
45
45
  goBackGesture: string | undefined,
46
- event: GestureUpdateEvent<PanGestureHandlerEventPayload>
46
+ event: GestureUpdateEvent<PanGestureHandlerEventPayload>,
47
47
  ) {
48
48
  'worklet';
49
49
  if (goBackGesture === 'swipeRight' && event.translationX < 0) {
@@ -62,7 +62,7 @@ export function checkIfTransitionCancelled(
62
62
  distanceX: number,
63
63
  requiredXDistance: number,
64
64
  distanceY: number,
65
- requiredYDistance: number
65
+ requiredYDistance: number,
66
66
  ) {
67
67
  'worklet';
68
68
  let isTransitionCanceled = false;
@@ -29,7 +29,7 @@ if (isFabric()) {
29
29
  }
30
30
 
31
31
  export function getShadowNodeWrapperAndTagFromRef(
32
- ref: React.Ref<NativeStackNavigatorProps> | React.Component
32
+ ref: React.Ref<NativeStackNavigatorProps> | React.Component,
33
33
  ) {
34
34
  const hostInstance = findHostInstance(ref as React.Component);
35
35
  return {
@@ -3,5 +3,5 @@ import { GestureProviderProps } from '../types';
3
3
 
4
4
  // context to be used when the user wants full screen swipe (see `gesture-handler` folder in repo)
5
5
  export const GHContext = React.createContext(
6
- (props: PropsWithChildren<GestureProviderProps>) => <>{props.children}</>
6
+ (props: PropsWithChildren<GestureProviderProps>) => <>{props.children}</>,
7
7
  );