import { createNavigatorFactory, EventArg, ParamListBase, StackActionHelpers, StackActions, StackNavigationState, StackRouter, StackRouterOptions, useNavigationBuilder, } from '@react-navigation/native'; import * as React from 'react'; import type { NativeStackNavigationEventMap, NativeStackNavigationOptions, NativeStackNavigatorProps, } from '../types'; import NativeStackView from '../views/NativeStackView'; function NativeStackNavigator({ id, initialRouteName, children, screenListeners, screenOptions, ...rest }: NativeStackNavigatorProps) { const { state, descriptors, navigation, NavigationContent } = useNavigationBuilder< StackNavigationState, StackRouterOptions, StackActionHelpers, NativeStackNavigationOptions, NativeStackNavigationEventMap >(StackRouter, { id, initialRouteName, children, screenListeners, screenOptions, }); React.useEffect( () => // @ts-expect-error: there may not be a tab navigator in parent navigation?.addListener?.('tabPress', (e: any) => { const isFocused = navigation.isFocused(); // Run the operation in the next frame so we're sure all listeners have been run // This is necessary to know if preventDefault() has been called requestAnimationFrame(() => { if ( state.index > 0 && isFocused && !(e as EventArg<'tabPress', true>).defaultPrevented ) { // When user taps on already focused tab and we're inside the tab, // reset the stack to replicate native behaviour navigation.dispatch({ ...StackActions.popToTop(), target: state.key, }); } }); }), [navigation, state.index, state.key] ); return ( ); } export default createNavigatorFactory< StackNavigationState, NativeStackNavigationOptions, NativeStackNavigationEventMap, typeof NativeStackNavigator >(NativeStackNavigator);