@react-navigation/native-stack 7.0.0-rc.23 → 7.0.0-rc.25

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/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
  /**
@@ -350,7 +348,11 @@ export type NativeStackNavigationOptions = {
350
348
  *
351
349
  * In such cases, the "default" mode will be used instead.
352
350
  *
353
- * @platform ios
351
+ * Defaults to "default" on iOS, and "minimal" on other platforms.
352
+ *
353
+ * Only supported on iOS and Web.
354
+ *
355
+ * @platform ios, web
354
356
  */
355
357
  headerBackButtonDisplayMode?: ScreenStackHeaderConfigProps['backButtonDisplayMode'];
356
358
  /**
@@ -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
  }