Stack navigator component for iOS and Android with animated transitions and gestures
npx @tessl/cli install tessl/npm-react-navigation--stack@6.4.0React Navigation Stack is a powerful navigation component that provides stack-based navigation for React Native applications, supporting both iOS and Android platforms. It delivers native-feeling navigation experiences with smooth animated transitions, gesture handling, and extensive customization options including custom animations, header styling, and screen configurations.
npm install @react-navigation/stackimport { createStackNavigator } from '@react-navigation/stack';For complete transition control:
import {
createStackNavigator,
StackNavigationProp,
StackScreenProps,
CardStyleInterpolators,
HeaderStyleInterpolators,
TransitionPresets,
TransitionSpecs,
} from '@react-navigation/stack';import React from 'react';
import { createStackNavigator } from '@react-navigation/stack';
import { View, Text, Button } from 'react-native';
type RootStackParamList = {
Home: undefined;
Details: { itemId: number };
};
const Stack = createStackNavigator<RootStackParamList>();
function HomeScreen({ navigation }: StackScreenProps<RootStackParamList, 'Home'>) {
return (
<View>
<Text>Home Screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.navigate('Details', { itemId: 42 })}
/>
</View>
);
}
function DetailsScreen({ route }: StackScreenProps<RootStackParamList, 'Details'>) {
return (
<View>
<Text>Details Screen</Text>
<Text>Item ID: {route.params.itemId}</Text>
</View>
);
}
export default function App() {
return (
<Stack.Navigator initialRouteName="Home">
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Details" component={DetailsScreen} />
</Stack.Navigator>
);
}React Navigation Stack is built around several key components:
createStackNavigator creates stack navigation instances with type safetyStackView and Header provide the core navigation UICore navigator factory function for creating stack navigation instances with type-safe parameter lists and screen configuration.
function createStackNavigator<ParamList extends ParamListBase = ParamListBase>(): {
Navigator: React.ComponentType<StackNavigatorProps>;
Screen: React.ComponentType<StackScreenConfig>;
Group: React.ComponentType<StackGroupConfig>;
};Comprehensive collection of card transition interpolators providing platform-specific animations for screen transitions.
interface CardStyleInterpolators {
forHorizontalIOS: StackCardStyleInterpolator;
forVerticalIOS: StackCardStyleInterpolator;
forModalPresentationIOS: StackCardStyleInterpolator;
forFadeFromBottomAndroid: StackCardStyleInterpolator;
forRevealFromBottomAndroid: StackCardStyleInterpolator;
forScaleFromCenterAndroid: StackCardStyleInterpolator;
forBottomSheetAndroid: StackCardStyleInterpolator;
forFadeFromCenter: StackCardStyleInterpolator;
forNoAnimation: StackCardStyleInterpolator;
}Header transition interpolators for coordinating header animations with screen transitions, including cross-fade and slide effects.
interface HeaderStyleInterpolators {
forUIKit: StackHeaderStyleInterpolator;
forFade: StackHeaderStyleInterpolator;
forSlideLeft: StackHeaderStyleInterpolator;
forSlideRight: StackHeaderStyleInterpolator;
forSlideUp: StackHeaderStyleInterpolator;
forNoAnimation: StackHeaderStyleInterpolator;
}Complete transition configurations combining card, header, and timing specifications for common platform patterns.
interface TransitionPresets {
SlideFromRightIOS: TransitionPreset;
ModalSlideFromBottomIOS: TransitionPreset;
ModalPresentationIOS: TransitionPreset;
FadeFromBottomAndroid: TransitionPreset;
RevealFromBottomAndroid: TransitionPreset;
ScaleFromCenterAndroid: TransitionPreset;
BottomSheetAndroid: TransitionPreset;
ModalFadeTransition: TransitionPreset;
DefaultTransition: TransitionPreset;
ModalTransition: TransitionPreset;
}Animation timing and easing configurations that control the duration and feel of screen transitions.
interface TransitionSpecs {
TransitionIOSSpec: TransitionSpec;
FadeInFromBottomAndroidSpec: TransitionSpec;
FadeOutToBottomAndroidSpec: TransitionSpec;
RevealFromBottomAndroidSpec: TransitionSpec;
ScaleFromCenterAndroidSpec: TransitionSpec;
BottomSheetSlideInSpec: TransitionSpec;
BottomSheetSlideOutSpec: TransitionSpec;
}Utility hooks and context providers for accessing animation values and gesture handlers within screen components.
function useCardAnimation(): StackCardInterpolationProps;
function useGestureHandlerRef(): React.Ref<PanGestureHandler>;
const CardAnimationContext: React.Context<StackCardInterpolationProps | undefined>;
const GestureHandlerRefContext: React.Context<React.Ref<PanGestureHandler> | null>;type StackNavigationProp<
ParamList extends ParamListBase,
RouteName extends keyof ParamList = keyof ParamList,
NavigatorID extends string | undefined = undefined
> = NavigationProp<
ParamList,
RouteName,
NavigatorID,
StackNavigationState<ParamList>,
StackNavigationOptions,
StackNavigationEventMap
> & StackActionHelpers<ParamList>;
type StackScreenProps<
ParamList extends ParamListBase,
RouteName extends keyof ParamList = keyof ParamList,
NavigatorID extends string | undefined = undefined
> = {
navigation: StackNavigationProp<ParamList, RouteName, NavigatorID>;
route: RouteProp<ParamList, RouteName>;
};
interface StackNavigationEventMap {
transitionStart: { data: { closing: boolean } };
transitionEnd: { data: { closing: boolean } };
gestureStart: { data: undefined };
gestureEnd: { data: undefined };
gestureCancel: { data: undefined };
}interface TransitionPreset {
gestureDirection: GestureDirection;
transitionSpec: {
open: TransitionSpec;
close: TransitionSpec;
};
cardStyleInterpolator: StackCardStyleInterpolator;
headerStyleInterpolator: StackHeaderStyleInterpolator;
}
type TransitionSpec = {
animation: 'spring';
config: Omit<Animated.SpringAnimationConfig, 'toValue' | keyof Animated.AnimationConfig>;
} | {
animation: 'timing';
config: Omit<Animated.TimingAnimationConfig, 'toValue' | keyof Animated.AnimationConfig>;
};
type StackCardStyleInterpolator = (
props: StackCardInterpolationProps
) => StackCardInterpolatedStyle;
type StackHeaderStyleInterpolator = (
props: StackHeaderInterpolationProps
) => StackHeaderInterpolatedStyle;interface StackNavigationOptions extends StackHeaderOptions {
title?: string;
header?: (props: StackHeaderProps) => React.ReactNode;
headerMode?: StackHeaderMode;
headerShown?: boolean;
cardShadowEnabled?: boolean;
cardOverlayEnabled?: boolean;
cardOverlay?: (props: { style: Animated.WithAnimatedValue<StyleProp<ViewStyle>> }) => React.ReactNode;
cardStyle?: StyleProp<ViewStyle>;
presentation?: 'card' | 'modal' | 'transparentModal';
animationEnabled?: boolean;
animationTypeForReplace?: 'push' | 'pop';
gestureEnabled?: boolean;
gestureResponseDistance?: number;
gestureVelocityImpact?: number;
detachPreviousScreen?: boolean;
keyboardHandlingEnabled?: boolean;
freezeOnBlur?: boolean;
}
interface StackNavigationConfig {
detachInactiveScreens?: boolean;
}
interface StackHeaderProps {
layout: Layout;
back?: {
title: string;
};
progress: SceneProgress;
options: StackNavigationOptions;
route: Route<string>;
navigation: StackNavigationProp<ParamListBase>;
styleInterpolator: StackHeaderStyleInterpolator;
}
type StackHeaderMode = 'float' | 'screen';
type GestureDirection = 'horizontal' | 'horizontal-inverted' | 'vertical' | 'vertical-inverted';interface StackCardInterpolationProps {
current: {
progress: Animated.AnimatedInterpolation<number>;
};
next?: {
progress: Animated.AnimatedInterpolation<number>;
};
index: number;
closing: Animated.AnimatedInterpolation<0 | 1>;
swiping: Animated.AnimatedInterpolation<0 | 1>;
inverted: Animated.AnimatedInterpolation<-1 | 1>;
layouts: {
screen: Layout;
};
insets: {
top: number;
right: number;
bottom: number;
left: number;
};
}
interface StackCardInterpolatedStyle {
containerStyle?: any;
cardStyle?: any;
overlayStyle?: any;
shadowStyle?: any;
}
interface StackHeaderInterpolationProps {
current: {
progress: Animated.AnimatedInterpolation<number>;
};
next?: {
progress: Animated.AnimatedInterpolation<number>;
};
layouts: {
header: Layout;
screen: Layout;
title?: Layout;
leftLabel?: Layout;
};
}
interface StackHeaderInterpolatedStyle {
leftLabelStyle?: any;
leftButtonStyle?: any;
rightButtonStyle?: any;
titleStyle?: any;
backgroundStyle?: any;
}