@react-navigation/drawer 7.0.0-alpha.0 → 7.0.0-alpha.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/commonjs/index.js +20 -21
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/navigators/createDrawerNavigator.js +11 -9
- package/lib/commonjs/navigators/createDrawerNavigator.js.map +1 -1
- package/lib/commonjs/types.js.map +1 -1
- package/lib/commonjs/utils/DrawerPositionContext.js +4 -5
- package/lib/commonjs/utils/DrawerPositionContext.js.map +1 -1
- package/lib/commonjs/utils/DrawerStatusContext.js +4 -6
- package/lib/commonjs/utils/DrawerStatusContext.js.map +1 -1
- package/lib/commonjs/utils/addCancelListener.js +19 -0
- package/lib/commonjs/utils/addCancelListener.js.map +1 -0
- package/lib/commonjs/utils/addCancelListener.native.js +15 -0
- package/lib/commonjs/utils/addCancelListener.native.js.map +1 -0
- package/lib/commonjs/utils/getDrawerStatusFromState.js +2 -2
- package/lib/commonjs/utils/getDrawerStatusFromState.js.map +1 -1
- package/lib/commonjs/utils/useDrawerStatus.js +5 -6
- package/lib/commonjs/utils/useDrawerStatus.js.map +1 -1
- package/lib/commonjs/views/DrawerContent.js +7 -8
- package/lib/commonjs/views/DrawerContent.js.map +1 -1
- package/lib/commonjs/views/DrawerContentScrollView.js +12 -10
- package/lib/commonjs/views/DrawerContentScrollView.js.map +1 -1
- package/lib/commonjs/views/DrawerItem.js +14 -64
- package/lib/commonjs/views/DrawerItem.js.map +1 -1
- package/lib/commonjs/views/DrawerItemList.js +6 -7
- package/lib/commonjs/views/DrawerItemList.js.map +1 -1
- package/lib/commonjs/views/DrawerToggleButton.js +5 -7
- package/lib/commonjs/views/DrawerToggleButton.js.map +1 -1
- package/lib/commonjs/views/DrawerView.js +69 -38
- package/lib/commonjs/views/DrawerView.js.map +1 -1
- package/lib/commonjs/views/ScreenFallback.js +4 -6
- package/lib/commonjs/views/ScreenFallback.js.map +1 -1
- package/lib/module/index.js +10 -10
- package/lib/module/index.js.map +1 -1
- package/lib/module/navigators/createDrawerNavigator.js +7 -3
- package/lib/module/navigators/createDrawerNavigator.js.map +1 -1
- package/lib/module/types.js.map +1 -1
- package/lib/module/utils/DrawerPositionContext.js +1 -1
- package/lib/module/utils/DrawerPositionContext.js.map +1 -1
- package/lib/module/utils/DrawerStatusContext.js +1 -2
- package/lib/module/utils/DrawerStatusContext.js.map +1 -1
- package/lib/module/utils/addCancelListener.js +12 -0
- package/lib/module/utils/addCancelListener.js.map +1 -0
- package/lib/module/utils/addCancelListener.native.js +8 -0
- package/lib/module/utils/addCancelListener.native.js.map +1 -0
- package/lib/module/utils/getDrawerStatusFromState.js +2 -2
- package/lib/module/utils/getDrawerStatusFromState.js.map +1 -1
- package/lib/module/utils/useDrawerStatus.js +2 -2
- package/lib/module/utils/useDrawerStatus.js.map +1 -1
- package/lib/module/views/DrawerContent.js +3 -3
- package/lib/module/views/DrawerContent.js.map +1 -1
- package/lib/module/views/DrawerContentScrollView.js +9 -5
- package/lib/module/views/DrawerContentScrollView.js.map +1 -1
- package/lib/module/views/DrawerItem.js +14 -64
- package/lib/module/views/DrawerItem.js.map +1 -1
- package/lib/module/views/DrawerItemList.js +4 -4
- package/lib/module/views/DrawerItemList.js.map +1 -1
- package/lib/module/views/DrawerToggleButton.js +3 -5
- package/lib/module/views/DrawerToggleButton.js.map +1 -1
- package/lib/module/views/DrawerView.js +65 -34
- package/lib/module/views/DrawerView.js.map +1 -1
- package/lib/module/views/ScreenFallback.js +2 -4
- package/lib/module/views/ScreenFallback.js.map +1 -1
- package/lib/typescript/src/index.d.ts +10 -10
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/navigators/createDrawerNavigator.d.ts +6 -6
- package/lib/typescript/src/navigators/createDrawerNavigator.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +34 -10
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/lib/typescript/src/utils/DrawerPositionContext.d.ts +1 -2
- package/lib/typescript/src/utils/DrawerPositionContext.d.ts.map +1 -1
- package/lib/typescript/src/utils/DrawerStatusContext.d.ts +1 -2
- package/lib/typescript/src/utils/DrawerStatusContext.d.ts.map +1 -1
- package/lib/typescript/src/utils/addCancelListener.d.ts +2 -0
- package/lib/typescript/src/utils/addCancelListener.d.ts.map +1 -0
- package/lib/typescript/src/utils/addCancelListener.native.d.ts +2 -0
- package/lib/typescript/src/utils/addCancelListener.native.d.ts.map +1 -0
- package/lib/typescript/src/utils/getDrawerStatusFromState.d.ts +1 -1
- package/lib/typescript/src/utils/getDrawerStatusFromState.d.ts.map +1 -1
- package/lib/typescript/src/utils/useDrawerStatus.d.ts +1 -1
- package/lib/typescript/src/utils/useDrawerStatus.d.ts.map +1 -1
- package/lib/typescript/src/views/DrawerContent.d.ts +2 -2
- package/lib/typescript/src/views/DrawerContent.d.ts.map +1 -1
- package/lib/typescript/src/views/DrawerContentScrollView.d.ts +2 -3
- package/lib/typescript/src/views/DrawerContentScrollView.d.ts.map +1 -1
- package/lib/typescript/src/views/DrawerItem.d.ts +3 -3
- package/lib/typescript/src/views/DrawerItem.d.ts.map +1 -1
- package/lib/typescript/src/views/DrawerItemList.d.ts +2 -2
- package/lib/typescript/src/views/DrawerItemList.d.ts.map +1 -1
- package/lib/typescript/src/views/DrawerToggleButton.d.ts +2 -2
- package/lib/typescript/src/views/DrawerToggleButton.d.ts.map +1 -1
- package/lib/typescript/src/views/DrawerView.d.ts +3 -3
- package/lib/typescript/src/views/DrawerView.d.ts.map +1 -1
- package/lib/typescript/src/views/ScreenFallback.d.ts +3 -3
- package/lib/typescript/src/views/ScreenFallback.d.ts.map +1 -1
- package/package.json +24 -24
- package/src/index.tsx +10 -10
- package/src/navigators/createDrawerNavigator.tsx +11 -7
- package/src/types.tsx +22 -12
- package/src/utils/DrawerPositionContext.tsx +3 -1
- package/src/utils/DrawerStatusContext.tsx +3 -5
- package/src/utils/addCancelListener.native.tsx +12 -0
- package/src/utils/addCancelListener.tsx +13 -0
- package/src/utils/getDrawerStatusFromState.tsx +1 -1
- package/src/utils/useDrawerStatus.tsx +2 -2
- package/src/views/DrawerContent.tsx +3 -3
- package/src/views/DrawerContentScrollView.tsx +12 -12
- package/src/views/DrawerItem.tsx +12 -85
- package/src/views/DrawerItemList.tsx +8 -12
- package/src/views/DrawerToggleButton.tsx +3 -5
- package/src/views/DrawerView.tsx +75 -40
- package/src/views/ScreenFallback.tsx +6 -1
package/src/types.tsx
CHANGED
|
@@ -35,16 +35,6 @@ export type DrawerNavigationConfig = {
|
|
|
35
35
|
* Defaults to `true`.
|
|
36
36
|
*/
|
|
37
37
|
detachInactiveScreens?: boolean;
|
|
38
|
-
/**
|
|
39
|
-
* Whether to use the legacy implementation based on Reanimated 1.
|
|
40
|
-
* The new implementation based on Reanimated 2 will perform better,
|
|
41
|
-
* but it's not possible to use Chrome remote debugger.
|
|
42
|
-
*
|
|
43
|
-
* This defaults to `true` if Reanimated 2 is not configured.
|
|
44
|
-
*
|
|
45
|
-
* Otherwise, it defaults to `false`
|
|
46
|
-
*/
|
|
47
|
-
useLegacyImplementation?: boolean;
|
|
48
38
|
};
|
|
49
39
|
|
|
50
40
|
export type DrawerNavigationOptions = HeaderOptions & {
|
|
@@ -258,6 +248,26 @@ export type DrawerNavigationEventMap = {
|
|
|
258
248
|
* Event which fires on tapping on the item in the drawer menu.
|
|
259
249
|
*/
|
|
260
250
|
drawerItemPress: { data: undefined; canPreventDefault: true };
|
|
251
|
+
/**
|
|
252
|
+
* Event which fires when a transition animation starts.
|
|
253
|
+
*/
|
|
254
|
+
transitionStart: { data: { closing: boolean } };
|
|
255
|
+
/**
|
|
256
|
+
* Event which fires when a transition animation ends.
|
|
257
|
+
*/
|
|
258
|
+
transitionEnd: { data: { closing: boolean } };
|
|
259
|
+
/**
|
|
260
|
+
* Event which fires when navigation gesture starts.
|
|
261
|
+
*/
|
|
262
|
+
gestureStart: { data: undefined };
|
|
263
|
+
/**
|
|
264
|
+
* Event which fires when navigation gesture is completed.
|
|
265
|
+
*/
|
|
266
|
+
gestureEnd: { data: undefined };
|
|
267
|
+
/**
|
|
268
|
+
* Event which fires when navigation gesture is canceled.
|
|
269
|
+
*/
|
|
270
|
+
gestureCancel: { data: undefined };
|
|
261
271
|
};
|
|
262
272
|
|
|
263
273
|
export type DrawerNavigationHelpers = NavigationHelpers<
|
|
@@ -269,7 +279,7 @@ export type DrawerNavigationHelpers = NavigationHelpers<
|
|
|
269
279
|
export type DrawerNavigationProp<
|
|
270
280
|
ParamList extends ParamListBase,
|
|
271
281
|
RouteName extends keyof ParamList = keyof ParamList,
|
|
272
|
-
NavigatorID extends string | undefined = undefined
|
|
282
|
+
NavigatorID extends string | undefined = undefined,
|
|
273
283
|
> = NavigationProp<
|
|
274
284
|
ParamList,
|
|
275
285
|
RouteName,
|
|
@@ -283,7 +293,7 @@ export type DrawerNavigationProp<
|
|
|
283
293
|
export type DrawerScreenProps<
|
|
284
294
|
ParamList extends ParamListBase,
|
|
285
295
|
RouteName extends keyof ParamList = keyof ParamList,
|
|
286
|
-
NavigatorID extends string | undefined = undefined
|
|
296
|
+
NavigatorID extends string | undefined = undefined,
|
|
287
297
|
> = {
|
|
288
298
|
navigation: DrawerNavigationProp<ParamList, RouteName, NavigatorID>;
|
|
289
299
|
route: RouteProp<ParamList, RouteName>;
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import type { DrawerStatus } from '@react-navigation/native';
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
|
|
4
|
-
const DrawerStatusContext = React.createContext<
|
|
5
|
-
undefined
|
|
6
|
-
);
|
|
7
|
-
|
|
8
|
-
export default DrawerStatusContext;
|
|
4
|
+
export const DrawerStatusContext = React.createContext<
|
|
5
|
+
DrawerStatus | undefined
|
|
6
|
+
>(undefined);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BackHandler } from 'react-native';
|
|
2
|
+
|
|
3
|
+
export const addCancelListener = (callback: () => boolean) => {
|
|
4
|
+
const subscription = BackHandler.addEventListener(
|
|
5
|
+
'hardwareBackPress',
|
|
6
|
+
callback
|
|
7
|
+
);
|
|
8
|
+
|
|
9
|
+
return () => {
|
|
10
|
+
subscription.remove();
|
|
11
|
+
};
|
|
12
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export const addCancelListener = (callback: () => boolean) => {
|
|
2
|
+
const handleEscape = (e: KeyboardEvent) => {
|
|
3
|
+
if (e.key === 'Escape') {
|
|
4
|
+
callback();
|
|
5
|
+
}
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
document?.body?.addEventListener?.('keyup', handleEscape);
|
|
9
|
+
|
|
10
|
+
return () => {
|
|
11
|
+
document?.body?.removeEventListener?.('keyup', handleEscape);
|
|
12
|
+
};
|
|
13
|
+
};
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import type { DrawerStatus } from '@react-navigation/native';
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
|
|
4
|
-
import DrawerStatusContext from './DrawerStatusContext';
|
|
4
|
+
import { DrawerStatusContext } from './DrawerStatusContext';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Hook to detect if the drawer's status in a parent navigator.
|
|
8
8
|
* Returns 'open' if the drawer is open, 'closed' if the drawer is closed.
|
|
9
9
|
*/
|
|
10
|
-
export
|
|
10
|
+
export function useDrawerStatus(): DrawerStatus {
|
|
11
11
|
const drawerStatus = React.useContext(DrawerStatusContext);
|
|
12
12
|
|
|
13
13
|
if (drawerStatus === undefined) {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
|
|
3
3
|
import type { DrawerContentComponentProps } from '../types';
|
|
4
|
-
import DrawerContentScrollView from './DrawerContentScrollView';
|
|
5
|
-
import DrawerItemList from './DrawerItemList';
|
|
4
|
+
import { DrawerContentScrollView } from './DrawerContentScrollView';
|
|
5
|
+
import { DrawerItemList } from './DrawerItemList';
|
|
6
6
|
|
|
7
|
-
export
|
|
7
|
+
export function DrawerContent({
|
|
8
8
|
descriptors,
|
|
9
9
|
state,
|
|
10
10
|
...rest
|
|
@@ -1,28 +1,26 @@
|
|
|
1
|
+
import { useLocale } from '@react-navigation/native';
|
|
1
2
|
import * as React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
I18nManager,
|
|
4
|
-
ScrollView,
|
|
5
|
-
ScrollViewProps,
|
|
6
|
-
StyleSheet,
|
|
7
|
-
} from 'react-native';
|
|
3
|
+
import { ScrollView, type ScrollViewProps, StyleSheet } from 'react-native';
|
|
8
4
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
9
5
|
|
|
10
|
-
import DrawerPositionContext from '../utils/DrawerPositionContext';
|
|
6
|
+
import { DrawerPositionContext } from '../utils/DrawerPositionContext';
|
|
11
7
|
|
|
12
8
|
type Props = ScrollViewProps & {
|
|
13
9
|
children: React.ReactNode;
|
|
14
10
|
};
|
|
15
11
|
|
|
16
|
-
function
|
|
12
|
+
function DrawerContentScrollViewInner(
|
|
17
13
|
{ contentContainerStyle, style, children, ...rest }: Props,
|
|
18
14
|
ref?: React.Ref<ScrollView>
|
|
19
15
|
) {
|
|
20
16
|
const drawerPosition = React.useContext(DrawerPositionContext);
|
|
21
17
|
const insets = useSafeAreaInsets();
|
|
18
|
+
const { direction } = useLocale();
|
|
22
19
|
|
|
23
|
-
const isRight =
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
const isRight =
|
|
21
|
+
direction === 'rtl'
|
|
22
|
+
? drawerPosition === 'left'
|
|
23
|
+
: drawerPosition === 'right';
|
|
26
24
|
|
|
27
25
|
return (
|
|
28
26
|
<ScrollView
|
|
@@ -43,7 +41,9 @@ function DrawerContentScrollView(
|
|
|
43
41
|
);
|
|
44
42
|
}
|
|
45
43
|
|
|
46
|
-
export
|
|
44
|
+
export const DrawerContentScrollView = React.forwardRef(
|
|
45
|
+
DrawerContentScrollViewInner
|
|
46
|
+
);
|
|
47
47
|
|
|
48
48
|
const styles = StyleSheet.create({
|
|
49
49
|
container: {
|
package/src/views/DrawerItem.tsx
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
import { PlatformPressable } from '@react-navigation/elements';
|
|
2
|
-
import {
|
|
1
|
+
import { PlatformPressable, Text } from '@react-navigation/elements';
|
|
2
|
+
import { type Route, useTheme } from '@react-navigation/native';
|
|
3
3
|
import Color from 'color';
|
|
4
4
|
import * as React from 'react';
|
|
5
5
|
import {
|
|
6
|
-
|
|
7
|
-
StyleProp,
|
|
6
|
+
type StyleProp,
|
|
8
7
|
StyleSheet,
|
|
9
|
-
|
|
10
|
-
TextStyle,
|
|
8
|
+
type TextStyle,
|
|
11
9
|
View,
|
|
12
|
-
ViewStyle,
|
|
10
|
+
type ViewStyle,
|
|
13
11
|
} from 'react-native';
|
|
14
12
|
|
|
15
13
|
type Props = {
|
|
@@ -96,73 +94,13 @@ type Props = {
|
|
|
96
94
|
testID?: string;
|
|
97
95
|
};
|
|
98
96
|
|
|
99
|
-
const LinkPressable = ({
|
|
100
|
-
route,
|
|
101
|
-
href,
|
|
102
|
-
children,
|
|
103
|
-
style,
|
|
104
|
-
onPress,
|
|
105
|
-
onLongPress,
|
|
106
|
-
onPressIn,
|
|
107
|
-
onPressOut,
|
|
108
|
-
accessibilityRole,
|
|
109
|
-
...rest
|
|
110
|
-
}: Omit<React.ComponentProps<typeof PlatformPressable>, 'style'> & {
|
|
111
|
-
style: StyleProp<ViewStyle>;
|
|
112
|
-
} & {
|
|
113
|
-
route: Route<string>;
|
|
114
|
-
href?: string;
|
|
115
|
-
children: React.ReactNode;
|
|
116
|
-
onPress?: () => void;
|
|
117
|
-
}) => {
|
|
118
|
-
if (Platform.OS === 'web') {
|
|
119
|
-
// React Native Web doesn't forward `onClick` if we use `TouchableWithoutFeedback`.
|
|
120
|
-
// We need to use `onClick` to be able to prevent default browser handling of links.
|
|
121
|
-
return (
|
|
122
|
-
<Link
|
|
123
|
-
{...rest}
|
|
124
|
-
href={href}
|
|
125
|
-
action={CommonActions.navigate(route.name, route.params)}
|
|
126
|
-
style={[styles.button, style]}
|
|
127
|
-
onPress={(e: any) => {
|
|
128
|
-
if (
|
|
129
|
-
!(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey) && // ignore clicks with modifier keys
|
|
130
|
-
(e.button == null || e.button === 0) // ignore everything but left clicks
|
|
131
|
-
) {
|
|
132
|
-
e.preventDefault();
|
|
133
|
-
onPress?.(e);
|
|
134
|
-
}
|
|
135
|
-
}}
|
|
136
|
-
// types for PressableProps and TextProps are incompatible with each other by `null` so we
|
|
137
|
-
// can't use {...rest} for these 3 props
|
|
138
|
-
onLongPress={onLongPress ?? undefined}
|
|
139
|
-
onPressIn={onPressIn ?? undefined}
|
|
140
|
-
onPressOut={onPressOut ?? undefined}
|
|
141
|
-
>
|
|
142
|
-
{children}
|
|
143
|
-
</Link>
|
|
144
|
-
);
|
|
145
|
-
} else {
|
|
146
|
-
return (
|
|
147
|
-
<PlatformPressable
|
|
148
|
-
{...rest}
|
|
149
|
-
accessibilityRole={accessibilityRole}
|
|
150
|
-
onPress={onPress}
|
|
151
|
-
>
|
|
152
|
-
<View style={style}>{children}</View>
|
|
153
|
-
</PlatformPressable>
|
|
154
|
-
);
|
|
155
|
-
}
|
|
156
|
-
};
|
|
157
|
-
|
|
158
97
|
/**
|
|
159
98
|
* A component used to show an action item with an icon and a label in a navigation drawer.
|
|
160
99
|
*/
|
|
161
|
-
export
|
|
162
|
-
const { colors } = useTheme();
|
|
100
|
+
export function DrawerItem(props: Props) {
|
|
101
|
+
const { colors, fonts } = useTheme();
|
|
163
102
|
|
|
164
103
|
const {
|
|
165
|
-
route,
|
|
166
104
|
href,
|
|
167
105
|
icon,
|
|
168
106
|
label,
|
|
@@ -196,19 +134,17 @@ export default function DrawerItem(props: Props) {
|
|
|
196
134
|
{...rest}
|
|
197
135
|
style={[styles.container, { borderRadius, backgroundColor }, style]}
|
|
198
136
|
>
|
|
199
|
-
<
|
|
137
|
+
<PlatformPressable
|
|
200
138
|
testID={testID}
|
|
201
139
|
onPress={onPress}
|
|
202
|
-
style={[styles.wrapper, { borderRadius }]}
|
|
203
140
|
accessibilityLabel={accessibilityLabel}
|
|
204
141
|
accessibilityRole="button"
|
|
205
142
|
accessibilityState={{ selected: focused }}
|
|
206
143
|
pressColor={pressColor}
|
|
207
144
|
pressOpacity={pressOpacity}
|
|
208
|
-
route={route}
|
|
209
145
|
href={href}
|
|
210
146
|
>
|
|
211
|
-
<
|
|
147
|
+
<View style={[styles.wrapper, { borderRadius }]}>
|
|
212
148
|
{iconNode}
|
|
213
149
|
<View
|
|
214
150
|
style={[
|
|
@@ -220,13 +156,7 @@ export default function DrawerItem(props: Props) {
|
|
|
220
156
|
<Text
|
|
221
157
|
numberOfLines={1}
|
|
222
158
|
allowFontScaling={allowFontScaling}
|
|
223
|
-
style={[
|
|
224
|
-
{
|
|
225
|
-
color,
|
|
226
|
-
fontWeight: '500',
|
|
227
|
-
},
|
|
228
|
-
labelStyle,
|
|
229
|
-
]}
|
|
159
|
+
style={[{ color }, fonts.medium, labelStyle]}
|
|
230
160
|
>
|
|
231
161
|
{label}
|
|
232
162
|
</Text>
|
|
@@ -234,8 +164,8 @@ export default function DrawerItem(props: Props) {
|
|
|
234
164
|
label({ color, focused })
|
|
235
165
|
)}
|
|
236
166
|
</View>
|
|
237
|
-
</
|
|
238
|
-
</
|
|
167
|
+
</View>
|
|
168
|
+
</PlatformPressable>
|
|
239
169
|
</View>
|
|
240
170
|
);
|
|
241
171
|
}
|
|
@@ -255,7 +185,4 @@ const styles = StyleSheet.create({
|
|
|
255
185
|
marginRight: 32,
|
|
256
186
|
flex: 1,
|
|
257
187
|
},
|
|
258
|
-
button: {
|
|
259
|
-
display: 'flex',
|
|
260
|
-
},
|
|
261
188
|
});
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CommonActions,
|
|
3
3
|
DrawerActions,
|
|
4
|
-
DrawerNavigationState,
|
|
5
|
-
ParamListBase,
|
|
6
|
-
|
|
4
|
+
type DrawerNavigationState,
|
|
5
|
+
type ParamListBase,
|
|
6
|
+
useLinkBuilder,
|
|
7
7
|
} from '@react-navigation/native';
|
|
8
8
|
import * as React from 'react';
|
|
9
9
|
|
|
10
10
|
import type { DrawerDescriptorMap, DrawerNavigationHelpers } from '../types';
|
|
11
|
-
import DrawerItem from './DrawerItem';
|
|
11
|
+
import { DrawerItem } from './DrawerItem';
|
|
12
12
|
|
|
13
13
|
type Props = {
|
|
14
14
|
state: DrawerNavigationState<ParamListBase>;
|
|
@@ -19,12 +19,8 @@ type Props = {
|
|
|
19
19
|
/**
|
|
20
20
|
* Component that renders the navigation list in the drawer.
|
|
21
21
|
*/
|
|
22
|
-
export
|
|
23
|
-
|
|
24
|
-
navigation,
|
|
25
|
-
descriptors,
|
|
26
|
-
}: Props) {
|
|
27
|
-
const { buildHref } = useLinkTools();
|
|
22
|
+
export function DrawerItemList({ state, navigation, descriptors }: Props) {
|
|
23
|
+
const { buildHref } = useLinkBuilder();
|
|
28
24
|
|
|
29
25
|
const focusedRoute = state.routes[state.index];
|
|
30
26
|
const focusedDescriptor = descriptors[focusedRoute.key];
|
|
@@ -75,8 +71,8 @@ export default function DrawerItemList({
|
|
|
75
71
|
drawerLabel !== undefined
|
|
76
72
|
? drawerLabel
|
|
77
73
|
: title !== undefined
|
|
78
|
-
|
|
79
|
-
|
|
74
|
+
? title
|
|
75
|
+
: route.name
|
|
80
76
|
}
|
|
81
77
|
icon={drawerIcon}
|
|
82
78
|
focused={focused}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { PlatformPressable } from '@react-navigation/elements';
|
|
2
2
|
import {
|
|
3
3
|
DrawerActions,
|
|
4
|
-
ParamListBase,
|
|
4
|
+
type ParamListBase,
|
|
5
5
|
useNavigation,
|
|
6
6
|
} from '@react-navigation/native';
|
|
7
7
|
import * as React from 'react';
|
|
@@ -16,14 +16,12 @@ type Props = {
|
|
|
16
16
|
tintColor?: string;
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
-
export
|
|
19
|
+
export function DrawerToggleButton({ tintColor, ...rest }: Props) {
|
|
20
20
|
const navigation = useNavigation<DrawerNavigationProp<ParamListBase>>();
|
|
21
21
|
|
|
22
22
|
return (
|
|
23
23
|
<PlatformPressable
|
|
24
24
|
{...rest}
|
|
25
|
-
accessible
|
|
26
|
-
accessibilityRole="button"
|
|
27
25
|
android_ripple={{ borderless: true }}
|
|
28
26
|
onPress={() => navigation.dispatch(DrawerActions.toggleDrawer())}
|
|
29
27
|
style={styles.touchable}
|
|
@@ -34,6 +32,7 @@ export default function DrawerToggleButton({ tintColor, ...rest }: Props) {
|
|
|
34
32
|
>
|
|
35
33
|
<Image
|
|
36
34
|
style={[styles.icon, tintColor ? { tintColor } : null]}
|
|
35
|
+
resizeMode="contain"
|
|
37
36
|
source={require('./assets/toggle-drawer-icon.png')}
|
|
38
37
|
fadeDuration={0}
|
|
39
38
|
/>
|
|
@@ -46,7 +45,6 @@ const styles = StyleSheet.create({
|
|
|
46
45
|
height: 24,
|
|
47
46
|
width: 24,
|
|
48
47
|
margin: 3,
|
|
49
|
-
resizeMode: 'contain',
|
|
50
48
|
},
|
|
51
49
|
touchable: {
|
|
52
50
|
marginHorizontal: 11,
|
package/src/views/DrawerView.tsx
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
getDefaultSidebarWidth,
|
|
2
3
|
getHeaderTitle,
|
|
3
4
|
Header,
|
|
4
5
|
SafeAreaProviderCompat,
|
|
@@ -6,15 +7,17 @@ import {
|
|
|
6
7
|
} from '@react-navigation/elements';
|
|
7
8
|
import {
|
|
8
9
|
DrawerActions,
|
|
9
|
-
DrawerNavigationState,
|
|
10
|
-
DrawerStatus,
|
|
11
|
-
ParamListBase,
|
|
10
|
+
type DrawerNavigationState,
|
|
11
|
+
type DrawerStatus,
|
|
12
|
+
type ParamListBase,
|
|
13
|
+
useLocale,
|
|
12
14
|
useTheme,
|
|
13
15
|
} from '@react-navigation/native';
|
|
14
16
|
import * as React from 'react';
|
|
15
|
-
import {
|
|
17
|
+
import { Platform, StyleSheet } from 'react-native';
|
|
16
18
|
import { Drawer } from 'react-native-drawer-layout';
|
|
17
19
|
import { useSafeAreaFrame } from 'react-native-safe-area-context';
|
|
20
|
+
import useLatestCallback from 'use-latest-callback';
|
|
18
21
|
|
|
19
22
|
import type {
|
|
20
23
|
DrawerContentComponentProps,
|
|
@@ -24,11 +27,12 @@ import type {
|
|
|
24
27
|
DrawerNavigationHelpers,
|
|
25
28
|
DrawerNavigationProp,
|
|
26
29
|
} from '../types';
|
|
27
|
-
import
|
|
28
|
-
import
|
|
29
|
-
import
|
|
30
|
-
import
|
|
31
|
-
import
|
|
30
|
+
import { addCancelListener } from '../utils/addCancelListener';
|
|
31
|
+
import { DrawerPositionContext } from '../utils/DrawerPositionContext';
|
|
32
|
+
import { DrawerStatusContext } from '../utils/DrawerStatusContext';
|
|
33
|
+
import { getDrawerStatusFromState } from '../utils/getDrawerStatusFromState';
|
|
34
|
+
import { DrawerContent } from './DrawerContent';
|
|
35
|
+
import { DrawerToggleButton } from './DrawerToggleButton';
|
|
32
36
|
import { MaybeScreen, MaybeScreenContainer } from './ScreenFallback';
|
|
33
37
|
|
|
34
38
|
type Props = DrawerNavigationConfig & {
|
|
@@ -50,10 +54,12 @@ function DrawerViewBase({
|
|
|
50
54
|
Platform.OS === 'android' ||
|
|
51
55
|
Platform.OS === 'ios',
|
|
52
56
|
}: Props) {
|
|
57
|
+
const { direction } = useLocale();
|
|
58
|
+
|
|
53
59
|
const focusedRouteKey = state.routes[state.index].key;
|
|
54
60
|
const {
|
|
55
61
|
drawerHideStatusBarOnOpen,
|
|
56
|
-
drawerPosition =
|
|
62
|
+
drawerPosition = direction === 'rtl' ? 'right' : 'left',
|
|
57
63
|
drawerStatusBarAnimation,
|
|
58
64
|
drawerStyle,
|
|
59
65
|
drawerType,
|
|
@@ -80,19 +86,56 @@ function DrawerViewBase({
|
|
|
80
86
|
|
|
81
87
|
const drawerStatus = getDrawerStatusFromState(state);
|
|
82
88
|
|
|
83
|
-
const handleDrawerOpen =
|
|
89
|
+
const handleDrawerOpen = useLatestCallback(() => {
|
|
84
90
|
navigation.dispatch({
|
|
85
91
|
...DrawerActions.openDrawer(),
|
|
86
92
|
target: state.key,
|
|
87
93
|
});
|
|
88
|
-
}
|
|
94
|
+
});
|
|
89
95
|
|
|
90
|
-
const handleDrawerClose =
|
|
96
|
+
const handleDrawerClose = useLatestCallback(() => {
|
|
91
97
|
navigation.dispatch({
|
|
92
98
|
...DrawerActions.closeDrawer(),
|
|
93
99
|
target: state.key,
|
|
94
100
|
});
|
|
95
|
-
}
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
const handleGestureStart = useLatestCallback(() => {
|
|
104
|
+
navigation.emit({
|
|
105
|
+
type: 'gestureStart',
|
|
106
|
+
target: state.key,
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
const handleGestureEnd = useLatestCallback(() => {
|
|
111
|
+
navigation.emit({
|
|
112
|
+
type: 'gestureEnd',
|
|
113
|
+
target: state.key,
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
const handleGestureCancel = useLatestCallback(() => {
|
|
118
|
+
navigation.emit({
|
|
119
|
+
type: 'gestureCancel',
|
|
120
|
+
target: state.key,
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
const handleTransitionStart = useLatestCallback((closing: boolean) => {
|
|
125
|
+
navigation.emit({
|
|
126
|
+
type: 'transitionStart',
|
|
127
|
+
data: { closing },
|
|
128
|
+
target: state.key,
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
const handleTransitionEnd = useLatestCallback((closing: boolean) => {
|
|
133
|
+
navigation.emit({
|
|
134
|
+
type: 'transitionEnd',
|
|
135
|
+
data: { closing },
|
|
136
|
+
target: state.key,
|
|
137
|
+
});
|
|
138
|
+
});
|
|
96
139
|
|
|
97
140
|
React.useEffect(() => {
|
|
98
141
|
if (drawerStatus === defaultStatus || drawerType === 'permanent') {
|
|
@@ -115,31 +158,10 @@ function DrawerViewBase({
|
|
|
115
158
|
return true;
|
|
116
159
|
};
|
|
117
160
|
|
|
118
|
-
const handleEscape = (e: KeyboardEvent) => {
|
|
119
|
-
if (e.key === 'Escape') {
|
|
120
|
-
handleHardwareBack();
|
|
121
|
-
}
|
|
122
|
-
};
|
|
123
|
-
|
|
124
161
|
// We only add the listeners when drawer opens
|
|
125
162
|
// This way we can make sure that the listener is added as late as possible
|
|
126
163
|
// This will make sure that our handler will run first when back button is pressed
|
|
127
|
-
|
|
128
|
-
'hardwareBackPress',
|
|
129
|
-
handleHardwareBack
|
|
130
|
-
);
|
|
131
|
-
|
|
132
|
-
if (Platform.OS === 'web') {
|
|
133
|
-
document?.body?.addEventListener?.('keyup', handleEscape);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
return () => {
|
|
137
|
-
subscription.remove();
|
|
138
|
-
|
|
139
|
-
if (Platform.OS === 'web') {
|
|
140
|
-
document?.body?.removeEventListener?.('keyup', handleEscape);
|
|
141
|
-
}
|
|
142
|
-
};
|
|
164
|
+
return addCancelListener(handleHardwareBack);
|
|
143
165
|
}, [
|
|
144
166
|
defaultStatus,
|
|
145
167
|
drawerStatus,
|
|
@@ -177,8 +199,13 @@ function DrawerViewBase({
|
|
|
177
199
|
return null;
|
|
178
200
|
}
|
|
179
201
|
|
|
180
|
-
if (
|
|
181
|
-
|
|
202
|
+
if (
|
|
203
|
+
lazy &&
|
|
204
|
+
!loaded.includes(route.key) &&
|
|
205
|
+
!isFocused &&
|
|
206
|
+
!state.preloadedRouteKeys.includes(route.key)
|
|
207
|
+
) {
|
|
208
|
+
// Don't render a lazy screen if we've never navigated to it or it wasn't preloaded
|
|
182
209
|
return null;
|
|
183
210
|
}
|
|
184
211
|
|
|
@@ -240,6 +267,11 @@ function DrawerViewBase({
|
|
|
240
267
|
open={drawerStatus !== 'closed'}
|
|
241
268
|
onOpen={handleDrawerOpen}
|
|
242
269
|
onClose={handleDrawerClose}
|
|
270
|
+
onGestureStart={handleGestureStart}
|
|
271
|
+
onGestureEnd={handleGestureEnd}
|
|
272
|
+
onGestureCancel={handleGestureCancel}
|
|
273
|
+
onTransitionStart={handleTransitionStart}
|
|
274
|
+
onTransitionEnd={handleTransitionEnd}
|
|
243
275
|
layout={dimensions}
|
|
244
276
|
gestureHandlerProps={gestureHandlerProps}
|
|
245
277
|
swipeEnabled={swipeEnabled}
|
|
@@ -252,7 +284,10 @@ function DrawerViewBase({
|
|
|
252
284
|
overlayAccessibilityLabel={overlayAccessibilityLabel}
|
|
253
285
|
drawerPosition={drawerPosition}
|
|
254
286
|
drawerStyle={[
|
|
255
|
-
{
|
|
287
|
+
{
|
|
288
|
+
backgroundColor: colors.card,
|
|
289
|
+
width: getDefaultSidebarWidth(dimensions),
|
|
290
|
+
},
|
|
256
291
|
drawerType === 'permanent' &&
|
|
257
292
|
(drawerPosition === 'left'
|
|
258
293
|
? {
|
|
@@ -274,7 +309,7 @@ function DrawerViewBase({
|
|
|
274
309
|
);
|
|
275
310
|
}
|
|
276
311
|
|
|
277
|
-
export
|
|
312
|
+
export function DrawerView({ navigation, ...rest }: Props) {
|
|
278
313
|
return (
|
|
279
314
|
<SafeAreaProviderCompat>
|
|
280
315
|
<DrawerViewBase navigation={navigation} {...rest} />
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { ResourceSavingView } from '@react-navigation/elements';
|
|
2
2
|
import * as React from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
type StyleProp,
|
|
5
|
+
View,
|
|
6
|
+
type ViewProps,
|
|
7
|
+
type ViewStyle,
|
|
8
|
+
} from 'react-native';
|
|
4
9
|
|
|
5
10
|
type Props = {
|
|
6
11
|
visible: boolean;
|