@react-navigation/native-stack 7.0.0-rc.22 → 7.0.0-rc.24

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 (29) hide show
  1. package/lib/commonjs/views/HeaderConfig.js +11 -3
  2. package/lib/commonjs/views/HeaderConfig.js.map +1 -1
  3. package/lib/commonjs/views/NativeStackView.js +15 -38
  4. package/lib/commonjs/views/NativeStackView.js.map +1 -1
  5. package/lib/commonjs/views/NativeStackView.native.js +52 -56
  6. package/lib/commonjs/views/NativeStackView.native.js.map +1 -1
  7. package/lib/module/views/HeaderConfig.js +11 -3
  8. package/lib/module/views/HeaderConfig.js.map +1 -1
  9. package/lib/module/views/NativeStackView.js +15 -38
  10. package/lib/module/views/NativeStackView.js.map +1 -1
  11. package/lib/module/views/NativeStackView.native.js +52 -56
  12. package/lib/module/views/NativeStackView.native.js.map +1 -1
  13. package/lib/typescript/commonjs/src/types.d.ts +19 -9
  14. package/lib/typescript/commonjs/src/types.d.ts.map +1 -1
  15. package/lib/typescript/commonjs/src/views/HeaderConfig.d.ts.map +1 -1
  16. package/lib/typescript/commonjs/src/views/NativeStackView.d.ts.map +1 -1
  17. package/lib/typescript/commonjs/src/views/NativeStackView.native.d.ts.map +1 -1
  18. package/lib/typescript/commonjs/tsconfig.build.tsbuildinfo +1 -1
  19. package/lib/typescript/module/src/types.d.ts +19 -9
  20. package/lib/typescript/module/src/types.d.ts.map +1 -1
  21. package/lib/typescript/module/src/views/HeaderConfig.d.ts.map +1 -1
  22. package/lib/typescript/module/src/views/NativeStackView.d.ts.map +1 -1
  23. package/lib/typescript/module/src/views/NativeStackView.native.d.ts.map +1 -1
  24. package/lib/typescript/module/tsconfig.build.tsbuildinfo +1 -1
  25. package/package.json +5 -5
  26. package/src/types.tsx +19 -9
  27. package/src/views/HeaderConfig.tsx +13 -4
  28. package/src/views/NativeStackView.native.tsx +86 -90
  29. package/src/views/NativeStackView.tsx +9 -33
package/src/types.tsx CHANGED
@@ -114,7 +114,7 @@ export type NativeStackHeaderRightProps = {
114
114
  /**
115
115
  * Whether it's possible to navigate back in stack.
116
116
  */
117
- canGoBack: boolean;
117
+ canGoBack?: boolean;
118
118
  };
119
119
 
120
120
  export type NativeStackHeaderLeftProps = NativeStackHeaderRightProps & {
@@ -150,9 +150,9 @@ export type NativeStackNavigationOptions = {
150
150
  * Defaults to the previous scene's title, or "Back" if there's not enough space.
151
151
  * Use `headerBackButtonDisplayMode: "minimal"` to hide it.
152
152
  *
153
- * Only supported on iOS.
153
+ * Only supported on iOS and Web.
154
154
  *
155
- * @platform ios
155
+ * @platform ios, web
156
156
  */
157
157
  headerBackTitle?: string;
158
158
  /**
@@ -160,9 +160,9 @@ export type NativeStackNavigationOptions = {
160
160
  * - fontFamily
161
161
  * - fontSize
162
162
  *
163
- * Only supported on iOS.
163
+ * Only supported on iOS and Web.
164
164
  *
165
- * @platform ios
165
+ * @platform ios, web
166
166
  */
167
167
  headerBackTitleStyle?: StyleProp<{
168
168
  fontFamily?: string;
@@ -321,8 +321,6 @@ export type NativeStackNavigationOptions = {
321
321
  * Options to render a native search bar.
322
322
  * You also need to specify `contentInsetAdjustmentBehavior="automatic"` in your `ScrollView`, `FlatList` etc.
323
323
  * If you don't have a `ScrollView`, specify `headerTransparent: false`.
324
- *
325
- * Only supported on iOS and Android.
326
324
  */
327
325
  headerSearchBarOptions?: Omit<SearchBarProps, 'ref'>;
328
326
  /**
@@ -339,10 +337,22 @@ export type NativeStackNavigationOptions = {
339
337
  *
340
338
  * Supported values:
341
339
  * - "default" - Displays one of the following depending on the available space: previous screen's title, generic title (e.g. 'Back') or no title (only icon).
342
- * - "generic" – Displays one of the following depending on the available space: generic title (e.g. 'Back') or no title (only icon). iOS >= 14 only, falls back to "default" on older iOS versions.
340
+ * - "generic" – Displays one of the following depending on the available space: generic title (e.g. 'Back') or no title (only icon).
343
341
  * - "minimal" – Always displays only the icon without a title.
344
342
  *
345
- * @platform ios
343
+ * The "generic" mode is not supported when:
344
+ * - The iOS version is lower than 14
345
+ * - Custom back title is set
346
+ * - Custom back title style is set
347
+ * - Back button menu is disabled
348
+ *
349
+ * In such cases, the "default" mode will be used instead.
350
+ *
351
+ * Defaults to "default" on iOS, and "minimal" on other platforms.
352
+ *
353
+ * Only supported on iOS and Web.
354
+ *
355
+ * @platform ios, web
346
356
  */
347
357
  headerBackButtonDisplayMode?: ScreenStackHeaderConfigProps['backButtonDisplayMode'];
348
358
  /**
@@ -176,8 +176,17 @@ export function HeaderConfig({
176
176
  Platform.OS === 'ios' &&
177
177
  headerTransparent !== false);
178
178
 
179
- const isBackButtonDisplayModeAvailableForCurrentPlatform =
180
- Platform.OS === 'ios' && parseInt(Platform.Version, 10) >= 14;
179
+ const isBackButtonDisplayModeAvailable =
180
+ // On iOS 14+
181
+ Platform.OS === 'ios' &&
182
+ parseInt(Platform.Version, 10) >= 14 &&
183
+ // Doesn't have custom back title
184
+ headerBackTitle == null &&
185
+ // Doesn't have custom styling
186
+ backTitleFontFamily == null &&
187
+ backTitleFontSize == null &&
188
+ // Back button menu is not disabled
189
+ headerBackButtonMenuEnabled !== false;
181
190
 
182
191
  return (
183
192
  <ScreenStackHeaderConfig
@@ -185,12 +194,12 @@ export function HeaderConfig({
185
194
  backgroundColor={headerBackgroundColor}
186
195
  backTitle={headerBackTitle}
187
196
  backTitleVisible={
188
- isBackButtonDisplayModeAvailableForCurrentPlatform
197
+ isBackButtonDisplayModeAvailable
189
198
  ? undefined
190
199
  : headerBackButtonDisplayMode !== 'minimal'
191
200
  }
192
201
  backButtonDisplayMode={
193
- isBackButtonDisplayModeAvailableForCurrentPlatform
202
+ isBackButtonDisplayModeAvailable
194
203
  ? headerBackButtonDisplayMode
195
204
  : undefined
196
205
  }
@@ -329,6 +329,8 @@ const SceneView = ({
329
329
  key={route.key}
330
330
  enabled
331
331
  isNativeStack
332
+ accessibilityElementsHidden={!focused}
333
+ importantForAccessibility={focused ? 'auto' : 'no-hide-descendants'}
332
334
  style={StyleSheet.absoluteFill}
333
335
  hasLargeHeader={options.headerLargeTitle ?? false}
334
336
  customAnimationOnSwipe={animationMatchesGesture}
@@ -430,99 +432,94 @@ const SceneView = ({
430
432
  >
431
433
  <NavigationContext.Provider value={navigation}>
432
434
  <NavigationRouteContext.Provider value={route}>
433
- <HeaderShownContext.Provider
434
- value={isParentHeaderShown || headerShown !== false}
435
- >
436
- <AnimatedHeaderHeightContext.Provider value={animatedHeaderHeight}>
437
- <HeaderHeightContext.Provider
438
- value={
439
- headerShown !== false ? headerHeight : parentHeaderHeight ?? 0
440
- }
441
- >
442
- {headerBackground != null ? (
443
- /**
444
- * To show a custom header background, we render it at the top of the screen below the header
445
- * The header also needs to be positioned absolutely (with `translucent` style)
446
- */
447
- <View
448
- style={[
449
- styles.background,
450
- headerTransparent ? styles.translucent : null,
451
- { height: headerHeight },
452
- ]}
453
- >
454
- {headerBackground()}
455
- </View>
456
- ) : null}
435
+ <AnimatedHeaderHeightContext.Provider value={animatedHeaderHeight}>
436
+ <HeaderHeightContext.Provider
437
+ value={
438
+ headerShown !== false ? headerHeight : parentHeaderHeight ?? 0
439
+ }
440
+ >
441
+ {headerBackground != null ? (
442
+ /**
443
+ * To show a custom header background, we render it at the top of the screen below the header
444
+ * The header also needs to be positioned absolutely (with `translucent` style)
445
+ */
446
+ <View
447
+ style={[
448
+ styles.background,
449
+ headerTransparent ? styles.translucent : null,
450
+ { height: headerHeight },
451
+ ]}
452
+ >
453
+ {headerBackground()}
454
+ </View>
455
+ ) : null}
456
+ {header !== undefined && headerShown !== false ? (
457
457
  <View
458
- accessibilityElementsHidden={!focused}
459
- importantForAccessibility={
460
- focused ? 'auto' : 'no-hide-descendants'
461
- }
462
- style={styles.scene}
458
+ onLayout={(e) => {
459
+ const headerHeight = e.nativeEvent.layout.height;
460
+
461
+ setHeaderHeight(headerHeight);
462
+ rawAnimatedHeaderHeight.setValue(headerHeight);
463
+ }}
464
+ style={[
465
+ styles.header,
466
+ headerTransparent ? styles.absolute : null,
467
+ ]}
463
468
  >
464
- <MaybeNestedStack
465
- options={options}
466
- route={route}
467
- presentation={presentation}
468
- headerHeight={headerHeight}
469
- headerTopInsetEnabled={headerTopInsetEnabled}
470
- >
471
- <HeaderBackContext.Provider value={headerBack}>
472
- {render()}
473
- </HeaderBackContext.Provider>
474
- </MaybeNestedStack>
475
- {header !== undefined && headerShown !== false ? (
476
- <View
477
- onLayout={(e) => {
478
- const headerHeight = e.nativeEvent.layout.height;
479
-
480
- setHeaderHeight(headerHeight);
481
- rawAnimatedHeaderHeight.setValue(headerHeight);
482
- }}
483
- style={headerTransparent ? styles.absolute : null}
484
- >
485
- {header({
486
- back: headerBack,
487
- options,
488
- route,
489
- navigation,
490
- })}
491
- </View>
492
- ) : null}
469
+ {header({
470
+ back: headerBack,
471
+ options,
472
+ route,
473
+ navigation,
474
+ })}
493
475
  </View>
494
- {/**
495
- * `HeaderConfig` needs to be the direct child of `Screen` without any intermediate `View`
496
- * We don't render it conditionally to make it possible to dynamically render a custom `header`
497
- * Otherwise dynamically rendering a custom `header` leaves the native header visible
498
- *
499
- * https://github.com/software-mansion/react-native-screens/blob/main/guides/GUIDE_FOR_LIBRARY_AUTHORS.md#screenstackheaderconfig
500
- *
501
- * HeaderConfig must not be first child of a Screen.
502
- * See https://github.com/software-mansion/react-native-screens/pull/1825
503
- * for detailed explanation
504
- */}
505
- <HeaderConfig
506
- {...options}
476
+ ) : null}
477
+ <HeaderShownContext.Provider
478
+ value={isParentHeaderShown || headerShown !== false}
479
+ >
480
+ <MaybeNestedStack
481
+ options={options}
507
482
  route={route}
508
- headerBackButtonMenuEnabled={
509
- isRemovePrevented !== undefined
510
- ? !isRemovePrevented
511
- : headerBackButtonMenuEnabled
512
- }
513
- headerShown={header !== undefined ? false : headerShown}
483
+ presentation={presentation}
514
484
  headerHeight={headerHeight}
515
- headerBackTitle={
516
- options.headerBackTitle !== undefined
517
- ? options.headerBackTitle
518
- : undefined
519
- }
520
485
  headerTopInsetEnabled={headerTopInsetEnabled}
521
- canGoBack={headerBack !== undefined}
522
- />
523
- </HeaderHeightContext.Provider>
524
- </AnimatedHeaderHeightContext.Provider>
525
- </HeaderShownContext.Provider>
486
+ >
487
+ <HeaderBackContext.Provider value={headerBack}>
488
+ {render()}
489
+ </HeaderBackContext.Provider>
490
+ </MaybeNestedStack>
491
+ </HeaderShownContext.Provider>
492
+ {/**
493
+ * `HeaderConfig` needs to be the direct child of `Screen` without any intermediate `View`
494
+ * We don't render it conditionally to make it possible to dynamically render a custom `header`
495
+ * Otherwise dynamically rendering a custom `header` leaves the native header visible
496
+ *
497
+ * https://github.com/software-mansion/react-native-screens/blob/main/guides/GUIDE_FOR_LIBRARY_AUTHORS.md#screenstackheaderconfig
498
+ *
499
+ * HeaderConfig must not be first child of a Screen.
500
+ * See https://github.com/software-mansion/react-native-screens/pull/1825
501
+ * for detailed explanation
502
+ */}
503
+ <HeaderConfig
504
+ {...options}
505
+ route={route}
506
+ headerBackButtonMenuEnabled={
507
+ isRemovePrevented !== undefined
508
+ ? !isRemovePrevented
509
+ : headerBackButtonMenuEnabled
510
+ }
511
+ headerShown={header !== undefined ? false : headerShown}
512
+ headerHeight={headerHeight}
513
+ headerBackTitle={
514
+ options.headerBackTitle !== undefined
515
+ ? options.headerBackTitle
516
+ : undefined
517
+ }
518
+ headerTopInsetEnabled={headerTopInsetEnabled}
519
+ canGoBack={headerBack !== undefined}
520
+ />
521
+ </HeaderHeightContext.Provider>
522
+ </AnimatedHeaderHeightContext.Provider>
526
523
  </NavigationRouteContext.Provider>
527
524
  </NavigationContext.Provider>
528
525
  </Screen>
@@ -637,9 +634,8 @@ const styles = StyleSheet.create({
637
634
  container: {
638
635
  flex: 1,
639
636
  },
640
- scene: {
641
- flex: 1,
642
- flexDirection: 'column-reverse',
637
+ header: {
638
+ zIndex: 1,
643
639
  },
644
640
  absolute: {
645
641
  position: 'absolute',
@@ -75,20 +75,13 @@ export function NativeStackView({ state, descriptors }: Props) {
75
75
  const {
76
76
  header,
77
77
  headerShown,
78
- headerTintColor,
79
78
  headerBackImageSource,
80
79
  headerLeft,
81
- headerRight,
82
- headerTitle,
83
- headerTitleAlign,
84
- headerTitleStyle,
85
- headerStyle,
86
- headerShadowVisible,
87
80
  headerTransparent,
88
- headerBackground,
89
81
  headerBackTitle,
90
82
  presentation,
91
83
  contentStyle,
84
+ ...rest
92
85
  } = options;
93
86
 
94
87
  const nextPresentation = nextDescriptor?.options.presentation;
@@ -111,20 +104,21 @@ export function NativeStackView({ state, descriptors }: Props) {
111
104
  })
112
105
  ) : (
113
106
  <Header
107
+ {...rest}
108
+ back={headerBack}
114
109
  title={getHeaderTitle(options, route.name)}
115
- headerTintColor={headerTintColor}
116
110
  headerLeft={
117
111
  typeof headerLeft === 'function'
118
- ? ({ tintColor }) =>
112
+ ? ({ label, ...rest }) =>
119
113
  headerLeft({
120
- tintColor,
121
- canGoBack,
122
- label: headerBackTitle,
123
- href: headerBack?.href,
114
+ ...rest,
115
+ label: headerBackTitle ?? label,
124
116
  })
125
117
  : headerLeft === undefined && canGoBack
126
- ? ({ tintColor }) => (
118
+ ? ({ tintColor, label, ...rest }) => (
127
119
  <HeaderBackButton
120
+ {...rest}
121
+ label={headerBackTitle ?? label}
128
122
  tintColor={tintColor}
129
123
  backImage={
130
124
  headerBackImageSource !== undefined
@@ -141,28 +135,10 @@ export function NativeStackView({ state, descriptors }: Props) {
141
135
  : undefined
142
136
  }
143
137
  onPress={navigation.goBack}
144
- href={headerBack.href}
145
138
  />
146
139
  )
147
140
  : headerLeft
148
141
  }
149
- headerRight={
150
- typeof headerRight === 'function'
151
- ? ({ tintColor }) => headerRight({ tintColor, canGoBack })
152
- : headerRight
153
- }
154
- headerTitle={
155
- typeof headerTitle === 'function'
156
- ? ({ children, tintColor }) =>
157
- headerTitle({ children, tintColor })
158
- : headerTitle
159
- }
160
- headerTitleAlign={headerTitleAlign}
161
- headerTitleStyle={headerTitleStyle}
162
- headerTransparent={headerTransparent}
163
- headerShadowVisible={headerShadowVisible}
164
- headerBackground={headerBackground}
165
- headerStyle={headerStyle}
166
142
  />
167
143
  )
168
144
  }