Files
Chromacase/front/utils/navigator.tsx

127 lines
3.4 KiB
TypeScript

import {
createNavigatorFactory,
type DefaultNavigatorOptions,
type ParamListBase,
type TabActionHelpers,
type TabNavigationState,
TabRouter,
type TabRouterOptions,
useNavigationBuilder,
} from '@react-navigation/native';
import * as React from 'react';
import type { BottomTabNavigationConfig } from '@react-navigation/bottom-tabs/src/types';
import type {
BottomTabHeaderProps,
BottomTabNavigationEventMap,
BottomTabNavigationOptions,
BottomTabNavigationProp,
} from '@react-navigation/bottom-tabs';
import { BottomTabView } from '@react-navigation/bottom-tabs';
import { Screen, Header, getHeaderTitle, SafeAreaProviderCompat } from '@react-navigation/elements';
import ScaffoldMobileCC from '../components/UI/ScaffoldMobileCC';
import { useBreakpointValue } from 'native-base';
import ScaffoldDesktopCC from '../components/UI/ScaffoldDesktopCC';
type Props = DefaultNavigatorOptions<
ParamListBase,
TabNavigationState<ParamListBase>,
BottomTabNavigationOptions,
BottomTabNavigationEventMap
> &
TabRouterOptions &
BottomTabNavigationConfig & { layout?: unknown };
function BottomTabNavigator({
id,
initialRouteName,
backBehavior,
children,
layout,
screenListeners,
screenOptions,
sceneContainerStyle,
...rest
}: Props) {
const { state, descriptors, navigation, NavigationContent } = useNavigationBuilder<
TabNavigationState<ParamListBase>,
TabRouterOptions,
TabActionHelpers<ParamListBase>,
BottomTabNavigationOptions,
BottomTabNavigationEventMap
>(TabRouter, {
id,
initialRouteName,
backBehavior,
children,
// @ts-expect-error The layout property has been added after the last release of react-navigation.
layout,
screenListeners,
screenOptions,
});
const screenSize = useBreakpointValue({ base: 'small', md: 'big' });
const descriptor = descriptors[state.routes[state.index]!.key]!;
const header =
descriptor.options.header ??
(({ layout, options }: BottomTabHeaderProps) => (
<Header
{...options}
layout={layout}
title={getHeaderTitle(options, state.routes[state.index]!.name)}
/>
));
const dimensions = SafeAreaProviderCompat.initialMetrics.frame;
return (
<NavigationContent>
{screenSize === 'small' ? (
<BottomTabView
tabBar={ScaffoldMobileCC}
{...rest}
state={state}
navigation={navigation}
descriptors={descriptors}
sceneContainerStyle={[
sceneContainerStyle,
{
backgroundColor: 'transparent',
paddingBottom: 8,
},
]}
/>
) : (
<ScaffoldDesktopCC state={state} navigation={navigation} descriptors={descriptors}>
<Screen
focused
navigation={descriptor.navigation}
route={descriptor.route}
headerShown={descriptor.options.headerShown}
headerStatusBarHeight={descriptor.options.headerStatusBarHeight}
headerTransparent={descriptor.options.headerTransparent}
header={header({
layout: dimensions,
route: descriptor.route,
navigation:
descriptor.navigation as BottomTabNavigationProp<ParamListBase>,
options: descriptor.options,
})}
style={[sceneContainerStyle, { backgroundColor: 'transparent' }]}
>
{descriptor.render()}
</Screen>
</ScaffoldDesktopCC>
)}
</NavigationContent>
);
}
export const createCustomNavigator = createNavigatorFactory<
TabNavigationState<ParamListBase>,
BottomTabNavigationOptions,
BottomTabNavigationEventMap,
typeof BottomTabNavigator
>(BottomTabNavigator);