DrawerNavigator.js
4.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/* @flow */
import * as React from 'react';
import { Dimensions, Platform, ScrollView } from 'react-native';
import createNavigator from './createNavigator';
import createNavigationContainer from '../createNavigationContainer';
import TabRouter from '../routers/TabRouter';
import DrawerScreen from '../views/Drawer/DrawerScreen';
import DrawerView from '../views/Drawer/DrawerView';
import DrawerItems from '../views/Drawer/DrawerNavigatorItems';
import SafeAreaView from '../views/SafeAreaView';
import NavigatorTypes from './NavigatorTypes';
import type { DrawerViewConfig } from '../views/Drawer/DrawerView';
import type {
NavigationState,
NavigationRouteConfigMap,
NavigationTabRouterConfig,
NavigationDrawerScreenOptions,
NavigationNavigatorProps,
} from '../TypeDefinition';
export type DrawerNavigatorConfig = {
containerConfig?: void,
} & NavigationTabRouterConfig &
DrawerViewConfig;
// A stack navigators props are the intersection between
// the base navigator props (navgiation, screenProps, etc)
// and the view's props
type DrawerNavigatorProps = NavigationNavigatorProps<
NavigationDrawerScreenOptions,
NavigationState
> &
React.ElementProps<typeof DrawerView>;
const defaultContentComponent = (
props: React.ElementProps<typeof DrawerItems>
) => (
<ScrollView alwaysBounceVertical={false}>
<SafeAreaView forceInset={{ top: 'always', horizontal: 'never' }}>
<DrawerItems {...props} />
</SafeAreaView>
</ScrollView>
);
const DefaultDrawerConfig = {
drawerWidth: () => {
/*
* Default drawer width is screen width - header height
* with a max width of 280 on mobile and 320 on tablet
* https://material.io/guidelines/patterns/navigation-drawer.html
*/
const { height, width } = Dimensions.get('window');
const smallerAxisSize = Math.min(height, width);
const isLandscape = width > height;
const isTablet = smallerAxisSize >= 600;
const appBarHeight = Platform.OS === 'ios' ? (isLandscape ? 32 : 44) : 56;
const maxWidth = isTablet ? 320 : 280;
return Math.min(smallerAxisSize - appBarHeight, maxWidth);
},
contentComponent: defaultContentComponent,
drawerPosition: 'left',
drawerBackgroundColor: 'white',
useNativeAnimations: true,
};
const DrawerNavigator = (
routeConfigs: NavigationRouteConfigMap,
config: DrawerNavigatorConfig = {
drawerOpenRoute: 'DrawerOpen',
drawerCloseRoute: 'DrawerClose',
drawerToggleRoute: 'DrawerToggle',
}
) => {
const mergedConfig = { ...DefaultDrawerConfig, ...config };
const {
containerConfig,
drawerWidth,
drawerLockMode,
contentComponent,
contentOptions,
drawerPosition,
useNativeAnimations,
drawerBackgroundColor,
drawerOpenRoute,
drawerCloseRoute,
drawerToggleRoute,
...tabsConfig
} = mergedConfig;
const contentRouter = TabRouter(routeConfigs, tabsConfig);
const drawerRouter = TabRouter(
{
[drawerCloseRoute]: {
screen: createNavigator(
contentRouter,
routeConfigs,
config,
NavigatorTypes.DRAWER
)((props: React.ElementProps<typeof DrawerScreen>) => (
<DrawerScreen {...props} />
)),
},
[drawerOpenRoute]: {
screen: () => null,
},
[drawerToggleRoute]: {
screen: () => null,
},
},
{
initialRouteName: drawerCloseRoute,
}
);
const navigator = createNavigator(
drawerRouter,
routeConfigs,
config,
NavigatorTypes.DRAWER
)((props: DrawerNavigatorProps) => (
<DrawerView
{...props}
drawerBackgroundColor={drawerBackgroundColor}
drawerLockMode={drawerLockMode}
useNativeAnimations={useNativeAnimations}
drawerWidth={drawerWidth}
contentComponent={contentComponent}
contentOptions={contentOptions}
drawerPosition={drawerPosition}
drawerOpenRoute={drawerOpenRoute}
drawerCloseRoute={drawerCloseRoute}
drawerToggleRoute={drawerToggleRoute}
/>
));
return createNavigationContainer(navigator);
};
export default DrawerNavigator;