@react-navigation/native-stack 7.0.0-rc.3 → 7.0.0-rc.30

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 (142) hide show
  1. package/lib/commonjs/index.js +2 -2
  2. package/lib/commonjs/navigators/createNativeStackNavigator.js +11 -6
  3. package/lib/commonjs/navigators/createNativeStackNavigator.js.map +1 -1
  4. package/lib/commonjs/package.json +1 -0
  5. package/lib/commonjs/utils/debounce.js.map +1 -1
  6. package/lib/commonjs/views/FooterComponent.js +19 -0
  7. package/lib/commonjs/views/FooterComponent.js.map +1 -0
  8. package/lib/commonjs/views/NativeStackView.js +106 -106
  9. package/lib/commonjs/views/NativeStackView.js.map +1 -1
  10. package/lib/commonjs/views/NativeStackView.native.js +221 -219
  11. package/lib/commonjs/views/NativeStackView.native.js.map +1 -1
  12. package/lib/commonjs/views/{HeaderConfig.js → useHeaderConfigProps.js} +84 -43
  13. package/lib/commonjs/views/useHeaderConfigProps.js.map +1 -0
  14. package/lib/module/index.js +4 -2
  15. package/lib/module/index.js.map +1 -1
  16. package/lib/module/navigators/createNativeStackNavigator.js +13 -6
  17. package/lib/module/navigators/createNativeStackNavigator.js.map +1 -1
  18. package/lib/module/package.json +1 -0
  19. package/lib/module/types.js +2 -0
  20. package/lib/module/utils/debounce.js +2 -0
  21. package/lib/module/utils/debounce.js.map +1 -1
  22. package/lib/module/utils/getModalRoutesKeys.js +2 -0
  23. package/lib/module/utils/getModalRoutesKeys.js.map +1 -1
  24. package/lib/module/utils/useAnimatedHeaderHeight.js +2 -0
  25. package/lib/module/utils/useAnimatedHeaderHeight.js.map +1 -1
  26. package/lib/module/utils/useDismissedRouteError.js +2 -0
  27. package/lib/module/utils/useDismissedRouteError.js.map +1 -1
  28. package/lib/module/utils/useInvalidPreventRemoveError.js +2 -0
  29. package/lib/module/utils/useInvalidPreventRemoveError.js.map +1 -1
  30. package/lib/module/views/FontProcessor.js +2 -0
  31. package/lib/module/views/FontProcessor.js.map +1 -1
  32. package/lib/module/views/FontProcessor.native.js +2 -0
  33. package/lib/module/views/FontProcessor.native.js.map +1 -1
  34. package/lib/module/views/FooterComponent.js +14 -0
  35. package/lib/module/views/FooterComponent.js.map +1 -0
  36. package/lib/module/views/NativeStackView.js +110 -108
  37. package/lib/module/views/NativeStackView.js.map +1 -1
  38. package/lib/module/views/NativeStackView.native.js +224 -219
  39. package/lib/module/views/NativeStackView.native.js.map +1 -1
  40. package/lib/module/views/{HeaderConfig.js → useHeaderConfigProps.js} +86 -41
  41. package/lib/module/views/useHeaderConfigProps.js.map +1 -0
  42. package/lib/typescript/commonjs/package.json +1 -0
  43. package/lib/typescript/{src → commonjs/src}/index.d.ts +1 -1
  44. package/lib/typescript/commonjs/src/index.d.ts.map +1 -0
  45. package/lib/typescript/{src → commonjs/src}/navigators/createNativeStackNavigator.d.ts +3 -4
  46. package/lib/typescript/commonjs/src/navigators/createNativeStackNavigator.d.ts.map +1 -0
  47. package/lib/typescript/{src → commonjs/src}/types.d.ts +112 -34
  48. package/lib/typescript/commonjs/src/types.d.ts.map +1 -0
  49. package/lib/typescript/commonjs/src/utils/debounce.d.ts.map +1 -0
  50. package/lib/typescript/commonjs/src/utils/getModalRoutesKeys.d.ts.map +1 -0
  51. package/lib/typescript/commonjs/src/utils/useAnimatedHeaderHeight.d.ts.map +1 -0
  52. package/lib/typescript/commonjs/src/utils/useDismissedRouteError.d.ts.map +1 -0
  53. package/lib/typescript/commonjs/src/utils/useInvalidPreventRemoveError.d.ts.map +1 -0
  54. package/lib/typescript/commonjs/src/views/FontProcessor.d.ts.map +1 -0
  55. package/lib/typescript/commonjs/src/views/FontProcessor.native.d.ts.map +1 -0
  56. package/lib/typescript/commonjs/src/views/FooterComponent.d.ts +7 -0
  57. package/lib/typescript/commonjs/src/views/FooterComponent.d.ts.map +1 -0
  58. package/lib/typescript/commonjs/src/views/NativeStackView.d.ts +11 -0
  59. package/lib/typescript/commonjs/src/views/NativeStackView.d.ts.map +1 -0
  60. package/lib/typescript/commonjs/src/views/NativeStackView.native.d.ts +11 -0
  61. package/lib/typescript/commonjs/src/views/NativeStackView.native.d.ts.map +1 -0
  62. package/lib/typescript/commonjs/src/views/useHeaderConfigProps.d.ts +41 -0
  63. package/lib/typescript/commonjs/src/views/useHeaderConfigProps.d.ts.map +1 -0
  64. package/lib/typescript/commonjs/tsconfig.build.tsbuildinfo +1 -0
  65. package/lib/typescript/module/package.json +1 -0
  66. package/lib/typescript/module/src/index.d.ts +17 -0
  67. package/lib/typescript/module/src/index.d.ts.map +1 -0
  68. package/lib/typescript/module/src/navigators/createNativeStackNavigator.d.ts +16 -0
  69. package/lib/typescript/module/src/navigators/createNativeStackNavigator.d.ts.map +1 -0
  70. package/lib/typescript/module/src/types.d.ts +623 -0
  71. package/lib/typescript/module/src/types.d.ts.map +1 -0
  72. package/lib/typescript/module/src/utils/debounce.d.ts +2 -0
  73. package/lib/typescript/module/src/utils/debounce.d.ts.map +1 -0
  74. package/lib/typescript/module/src/utils/getModalRoutesKeys.d.ts +4 -0
  75. package/lib/typescript/module/src/utils/getModalRoutesKeys.d.ts.map +1 -0
  76. package/lib/typescript/module/src/utils/useAnimatedHeaderHeight.d.ts +5 -0
  77. package/lib/typescript/module/src/utils/useAnimatedHeaderHeight.d.ts.map +1 -0
  78. package/lib/typescript/module/src/utils/useDismissedRouteError.d.ts +6 -0
  79. package/lib/typescript/module/src/utils/useDismissedRouteError.d.ts.map +1 -0
  80. package/lib/typescript/module/src/utils/useInvalidPreventRemoveError.d.ts +3 -0
  81. package/lib/typescript/module/src/utils/useInvalidPreventRemoveError.d.ts.map +1 -0
  82. package/lib/typescript/module/src/views/FontProcessor.d.ts +2 -0
  83. package/lib/typescript/module/src/views/FontProcessor.d.ts.map +1 -0
  84. package/lib/typescript/module/src/views/FontProcessor.native.d.ts +2 -0
  85. package/lib/typescript/module/src/views/FontProcessor.native.d.ts.map +1 -0
  86. package/lib/typescript/module/src/views/FooterComponent.d.ts +7 -0
  87. package/lib/typescript/module/src/views/FooterComponent.d.ts.map +1 -0
  88. package/lib/typescript/module/src/views/NativeStackView.d.ts +11 -0
  89. package/lib/typescript/module/src/views/NativeStackView.d.ts.map +1 -0
  90. package/lib/typescript/module/src/views/NativeStackView.native.d.ts +11 -0
  91. package/lib/typescript/module/src/views/NativeStackView.native.d.ts.map +1 -0
  92. package/lib/typescript/module/src/views/useHeaderConfigProps.d.ts +41 -0
  93. package/lib/typescript/module/src/views/useHeaderConfigProps.d.ts.map +1 -0
  94. package/lib/typescript/module/tsconfig.build.tsbuildinfo +1 -0
  95. package/package.json +41 -18
  96. package/src/index.tsx +2 -0
  97. package/src/navigators/createNativeStackNavigator.tsx +6 -7
  98. package/src/types.tsx +106 -34
  99. package/src/utils/debounce.tsx +1 -1
  100. package/src/views/FooterComponent.tsx +10 -0
  101. package/src/views/NativeStackView.native.tsx +167 -202
  102. package/src/views/NativeStackView.tsx +62 -50
  103. package/src/views/{HeaderConfig.tsx → useHeaderConfigProps.tsx} +80 -68
  104. package/lib/commonjs/views/DebugContainer.js +0 -19
  105. package/lib/commonjs/views/DebugContainer.js.map +0 -1
  106. package/lib/commonjs/views/DebugContainer.native.js +0 -42
  107. package/lib/commonjs/views/DebugContainer.native.js.map +0 -1
  108. package/lib/commonjs/views/HeaderConfig.js.map +0 -1
  109. package/lib/module/views/DebugContainer.js +0 -11
  110. package/lib/module/views/DebugContainer.js.map +0 -1
  111. package/lib/module/views/DebugContainer.native.js +0 -33
  112. package/lib/module/views/DebugContainer.native.js.map +0 -1
  113. package/lib/module/views/HeaderConfig.js.map +0 -1
  114. package/lib/typescript/src/index.d.ts.map +0 -1
  115. package/lib/typescript/src/navigators/createNativeStackNavigator.d.ts.map +0 -1
  116. package/lib/typescript/src/types.d.ts.map +0 -1
  117. package/lib/typescript/src/utils/debounce.d.ts.map +0 -1
  118. package/lib/typescript/src/utils/getModalRoutesKeys.d.ts.map +0 -1
  119. package/lib/typescript/src/utils/useAnimatedHeaderHeight.d.ts.map +0 -1
  120. package/lib/typescript/src/utils/useDismissedRouteError.d.ts.map +0 -1
  121. package/lib/typescript/src/utils/useInvalidPreventRemoveError.d.ts.map +0 -1
  122. package/lib/typescript/src/views/DebugContainer.d.ts +0 -10
  123. package/lib/typescript/src/views/DebugContainer.d.ts.map +0 -1
  124. package/lib/typescript/src/views/DebugContainer.native.d.ts +0 -15
  125. package/lib/typescript/src/views/DebugContainer.native.d.ts.map +0 -1
  126. package/lib/typescript/src/views/FontProcessor.d.ts.map +0 -1
  127. package/lib/typescript/src/views/FontProcessor.native.d.ts.map +0 -1
  128. package/lib/typescript/src/views/HeaderConfig.d.ts +0 -11
  129. package/lib/typescript/src/views/HeaderConfig.d.ts.map +0 -1
  130. package/lib/typescript/src/views/NativeStackView.d.ts +0 -11
  131. package/lib/typescript/src/views/NativeStackView.d.ts.map +0 -1
  132. package/lib/typescript/src/views/NativeStackView.native.d.ts +0 -11
  133. package/lib/typescript/src/views/NativeStackView.native.d.ts.map +0 -1
  134. package/src/views/DebugContainer.native.tsx +0 -36
  135. package/src/views/DebugContainer.tsx +0 -14
  136. /package/lib/typescript/{src → commonjs/src}/utils/debounce.d.ts +0 -0
  137. /package/lib/typescript/{src → commonjs/src}/utils/getModalRoutesKeys.d.ts +0 -0
  138. /package/lib/typescript/{src → commonjs/src}/utils/useAnimatedHeaderHeight.d.ts +0 -0
  139. /package/lib/typescript/{src → commonjs/src}/utils/useDismissedRouteError.d.ts +0 -0
  140. /package/lib/typescript/{src → commonjs/src}/utils/useInvalidPreventRemoveError.d.ts +0 -0
  141. /package/lib/typescript/{src → commonjs/src}/views/FontProcessor.d.ts +0 -0
  142. /package/lib/typescript/{src → commonjs/src}/views/FontProcessor.native.d.ts +0 -0
@@ -1,64 +1,20 @@
1
- function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
1
+ "use strict";
2
+
2
3
  import { getDefaultHeaderHeight, getHeaderTitle, HeaderBackContext, HeaderHeightContext, HeaderShownContext, SafeAreaProviderCompat } from '@react-navigation/elements';
3
4
  import { NavigationContext, NavigationRouteContext, StackActions, usePreventRemoveContext, useTheme } from '@react-navigation/native';
4
5
  import * as React from 'react';
5
6
  import { Animated, Platform, StatusBar, StyleSheet, useAnimatedValue, View } from 'react-native';
6
7
  import { useSafeAreaFrame, useSafeAreaInsets } from 'react-native-safe-area-context';
7
- import { Screen, ScreenStack } from 'react-native-screens';
8
- import warnOnce from 'warn-once';
9
- import { debounce } from '../utils/debounce';
10
- import { getModalRouteKeys } from '../utils/getModalRoutesKeys';
11
- import { AnimatedHeaderHeightContext } from '../utils/useAnimatedHeaderHeight';
12
- import { useDismissedRouteError } from '../utils/useDismissedRouteError';
13
- import { useInvalidPreventRemoveError } from '../utils/useInvalidPreventRemoveError';
14
- import { DebugContainer } from './DebugContainer';
15
- import { HeaderConfig } from './HeaderConfig';
16
- const isAndroid = Platform.OS === 'android';
17
- const MaybeNestedStack = ({
18
- options,
19
- route,
20
- presentation,
21
- headerHeight,
22
- headerTopInsetEnabled,
23
- children
24
- }) => {
25
- const {
26
- colors
27
- } = useTheme();
28
- const {
29
- header,
30
- headerShown = true,
31
- contentStyle
32
- } = options;
33
- const isHeaderInModal = isAndroid ? false : presentation !== 'card' && headerShown === true && header === undefined;
34
- const headerShownPreviousRef = React.useRef(headerShown);
35
- React.useEffect(() => {
36
- warnOnce(!isAndroid && presentation !== 'card' && headerShownPreviousRef.current !== headerShown, `Dynamically changing 'headerShown' in modals will result in remounting the screen and losing all local state. See options for the screen '${route.name}'.`);
37
- headerShownPreviousRef.current = headerShown;
38
- }, [headerShown, presentation, route.name]);
39
- const content = /*#__PURE__*/React.createElement(DebugContainer, {
40
- style: [styles.container, presentation !== 'transparentModal' && presentation !== 'containedTransparentModal' && {
41
- backgroundColor: colors.background
42
- }, contentStyle],
43
- stackPresentation: presentation === 'card' ? 'push' : presentation
44
- }, children);
45
- if (isHeaderInModal) {
46
- return /*#__PURE__*/React.createElement(ScreenStack, {
47
- style: styles.container
48
- }, /*#__PURE__*/React.createElement(Screen, {
49
- enabled: true,
50
- isNativeStack: true,
51
- hasLargeHeader: options.headerLargeTitle ?? false,
52
- style: StyleSheet.absoluteFill
53
- }, content, /*#__PURE__*/React.createElement(HeaderConfig, _extends({}, options, {
54
- route: route,
55
- headerHeight: headerHeight,
56
- headerTopInsetEnabled: headerTopInsetEnabled,
57
- canGoBack: true
58
- }))));
59
- }
60
- return content;
61
- };
8
+ import { ScreenStack, ScreenStackItem } from 'react-native-screens';
9
+ import { debounce } from "../utils/debounce.js";
10
+ import { getModalRouteKeys } from "../utils/getModalRoutesKeys.js";
11
+ import { AnimatedHeaderHeightContext } from "../utils/useAnimatedHeaderHeight.js";
12
+ import { useDismissedRouteError } from "../utils/useDismissedRouteError.js";
13
+ import { useInvalidPreventRemoveError } from "../utils/useInvalidPreventRemoveError.js";
14
+ import { FooterComponent } from "./FooterComponent.js";
15
+ import { useHeaderConfigProps } from "./useHeaderConfigProps.js";
16
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
17
+ const ANDROID_DEFAULT_HEADER_HEIGHT = 56;
62
18
  const SceneView = ({
63
19
  index,
64
20
  focused,
@@ -66,6 +22,7 @@ const SceneView = ({
66
22
  previousDescriptor,
67
23
  nextDescriptor,
68
24
  isPresentationModal,
25
+ isPreloaded,
69
26
  onWillDisappear,
70
27
  onWillAppear,
71
28
  onAppear,
@@ -73,7 +30,8 @@ const SceneView = ({
73
30
  onDismissed,
74
31
  onHeaderBackButtonClicked,
75
32
  onNativeDismissCancelled,
76
- onGestureCancel
33
+ onGestureCancel,
34
+ onSheetDetentChanged
77
35
  }) => {
78
36
  const {
79
37
  route,
@@ -90,6 +48,7 @@ const SceneView = ({
90
48
  const {
91
49
  animationDuration,
92
50
  animationTypeForReplace = 'push',
51
+ fullScreenGestureShadowEnabled = false,
93
52
  gestureEnabled,
94
53
  gestureDirection = presentation === 'card' ? 'horizontal' : 'vertical',
95
54
  gestureResponseDistance,
@@ -104,17 +63,21 @@ const SceneView = ({
104
63
  navigationBarTranslucent,
105
64
  navigationBarHidden,
106
65
  orientation,
107
- sheetAllowedDetents = 'large',
108
- sheetLargestUndimmedDetent = 'all',
66
+ sheetAllowedDetents = [1.0],
67
+ sheetLargestUndimmedDetentIndex = -1,
109
68
  sheetGrabberVisible = false,
110
69
  sheetCornerRadius = -1.0,
70
+ sheetElevation = 24,
111
71
  sheetExpandsWhenScrolledToEdge = true,
72
+ sheetInitialDetentIndex = 0,
112
73
  statusBarAnimation,
113
74
  statusBarHidden,
114
75
  statusBarStyle,
115
76
  statusBarTranslucent,
116
77
  statusBarBackgroundColor,
117
- freezeOnBlur
78
+ unstable_sheetFooter = null,
79
+ freezeOnBlur,
80
+ contentStyle
118
81
  } = options;
119
82
  if (gestureDirection === 'vertical' && Platform.OS === 'ios') {
120
83
  // for `vertical` direction to work, we need to set `fullScreenGestureEnabled` to `true`
@@ -142,6 +105,9 @@ const SceneView = ({
142
105
  // for navigator with first screen as `modal` and the next as `card`
143
106
  presentation = 'card';
144
107
  }
108
+ const {
109
+ colors
110
+ } = useTheme();
145
111
  const insets = useSafeAreaInsets();
146
112
  const frame = useSafeAreaFrame();
147
113
 
@@ -162,7 +128,7 @@ const SceneView = ({
162
128
  // FIXME: Currently screens isn't using Material 3
163
129
  // So our `getDefaultHeaderHeight` doesn't return the correct value
164
130
  // So we hardcode the value here for now until screens is updated
165
- android: 56 + topInset,
131
+ android: ANDROID_DEFAULT_HEADER_HEIGHT + topInset,
166
132
  default: getDefaultHeaderHeight(frame, isModal, topInset)
167
133
  });
168
134
  const [headerHeight, setHeaderHeight] = React.useState(defaultHeaderHeight);
@@ -173,7 +139,7 @@ const SceneView = ({
173
139
  debounce(setHeaderHeight, 100), []);
174
140
  const hasCustomHeader = header !== undefined;
175
141
  let headerHeightCorrectionOffset = 0;
176
- if (isAndroid && !hasCustomHeader) {
142
+ if (Platform.OS === 'android' && !hasCustomHeader) {
177
143
  const statusBarHeight = StatusBar.currentHeight ?? 0;
178
144
 
179
145
  // FIXME: On Android, the native header height is not correctly calculated
@@ -192,30 +158,45 @@ const SceneView = ({
192
158
  // we apply additional padding in header only if its true.
193
159
  // For more details see: https://github.com/react-navigation/react-navigation/pull/12014
194
160
  const headerTopInsetEnabled = typeof statusBarTranslucent === 'boolean' ? statusBarTranslucent : topInset !== 0;
161
+ const canGoBack = previousDescriptor != null || parentHeaderBack != null;
195
162
  const backTitle = previousDescriptor ? getHeaderTitle(previousDescriptor.options, previousDescriptor.route.name) : parentHeaderBack?.title;
196
- const headerBack = React.useMemo(() => ({
197
- // No href needed for native
198
- href: undefined,
199
- title: backTitle
200
- }), [backTitle]);
163
+ const headerBack = React.useMemo(() => {
164
+ if (canGoBack) {
165
+ return {
166
+ href: undefined,
167
+ // No href needed for native
168
+ title: backTitle
169
+ };
170
+ }
171
+ return undefined;
172
+ }, [canGoBack, backTitle]);
201
173
  const isRemovePrevented = preventedRoutes[route.key]?.preventRemove;
202
- return /*#__PURE__*/React.createElement(Screen, {
203
- key: route.key,
204
- enabled: true,
205
- isNativeStack: true,
174
+ const headerConfig = useHeaderConfigProps({
175
+ ...options,
176
+ route,
177
+ canGoBack,
178
+ headerBackButtonMenuEnabled: isRemovePrevented !== undefined ? !isRemovePrevented : headerBackButtonMenuEnabled,
179
+ headerBackTitle: options.headerBackTitle !== undefined ? options.headerBackTitle : undefined,
180
+ headerHeight,
181
+ headerShown: header !== undefined ? false : headerShown,
182
+ headerTopInsetEnabled
183
+ });
184
+ return /*#__PURE__*/_jsx(ScreenStackItem, {
185
+ activityState: isPreloaded ? 0 : 2,
206
186
  style: StyleSheet.absoluteFill,
207
- hasLargeHeader: options.headerLargeTitle ?? false,
187
+ accessibilityElementsHidden: !focused,
188
+ importantForAccessibility: focused ? 'auto' : 'no-hide-descendants',
208
189
  customAnimationOnSwipe: animationMatchesGesture,
209
190
  fullScreenSwipeEnabled: fullScreenGestureEnabled,
210
- gestureEnabled: isAndroid ?
191
+ fullScreenSwipeShadowEnabled: fullScreenGestureShadowEnabled,
192
+ freezeOnBlur: freezeOnBlur,
193
+ gestureEnabled: Platform.OS === 'android' ?
211
194
  // This prop enables handling of system back gestures on Android
212
195
  // Since we handle them in JS side, we disable this
213
196
  false : gestureEnabled,
214
197
  homeIndicatorHidden: autoHideHomeIndicator,
215
198
  hideKeyboardOnSwipe: keyboardHandlingEnabled,
216
- navigationBarColor: navigationBarColor
217
- // @ts-expect-error prop supported from react-native-screens 3.32.0 onwards
218
- ,
199
+ navigationBarColor: navigationBarColor,
219
200
  navigationBarTranslucent: navigationBarTranslucent,
220
201
  navigationBarHidden: navigationBarHidden,
221
202
  replaceAnimation: animationTypeForReplace,
@@ -223,9 +204,11 @@ const SceneView = ({
223
204
  stackAnimation: animation,
224
205
  screenOrientation: orientation,
225
206
  sheetAllowedDetents: sheetAllowedDetents,
226
- sheetLargestUndimmedDetent: sheetLargestUndimmedDetent,
207
+ sheetLargestUndimmedDetentIndex: sheetLargestUndimmedDetentIndex,
227
208
  sheetGrabberVisible: sheetGrabberVisible,
209
+ sheetInitialDetentIndex: sheetInitialDetentIndex,
228
210
  sheetCornerRadius: sheetCornerRadius,
211
+ sheetElevation: sheetElevation,
229
212
  sheetExpandsWhenScrolledToEdge: sheetExpandsWhenScrolledToEdge,
230
213
  statusBarAnimation: statusBarAnimation,
231
214
  statusBarHidden: statusBarHidden,
@@ -240,6 +223,7 @@ const SceneView = ({
240
223
  onDisappear: onDisappear,
241
224
  onDismissed: onDismissed,
242
225
  onGestureCancel: onGestureCancel,
226
+ onSheetDetentChanged: onSheetDetentChanged,
243
227
  gestureResponseDistance: gestureResponseDistance,
244
228
  nativeBackButtonDismissalEnabled: false // on Android
245
229
  ,
@@ -259,6 +243,12 @@ const SceneView = ({
259
243
  }], {
260
244
  useNativeDriver: true,
261
245
  listener: e => {
246
+ if (Platform.OS === 'android' && (options.headerBackground != null || options.headerTransparent)) {
247
+ // FIXME: On Android, we get 0 if the header is translucent
248
+ // So we set a default height in that case
249
+ setHeaderHeight(ANDROID_DEFAULT_HEADER_HEIGHT + topInset);
250
+ return;
251
+ }
262
252
  if (e.nativeEvent && typeof e.nativeEvent === 'object' && 'headerHeight' in e.nativeEvent && typeof e.nativeEvent.headerHeight === 'number') {
263
253
  const headerHeight = e.nativeEvent.headerHeight + headerHeightCorrectionOffset;
264
254
 
@@ -272,68 +262,67 @@ const SceneView = ({
272
262
  }
273
263
  }
274
264
  }
275
- })
276
- // this prop is available since rn-screens 3.16
265
+ }),
266
+ contentStyle: [presentation !== 'transparentModal' && presentation !== 'containedTransparentModal' && {
267
+ backgroundColor: colors.background
268
+ }, contentStyle],
269
+ headerConfig: headerConfig
270
+ // When ts-expect-error is added, it affects all the props below it
271
+ // So we keep any props that need it at the end
272
+ // Otherwise invalid props may not be caught by TypeScript
277
273
  ,
278
- freezeOnBlur: freezeOnBlur
279
- }, /*#__PURE__*/React.createElement(NavigationContext.Provider, {
280
- value: navigation
281
- }, /*#__PURE__*/React.createElement(NavigationRouteContext.Provider, {
282
- value: route
283
- }, /*#__PURE__*/React.createElement(HeaderShownContext.Provider, {
284
- value: isParentHeaderShown || headerShown !== false
285
- }, /*#__PURE__*/React.createElement(AnimatedHeaderHeightContext.Provider, {
286
- value: animatedHeaderHeight
287
- }, /*#__PURE__*/React.createElement(HeaderHeightContext.Provider, {
288
- value: headerShown !== false ? headerHeight : parentHeaderHeight ?? 0
289
- }, headerBackground != null ?
290
- /*#__PURE__*/
291
- /**
292
- * To show a custom header background, we render it at the top of the screen below the header
293
- * The header also needs to be positioned absolutely (with `translucent` style)
294
- */
295
- React.createElement(View, {
296
- style: [styles.background, headerTransparent ? styles.translucent : null, {
297
- height: headerHeight
298
- }]
299
- }, headerBackground()) : null, /*#__PURE__*/React.createElement(View, {
300
- accessibilityElementsHidden: !focused,
301
- importantForAccessibility: focused ? 'auto' : 'no-hide-descendants',
302
- style: styles.scene
303
- }, /*#__PURE__*/React.createElement(MaybeNestedStack, {
304
- options: options,
305
- route: route,
306
- presentation: presentation,
307
- headerHeight: headerHeight,
308
- headerTopInsetEnabled: headerTopInsetEnabled
309
- }, /*#__PURE__*/React.createElement(HeaderBackContext.Provider, {
310
- value: headerBack
311
- }, render())), header !== undefined && headerShown !== false ? /*#__PURE__*/React.createElement(View, {
312
- onLayout: e => {
313
- const headerHeight = e.nativeEvent.layout.height;
314
- setHeaderHeight(headerHeight);
315
- rawAnimatedHeaderHeight.setValue(headerHeight);
316
- },
317
- style: headerTransparent ? styles.absolute : null
318
- }, header({
319
- back: headerBack,
320
- options,
321
- route,
322
- navigation
323
- })) : null), /*#__PURE__*/React.createElement(HeaderConfig, _extends({}, options, {
324
- route: route,
325
- headerBackButtonMenuEnabled: isRemovePrevented !== undefined ? !isRemovePrevented : headerBackButtonMenuEnabled,
326
- headerShown: header !== undefined ? false : headerShown,
327
- headerHeight: headerHeight,
328
- headerBackTitle: options.headerBackTitle !== undefined ? options.headerBackTitle : undefined,
329
- headerTopInsetEnabled: headerTopInsetEnabled,
330
- canGoBack: headerBack !== undefined
331
- }))))))));
274
+ children: /*#__PURE__*/_jsx(NavigationContext.Provider, {
275
+ value: navigation,
276
+ children: /*#__PURE__*/_jsx(NavigationRouteContext.Provider, {
277
+ value: route,
278
+ children: /*#__PURE__*/_jsx(AnimatedHeaderHeightContext.Provider, {
279
+ value: animatedHeaderHeight,
280
+ children: /*#__PURE__*/_jsxs(HeaderHeightContext.Provider, {
281
+ value: headerShown !== false ? headerHeight : parentHeaderHeight ?? 0,
282
+ children: [headerBackground != null ?
283
+ /*#__PURE__*/
284
+ /**
285
+ * To show a custom header background, we render it at the top of the screen below the header
286
+ * The header also needs to be positioned absolutely (with `translucent` style)
287
+ */
288
+ _jsx(View, {
289
+ style: [styles.background, headerTransparent ? styles.translucent : null, {
290
+ height: headerHeight
291
+ }],
292
+ children: headerBackground()
293
+ }) : null, header !== undefined && headerShown !== false ? /*#__PURE__*/_jsx(View, {
294
+ onLayout: e => {
295
+ const headerHeight = e.nativeEvent.layout.height;
296
+ setHeaderHeight(headerHeight);
297
+ rawAnimatedHeaderHeight.setValue(headerHeight);
298
+ },
299
+ style: [styles.header, headerTransparent ? styles.absolute : null],
300
+ children: header({
301
+ back: headerBack,
302
+ options,
303
+ route,
304
+ navigation
305
+ })
306
+ }) : null, /*#__PURE__*/_jsx(HeaderShownContext.Provider, {
307
+ value: isParentHeaderShown || headerShown !== false,
308
+ children: /*#__PURE__*/_jsx(HeaderBackContext.Provider, {
309
+ value: headerBack,
310
+ children: render()
311
+ })
312
+ }), presentation === 'formSheet' && unstable_sheetFooter && /*#__PURE__*/_jsx(FooterComponent, {
313
+ children: unstable_sheetFooter()
314
+ })]
315
+ })
316
+ })
317
+ })
318
+ })
319
+ }, route.key);
332
320
  };
333
321
  export function NativeStackView({
334
322
  state,
335
323
  navigation,
336
- descriptors
324
+ descriptors,
325
+ describe
337
326
  }) {
338
327
  const {
339
328
  setNextDismissedKey
@@ -343,102 +332,118 @@ export function NativeStackView({
343
332
  } = useTheme();
344
333
  useInvalidPreventRemoveError(descriptors);
345
334
  const modalRouteKeys = getModalRouteKeys(state.routes, descriptors);
346
- return /*#__PURE__*/React.createElement(SafeAreaProviderCompat, {
335
+ const preloadedDescriptors = state.preloadedRoutes.reduce((acc, route) => {
336
+ acc[route.key] = acc[route.key] || describe(route, true);
337
+ return acc;
338
+ }, {});
339
+ return /*#__PURE__*/_jsx(SafeAreaProviderCompat, {
347
340
  style: {
348
341
  backgroundColor: colors.background
349
- }
350
- }, /*#__PURE__*/React.createElement(ScreenStack, {
351
- style: styles.container
352
- }, state.routes.map((route, index) => {
353
- const descriptor = descriptors[route.key];
354
- const isFocused = state.index === index;
355
- const previousKey = state.routes[index - 1]?.key;
356
- const nextKey = state.routes[index + 1]?.key;
357
- const previousDescriptor = previousKey ? descriptors[previousKey] : undefined;
358
- const nextDescriptor = nextKey ? descriptors[nextKey] : undefined;
359
- const isModal = modalRouteKeys.includes(route.key);
360
- return /*#__PURE__*/React.createElement(SceneView, {
361
- key: route.key,
362
- index: index,
363
- focused: isFocused,
364
- descriptor: descriptor,
365
- previousDescriptor: previousDescriptor,
366
- nextDescriptor: nextDescriptor,
367
- isPresentationModal: isModal,
368
- onWillDisappear: () => {
369
- navigation.emit({
370
- type: 'transitionStart',
371
- data: {
372
- closing: true
342
+ },
343
+ children: /*#__PURE__*/_jsx(ScreenStack, {
344
+ style: styles.container,
345
+ children: state.routes.concat(state.preloadedRoutes).map((route, index) => {
346
+ const descriptor = descriptors[route.key] ?? preloadedDescriptors[route.key];
347
+ const isFocused = state.index === index;
348
+ const previousKey = state.routes[index - 1]?.key;
349
+ const nextKey = state.routes[index + 1]?.key;
350
+ const previousDescriptor = previousKey ? descriptors[previousKey] : undefined;
351
+ const nextDescriptor = nextKey ? descriptors[nextKey] : undefined;
352
+ const isModal = modalRouteKeys.includes(route.key);
353
+ const isPreloaded = preloadedDescriptors[route.key] !== undefined && descriptors[route.key] === undefined;
354
+ return /*#__PURE__*/_jsx(SceneView, {
355
+ index: index,
356
+ focused: isFocused,
357
+ descriptor: descriptor,
358
+ previousDescriptor: previousDescriptor,
359
+ nextDescriptor: nextDescriptor,
360
+ isPresentationModal: isModal,
361
+ isPreloaded: isPreloaded,
362
+ onWillDisappear: () => {
363
+ navigation.emit({
364
+ type: 'transitionStart',
365
+ data: {
366
+ closing: true
367
+ },
368
+ target: route.key
369
+ });
373
370
  },
374
- target: route.key
375
- });
376
- },
377
- onWillAppear: () => {
378
- navigation.emit({
379
- type: 'transitionStart',
380
- data: {
381
- closing: false
371
+ onWillAppear: () => {
372
+ navigation.emit({
373
+ type: 'transitionStart',
374
+ data: {
375
+ closing: false
376
+ },
377
+ target: route.key
378
+ });
382
379
  },
383
- target: route.key
384
- });
385
- },
386
- onAppear: () => {
387
- navigation.emit({
388
- type: 'transitionEnd',
389
- data: {
390
- closing: false
380
+ onAppear: () => {
381
+ navigation.emit({
382
+ type: 'transitionEnd',
383
+ data: {
384
+ closing: false
385
+ },
386
+ target: route.key
387
+ });
391
388
  },
392
- target: route.key
393
- });
394
- },
395
- onDisappear: () => {
396
- navigation.emit({
397
- type: 'transitionEnd',
398
- data: {
399
- closing: true
389
+ onDisappear: () => {
390
+ navigation.emit({
391
+ type: 'transitionEnd',
392
+ data: {
393
+ closing: true
394
+ },
395
+ target: route.key
396
+ });
400
397
  },
401
- target: route.key
402
- });
403
- },
404
- onDismissed: event => {
405
- navigation.dispatch({
406
- ...StackActions.pop(event.nativeEvent.dismissCount),
407
- source: route.key,
408
- target: state.key
409
- });
410
- setNextDismissedKey(route.key);
411
- },
412
- onHeaderBackButtonClicked: () => {
413
- navigation.dispatch({
414
- ...StackActions.pop(),
415
- source: route.key,
416
- target: state.key
417
- });
418
- },
419
- onNativeDismissCancelled: event => {
420
- navigation.dispatch({
421
- ...StackActions.pop(event.nativeEvent.dismissCount),
422
- source: route.key,
423
- target: state.key
424
- });
425
- },
426
- onGestureCancel: () => {
427
- navigation.emit({
428
- type: 'gestureCancel',
429
- target: route.key
430
- });
431
- }
432
- });
433
- })));
398
+ onDismissed: event => {
399
+ navigation.dispatch({
400
+ ...StackActions.pop(event.nativeEvent.dismissCount),
401
+ source: route.key,
402
+ target: state.key
403
+ });
404
+ setNextDismissedKey(route.key);
405
+ },
406
+ onHeaderBackButtonClicked: () => {
407
+ navigation.dispatch({
408
+ ...StackActions.pop(),
409
+ source: route.key,
410
+ target: state.key
411
+ });
412
+ },
413
+ onNativeDismissCancelled: event => {
414
+ navigation.dispatch({
415
+ ...StackActions.pop(event.nativeEvent.dismissCount),
416
+ source: route.key,
417
+ target: state.key
418
+ });
419
+ },
420
+ onGestureCancel: () => {
421
+ navigation.emit({
422
+ type: 'gestureCancel',
423
+ target: route.key
424
+ });
425
+ },
426
+ onSheetDetentChanged: event => {
427
+ navigation.emit({
428
+ type: 'sheetDetentChange',
429
+ target: route.key,
430
+ data: {
431
+ index: event.nativeEvent.index,
432
+ stable: event.nativeEvent.isStable
433
+ }
434
+ });
435
+ }
436
+ }, route.key);
437
+ })
438
+ })
439
+ });
434
440
  }
435
441
  const styles = StyleSheet.create({
436
442
  container: {
437
443
  flex: 1
438
444
  },
439
- scene: {
440
- flex: 1,
441
- flexDirection: 'column-reverse'
445
+ header: {
446
+ zIndex: 1
442
447
  },
443
448
  absolute: {
444
449
  position: 'absolute',