react-native-screens 3.32.0 → 3.34.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.
- package/README.md +17 -13
- package/RNScreens.podspec +10 -52
- package/android/CMakeLists.txt +48 -4
- package/android/build.gradle +9 -81
- package/android/src/fabric/java/com/swmansion/rnscreens/FabricEnabledViewGroup.kt +25 -16
- package/android/src/fabric/java/com/swmansion/rnscreens/NativeProxy.kt +53 -0
- package/android/src/main/cpp/NativeProxy.cpp +51 -0
- package/android/src/main/cpp/NativeProxy.h +35 -0
- package/android/src/main/cpp/OnLoad.cpp +8 -0
- package/android/src/main/java/com/swmansion/rnscreens/CustomSearchView.kt +5 -2
- package/android/src/main/java/com/swmansion/rnscreens/CustomToolbar.kt +4 -1
- package/android/src/main/java/com/swmansion/rnscreens/FragmentBackPressOverrider.kt +2 -2
- package/android/src/main/java/com/swmansion/rnscreens/RNScreensPackage.kt +36 -17
- package/android/src/main/java/com/swmansion/rnscreens/Screen.kt +134 -38
- package/android/src/main/java/com/swmansion/rnscreens/ScreenContainer.kt +52 -30
- package/android/src/main/java/com/swmansion/rnscreens/ScreenContainerViewManager.kt +17 -7
- package/android/src/main/java/com/swmansion/rnscreens/ScreenEventDispatcher.kt +10 -2
- package/android/src/main/java/com/swmansion/rnscreens/ScreenFragment.kt +56 -27
- package/android/src/main/java/com/swmansion/rnscreens/ScreenFragmentWrapper.kt +8 -1
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt +50 -19
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragment.kt +60 -37
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragmentWrapper.kt +4 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfig.kt +85 -58
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfigViewManager.kt +128 -37
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubview.kt +19 -4
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubviewManager.kt +16 -10
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackViewManager.kt +28 -25
- package/android/src/main/java/com/swmansion/rnscreens/ScreenViewManager.kt +173 -78
- package/android/src/main/java/com/swmansion/rnscreens/ScreenWindowTraits.kt +59 -24
- package/android/src/main/java/com/swmansion/rnscreens/ScreensModule.kt +30 -8
- package/android/src/main/java/com/swmansion/rnscreens/ScreensShadowNode.kt +3 -1
- package/android/src/main/java/com/swmansion/rnscreens/SearchBarManager.kt +101 -50
- package/android/src/main/java/com/swmansion/rnscreens/SearchBarView.kt +29 -22
- package/android/src/main/java/com/swmansion/rnscreens/SearchViewFormatter.kt +7 -2
- package/android/src/main/java/com/swmansion/rnscreens/events/HeaderAttachedEvent.kt +4 -1
- package/android/src/main/java/com/swmansion/rnscreens/events/HeaderBackButtonClickedEvent.kt +4 -1
- package/android/src/main/java/com/swmansion/rnscreens/events/HeaderDetachedEvent.kt +4 -1
- package/android/src/main/java/com/swmansion/rnscreens/events/HeaderHeightChangeEvent.kt +5 -5
- package/android/src/main/java/com/swmansion/rnscreens/events/ScreenAppearEvent.kt +4 -1
- package/android/src/main/java/com/swmansion/rnscreens/events/ScreenDisappearEvent.kt +4 -1
- package/android/src/main/java/com/swmansion/rnscreens/events/ScreenDismissedEvent.kt +8 -4
- package/android/src/main/java/com/swmansion/rnscreens/events/ScreenTransitionProgressEvent.kt +7 -6
- package/android/src/main/java/com/swmansion/rnscreens/events/ScreenWillAppearEvent.kt +4 -1
- package/android/src/main/java/com/swmansion/rnscreens/events/ScreenWillDisappearEvent.kt +4 -1
- package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarBlurEvent.kt +4 -1
- package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarChangeTextEvent.kt +4 -3
- package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarCloseEvent.kt +4 -1
- package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarFocusEvent.kt +4 -1
- package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarOpenEvent.kt +4 -1
- package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarSearchButtonPressEvent.kt +9 -4
- package/android/src/main/java/com/swmansion/rnscreens/events/StackFinishTransitioningEvent.kt +4 -1
- package/android/src/main/java/com/swmansion/rnscreens/utils/DeviceUtils.kt +1 -5
- package/android/src/main/java/com/swmansion/rnscreens/utils/ScreenDummyLayoutHelper.kt +245 -0
- package/android/src/main/jni/CMakeLists.txt +5 -4
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerDelegate.java +3 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerInterface.java +1 -0
- package/android/src/paper/java/com/swmansion/rnscreens/FabricEnabledViewGroup.kt +10 -5
- package/android/src/paper/java/com/swmansion/rnscreens/NativeProxy.kt +19 -0
- package/android/src/paper/java/com/swmansion/rnscreens/NativeScreensModuleSpec.java +4 -0
- package/common/cpp/react/renderer/components/rnscreens/FrameCorrectionModes.h +51 -0
- package/common/cpp/react/renderer/components/rnscreens/RNSModalScreenShadowNode.cpp +2 -1
- package/common/cpp/react/renderer/components/rnscreens/RNSModalScreenShadowNode.h +1 -1
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenComponentDescriptor.h +140 -1
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.cpp +51 -1
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.h +23 -1
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenState.cpp +20 -0
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenState.h +23 -1
- package/common/cpp/react/renderer/components/rnscreens/utils/RectUtil.h +36 -0
- package/cpp/RNSScreenRemovalListener.cpp +25 -0
- package/cpp/RNSScreenRemovalListener.h +20 -0
- package/ios/RNSConvert.h +1 -0
- package/ios/RNSModalScreen.mm +22 -0
- package/ios/RNSModule.mm +1 -1
- package/ios/RNSScreen.h +2 -1
- package/ios/RNSScreen.mm +27 -19
- package/ios/RNSScreenStack.mm +24 -77
- package/ios/RNSScreenStackAnimator.mm +43 -6
- package/ios/RNSScreenStackHeaderConfig.mm +49 -11
- package/ios/RNSScreenStackHeaderSubview.mm +8 -0
- package/ios/utils/UIView+RNSUtility.h +23 -0
- package/ios/utils/UIView+RNSUtility.mm +55 -0
- package/lib/commonjs/components/ScreenStack.js +8 -1
- package/lib/commonjs/components/ScreenStack.js.map +1 -1
- package/lib/commonjs/fabric/ModalScreenNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/ScreenNativeComponent.js.map +1 -1
- package/lib/commonjs/native-stack/views/NativeStackView.js +2 -0
- package/lib/commonjs/native-stack/views/NativeStackView.js.map +1 -1
- package/lib/module/components/ScreenStack.js +8 -1
- package/lib/module/components/ScreenStack.js.map +1 -1
- package/lib/module/fabric/ModalScreenNativeComponent.js.map +1 -1
- package/lib/module/fabric/ScreenNativeComponent.js.map +1 -1
- package/lib/module/native-stack/views/NativeStackView.js +2 -0
- package/lib/module/native-stack/views/NativeStackView.js.map +1 -1
- package/lib/typescript/components/ScreenStack.d.ts.map +1 -1
- package/lib/typescript/fabric/ModalScreenNativeComponent.d.ts +1 -0
- package/lib/typescript/fabric/ModalScreenNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/ScreenNativeComponent.d.ts +1 -0
- package/lib/typescript/fabric/ScreenNativeComponent.d.ts.map +1 -1
- package/lib/typescript/native-stack/types.d.ts +10 -0
- package/lib/typescript/native-stack/types.d.ts.map +1 -1
- package/lib/typescript/native-stack/views/NativeStackView.d.ts.map +1 -1
- package/lib/typescript/types.d.ts +10 -0
- package/lib/typescript/types.d.ts.map +1 -1
- package/native-stack/README.md +110 -99
- package/package.json +6 -3
- package/react-native.config.js +17 -15
- package/src/TransitionProgressContext.tsx +1 -1
- package/src/components/Screen.tsx +4 -4
- package/src/components/ScreenStack.tsx +11 -1
- package/src/components/ScreenStackHeaderConfig.tsx +5 -5
- package/src/components/ScreenStackHeaderConfig.web.tsx +6 -6
- package/src/components/SearchBar.tsx +4 -4
- package/src/core.ts +1 -1
- package/src/fabric/ModalScreenNativeComponent.ts +1 -0
- package/src/fabric/ScreenNativeComponent.ts +1 -0
- package/src/fabric/ScreenNavigationContainerNativeComponent.ts +1 -1
- package/src/fabric/ScreenStackHeaderConfigNativeComponent.ts +1 -1
- package/src/fabric/ScreenStackHeaderSubviewNativeComponent.ts +1 -1
- package/src/fabric/SearchBarNativeComponent.ts +1 -1
- package/src/gesture-handler/ScreenGestureDetector.tsx +5 -5
- package/src/gesture-handler/constraints.ts +5 -5
- package/src/gesture-handler/fabricUtils.ts +1 -1
- package/src/native-stack/contexts/GHContext.tsx +1 -1
- package/src/native-stack/navigators/createNativeStackNavigator.tsx +3 -3
- package/src/native-stack/types.tsx +14 -4
- package/src/native-stack/utils/getDefaultHeaderHeight.tsx +1 -1
- package/src/native-stack/utils/getStatusBarHeight.tsx +1 -1
- package/src/native-stack/utils/useAnimatedHeaderHeight.tsx +1 -1
- package/src/native-stack/utils/useBackPressSubscription.tsx +1 -1
- package/src/native-stack/utils/useHeaderHeight.tsx +1 -1
- package/src/native-stack/views/FontProcessor.tsx +1 -1
- package/src/native-stack/views/HeaderConfig.tsx +1 -1
- package/src/native-stack/views/NativeStackView.tsx +11 -9
- package/src/reanimated/ReanimatedHeaderHeightContext.tsx +1 -1
- package/src/reanimated/ReanimatedNativeStackScreen.tsx +5 -5
- package/src/reanimated/ReanimatedScreen.tsx +2 -2
- package/src/reanimated/ReanimatedScreenProvider.tsx +1 -1
- package/src/reanimated/useReanimatedHeaderHeight.tsx +1 -1
- package/src/reanimated/useReanimatedTransitionProgress.tsx +1 -1
- package/src/types.tsx +15 -5
- package/src/useTransitionProgress.tsx +1 -1
- package/windows/README.md +4 -1
package/native-stack/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Native Stack Navigator
|
|
2
2
|
|
|
3
|
-
> **_NOTE:_**
|
|
3
|
+
> **_NOTE:_** This README is dedicated for using `native-stack` with React Navigation **v5**. For using `native-stack` in React Navigation **v6** please refer to the [Native Stack Navigator part of React Navigation documentation](https://reactnavigation.org/docs/native-stack-navigator).
|
|
4
4
|
|
|
5
5
|
Provides a way for your app to transition between screens where each new screen is placed on top of a stack.
|
|
6
6
|
|
|
@@ -81,7 +81,8 @@ Boolean indicating whether to show the menu on longPress of iOS >= 14 back butto
|
|
|
81
81
|
|
|
82
82
|
#### `backButtonDisplayMode` (iOS only)
|
|
83
83
|
|
|
84
|
-
Enum value indicating display mode of **default** back button. It works on iOS >= 14, and is used only when none of:
|
|
84
|
+
Enum value indicating display mode of **default** back button. It works on iOS >= 14, and is used only when none of: `backTitleFontFamily`, `backTitleFontSize`, `disableBackButtonMenu` or `backTitle` is set. Otherwise, when the button is customized, under the hood we use iOS native `backButtonItem` which overrides `backButtonDisplayMode`. Read more [#2123](https://github.com/software-mansion/react-native-screens/pull/2123). Possible options:
|
|
85
|
+
|
|
85
86
|
- `default` – show given back button previous controller title, system generic or just icon based on available space
|
|
86
87
|
- `generic` – show given system generic or just icon based on available space
|
|
87
88
|
- `minimal` – show just an icon
|
|
@@ -90,13 +91,19 @@ Enum value indicating display mode of **default** back button. It works on iOS >
|
|
|
90
91
|
|
|
91
92
|
Boolean indicating whether the swipe gesture should work on whole screen. Swiping with this option results in the same transition animation as `simple_push` by default. It can be changed to other custom animations with `customAnimationOnSwipe` prop, but default iOS swipe animation is not achievable due to usage of custom recognizer. Defaults to `false`.
|
|
92
93
|
|
|
94
|
+
### `fullScreenSwipeShadowEnabled` (iOS only)
|
|
95
|
+
|
|
96
|
+
Boolean indicating whether the full screen dismiss gesture has shadow under view during transition. The gesture uses custom transition and thus
|
|
97
|
+
doesn't have a shadow by default. When enabled, a custom shadow view is added during the transition which tries to mimic the
|
|
98
|
+
default iOS shadow. Defaults to `false`.
|
|
99
|
+
|
|
93
100
|
#### `gestureEnabled` (iOS only)
|
|
94
101
|
|
|
95
102
|
Whether you can use gestures to dismiss this screen. Defaults to `true`.
|
|
96
103
|
|
|
97
104
|
#### `gestureResponseDistance` (iOS only)
|
|
98
105
|
|
|
99
|
-
Use it to restrict the distance from the edges of screen in which the gesture should be recognized. To be used alongside `fullScreenSwipeEnabled`. The responsive area is covered with 4 values: `start`, `end`, `top`, `bottom`. Example usage:
|
|
106
|
+
Use it to restrict the distance from the edges of screen in which the gesture should be recognized. To be used alongside `fullScreenSwipeEnabled`. The responsive area is covered with 4 values: `start`, `end`, `top`, `bottom`. Example usage:
|
|
100
107
|
|
|
101
108
|
```tsx
|
|
102
109
|
gestureResponseDistance: {
|
|
@@ -196,13 +203,13 @@ Style object for header title. Supported properties:
|
|
|
196
203
|
|
|
197
204
|
#### `headerTopInsetEnabled` (Android only)
|
|
198
205
|
|
|
199
|
-
A Boolean to that lets you opt out of insetting the header. You may want to
|
|
206
|
+
A Boolean to that lets you opt out of insetting the header. You may want to \* set this to `false` if you use an opaque status bar. Defaults to `true`. Insets are always applied on iOS because the header cannot be opaque.
|
|
200
207
|
|
|
201
208
|
#### `headerTranslucent`
|
|
202
209
|
|
|
203
210
|
Boolean indicating whether the navigation bar is translucent.
|
|
204
211
|
|
|
205
|
-
####
|
|
212
|
+
#### `hideKeyboardOnSwipe` (iOS only)
|
|
206
213
|
|
|
207
214
|
Whether the keyboard should hide when swiping to the previous screen. Defaults to `false`.
|
|
208
215
|
|
|
@@ -229,14 +236,15 @@ Sets the visibility of the navigation bar. Defaults to `false`.
|
|
|
229
236
|
|
|
230
237
|
How should the screen replacing another screen animate.
|
|
231
238
|
The following values are currently supported:
|
|
232
|
-
|
|
233
|
-
|
|
239
|
+
|
|
240
|
+
- `push` – the new screen will perform push animation.
|
|
241
|
+
- `pop` – the new screen will perform pop animation.
|
|
234
242
|
|
|
235
243
|
Defaults to `pop`.
|
|
236
244
|
|
|
237
245
|
#### `sheetAllowedDetents` (iOS only)
|
|
238
246
|
|
|
239
|
-
Describes heights where a sheet can rest.
|
|
247
|
+
Describes heights where a sheet can rest.
|
|
240
248
|
Works only when `stackPresentation` is set to `formSheet`.
|
|
241
249
|
|
|
242
250
|
Available values:
|
|
@@ -271,16 +279,16 @@ Defaults to `false`.
|
|
|
271
279
|
|
|
272
280
|
#### `sheetLargestUndimmedDetent` (iOS only)
|
|
273
281
|
|
|
274
|
-
|
|
275
|
-
|
|
282
|
+
The largest sheet detent for which a view underneath won't be dimmed.
|
|
283
|
+
Works only when `stackPresentation` is set to `formSheet`.
|
|
276
284
|
|
|
277
|
-
|
|
285
|
+
If this prop is set to:
|
|
278
286
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
287
|
+
- `large` - the view underneath won't be dimmed at any detent level
|
|
288
|
+
- `medium` - the view underneath will be dimmed only when detent level is `large`
|
|
289
|
+
- `all` - the view underneath will be dimmed for any detent level
|
|
282
290
|
|
|
283
|
-
|
|
291
|
+
Defaults to `all`.
|
|
284
292
|
|
|
285
293
|
#### `stackAnimation`
|
|
286
294
|
|
|
@@ -318,6 +326,7 @@ Using `containedModal` and `containedTransparentModal` with other types of modal
|
|
|
318
326
|
#### `swipeDirection` (iOS only)
|
|
319
327
|
|
|
320
328
|
Sets the direction in which you should swipe to dismiss the screen. The following values are supported:
|
|
329
|
+
|
|
321
330
|
- `vertical` – dismiss screen vertically
|
|
322
331
|
- `horizontal` – dismiss screen horizontally (default)
|
|
323
332
|
|
|
@@ -342,25 +351,28 @@ Defaults to `false`. When `enableFreeze()` is run at the top of the application
|
|
|
342
351
|
#### `useTransitionProgress`
|
|
343
352
|
|
|
344
353
|
Hook providing context value of transition progress of the current screen to be used with `react-native` `Animated`. It consists of 2 values:
|
|
354
|
+
|
|
345
355
|
- `progress` - `Animated.Value` between `0.0` and `1.0` with the progress of the current transition.
|
|
346
356
|
- `closing` - `Animated.Value` of `1` or `0` indicating if the current screen is being navigated into or from.
|
|
347
357
|
- `goingForward` - `Animated.Value` of `1` or `0` indicating if the current transition is pushing or removing screens.
|
|
348
358
|
|
|
349
359
|
```jsx
|
|
350
|
-
import {Animated} from 'react-native';
|
|
351
|
-
import {useTransitionProgress} from 'react-native-screens';
|
|
360
|
+
import { Animated } from 'react-native';
|
|
361
|
+
import { useTransitionProgress } from 'react-native-screens';
|
|
352
362
|
|
|
353
363
|
function Home() {
|
|
354
|
-
const {progress} = useTransitionProgress();
|
|
364
|
+
const { progress } = useTransitionProgress();
|
|
355
365
|
|
|
356
366
|
const opacity = progress.interpolate({
|
|
357
367
|
inputRange: [0, 0.5, 1],
|
|
358
|
-
outputRange: [1.0, 0.0
|
|
368
|
+
outputRange: [1.0, 0.0, 1.0],
|
|
359
369
|
extrapolate: 'clamp',
|
|
360
370
|
});
|
|
361
371
|
|
|
362
372
|
return (
|
|
363
|
-
<Animated.View
|
|
373
|
+
<Animated.View
|
|
374
|
+
style={{ opacity, height: 50, width: '100%', backgroundColor: 'green' }}
|
|
375
|
+
/>
|
|
364
376
|
);
|
|
365
377
|
}
|
|
366
378
|
```
|
|
@@ -368,14 +380,15 @@ function Home() {
|
|
|
368
380
|
#### `useReanimatedTransitionProgress`
|
|
369
381
|
|
|
370
382
|
A callback called every frame during the transition of screens to be used with `react-native-reanimated` version `2.x`. It consists of 2 shared values:
|
|
383
|
+
|
|
371
384
|
- `progress` - between `0.0` and `1.0` with the progress of the current transition.
|
|
372
|
-
- `closing` -
|
|
385
|
+
- `closing` - `1` or `0` indicating if the current screen is being navigated into or from.
|
|
373
386
|
- `goingForward` - `1` or `0` indicating if the current transition is pushing or removing screens.
|
|
374
387
|
|
|
375
388
|
In order to use it, you need to have `react-native-reanimated` version `2.x` installed in your project and wrap your code with `ReanimatedScreenProvider`, like this:
|
|
376
389
|
|
|
377
390
|
```jsx
|
|
378
|
-
import {ReanimatedScreenProvider} from 'react-native-screens/reanimated';
|
|
391
|
+
import { ReanimatedScreenProvider } from 'react-native-screens/reanimated';
|
|
379
392
|
|
|
380
393
|
export default function App() {
|
|
381
394
|
return (
|
|
@@ -389,12 +402,20 @@ export default function App() {
|
|
|
389
402
|
Then you can use `useReanimatedTransitionProgress` to get the shared values:
|
|
390
403
|
|
|
391
404
|
```jsx
|
|
392
|
-
import {useReanimatedTransitionProgress} from 'react-native-screens/reanimated';
|
|
393
|
-
import Animated, {
|
|
405
|
+
import { useReanimatedTransitionProgress } from 'react-native-screens/reanimated';
|
|
406
|
+
import Animated, {
|
|
407
|
+
useAnimatedStyle,
|
|
408
|
+
useDerivedValue,
|
|
409
|
+
} from 'react-native-reanimated';
|
|
394
410
|
|
|
395
411
|
function Home() {
|
|
396
412
|
const reaProgress = useReanimatedTransitionProgress();
|
|
397
|
-
const sv = useDerivedValue(
|
|
413
|
+
const sv = useDerivedValue(
|
|
414
|
+
() =>
|
|
415
|
+
(reaProgress.progress.value < 0.5
|
|
416
|
+
? reaProgress.progress.value * 50
|
|
417
|
+
: (1 - reaProgress.progress.value) * 50) + 50,
|
|
418
|
+
);
|
|
398
419
|
const reaStyle = useAnimatedStyle(() => {
|
|
399
420
|
return {
|
|
400
421
|
width: sv.value,
|
|
@@ -403,9 +424,7 @@ function Home() {
|
|
|
403
424
|
};
|
|
404
425
|
});
|
|
405
426
|
|
|
406
|
-
return
|
|
407
|
-
<Animated.View style={reaStyle} />
|
|
408
|
-
);
|
|
427
|
+
return <Animated.View style={reaStyle} />;
|
|
409
428
|
}
|
|
410
429
|
```
|
|
411
430
|
|
|
@@ -413,10 +432,11 @@ function Home() {
|
|
|
413
432
|
|
|
414
433
|
With `native-stack`, the status bar and screen orientation can be managed by `UIViewController` on iOS. On Android, the status bar and screen orientation can be managed by `FragmentActivity`. On iOS, it requires:
|
|
415
434
|
|
|
416
|
-
1. For status bar managment: enabling (or deleting) `View controller-based status bar appearance` in your Info.plist file (it disables the option to use React Native's `StatusBar` component).
|
|
435
|
+
1. For status bar managment: enabling (or deleting) `View controller-based status bar appearance` in your Info.plist file (it disables the option to use React Native's `StatusBar` component).
|
|
417
436
|
2. For both status bar and orientation managment: adding `#import <RNScreens/UIViewController+RNScreens.h>` in your project's `AppDelegate.m` (you can see this change applied in the `AppDelegate.m` of `Example` project).
|
|
418
437
|
|
|
419
438
|
On Android, no additional setup is required, although, you should keep in mind that once you set the orientation or status bar props, `react-native-screens` will manage them on every screen, so you shouldn't use other methods of manipulating them then.
|
|
439
|
+
|
|
420
440
|
#### `screenOrientation`
|
|
421
441
|
|
|
422
442
|
Sets the current screen's available orientations and forces rotation if current orientation is not included. On iOS, if you have supported orientations set in `info.plist`, they will take precedence over this prop. Possible values:
|
|
@@ -462,14 +482,14 @@ Sets the translucency of the status bar (similar to the `StatusBar` component).
|
|
|
462
482
|
|
|
463
483
|
The search bar is just a `searchBar` property that can be specified in the navigator's `screenOptions` or an individual screen's `options`. Search bars are rarely static so normally it is controlled by passing an object to `searchBar` navigation option in the component's body.
|
|
464
484
|
|
|
465
|
-
Example:
|
|
485
|
+
Example:
|
|
466
486
|
|
|
467
487
|
```js
|
|
468
488
|
React.useLayoutEffect(() => {
|
|
469
489
|
navigation.setOptions({
|
|
470
490
|
searchBar: {
|
|
471
491
|
// search bar options
|
|
472
|
-
}
|
|
492
|
+
},
|
|
473
493
|
});
|
|
474
494
|
}, [navigation]);
|
|
475
495
|
```
|
|
@@ -510,7 +530,7 @@ The text to be used instead of default `Cancel` button text.
|
|
|
510
530
|
|
|
511
531
|
#### `disableBackButtonOverride` (Android only)
|
|
512
532
|
|
|
513
|
-
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`
|
|
533
|
+
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`
|
|
514
534
|
|
|
515
535
|
#### `hideNavigationBar` (iOS only)
|
|
516
536
|
|
|
@@ -529,12 +549,13 @@ Defaults to `true`.
|
|
|
529
549
|
This prop is used to change type of the input and keyboard. Default value is `'text'`.
|
|
530
550
|
|
|
531
551
|
All values:
|
|
552
|
+
|
|
532
553
|
- `'text'` - normal text input
|
|
533
554
|
- `'number'` - number input
|
|
534
555
|
- `'email'` - email input
|
|
535
556
|
- `'phone'` - phone input
|
|
536
557
|
|
|
537
|
-
####
|
|
558
|
+
#### `obscureBackground` (iOS only)
|
|
538
559
|
|
|
539
560
|
Boolean indicating whether to obscure the underlying content with semi-transparent overlay.
|
|
540
561
|
|
|
@@ -560,11 +581,12 @@ const [search, setSearch] = React.useState('');
|
|
|
560
581
|
React.useLayoutEffect(() => {
|
|
561
582
|
navigation.setOptions({
|
|
562
583
|
searchBar: {
|
|
563
|
-
onChangeText:
|
|
564
|
-
}
|
|
584
|
+
onChangeText: event => setSearch(event.nativeEvent.text),
|
|
585
|
+
},
|
|
565
586
|
});
|
|
566
587
|
}, [navigation]);
|
|
567
588
|
```
|
|
589
|
+
|
|
568
590
|
#### `onClose` (Android only)
|
|
569
591
|
|
|
570
592
|
A callback that gets called when search bar is closing
|
|
@@ -590,15 +612,15 @@ Defaults to an empty string.
|
|
|
590
612
|
#### `placement` (iOS only)
|
|
591
613
|
|
|
592
614
|
Position of the search bar
|
|
593
|
-
|
|
615
|
+
|
|
594
616
|
Supported values:
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
617
|
+
|
|
618
|
+
- `automatic` - the search bar is placed according to current layout
|
|
619
|
+
- `inline` - the search bar is placed on the trailing edge of navigation bar
|
|
620
|
+
- `stacked` - the search bar is placed below the other content in navigation bar
|
|
599
621
|
|
|
600
622
|
Defaults to `stacked`
|
|
601
|
-
|
|
623
|
+
|
|
602
624
|
#### `textColor`
|
|
603
625
|
|
|
604
626
|
The search field text color.
|
|
@@ -619,12 +641,12 @@ Show the search hint icon when search bar is focused. (Android only)
|
|
|
619
641
|
|
|
620
642
|
A React ref to imperatively modify search bar. Supported actions:
|
|
621
643
|
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
644
|
+
- `focus` - focus on search bar
|
|
645
|
+
- `blur` - remove focus from search bar
|
|
646
|
+
- `clearText` - clear text in search bar
|
|
647
|
+
- `setText` - set search bar's content to given string
|
|
648
|
+
- `cancelSearch` - cancel search in search bar.
|
|
649
|
+
- `toggleCancelButton` (iOS only) - toggle cancel button display near search bar.
|
|
628
650
|
|
|
629
651
|
### Events
|
|
630
652
|
|
|
@@ -639,16 +661,13 @@ Event which fires when the screen appears.
|
|
|
639
661
|
Example:
|
|
640
662
|
|
|
641
663
|
```js
|
|
642
|
-
React.useEffect(
|
|
643
|
-
(
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
},
|
|
650
|
-
[navigation]
|
|
651
|
-
);
|
|
664
|
+
React.useEffect(() => {
|
|
665
|
+
const unsubscribe = navigation.addListener('appear', e => {
|
|
666
|
+
// Do something
|
|
667
|
+
});
|
|
668
|
+
|
|
669
|
+
return unsubscribe;
|
|
670
|
+
}, [navigation]);
|
|
652
671
|
```
|
|
653
672
|
|
|
654
673
|
#### `dismiss`
|
|
@@ -658,16 +677,13 @@ Event which fires when the current screen is dismissed by hardware back (on Andr
|
|
|
658
677
|
Example:
|
|
659
678
|
|
|
660
679
|
```js
|
|
661
|
-
React.useEffect(
|
|
662
|
-
(
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
},
|
|
669
|
-
[navigation]
|
|
670
|
-
);
|
|
680
|
+
React.useEffect(() => {
|
|
681
|
+
const unsubscribe = navigation.addListener('dismiss', e => {
|
|
682
|
+
// Do something
|
|
683
|
+
});
|
|
684
|
+
|
|
685
|
+
return unsubscribe;
|
|
686
|
+
}, [navigation]);
|
|
671
687
|
```
|
|
672
688
|
|
|
673
689
|
#### `transitionStart`
|
|
@@ -681,20 +697,17 @@ Event data:
|
|
|
681
697
|
Example:
|
|
682
698
|
|
|
683
699
|
```js
|
|
684
|
-
React.useEffect(
|
|
685
|
-
(
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
},
|
|
696
|
-
[navigation]
|
|
697
|
-
);
|
|
700
|
+
React.useEffect(() => {
|
|
701
|
+
const unsubscribe = navigation.addListener('transitionStart', e => {
|
|
702
|
+
if (e.data.closing) {
|
|
703
|
+
// Will be dismissed
|
|
704
|
+
} else {
|
|
705
|
+
// Will appear
|
|
706
|
+
}
|
|
707
|
+
});
|
|
708
|
+
|
|
709
|
+
return unsubscribe;
|
|
710
|
+
}, [navigation]);
|
|
698
711
|
```
|
|
699
712
|
|
|
700
713
|
#### `transitionEnd`
|
|
@@ -708,20 +721,17 @@ Event data:
|
|
|
708
721
|
Example:
|
|
709
722
|
|
|
710
723
|
```js
|
|
711
|
-
React.useEffect(
|
|
712
|
-
(
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
},
|
|
723
|
-
[navigation]
|
|
724
|
-
);
|
|
724
|
+
React.useEffect(() => {
|
|
725
|
+
const unsubscribe = navigation.addListener('transitionEnd', e => {
|
|
726
|
+
if (e.data.closing) {
|
|
727
|
+
// Was dismissed
|
|
728
|
+
} else {
|
|
729
|
+
// Did appear
|
|
730
|
+
}
|
|
731
|
+
});
|
|
732
|
+
|
|
733
|
+
return unsubscribe;
|
|
734
|
+
}, [navigation]);
|
|
725
735
|
```
|
|
726
736
|
|
|
727
737
|
### Helpers
|
|
@@ -760,9 +770,10 @@ navigation.popToTop();
|
|
|
760
770
|
### Measuring header's height
|
|
761
771
|
|
|
762
772
|
To measure header's height, you can use the `useHeaderHeight`, `useAnimatedHeaderHeight` or `useReanimatedHeaderHeight` hook.
|
|
773
|
+
|
|
763
774
|
- `useHeaderHeight` returns the static header's height. The value provided by this hook changes when screen appears, when there's a change in header options or screen orientation.
|
|
764
775
|
Use this hook if you're sure your header height won't change dynamically, or when the screen is heavy.
|
|
765
|
-
- `useAnimatedHeaderHeight` dynamically calculates the header's height. The value provided by this hook changes with every view layout (such as shrinking a large header into small one with a ScrollView). It returns an Animated.Value.
|
|
776
|
+
- `useAnimatedHeaderHeight` dynamically calculates the header's height. The value provided by this hook changes with every view layout (such as shrinking a large header into small one with a ScrollView). It returns an Animated.Value.
|
|
766
777
|
Please beware of using this hook in heavy components, as it may result in performance issues.
|
|
767
778
|
- `useReanimatedHeaderHeight` also dynamically calculates the header's height but uses React Native Reanimated under the hood. It returns an Animated.SharedValue.
|
|
768
779
|
Make sure to wrap your Stack.Navigator with `ReanimatedScreenProvider` before using this hook.
|
|
@@ -771,13 +782,13 @@ We recommend using `useReanimatedHeaderHeight` rather than `useAnimatedHeaderHei
|
|
|
771
782
|
|
|
772
783
|
```tsx
|
|
773
784
|
// for using useHeaderHeight
|
|
774
|
-
import {useHeaderHeight} from 'react-native-screens/native-stack';
|
|
785
|
+
import { useHeaderHeight } from 'react-native-screens/native-stack';
|
|
775
786
|
|
|
776
787
|
// for using useAnimatedHeaderHeight
|
|
777
|
-
import {useAnimatedHeaderHeight} from 'react-native-screens/native-stack';
|
|
788
|
+
import { useAnimatedHeaderHeight } from 'react-native-screens/native-stack';
|
|
778
789
|
|
|
779
790
|
// for using useReanimatedHeaderHeight
|
|
780
|
-
import {useReanimatedHeaderHeight} from 'react-native-screens/reanimated';
|
|
791
|
+
import { useReanimatedHeaderHeight } from 'react-native-screens/reanimated';
|
|
781
792
|
```
|
|
782
793
|
|
|
783
794
|
## Example
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-screens",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.34.0",
|
|
4
4
|
"description": "Native navigation primitives for your React Native app.",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"submodules": "git submodule update --init --recursive && (cd react-navigation && yarn)",
|
|
@@ -18,7 +18,9 @@
|
|
|
18
18
|
"lint-android": "./android/gradlew -p android spotlessCheck -q",
|
|
19
19
|
"lint": "yarn lint-js && yarn lint-android",
|
|
20
20
|
"release": "yarn prepare && npm login && release-it",
|
|
21
|
-
"prepare": "bob build && husky install"
|
|
21
|
+
"prepare": "bob build && husky install",
|
|
22
|
+
"architectures-consistency-check": "node ./scripts/codegen-check-consistency.js",
|
|
23
|
+
"sync-architectures": "node ./scripts/codegen-sync-archs.js"
|
|
22
24
|
},
|
|
23
25
|
"main": "lib/commonjs/index",
|
|
24
26
|
"module": "lib/module/index",
|
|
@@ -127,7 +129,8 @@
|
|
|
127
129
|
"cpp/**/*.{h,cpp}": "yarn format-cpp",
|
|
128
130
|
"android/src/main/cpp/.{cpp, h}": "yarn format-android-cpp",
|
|
129
131
|
"android/**/*.kt": "yarn format-android",
|
|
130
|
-
"ios/**/*.{h,m,mm,cpp}": "yarn format-ios"
|
|
132
|
+
"ios/**/*.{h,m,mm,cpp}": "yarn format-ios",
|
|
133
|
+
"src/fabric/*.ts": "yarn sync-architectures"
|
|
131
134
|
},
|
|
132
135
|
"react-native-builder-bob": {
|
|
133
136
|
"source": "src",
|
package/react-native.config.js
CHANGED
|
@@ -11,20 +11,22 @@ try {
|
|
|
11
11
|
module.exports = {
|
|
12
12
|
dependency: {
|
|
13
13
|
platforms: {
|
|
14
|
-
android: supportsCodegenConfig
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
14
|
+
android: supportsCodegenConfig
|
|
15
|
+
? {
|
|
16
|
+
componentDescriptors: [
|
|
17
|
+
'RNSFullWindowOverlayComponentDescriptor',
|
|
18
|
+
'RNSScreenContainerComponentDescriptor',
|
|
19
|
+
'RNSScreenNavigationContainerComponentDescriptor',
|
|
20
|
+
'RNSScreenStackHeaderConfigComponentDescriptor',
|
|
21
|
+
'RNSScreenStackHeaderSubviewComponentDescriptor',
|
|
22
|
+
'RNSScreenStackComponentDescriptor',
|
|
23
|
+
'RNSSearchBarComponentDescriptor',
|
|
24
|
+
'RNSScreenComponentDescriptor',
|
|
25
|
+
'RNSModalScreenComponentDescriptor',
|
|
26
|
+
],
|
|
27
|
+
cmakeListsPath: '../android/src/main/jni/CMakeLists.txt',
|
|
28
|
+
}
|
|
29
|
+
: {},
|
|
28
30
|
},
|
|
29
31
|
},
|
|
30
|
-
}
|
|
32
|
+
};
|
|
@@ -19,7 +19,7 @@ export const NativeScreen: React.ComponentType<ScreenProps> =
|
|
|
19
19
|
ScreenNativeComponent as React.ComponentType<ScreenProps>;
|
|
20
20
|
const AnimatedNativeScreen = Animated.createAnimatedComponent(NativeScreen);
|
|
21
21
|
const AnimatedNativeModalScreen = Animated.createAnimatedComponent(
|
|
22
|
-
ModalScreenNativeComponent as React.ComponentType<ScreenProps
|
|
22
|
+
ModalScreenNativeComponent as React.ComponentType<ScreenProps>,
|
|
23
23
|
);
|
|
24
24
|
|
|
25
25
|
// Incomplete type, all accessible properties available at:
|
|
@@ -98,7 +98,7 @@ export const InnerScreen = React.forwardRef<View, ScreenProps>(
|
|
|
98
98
|
|
|
99
99
|
if (active !== undefined && activityState === undefined) {
|
|
100
100
|
console.warn(
|
|
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'
|
|
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',
|
|
102
102
|
);
|
|
103
103
|
activityState = active !== 0 ? 2 : 0; // in the new version, we need one of the screens to have value of 2 after the transition
|
|
104
104
|
}
|
|
@@ -151,7 +151,7 @@ export const InnerScreen = React.forwardRef<View, ScreenProps>(
|
|
|
151
151
|
},
|
|
152
152
|
},
|
|
153
153
|
],
|
|
154
|
-
{ useNativeDriver: true }
|
|
154
|
+
{ useNativeDriver: true },
|
|
155
155
|
)
|
|
156
156
|
}
|
|
157
157
|
onGestureCancel={
|
|
@@ -197,7 +197,7 @@ export const InnerScreen = React.forwardRef<View, ScreenProps>(
|
|
|
197
197
|
/>
|
|
198
198
|
);
|
|
199
199
|
}
|
|
200
|
-
}
|
|
200
|
+
},
|
|
201
201
|
);
|
|
202
202
|
|
|
203
203
|
// context to be used when the user wants to use enhanced implementation
|
|
@@ -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 &&
|
|
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<
|