Native stack navigator for React Native applications that uses react-native-screens under the hood to deliver optimal performance by leveraging native navigation primitives.
—
Comprehensive screen configuration options for native stack navigation, including headers, animations, presentations, gestures, and platform-specific behaviors.
The complete interface for configuring screen behavior and appearance.
/**
* Comprehensive configuration options for native stack screens
*/
interface NativeStackNavigationOptions {
// Basic Options
title?: string;
header?: (props: NativeStackHeaderProps) => React.ReactNode;
headerShown?: boolean;
// Header Styling
headerStyle?: StyleProp<{ backgroundColor?: string }>;
headerTintColor?: string;
headerTitleAlign?: 'left' | 'center';
headerTitleStyle?: StyleProp<Pick<TextStyle, 'fontFamily' | 'fontSize' | 'fontWeight'> & { color?: string }>;
headerShadowVisible?: boolean;
headerTransparent?: boolean;
headerBlurEffect?: ScreenStackHeaderConfigProps['blurEffect'];
headerBackground?: () => React.ReactNode;
// Header Components
headerLeft?: (props: NativeStackHeaderLeftProps) => React.ReactNode;
headerRight?: (props: NativeStackHeaderRightProps) => React.ReactNode;
headerTitle?: string | ((props: { children: string; tintColor?: string }) => React.ReactNode);
// Back Button Configuration
headerBackVisible?: boolean;
headerBackTitle?: string;
headerBackTitleStyle?: StyleProp<{ fontFamily?: string; fontSize?: number }>;
headerBackImageSource?: ImageSourcePropType;
headerBackButtonMenuEnabled?: boolean;
headerBackButtonDisplayMode?: ScreenStackHeaderConfigProps['backButtonDisplayMode'];
// Large Title (iOS)
headerLargeTitle?: boolean;
headerLargeStyle?: StyleProp<{ backgroundColor?: string }>;
headerLargeTitleShadowVisible?: boolean;
headerLargeTitleStyle?: StyleProp<{
fontFamily?: string;
fontSize?: number;
fontWeight?: string;
color?: string;
}>;
// Search Bar
headerSearchBarOptions?: SearchBarProps;
// Screen Presentation
presentation?: 'card' | 'modal' | 'transparentModal' | 'containedModal' |
'containedTransparentModal' | 'fullScreenModal' | 'formSheet';
// Animations
animation?: 'default' | 'fade' | 'fade_from_bottom' | 'flip' | 'simple_push' |
'slide_from_bottom' | 'slide_from_right' | 'slide_from_left' |
'ios_from_right' | 'ios_from_left' | 'none';
animationDuration?: number;
animationTypeForReplace?: ScreenProps['replaceAnimation'];
animationMatchesGesture?: boolean;
// Gesture Configuration
gestureEnabled?: boolean;
gestureDirection?: ScreenProps['swipeDirection'];
fullScreenGestureEnabled?: boolean;
fullScreenGestureShadowEnabled?: boolean;
gestureResponseDistance?: ScreenProps['gestureResponseDistance'];
// Sheet Presentation Options
sheetAllowedDetents?: number[] | 'fitToContents';
sheetInitialDetentIndex?: number | 'last';
sheetExpandsWhenScrolledToEdge?: boolean;
sheetCornerRadius?: number;
sheetGrabberVisible?: boolean;
sheetLargestUndimmedDetentIndex?: number | 'none' | 'last';
sheetElevation?: number;
unstable_sheetFooter?: () => React.ReactNode;
// Status Bar
statusBarStyle?: ScreenProps['statusBarStyle'];
statusBarAnimation?: ScreenProps['statusBarAnimation'];
statusBarHidden?: boolean;
statusBarBackgroundColor?: string;
statusBarTranslucent?: boolean;
// Navigation Bar (Android)
navigationBarColor?: string;
navigationBarHidden?: boolean;
navigationBarTranslucent?: boolean;
// Other Options
contentStyle?: StyleProp<ViewStyle>;
orientation?: ScreenProps['screenOrientation'];
freezeOnBlur?: boolean;
autoHideHomeIndicator?: boolean;
keyboardHandlingEnabled?: boolean;
}Configure header appearance and behavior with extensive customization options.
Basic Header Options:
// Hide header completely
options={{ headerShown: false }}
// Custom header title
options={{ title: "My Screen" }}
// Custom header styling
options={{
headerStyle: { backgroundColor: '#6a51ae' },
headerTintColor: '#fff',
headerTitleStyle: { fontWeight: 'bold' },
}}
// Transparent header
options={{
headerTransparent: true,
headerBlurEffect: 'regular', // iOS only
}}Custom Header Components:
// Custom header function
options={{
header: ({ navigation, route, options, back }) => (
<CustomHeader
title={options.title}
canGoBack={!!back}
onBack={() => navigation.goBack()}
/>
),
}}
// Custom header left/right components
options={{
headerLeft: ({ tintColor, canGoBack }) => (
<TouchableOpacity onPress={() => navigation.openDrawer()}>
<Icon name="menu" color={tintColor} />
</TouchableOpacity>
),
headerRight: ({ tintColor }) => (
<TouchableOpacity onPress={() => navigation.navigate('Settings')}>
<Icon name="settings" color={tintColor} />
</TouchableOpacity>
),
}}Configure how screens are presented with different modal and transition styles.
Presentation Types:
// Standard card presentation (default)
options={{ presentation: 'card' }}
// Modal presentation
options={{ presentation: 'modal' }}
// Transparent modal (previous screen visible)
options={{ presentation: 'transparentModal' }}
// Form sheet (iOS) - bottom sheet style
options={{
presentation: 'formSheet',
sheetAllowedDetents: [0.5, 1.0],
sheetInitialDetentIndex: 0,
sheetGrabberVisible: true,
}}Control screen transition animations and timing.
Animation Types:
// Fade transition
options={{ animation: 'fade' }}
// Slide from bottom
options={{
animation: 'slide_from_bottom',
animationDuration: 300,
}}
// iOS-style slide (Android)
options={{ animation: 'ios_from_right' }}
// No animation
options={{ animation: 'none' }}
// Custom animation matching gestures
options={{
animation: 'simple_push',
animationMatchesGesture: true,
}}Configure swipe gestures and interactions.
Gesture Options:
// Disable gestures
options={{ gestureEnabled: false }}
// Vertical dismissal gesture
options={{
gestureDirection: 'vertical',
fullScreenGestureEnabled: true,
animation: 'slide_from_bottom',
}}
// Custom gesture response area
options={{
fullScreenGestureEnabled: true,
gestureResponseDistance: { start: 25, end: 135, top: 0, bottom: 0 },
}}Complete Screen Configuration:
<Stack.Screen
name="Profile"
component={ProfileScreen}
options={({ route, navigation }) => ({
title: route.params?.name || 'Profile',
headerStyle: { backgroundColor: '#6a51ae' },
headerTintColor: '#fff',
headerRight: ({ tintColor }) => (
<TouchableOpacity
onPress={() => navigation.navigate('EditProfile')}
>
<Icon name="edit" color={tintColor} />
</TouchableOpacity>
),
presentation: 'card',
animation: 'slide_from_right',
gestureEnabled: true,
headerBackTitle: 'Back',
})}
/>Modal Screen with Sheet Presentation:
<Stack.Screen
name="Settings"
component={SettingsScreen}
options={{
presentation: 'formSheet',
sheetAllowedDetents: [0.6, 1.0],
sheetInitialDetentIndex: 0,
sheetGrabberVisible: true,
sheetCornerRadius: 16,
headerShown: false,
}}
/>interface NativeStackHeaderProps {
back?: {
title: string | undefined;
href: string | undefined;
};
options: NativeStackNavigationOptions;
route: Route<string>;
navigation: NativeStackNavigationProp<ParamListBase>;
}
interface NativeStackHeaderLeftProps {
tintColor?: string;
canGoBack?: boolean;
label?: string;
href?: string;
}
interface NativeStackHeaderRightProps {
tintColor?: string;
canGoBack?: boolean;
}
type StyleProp<T> = T | T[] | null | undefined;
type ImageSourcePropType = any; // React Native image sourceInstall with Tessl CLI
npx tessl i tessl/npm-react-navigation--native-stack