import React from 'react'; import { createNavigatorFactory, DefaultNavigatorOptions, EventArg, ParamListBase, NavigationHelpersContext, useNavigationBuilder, } from '@react-navigation/native'; import { BottomSheetRouter } from './router'; import type { BottomSheetNavigationConfig, BottomSheetNavigationEventMap, BottomSheetNavigationOptions, } from './types'; import { BottomSheetActionHelpers, SheetActions } from './actions'; import type { BottomSheetNavigationState, BottomSheetRouterOptions, } from './router'; import BottomSheetNavigatorView from './components/BottomSheetNavigatorView'; type Props = DefaultNavigatorOptions & BottomSheetRouterOptions & BottomSheetNavigationConfig; const BottomSheetNavigator = ({ initialRouteName, children, screenOptions, ...rest }: Props) => { const { state, descriptors, navigation } = useNavigationBuilder< BottomSheetNavigationState, BottomSheetRouterOptions, BottomSheetActionHelpers, BottomSheetNavigationOptions, BottomSheetNavigationEventMap >(BottomSheetRouter, { children, initialRouteName, screenOptions, }); React.useEffect( () => navigation.addListener?.('tabPress', (e) => { 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({ ...SheetActions.popToTop(), target: state.key, }); } }); }), [navigation, state.index, state.key] ); return ( ); }; export const createBottomSheetNavigator = createNavigatorFactory< BottomSheetNavigationState, BottomSheetNavigationOptions, BottomSheetNavigationEventMap, typeof BottomSheetNavigator >(BottomSheetNavigator);