127 lines
3.4 KiB
TypeScript
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);
|