@react-navigation/stack 7.0.0-alpha.9 → 7.0.0-rc.1

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 (160) hide show
  1. package/lib/commonjs/TransitionConfigs/CardStyleInterpolators.js +114 -67
  2. package/lib/commonjs/TransitionConfigs/CardStyleInterpolators.js.map +1 -1
  3. package/lib/commonjs/TransitionConfigs/HeaderStyleInterpolators.js +39 -39
  4. package/lib/commonjs/TransitionConfigs/HeaderStyleInterpolators.js.map +1 -1
  5. package/lib/commonjs/TransitionConfigs/TransitionPresets.js +24 -2
  6. package/lib/commonjs/TransitionConfigs/TransitionPresets.js.map +1 -1
  7. package/lib/commonjs/TransitionConfigs/TransitionSpecs.js +31 -3
  8. package/lib/commonjs/TransitionConfigs/TransitionSpecs.js.map +1 -1
  9. package/lib/commonjs/index.js +1 -1
  10. package/lib/commonjs/index.js.map +1 -1
  11. package/lib/commonjs/navigators/createStackNavigator.js +18 -17
  12. package/lib/commonjs/navigators/createStackNavigator.js.map +1 -1
  13. package/lib/commonjs/types.js.map +1 -1
  14. package/lib/commonjs/utils/CardAnimationContext.js +1 -1
  15. package/lib/commonjs/utils/CardAnimationContext.js.map +1 -1
  16. package/lib/commonjs/utils/GestureHandlerRefContext.js +1 -1
  17. package/lib/commonjs/utils/GestureHandlerRefContext.js.map +1 -1
  18. package/lib/commonjs/utils/ModalPresentationContext.js +1 -1
  19. package/lib/commonjs/utils/ModalPresentationContext.js.map +1 -1
  20. package/lib/commonjs/utils/conditional.js.map +1 -1
  21. package/lib/commonjs/utils/findLastIndex.js.map +1 -1
  22. package/lib/commonjs/utils/getDistanceForDirection.js.map +1 -1
  23. package/lib/commonjs/utils/getInvertedMultiplier.js.map +1 -1
  24. package/lib/commonjs/utils/getModalRoutesKeys.js +17 -0
  25. package/lib/commonjs/utils/getModalRoutesKeys.js.map +1 -0
  26. package/lib/commonjs/utils/memoize.js +1 -4
  27. package/lib/commonjs/utils/memoize.js.map +1 -1
  28. package/lib/commonjs/utils/throttle.js +18 -0
  29. package/lib/commonjs/utils/throttle.js.map +1 -0
  30. package/lib/commonjs/utils/useCardAnimation.js +1 -1
  31. package/lib/commonjs/utils/useCardAnimation.js.map +1 -1
  32. package/lib/commonjs/utils/useGestureHandlerRef.js +1 -1
  33. package/lib/commonjs/utils/useGestureHandlerRef.js.map +1 -1
  34. package/lib/commonjs/utils/useKeyboardManager.js +1 -1
  35. package/lib/commonjs/utils/useKeyboardManager.js.map +1 -1
  36. package/lib/commonjs/views/GestureHandler.android.js.map +1 -1
  37. package/lib/commonjs/views/GestureHandler.ios.js.map +1 -1
  38. package/lib/commonjs/views/GestureHandler.js +4 -7
  39. package/lib/commonjs/views/GestureHandler.js.map +1 -1
  40. package/lib/commonjs/views/GestureHandlerNative.js +2 -2
  41. package/lib/commonjs/views/GestureHandlerNative.js.map +1 -1
  42. package/lib/commonjs/views/Header/Header.js +13 -14
  43. package/lib/commonjs/views/Header/Header.js.map +1 -1
  44. package/lib/commonjs/views/Header/HeaderContainer.js +12 -13
  45. package/lib/commonjs/views/Header/HeaderContainer.js.map +1 -1
  46. package/lib/commonjs/views/Header/HeaderSegment.js +4 -5
  47. package/lib/commonjs/views/Header/HeaderSegment.js.map +1 -1
  48. package/lib/commonjs/views/Screens.js +11 -13
  49. package/lib/commonjs/views/Screens.js.map +1 -1
  50. package/lib/commonjs/views/Stack/Card.js +33 -40
  51. package/lib/commonjs/views/Stack/Card.js.map +1 -1
  52. package/lib/commonjs/views/Stack/CardContainer.js +42 -45
  53. package/lib/commonjs/views/Stack/CardContainer.js.map +1 -1
  54. package/lib/commonjs/views/Stack/CardSheet.js +8 -9
  55. package/lib/commonjs/views/Stack/CardSheet.js.map +1 -1
  56. package/lib/commonjs/views/Stack/CardStack.js +56 -30
  57. package/lib/commonjs/views/Stack/CardStack.js.map +1 -1
  58. package/lib/commonjs/views/Stack/StackView.js +42 -57
  59. package/lib/commonjs/views/Stack/StackView.js.map +1 -1
  60. package/lib/module/TransitionConfigs/CardStyleInterpolators.js +112 -67
  61. package/lib/module/TransitionConfigs/CardStyleInterpolators.js.map +1 -1
  62. package/lib/module/TransitionConfigs/HeaderStyleInterpolators.js +40 -40
  63. package/lib/module/TransitionConfigs/HeaderStyleInterpolators.js.map +1 -1
  64. package/lib/module/TransitionConfigs/TransitionPresets.js +24 -2
  65. package/lib/module/TransitionConfigs/TransitionPresets.js.map +1 -1
  66. package/lib/module/TransitionConfigs/TransitionSpecs.js +30 -2
  67. package/lib/module/TransitionConfigs/TransitionSpecs.js.map +1 -1
  68. package/lib/module/index.js.map +1 -1
  69. package/lib/module/navigators/createStackNavigator.js +16 -15
  70. package/lib/module/navigators/createStackNavigator.js.map +1 -1
  71. package/lib/module/types.js.map +1 -1
  72. package/lib/module/utils/CardAnimationContext.js.map +1 -1
  73. package/lib/module/utils/GestureHandlerRefContext.js.map +1 -1
  74. package/lib/module/utils/ModalPresentationContext.js.map +1 -1
  75. package/lib/module/utils/conditional.js.map +1 -1
  76. package/lib/module/utils/findLastIndex.js.map +1 -1
  77. package/lib/module/utils/getDistanceForDirection.js.map +1 -1
  78. package/lib/module/utils/getInvertedMultiplier.js.map +1 -1
  79. package/lib/module/utils/getModalRoutesKeys.js +10 -0
  80. package/lib/module/utils/getModalRoutesKeys.js.map +1 -0
  81. package/lib/module/utils/memoize.js +1 -4
  82. package/lib/module/utils/memoize.js.map +1 -1
  83. package/lib/module/utils/throttle.js +12 -0
  84. package/lib/module/utils/throttle.js.map +1 -0
  85. package/lib/module/utils/useCardAnimation.js.map +1 -1
  86. package/lib/module/utils/useGestureHandlerRef.js.map +1 -1
  87. package/lib/module/utils/useKeyboardManager.js.map +1 -1
  88. package/lib/module/views/GestureHandler.android.js.map +1 -1
  89. package/lib/module/views/GestureHandler.ios.js.map +1 -1
  90. package/lib/module/views/GestureHandler.js +3 -6
  91. package/lib/module/views/GestureHandler.js.map +1 -1
  92. package/lib/module/views/GestureHandlerNative.js +1 -1
  93. package/lib/module/views/GestureHandlerNative.js.map +1 -1
  94. package/lib/module/views/Header/Header.js +12 -13
  95. package/lib/module/views/Header/Header.js.map +1 -1
  96. package/lib/module/views/Header/HeaderContainer.js +11 -12
  97. package/lib/module/views/Header/HeaderContainer.js.map +1 -1
  98. package/lib/module/views/Header/HeaderSegment.js +3 -4
  99. package/lib/module/views/Header/HeaderSegment.js.map +1 -1
  100. package/lib/module/views/Screens.js +10 -12
  101. package/lib/module/views/Screens.js.map +1 -1
  102. package/lib/module/views/Stack/Card.js +31 -38
  103. package/lib/module/views/Stack/Card.js.map +1 -1
  104. package/lib/module/views/Stack/CardContainer.js +41 -44
  105. package/lib/module/views/Stack/CardContainer.js.map +1 -1
  106. package/lib/module/views/Stack/CardSheet.js +7 -8
  107. package/lib/module/views/Stack/CardSheet.js.map +1 -1
  108. package/lib/module/views/Stack/CardStack.js +56 -30
  109. package/lib/module/views/Stack/CardStack.js.map +1 -1
  110. package/lib/module/views/Stack/StackView.js +41 -56
  111. package/lib/module/views/Stack/StackView.js.map +1 -1
  112. package/lib/typescript/src/TransitionConfigs/CardStyleInterpolators.d.ts +8 -0
  113. package/lib/typescript/src/TransitionConfigs/CardStyleInterpolators.d.ts.map +1 -1
  114. package/lib/typescript/src/TransitionConfigs/HeaderStyleInterpolators.d.ts.map +1 -1
  115. package/lib/typescript/src/TransitionConfigs/TransitionPresets.d.ts +8 -0
  116. package/lib/typescript/src/TransitionConfigs/TransitionPresets.d.ts.map +1 -1
  117. package/lib/typescript/src/TransitionConfigs/TransitionSpecs.d.ts +10 -0
  118. package/lib/typescript/src/TransitionConfigs/TransitionSpecs.d.ts.map +1 -1
  119. package/lib/typescript/src/index.d.ts +1 -1
  120. package/lib/typescript/src/index.d.ts.map +1 -1
  121. package/lib/typescript/src/navigators/createStackNavigator.d.ts +14 -9
  122. package/lib/typescript/src/navigators/createStackNavigator.d.ts.map +1 -1
  123. package/lib/typescript/src/types.d.ts +24 -7
  124. package/lib/typescript/src/types.d.ts.map +1 -1
  125. package/lib/typescript/src/utils/getModalRoutesKeys.d.ts +4 -0
  126. package/lib/typescript/src/utils/getModalRoutesKeys.d.ts.map +1 -0
  127. package/lib/typescript/src/utils/throttle.d.ts +2 -0
  128. package/lib/typescript/src/utils/throttle.d.ts.map +1 -0
  129. package/lib/typescript/src/views/GestureHandler.d.ts +2 -1
  130. package/lib/typescript/src/views/GestureHandler.d.ts.map +1 -1
  131. package/lib/typescript/src/views/Header/HeaderSegment.d.ts.map +1 -1
  132. package/lib/typescript/src/views/Screens.d.ts +2 -2
  133. package/lib/typescript/src/views/Screens.d.ts.map +1 -1
  134. package/lib/typescript/src/views/Stack/Card.d.ts.map +1 -1
  135. package/lib/typescript/src/views/Stack/CardSheet.d.ts.map +1 -1
  136. package/lib/typescript/src/views/Stack/CardStack.d.ts.map +1 -1
  137. package/package.json +16 -16
  138. package/src/TransitionConfigs/CardStyleInterpolators.tsx +65 -0
  139. package/src/TransitionConfigs/HeaderStyleInterpolators.tsx +10 -2
  140. package/src/TransitionConfigs/TransitionPresets.tsx +31 -5
  141. package/src/TransitionConfigs/TransitionSpecs.tsx +30 -2
  142. package/src/index.tsx +2 -0
  143. package/src/navigators/createStackNavigator.tsx +33 -9
  144. package/src/types.tsx +39 -5
  145. package/src/utils/getModalRoutesKeys.ts +21 -0
  146. package/src/utils/throttle.tsx +16 -0
  147. package/src/views/Header/Header.tsx +2 -2
  148. package/src/views/Header/HeaderContainer.tsx +2 -2
  149. package/src/views/Header/HeaderSegment.tsx +2 -3
  150. package/src/views/Stack/Card.tsx +8 -8
  151. package/src/views/Stack/CardContainer.tsx +2 -2
  152. package/src/views/Stack/CardStack.tsx +85 -28
  153. package/src/views/Stack/StackView.tsx +1 -1
  154. package/lib/commonjs/utils/debounce.js +0 -21
  155. package/lib/commonjs/utils/debounce.js.map +0 -1
  156. package/lib/module/utils/debounce.js +0 -15
  157. package/lib/module/utils/debounce.js.map +0 -1
  158. package/lib/typescript/src/utils/debounce.d.ts +0 -2
  159. package/lib/typescript/src/utils/debounce.d.ts.map +0 -1
  160. package/src/utils/debounce.tsx +0 -16
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@react-navigation/stack",
3
3
  "description": "Stack navigator component for iOS and Android with animated transitions and gestures",
4
- "version": "7.0.0-alpha.9",
4
+ "version": "7.0.0-rc.1",
5
5
  "keywords": [
6
6
  "react-native-component",
7
7
  "react-component",
@@ -40,30 +40,30 @@
40
40
  "clean": "del lib"
41
41
  },
42
42
  "dependencies": {
43
- "@react-navigation/elements": "^2.0.0-alpha.6",
43
+ "@react-navigation/elements": "^2.0.0-rc.1",
44
44
  "color": "^4.2.3"
45
45
  },
46
46
  "devDependencies": {
47
- "@react-navigation/native": "^7.0.0-alpha.8",
47
+ "@react-navigation/native": "^7.0.0-rc.1",
48
48
  "@testing-library/react-native": "^12.4.3",
49
49
  "@types/color": "^3.0.6",
50
- "@types/react": "~18.2.45",
50
+ "@types/react": "~18.2.79",
51
51
  "del-cli": "^5.1.0",
52
52
  "react": "18.2.0",
53
- "react-native": "0.73.2",
53
+ "react-native": "0.74.2",
54
54
  "react-native-builder-bob": "^0.23.2",
55
- "react-native-gesture-handler": "~2.14.0",
56
- "react-native-safe-area-context": "4.8.2",
57
- "react-native-screens": "~3.29.0",
58
- "typescript": "^5.3.3"
55
+ "react-native-gesture-handler": "~2.16.1",
56
+ "react-native-safe-area-context": "4.10.1",
57
+ "react-native-screens": "3.31.1",
58
+ "typescript": "^5.5.2"
59
59
  },
60
60
  "peerDependencies": {
61
- "@react-navigation/native": "^7.0.0-alpha.8",
62
- "react": "*",
63
- "react-native": "0.73.2",
64
- "react-native-gesture-handler": "~2.14.0",
65
- "react-native-safe-area-context": "4.8.2",
66
- "react-native-screens": "~3.29.0"
61
+ "@react-navigation/native": "^7.0.0-rc.1",
62
+ "react": ">= 18.2.0",
63
+ "react-native": ">= 0.72.0",
64
+ "react-native-gesture-handler": ">= 2.0.0",
65
+ "react-native-safe-area-context": ">= 4.0.0",
66
+ "react-native-screens": ">= 3.0.0"
67
67
  },
68
68
  "react-native-builder-bob": {
69
69
  "source": "src",
@@ -79,5 +79,5 @@
79
79
  ]
80
80
  ]
81
81
  },
82
- "gitHead": "e4e445810a3a958c35cc34486b5499baa595500e"
82
+ "gitHead": "18c09f1478a3efcb3a809305c5947b748f10c951"
83
83
  }
@@ -63,6 +63,19 @@ export function forHorizontalIOS({
63
63
  };
64
64
  }
65
65
 
66
+ /**
67
+ * iOS-style slide in from the left.
68
+ */
69
+ export function forHorizontalIOSInverted({
70
+ inverted,
71
+ ...rest
72
+ }: StackCardInterpolationProps): StackCardInterpolatedStyle {
73
+ return forHorizontalIOS({
74
+ ...rest,
75
+ inverted: Animated.multiply(inverted, -1),
76
+ });
77
+ }
78
+
66
79
  /**
67
80
  * Standard iOS-style slide in from the bottom (used for modals).
68
81
  */
@@ -323,6 +336,58 @@ export function forScaleFromCenterAndroid({
323
336
  };
324
337
  }
325
338
 
339
+ /**
340
+ * Standard Android-style fade from right for Android 14.
341
+ */
342
+ export function forFadeFromRightAndroid({
343
+ current,
344
+ next,
345
+ inverted,
346
+ closing,
347
+ }: StackCardInterpolationProps): StackCardInterpolatedStyle {
348
+ const translateFocused = multiply(
349
+ current.progress.interpolate({
350
+ inputRange: [0, 1],
351
+ outputRange: [96, 0],
352
+ extrapolate: 'clamp',
353
+ }),
354
+ inverted
355
+ );
356
+
357
+ const translateUnfocused = next
358
+ ? multiply(
359
+ next.progress.interpolate({
360
+ inputRange: [0, 1],
361
+ outputRange: [0, -96],
362
+ extrapolate: 'clamp',
363
+ }),
364
+ inverted
365
+ )
366
+ : 0;
367
+
368
+ const opacity = conditional(
369
+ closing,
370
+ current.progress.interpolate({
371
+ inputRange: [0, 1],
372
+ outputRange: [0, 1],
373
+ extrapolate: 'clamp',
374
+ }),
375
+ current.progress
376
+ );
377
+
378
+ return {
379
+ cardStyle: {
380
+ opacity,
381
+ transform: [
382
+ // Translation for the animation of the current card
383
+ { translateX: translateFocused },
384
+ // Translation for the animation of the card on top of this
385
+ { translateX: translateUnfocused },
386
+ ],
387
+ },
388
+ };
389
+ }
390
+
326
391
  /**
327
392
  * Standard bottom sheet slide in from the bottom for Android.
328
393
  */
@@ -1,4 +1,4 @@
1
- import { Animated } from 'react-native';
1
+ import { Animated, Platform } from 'react-native';
2
2
 
3
3
  import type {
4
4
  StackHeaderInterpolatedStyle,
@@ -7,6 +7,10 @@ import type {
7
7
 
8
8
  const { add, multiply } = Animated;
9
9
 
10
+ // Width of the screen in split layout on portrait mode on iPad Mini
11
+ // Keep in sync with HeaderBackButton.tsx
12
+ const IPAD_MINI_MEDIUM_WIDTH = 414;
13
+
10
14
  /**
11
15
  * Standard UIKit style animation for the header where the title fades into the back button label.
12
16
  */
@@ -17,7 +21,11 @@ export function forUIKit({
17
21
  layouts,
18
22
  }: StackHeaderInterpolationProps): StackHeaderInterpolatedStyle {
19
23
  const defaultOffset = 100;
20
- const leftSpacing = 27;
24
+ const leftSpacing =
25
+ 27 +
26
+ (Platform.OS === 'ios' && layouts.screen.width >= IPAD_MINI_MEDIUM_WIDTH
27
+ ? 5 // Additional padding on iPad specified in Header.tsx
28
+ : 0);
21
29
 
22
30
  // The title and back button title should cross-fade to each other
23
31
  // When screen is fully open, the title should be in center, and back title should be on left
@@ -5,7 +5,9 @@ import {
5
5
  forBottomSheetAndroid,
6
6
  forFadeFromBottomAndroid,
7
7
  forFadeFromCenter as forFadeCard,
8
+ forFadeFromRightAndroid,
8
9
  forHorizontalIOS,
10
+ forHorizontalIOSInverted,
9
11
  forModalPresentationIOS,
10
12
  forRevealFromBottomAndroid,
11
13
  forScaleFromCenterAndroid,
@@ -24,6 +26,7 @@ import {
24
26
 
25
27
  const ANDROID_VERSION_PIE = 28;
26
28
  const ANDROID_VERSION_10 = 29;
29
+ const ANDROID_VERSION_14 = 34;
27
30
 
28
31
  /**
29
32
  * Standard iOS navigation transition.
@@ -103,6 +106,19 @@ export const ScaleFromCenterAndroid: TransitionPreset = {
103
106
  headerStyleInterpolator: forFade,
104
107
  };
105
108
 
109
+ /**
110
+ * Standard Android navigation transition when opening or closing an Activity on Android 14.
111
+ */
112
+ export const FadeFromRightAndroid: TransitionPreset = {
113
+ gestureDirection: 'horizontal',
114
+ transitionSpec: {
115
+ open: FadeInFromBottomAndroidSpec,
116
+ close: FadeOutToBottomAndroidSpec,
117
+ },
118
+ cardStyleInterpolator: forFadeFromRightAndroid,
119
+ headerStyleInterpolator: forFade,
120
+ };
121
+
106
122
  /**
107
123
  * Standard bottom sheet slide transition for Android 10.
108
124
  */
@@ -135,11 +151,13 @@ export const ModalFadeTransition: TransitionPreset = {
135
151
  export const DefaultTransition = Platform.select({
136
152
  ios: SlideFromRightIOS,
137
153
  android:
138
- Number(Platform.Version) >= ANDROID_VERSION_10
139
- ? ScaleFromCenterAndroid
140
- : Number(Platform.Version) >= ANDROID_VERSION_PIE
141
- ? RevealFromBottomAndroid
142
- : FadeFromBottomAndroid,
154
+ Number(Platform.Version) >= ANDROID_VERSION_14
155
+ ? FadeFromRightAndroid
156
+ : Number(Platform.Version) >= ANDROID_VERSION_10
157
+ ? ScaleFromCenterAndroid
158
+ : Number(Platform.Version) >= ANDROID_VERSION_PIE
159
+ ? RevealFromBottomAndroid
160
+ : FadeFromBottomAndroid,
143
161
  default: ScaleFromCenterAndroid,
144
162
  });
145
163
 
@@ -150,3 +168,11 @@ export const ModalTransition = Platform.select({
150
168
  ios: ModalPresentationIOS,
151
169
  default: BottomSheetAndroid,
152
170
  });
171
+
172
+ /**
173
+ * Slide from left transition.
174
+ */
175
+ export const SlideFromLeftIOS: TransitionPreset = {
176
+ ...SlideFromRightIOS,
177
+ cardStyleInterpolator: forHorizontalIOSInverted,
178
+ };
@@ -51,7 +51,7 @@ export const RevealFromBottomAndroidSpec: TransitionSpec = {
51
51
  duration: 425,
52
52
  // This is super rough approximation of the path used for the curve by android
53
53
  // See http://aosp.opersys.com/xref/android-9.0.0_r47/xref/frameworks/base/core/res/res/interpolator/fast_out_extra_slow_in.xml
54
- easing: Easing.bezier(0.35, 0.45, 0, 1),
54
+ easing: Easing.bezier(0.20833, 0.82, 0.25, 1),
55
55
  },
56
56
  };
57
57
 
@@ -65,7 +65,35 @@ export const ScaleFromCenterAndroidSpec: TransitionSpec = {
65
65
  duration: 400,
66
66
  // This is super rough approximation of the path used for the curve by android
67
67
  // See http://aosp.opersys.com/xref/android-10.0.0_r2/xref/frameworks/base/core/res/res/interpolator/fast_out_extra_slow_in.xml
68
- easing: Easing.bezier(0.35, 0.45, 0, 1),
68
+ easing: Easing.bezier(0.20833, 0.82, 0.25, 1),
69
+ },
70
+ };
71
+
72
+ /**
73
+ * Approximate configuration for activity open animation from Android 14.
74
+ * See https://android.googlesource.com/platform/frameworks/base/+/refs/tags/android-14.0.0_r51/core/res/res/anim/activity_open_enter.xml
75
+ */
76
+ export const FadeInFromRightAndroidSpec: TransitionSpec = {
77
+ animation: 'timing',
78
+ config: {
79
+ duration: 450,
80
+ // This is super rough approximation of the path used for the curve by android
81
+ // See https://android.googlesource.com/platform/frameworks/base/+/refs/tags/android-14.0.0_r51/core/res/res/interpolator/fast_out_extra_slow_in.xml
82
+ easing: Easing.bezier(0.20833, 0.82, 0.25, 1),
83
+ },
84
+ };
85
+
86
+ /**
87
+ * Approximate configuration for activity close animation from Android 14.
88
+ * See https://android.googlesource.com/platform/frameworks/base/+/refs/tags/android-14.0.0_r51/core/res/res/anim/activity_close_exit.xml
89
+ */
90
+ export const FadeOutToLeftAndroidSpec: TransitionSpec = {
91
+ animation: 'timing',
92
+ config: {
93
+ duration: 450,
94
+ // This is super rough approximation of the path used for the curve by android
95
+ // See https://android.googlesource.com/platform/frameworks/base/+/refs/tags/android-14.0.0_r51/core/res/res/interpolator/fast_out_extra_slow_in.xml
96
+ easing: Easing.bezier(0.20833, 0.82, 0.25, 1),
69
97
  },
70
98
  };
71
99
 
package/src/index.tsx CHANGED
@@ -36,6 +36,7 @@ export { useGestureHandlerRef } from './utils/useGestureHandlerRef';
36
36
  * Types
37
37
  */
38
38
  export type {
39
+ StackAnimationName,
39
40
  StackCardInterpolatedStyle,
40
41
  StackCardInterpolationProps,
41
42
  StackCardStyleInterpolator,
@@ -46,6 +47,7 @@ export type {
46
47
  StackNavigationEventMap,
47
48
  StackNavigationOptions,
48
49
  StackNavigationProp,
50
+ StackOptionsArgs,
49
51
  StackScreenProps,
50
52
  TransitionPreset,
51
53
  } from './types';
@@ -2,12 +2,15 @@ import {
2
2
  createNavigatorFactory,
3
3
  type DefaultNavigatorOptions,
4
4
  type EventArg,
5
+ type NavigatorTypeBagBase,
5
6
  type ParamListBase,
6
7
  type StackActionHelpers,
7
8
  StackActions,
8
9
  type StackNavigationState,
9
10
  StackRouter,
10
11
  type StackRouterOptions,
12
+ type StaticConfig,
13
+ type TypedNavigator,
11
14
  useLocale,
12
15
  useNavigationBuilder,
13
16
  } from '@react-navigation/native';
@@ -17,14 +20,17 @@ import type {
17
20
  StackNavigationConfig,
18
21
  StackNavigationEventMap,
19
22
  StackNavigationOptions,
23
+ StackNavigationProp,
20
24
  } from '../types';
21
25
  import { StackView } from '../views/Stack/StackView';
22
26
 
23
27
  type Props = DefaultNavigatorOptions<
24
28
  ParamListBase,
29
+ string | undefined,
25
30
  StackNavigationState<ParamListBase>,
26
31
  StackNavigationOptions,
27
- StackNavigationEventMap
32
+ StackNavigationEventMap,
33
+ StackNavigationProp<ParamListBase>
28
34
  > &
29
35
  StackRouterOptions &
30
36
  StackNavigationConfig;
@@ -32,12 +38,12 @@ type Props = DefaultNavigatorOptions<
32
38
  function StackNavigator({
33
39
  id,
34
40
  initialRouteName,
35
- getStateForRouteNamesChange,
36
41
  children,
37
42
  layout,
38
43
  screenListeners,
39
44
  screenOptions,
40
45
  screenLayout,
46
+ UNSTABLE_getStateForRouteNamesChange,
41
47
  ...rest
42
48
  }: Props) {
43
49
  const { direction } = useLocale();
@@ -57,7 +63,7 @@ function StackNavigator({
57
63
  screenListeners,
58
64
  screenOptions,
59
65
  screenLayout,
60
- getStateForRouteNamesChange,
66
+ UNSTABLE_getStateForRouteNamesChange,
61
67
  });
62
68
 
63
69
  React.useEffect(
@@ -100,9 +106,27 @@ function StackNavigator({
100
106
  );
101
107
  }
102
108
 
103
- export const createStackNavigator = createNavigatorFactory<
104
- StackNavigationState<ParamListBase>,
105
- StackNavigationOptions,
106
- StackNavigationEventMap,
107
- typeof StackNavigator
108
- >(StackNavigator);
109
+ export function createStackNavigator<
110
+ ParamList extends ParamListBase,
111
+ NavigatorID extends string | undefined = undefined,
112
+ TypeBag extends NavigatorTypeBagBase = {
113
+ ParamList: ParamList;
114
+ NavigatorID: NavigatorID;
115
+ State: StackNavigationState<ParamList>;
116
+ ScreenOptions: StackNavigationOptions;
117
+ EventMap: StackNavigationEventMap;
118
+ NavigationList: {
119
+ [RouteName in keyof ParamList]: StackNavigationProp<
120
+ ParamList,
121
+ RouteName,
122
+ NavigatorID
123
+ >;
124
+ };
125
+ Navigator: typeof StackNavigator;
126
+ },
127
+ Config extends StaticConfig<TypeBag> | undefined =
128
+ | StaticConfig<TypeBag>
129
+ | undefined,
130
+ >(config?: Config): TypedNavigator<TypeBag, Config> {
131
+ return createNavigatorFactory(StackNavigator)(config);
132
+ }
package/src/types.tsx CHANGED
@@ -14,6 +14,7 @@ import type {
14
14
  RouteProp,
15
15
  StackActionHelpers,
16
16
  StackNavigationState,
17
+ Theme,
17
18
  } from '@react-navigation/native';
18
19
  import type * as React from 'react';
19
20
  import type { Animated, StyleProp, TextStyle, ViewStyle } from 'react-native';
@@ -70,6 +71,14 @@ export type StackScreenProps<
70
71
  route: RouteProp<ParamList, RouteName>;
71
72
  };
72
73
 
74
+ export type StackOptionsArgs<
75
+ ParamList extends ParamListBase,
76
+ RouteName extends keyof ParamList = keyof ParamList,
77
+ NavigatorID extends string | undefined = undefined,
78
+ > = StackScreenProps<ParamList, RouteName, NavigatorID> & {
79
+ theme: Theme;
80
+ };
81
+
73
82
  export type Layout = { width: number; height: number };
74
83
 
75
84
  export type GestureDirection =
@@ -78,8 +87,20 @@ export type GestureDirection =
78
87
  | 'vertical'
79
88
  | 'vertical-inverted';
80
89
 
90
+ export type StackAnimationName =
91
+ | 'default'
92
+ | 'fade'
93
+ | 'fade_from_bottom'
94
+ | 'fade_from_right'
95
+ | 'none'
96
+ | 'reveal_from_bottom'
97
+ | 'scale_from_center'
98
+ | 'slide_from_bottom'
99
+ | 'slide_from_right'
100
+ | 'slide_from_left';
101
+
81
102
  type SceneOptionsDefaults = TransitionPreset & {
82
- animationEnabled: boolean;
103
+ animation: StackAnimationName;
83
104
  gestureEnabled: boolean;
84
105
  cardOverlayEnabled: boolean;
85
106
  headerMode: StackHeaderMode;
@@ -244,6 +265,10 @@ export type StackHeaderRightProps = {
244
265
  };
245
266
 
246
267
  export type StackHeaderLeftProps = HeaderBackButtonProps & {
268
+ /**
269
+ * The `href` to use for the anchor tag on web
270
+ */
271
+ href?: string;
247
272
  /**
248
273
  * Whether it's possible to navigate back in stack.
249
274
  */
@@ -326,11 +351,20 @@ export type StackNavigationOptions = StackHeaderOptions &
326
351
  */
327
352
  presentation?: 'card' | 'modal' | 'transparentModal';
328
353
  /**
329
- * Whether transition animation should be enabled the screen.
330
- * If you set it to `false`, the screen won't animate when pushing or popping.
331
- * Defaults to `true` on Android and iOS, `false` on Web.
354
+ * How the screen should animate when pushed or popped.
355
+ *
356
+ * Supported values:
357
+ * - 'none': don't animate the screen
358
+ * - 'default': use the platform default animation
359
+ * - 'fade': fade screen in or out
360
+ * - 'fade_from_bottom': fade screen in or out from bottom
361
+ * - 'slide_from_bottom': slide in the new screen from bottom
362
+ * - 'slide_from_right': slide in the new screen from right
363
+ * - 'slide_from_left': slide in the new screen from left
364
+ * - 'reveal_from_bottom': reveal screen in from bottom to top
365
+ * - 'scale_from_center': scale screen in from center
332
366
  */
333
- animationEnabled?: boolean;
367
+ animation?: StackAnimationName;
334
368
  /**
335
369
  * The type of animation to use when this screen replaces another screen. Defaults to `push`.
336
370
  * When `pop` is used, the `pop` animation is applied to the screen being replaced.
@@ -0,0 +1,21 @@
1
+ import type { Route } from '@react-navigation/native';
2
+
3
+ import type { StackDescriptorMap } from '../types';
4
+
5
+ export const getModalRouteKeys = (
6
+ routes: Route<string>[],
7
+ descriptors: StackDescriptorMap
8
+ ) =>
9
+ routes.reduce<string[]>((acc, route) => {
10
+ const { presentation } = descriptors[route.key]?.options ?? {};
11
+
12
+ if (
13
+ (acc.length && !presentation) ||
14
+ presentation === 'modal' ||
15
+ presentation === 'transparentModal'
16
+ ) {
17
+ acc.push(route.key);
18
+ }
19
+
20
+ return acc;
21
+ }, []);
@@ -0,0 +1,16 @@
1
+ export function throttle<T extends (...args: any[]) => void>(
2
+ func: T,
3
+ duration: number
4
+ ): T {
5
+ let timeout: NodeJS.Timeout | undefined;
6
+
7
+ return function (this: unknown, ...args) {
8
+ if (timeout == null) {
9
+ func.apply(this, args);
10
+
11
+ timeout = setTimeout(() => {
12
+ timeout = undefined;
13
+ }, duration);
14
+ }
15
+ } as T;
16
+ }
@@ -4,8 +4,8 @@ import * as React from 'react';
4
4
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
5
5
 
6
6
  import type { StackHeaderProps } from '../../types';
7
- import { debounce } from '../../utils/debounce';
8
7
  import { ModalPresentationContext } from '../../utils/ModalPresentationContext';
8
+ import { throttle } from '../../utils/throttle';
9
9
  import { HeaderSegment } from './HeaderSegment';
10
10
 
11
11
  export const Header = React.memo(function Header({
@@ -31,7 +31,7 @@ export const Header = React.memo(function Header({
31
31
 
32
32
  // eslint-disable-next-line react-hooks/exhaustive-deps
33
33
  const goBack = React.useCallback(
34
- debounce(() => {
34
+ throttle(() => {
35
35
  if (navigation.isFocused() && navigation.canGoBack()) {
36
36
  navigation.dispatch({
37
37
  ...StackActions.pop(),
@@ -191,7 +191,7 @@ const styles = StyleSheet.create({
191
191
  header: {
192
192
  position: 'absolute',
193
193
  top: 0,
194
- left: 0,
195
- right: 0,
194
+ start: 0,
195
+ end: 0,
196
196
  },
197
197
  });
@@ -109,9 +109,7 @@ export function HeaderSegment(props: Props) {
109
109
  backHref,
110
110
  headerTitle: title,
111
111
  headerLeft: left = onGoBack
112
- ? (props: HeaderBackButtonProps) => (
113
- <HeaderBackButton {...props} href={backHref} />
114
- )
112
+ ? (props: HeaderBackButtonProps) => <HeaderBackButton {...props} />
115
113
  : undefined,
116
114
  headerRight: right,
117
115
  headerBackImage,
@@ -162,6 +160,7 @@ export function HeaderSegment(props: Props) {
162
160
  ? (props) =>
163
161
  left({
164
162
  ...props,
163
+ href: backHref,
165
164
  backImage: headerBackImage,
166
165
  accessibilityLabel: headerBackAccessibilityLabel,
167
166
  testID: headerBackTestID,
@@ -571,9 +571,9 @@ export class Card extends React.Component<Props> {
571
571
  style={[
572
572
  styles.shadow,
573
573
  gestureDirection === 'horizontal'
574
- ? [styles.shadowHorizontal, styles.shadowLeft]
574
+ ? [styles.shadowHorizontal, styles.shadowStart]
575
575
  : gestureDirection === 'horizontal-inverted'
576
- ? [styles.shadowHorizontal, styles.shadowRight]
576
+ ? [styles.shadowHorizontal, styles.shadowEnd]
577
577
  : gestureDirection === 'vertical'
578
578
  ? [styles.shadowVertical, styles.shadowTop]
579
579
  : [styles.shadowVertical, styles.shadowBottom],
@@ -620,15 +620,15 @@ const styles = StyleSheet.create({
620
620
  width: 3,
621
621
  shadowOffset: { width: -1, height: 1 },
622
622
  },
623
- shadowLeft: {
624
- left: 0,
623
+ shadowStart: {
624
+ start: 0,
625
625
  },
626
- shadowRight: {
627
- right: 0,
626
+ shadowEnd: {
627
+ end: 0,
628
628
  },
629
629
  shadowVertical: {
630
- left: 0,
631
- right: 0,
630
+ start: 0,
631
+ end: 0,
632
632
  height: 3,
633
633
  shadowOffset: { width: 1, height: -1 },
634
634
  },
@@ -190,7 +190,7 @@ function CardContainerInner({
190
190
 
191
191
  const {
192
192
  presentation,
193
- animationEnabled,
193
+ animation,
194
194
  cardOverlay,
195
195
  cardOverlayEnabled,
196
196
  cardShadowEnabled,
@@ -275,7 +275,7 @@ function CardContainerInner({
275
275
  display:
276
276
  // Hide unfocused screens when animation isn't enabled
277
277
  // This is also necessary for a11y on web
278
- animationEnabled === false &&
278
+ animation === 'none' &&
279
279
  isNextScreenTransparent === false &&
280
280
  detachCurrentScreen !== false &&
281
281
  !focused