@react-navigation/drawer 8.0.0-alpha.5 → 8.0.0-alpha.51
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/module/index.js.map +1 -1
- package/lib/module/navigators/createDrawerNavigator.js +3 -7
- package/lib/module/navigators/createDrawerNavigator.js.map +1 -1
- package/lib/module/utils/getDrawerStatusFromState.js.map +1 -1
- package/lib/module/utils/useDrawerStatus.js +1 -1
- package/lib/module/utils/useDrawerStatus.js.map +1 -1
- package/lib/module/views/DrawerContent.js +4 -2
- package/lib/module/views/DrawerContent.js.map +1 -1
- package/lib/module/views/DrawerContentScrollView.js +30 -13
- package/lib/module/views/DrawerContentScrollView.js.map +1 -1
- package/lib/module/views/DrawerItem.js +26 -8
- package/lib/module/views/DrawerItem.js.map +1 -1
- package/lib/module/views/DrawerItemList.js +17 -7
- package/lib/module/views/DrawerItemList.js.map +1 -1
- package/lib/module/views/DrawerToggleButton.js +27 -10
- package/lib/module/views/DrawerToggleButton.js.map +1 -1
- package/lib/module/views/DrawerView.js +28 -20
- package/lib/module/views/DrawerView.js.map +1 -1
- package/lib/typescript/src/index.d.ts +11 -11
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/navigators/createDrawerNavigator.d.ts +9 -15
- package/lib/typescript/src/navigators/createDrawerNavigator.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +24 -25
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/lib/typescript/src/utils/getDrawerStatusFromState.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 +5 -2
- package/lib/typescript/src/views/DrawerContentScrollView.d.ts.map +1 -1
- package/lib/typescript/src/views/DrawerItem.d.ts +18 -17
- package/lib/typescript/src/views/DrawerItem.d.ts.map +1 -1
- package/lib/typescript/src/views/DrawerItemList.d.ts +1 -1
- package/lib/typescript/src/views/DrawerItemList.d.ts.map +1 -1
- package/lib/typescript/src/views/DrawerToggleButton.d.ts +12 -7
- package/lib/typescript/src/views/DrawerToggleButton.d.ts.map +1 -1
- package/lib/typescript/src/views/DrawerView.d.ts +3 -2
- package/lib/typescript/src/views/DrawerView.d.ts.map +1 -1
- package/package.json +26 -26
- package/src/index.tsx +1 -0
- package/src/navigators/createDrawerNavigator.tsx +9 -40
- package/src/types.tsx +30 -25
- package/src/utils/getDrawerStatusFromState.tsx +1 -3
- package/src/utils/useDrawerStatus.tsx +1 -1
- package/src/views/DrawerContent.tsx +6 -2
- package/src/views/DrawerContentScrollView.tsx +31 -15
- package/src/views/DrawerItem.tsx +57 -23
- package/src/views/DrawerItemList.tsx +22 -8
- package/src/views/DrawerToggleButton.tsx +48 -22
- package/src/views/DrawerView.tsx +47 -26
- package/lib/module/views/assets/toggle-drawer-icon@1x.android.png +0 -0
- package/lib/module/views/assets/toggle-drawer-icon@1x.ios.png +0 -0
- package/lib/module/views/assets/toggle-drawer-icon@2x.android.png +0 -0
- package/lib/module/views/assets/toggle-drawer-icon@2x.ios.png +0 -0
- package/lib/module/views/assets/toggle-drawer-icon@3x.android.png +0 -0
- package/lib/module/views/assets/toggle-drawer-icon@3x.ios.png +0 -0
- package/lib/module/views/assets/toggle-drawer-icon@4x.android.png +0 -0
- package/lib/module/views/assets/toggle-drawer-icon@4x.ios.png +0 -0
- package/src/views/assets/toggle-drawer-icon@1x.android.png +0 -0
- package/src/views/assets/toggle-drawer-icon@1x.ios.png +0 -0
- package/src/views/assets/toggle-drawer-icon@2x.android.png +0 -0
- package/src/views/assets/toggle-drawer-icon@2x.ios.png +0 -0
- package/src/views/assets/toggle-drawer-icon@3x.android.png +0 -0
- package/src/views/assets/toggle-drawer-icon@3x.ios.png +0 -0
- package/src/views/assets/toggle-drawer-icon@4x.android.png +0 -0
- package/src/views/assets/toggle-drawer-icon@4x.ios.png +0 -0
package/src/types.tsx
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { HeaderOptions } from '@react-navigation/elements';
|
|
1
|
+
import type { HeaderOptions, Icon } from '@react-navigation/elements';
|
|
2
|
+
import type { Screen } from '@react-navigation/elements/internal';
|
|
2
3
|
import type {
|
|
3
4
|
DefaultNavigatorOptions,
|
|
4
5
|
Descriptor,
|
|
@@ -13,7 +14,7 @@ import type {
|
|
|
13
14
|
Theme,
|
|
14
15
|
} from '@react-navigation/native';
|
|
15
16
|
import type { ColorValue, StyleProp, TextStyle, ViewStyle } from 'react-native';
|
|
16
|
-
import type {
|
|
17
|
+
import type { PanGestureConfig } from 'react-native-gesture-handler';
|
|
17
18
|
|
|
18
19
|
export type Scene = {
|
|
19
20
|
route: Route<string>;
|
|
@@ -29,12 +30,6 @@ export type DrawerNavigationConfig = {
|
|
|
29
30
|
* Defaults to `DrawerContent`.
|
|
30
31
|
*/
|
|
31
32
|
drawerContent?: (props: DrawerContentComponentProps) => React.ReactNode;
|
|
32
|
-
/**
|
|
33
|
-
* Whether inactive screens should be detached from the view hierarchy to save memory.
|
|
34
|
-
* Make sure to call `enableScreens` from `react-native-screens` to make it work.
|
|
35
|
-
* Defaults to `true`.
|
|
36
|
-
*/
|
|
37
|
-
detachInactiveScreens?: boolean;
|
|
38
33
|
};
|
|
39
34
|
|
|
40
35
|
export type DrawerNavigationOptions = HeaderOptions & {
|
|
@@ -70,13 +65,15 @@ export type DrawerNavigationOptions = HeaderOptions & {
|
|
|
70
65
|
| ((props: { color: ColorValue; focused: boolean }) => React.ReactNode);
|
|
71
66
|
|
|
72
67
|
/**
|
|
73
|
-
*
|
|
68
|
+
* Icon to display for the drawer item.
|
|
74
69
|
*/
|
|
75
|
-
drawerIcon?:
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
70
|
+
drawerIcon?:
|
|
71
|
+
| Icon
|
|
72
|
+
| ((props: {
|
|
73
|
+
color: ColorValue;
|
|
74
|
+
size: number;
|
|
75
|
+
focused: boolean;
|
|
76
|
+
}) => Icon | React.ReactNode);
|
|
80
77
|
|
|
81
78
|
/**
|
|
82
79
|
* Color for the icon and label in the active item in the drawer.
|
|
@@ -108,6 +105,11 @@ export type DrawerNavigationOptions = HeaderOptions & {
|
|
|
108
105
|
*/
|
|
109
106
|
drawerItemStyle?: StyleProp<ViewStyle>;
|
|
110
107
|
|
|
108
|
+
/**
|
|
109
|
+
* ID to locate this drawer item in tests.
|
|
110
|
+
*/
|
|
111
|
+
drawerItemTestID?: string;
|
|
112
|
+
|
|
111
113
|
/**
|
|
112
114
|
* Style object to apply to the `Text` inside content section which renders a label.
|
|
113
115
|
*/
|
|
@@ -143,7 +145,7 @@ export type DrawerNavigationOptions = HeaderOptions & {
|
|
|
143
145
|
*
|
|
144
146
|
* Defaults to `slide` on iOS and `front` on other platforms.
|
|
145
147
|
*/
|
|
146
|
-
drawerType?: 'front' | 'back' | 'slide' | 'permanent';
|
|
148
|
+
drawerType?: 'front' | 'back' | 'slide' | 'permanent' | undefined;
|
|
147
149
|
|
|
148
150
|
/**
|
|
149
151
|
* Whether the statusbar should be hidden when the drawer is pulled or opens,
|
|
@@ -170,12 +172,12 @@ export type DrawerNavigationOptions = HeaderOptions & {
|
|
|
170
172
|
/**
|
|
171
173
|
* Style object for the component wrapping the screen content.
|
|
172
174
|
*/
|
|
173
|
-
sceneStyle?:
|
|
175
|
+
sceneStyle?: React.ComponentProps<typeof Screen>['style'];
|
|
174
176
|
|
|
175
177
|
/**
|
|
176
|
-
* Function to modify the pan gesture
|
|
178
|
+
* Function to modify the pan gesture config.
|
|
177
179
|
*/
|
|
178
|
-
configureGestureHandler?: (gesture:
|
|
180
|
+
configureGestureHandler?: (gesture: PanGestureConfig) => PanGestureConfig;
|
|
179
181
|
|
|
180
182
|
/**
|
|
181
183
|
* Whether you can use swipe gestures to open or close the drawer.
|
|
@@ -208,13 +210,17 @@ export type DrawerNavigationOptions = HeaderOptions & {
|
|
|
208
210
|
popToTopOnBlur?: boolean;
|
|
209
211
|
|
|
210
212
|
/**
|
|
211
|
-
*
|
|
212
|
-
*
|
|
213
|
-
*
|
|
213
|
+
* What should happen when screens become inactive.
|
|
214
|
+
* - `pause`: Effects are cleaned up.
|
|
215
|
+
* - `none`: Screen renders normally
|
|
216
|
+
*
|
|
217
|
+
* Defaults to `pause`.
|
|
214
218
|
*
|
|
215
|
-
*
|
|
219
|
+
* If you set `lazy: false` or preload a screen,
|
|
220
|
+
* It won't be paused until after the first time it becomes focused.
|
|
221
|
+
* This makes sure that effects are run to initialize the screen.
|
|
216
222
|
*/
|
|
217
|
-
|
|
223
|
+
inactiveBehavior?: 'pause' | 'none';
|
|
218
224
|
};
|
|
219
225
|
|
|
220
226
|
export type DrawerContentComponentProps = {
|
|
@@ -307,11 +313,10 @@ export type DrawerDescriptor = Descriptor<
|
|
|
307
313
|
export type DrawerDescriptorMap = Record<string, DrawerDescriptor>;
|
|
308
314
|
|
|
309
315
|
export type DrawerProps = {
|
|
310
|
-
dimensions: { width: number; height: number };
|
|
311
316
|
drawerPosition: 'left' | 'right';
|
|
312
317
|
drawerStyle?: StyleProp<ViewStyle>;
|
|
313
318
|
drawerType: 'front' | 'back' | 'slide' | 'permanent';
|
|
314
|
-
configureGestureHandler?: (gesture:
|
|
319
|
+
configureGestureHandler?: (gesture: PanGestureConfig) => PanGestureConfig;
|
|
315
320
|
hideStatusBarOnOpen: boolean;
|
|
316
321
|
keyboardDismissMode: 'none' | 'on-drag';
|
|
317
322
|
onClose: () => void;
|
|
@@ -13,9 +13,7 @@ export function getDrawerStatusFromState(
|
|
|
13
13
|
);
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
const entry = state.history.findLast((it) => it.type === 'drawer')
|
|
17
|
-
| { type: 'drawer'; status: DrawerStatus }
|
|
18
|
-
| undefined;
|
|
16
|
+
const entry = state.history.findLast((it) => it.type === 'drawer');
|
|
19
17
|
|
|
20
18
|
return entry?.status ?? state.default ?? 'closed';
|
|
21
19
|
}
|
|
@@ -8,7 +8,7 @@ import { DrawerStatusContext } from './DrawerStatusContext';
|
|
|
8
8
|
* Returns 'open' if the drawer is open, 'closed' if the drawer is closed.
|
|
9
9
|
*/
|
|
10
10
|
export function useDrawerStatus(): DrawerStatus {
|
|
11
|
-
const drawerStatus = React.
|
|
11
|
+
const drawerStatus = React.use(DrawerStatusContext);
|
|
12
12
|
|
|
13
13
|
if (drawerStatus === undefined) {
|
|
14
14
|
throw new Error(
|
|
@@ -8,8 +8,12 @@ export function DrawerContent({
|
|
|
8
8
|
...rest
|
|
9
9
|
}: DrawerContentComponentProps) {
|
|
10
10
|
const focusedRoute = state.routes[state.index];
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
|
|
12
|
+
if (focusedRoute == null) {
|
|
13
|
+
throw new Error(`Couldn't find a route at index ${state.index}.`);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const focusedOptions = descriptors[focusedRoute.key]?.options ?? {};
|
|
13
17
|
|
|
14
18
|
const { drawerContentStyle, drawerContentContainerStyle } = focusedOptions;
|
|
15
19
|
|
|
@@ -1,21 +1,31 @@
|
|
|
1
|
-
import { useLocale } from '@react-navigation/native';
|
|
1
|
+
import { UNSTABLE_CornerInset, useLocale } from '@react-navigation/native';
|
|
2
2
|
import * as React from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
Platform,
|
|
5
|
+
ScrollView,
|
|
6
|
+
type ScrollViewProps,
|
|
7
|
+
StyleSheet,
|
|
8
|
+
} from 'react-native';
|
|
4
9
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
5
10
|
|
|
6
11
|
import { DrawerPositionContext } from '../utils/DrawerPositionContext';
|
|
7
12
|
|
|
8
13
|
type Props = ScrollViewProps & {
|
|
9
14
|
children: React.ReactNode;
|
|
15
|
+
ref?: React.Ref<React.ComponentRef<typeof ScrollView>>;
|
|
10
16
|
};
|
|
11
17
|
|
|
12
18
|
const SPACING = 12;
|
|
13
19
|
|
|
14
|
-
function
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
20
|
+
export function DrawerContentScrollView({
|
|
21
|
+
contentInsetAdjustmentBehavior = 'automatic',
|
|
22
|
+
contentContainerStyle,
|
|
23
|
+
style,
|
|
24
|
+
children,
|
|
25
|
+
ref,
|
|
26
|
+
...rest
|
|
27
|
+
}: Props) {
|
|
28
|
+
const drawerPosition = React.use(DrawerPositionContext);
|
|
19
29
|
const insets = useSafeAreaInsets();
|
|
20
30
|
const { direction } = useLocale();
|
|
21
31
|
|
|
@@ -28,26 +38,32 @@ function DrawerContentScrollViewInner(
|
|
|
28
38
|
<ScrollView
|
|
29
39
|
{...rest}
|
|
30
40
|
ref={ref}
|
|
41
|
+
contentInsetAdjustmentBehavior={contentInsetAdjustmentBehavior}
|
|
31
42
|
contentContainerStyle={[
|
|
32
43
|
{
|
|
33
|
-
paddingTop:
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
44
|
+
paddingTop:
|
|
45
|
+
SPACING + Platform.select({ ios: 0, default: insets.top }),
|
|
46
|
+
paddingBottom:
|
|
47
|
+
SPACING + Platform.select({ ios: 0, default: insets.bottom }),
|
|
48
|
+
paddingStart:
|
|
49
|
+
SPACING +
|
|
50
|
+
(!isRight ? Platform.select({ ios: 0, default: insets.left }) : 0),
|
|
51
|
+
paddingEnd:
|
|
52
|
+
SPACING +
|
|
53
|
+
(isRight ? Platform.select({ ios: 0, default: insets.right }) : 0),
|
|
37
54
|
},
|
|
38
55
|
contentContainerStyle,
|
|
39
56
|
]}
|
|
40
57
|
style={[styles.container, style]}
|
|
41
58
|
>
|
|
59
|
+
{Platform.OS === 'ios' && contentInsetAdjustmentBehavior !== 'never' && (
|
|
60
|
+
<UNSTABLE_CornerInset direction="vertical" edge="top" />
|
|
61
|
+
)}
|
|
42
62
|
{children}
|
|
43
63
|
</ScrollView>
|
|
44
64
|
);
|
|
45
65
|
}
|
|
46
66
|
|
|
47
|
-
export const DrawerContentScrollView = React.forwardRef(
|
|
48
|
-
DrawerContentScrollViewInner
|
|
49
|
-
);
|
|
50
|
-
|
|
51
67
|
const styles = StyleSheet.create({
|
|
52
68
|
container: {
|
|
53
69
|
flex: 1,
|
package/src/views/DrawerItem.tsx
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
type Icon,
|
|
3
|
+
PlatformIcon,
|
|
4
|
+
PlatformPressable,
|
|
5
|
+
Text,
|
|
6
|
+
} from '@react-navigation/elements';
|
|
2
7
|
import { Color } from '@react-navigation/elements/internal';
|
|
3
8
|
import { type Route, useTheme } from '@react-navigation/native';
|
|
4
9
|
import * as React from 'react';
|
|
@@ -16,11 +21,11 @@ type Props = {
|
|
|
16
21
|
/**
|
|
17
22
|
* The route object which should be specified by the drawer item.
|
|
18
23
|
*/
|
|
19
|
-
route?: Route<string
|
|
24
|
+
route?: Route<string> | undefined;
|
|
20
25
|
/**
|
|
21
26
|
* The `href` to use for the anchor tag on web
|
|
22
27
|
*/
|
|
23
|
-
href?: string;
|
|
28
|
+
href?: string | undefined;
|
|
24
29
|
/**
|
|
25
30
|
* The label text of the item.
|
|
26
31
|
*/
|
|
@@ -30,15 +35,18 @@ type Props = {
|
|
|
30
35
|
/**
|
|
31
36
|
* Icon to display for the `DrawerItem`.
|
|
32
37
|
*/
|
|
33
|
-
icon?:
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
icon?:
|
|
39
|
+
| Icon
|
|
40
|
+
| ((props: {
|
|
41
|
+
focused: boolean;
|
|
42
|
+
size: number;
|
|
43
|
+
color: ColorValue;
|
|
44
|
+
}) => Icon | React.ReactNode)
|
|
45
|
+
| undefined;
|
|
38
46
|
/**
|
|
39
47
|
* Whether to highlight the drawer item as active.
|
|
40
48
|
*/
|
|
41
|
-
focused?: boolean;
|
|
49
|
+
focused?: boolean | undefined;
|
|
42
50
|
/**
|
|
43
51
|
* Function to execute on press.
|
|
44
52
|
*/
|
|
@@ -46,54 +54,54 @@ type Props = {
|
|
|
46
54
|
/**
|
|
47
55
|
* Color for the icon and label when the item is active.
|
|
48
56
|
*/
|
|
49
|
-
activeTintColor?: ColorValue;
|
|
57
|
+
activeTintColor?: ColorValue | undefined;
|
|
50
58
|
/**
|
|
51
59
|
* Color for the icon and label when the item is inactive.
|
|
52
60
|
*/
|
|
53
|
-
inactiveTintColor?: ColorValue;
|
|
61
|
+
inactiveTintColor?: ColorValue | undefined;
|
|
54
62
|
/**
|
|
55
63
|
* Background color for item when its active.
|
|
56
64
|
*/
|
|
57
|
-
activeBackgroundColor?: ColorValue;
|
|
65
|
+
activeBackgroundColor?: ColorValue | undefined;
|
|
58
66
|
/**
|
|
59
67
|
* Background color for item when its inactive.
|
|
60
68
|
*/
|
|
61
|
-
inactiveBackgroundColor?: ColorValue;
|
|
69
|
+
inactiveBackgroundColor?: ColorValue | undefined;
|
|
62
70
|
/**
|
|
63
71
|
* Color of the touchable effect on press.
|
|
64
72
|
* Only supported on Android.
|
|
65
73
|
*
|
|
66
74
|
* @platform android
|
|
67
75
|
*/
|
|
68
|
-
pressColor?: ColorValue;
|
|
76
|
+
pressColor?: ColorValue | undefined;
|
|
69
77
|
/**
|
|
70
78
|
* Opacity of the touchable effect on press.
|
|
71
79
|
* Only supported on iOS.
|
|
72
80
|
*
|
|
73
81
|
* @platform ios
|
|
74
82
|
*/
|
|
75
|
-
pressOpacity?: number;
|
|
83
|
+
pressOpacity?: number | undefined;
|
|
76
84
|
/**
|
|
77
85
|
* Style object for the label element.
|
|
78
86
|
*/
|
|
79
|
-
labelStyle?: StyleProp<TextStyle
|
|
87
|
+
labelStyle?: StyleProp<TextStyle> | undefined;
|
|
80
88
|
/**
|
|
81
89
|
* Style object for the wrapper element.
|
|
82
90
|
*/
|
|
83
|
-
style?: StyleProp<ViewStyle
|
|
91
|
+
style?: StyleProp<ViewStyle> | undefined;
|
|
84
92
|
/**
|
|
85
93
|
* Whether label font should scale to respect Text Size accessibility settings.
|
|
86
94
|
*/
|
|
87
|
-
allowFontScaling?: boolean;
|
|
95
|
+
allowFontScaling?: boolean | undefined;
|
|
88
96
|
|
|
89
97
|
/**
|
|
90
98
|
* Accessibility label for drawer item.
|
|
91
99
|
*/
|
|
92
|
-
accessibilityLabel?: string;
|
|
100
|
+
accessibilityLabel?: string | undefined;
|
|
93
101
|
/**
|
|
94
102
|
* ID to locate this drawer item in tests.
|
|
95
103
|
*/
|
|
96
|
-
testID?: string;
|
|
104
|
+
testID?: string | undefined;
|
|
97
105
|
};
|
|
98
106
|
|
|
99
107
|
/**
|
|
@@ -122,7 +130,7 @@ export function DrawerItem(props: Props) {
|
|
|
122
130
|
...rest
|
|
123
131
|
} = props;
|
|
124
132
|
|
|
125
|
-
const { borderRadius = 56 } = StyleSheet.flatten(style || {}
|
|
133
|
+
const { borderRadius = 56 } = StyleSheet.flatten(style) || {};
|
|
126
134
|
const color: ColorValue = focused
|
|
127
135
|
? activeTintColor
|
|
128
136
|
: (inactiveTintColor ??
|
|
@@ -134,7 +142,30 @@ export function DrawerItem(props: Props) {
|
|
|
134
142
|
'rgba(0, 0, 0, 0.06)')
|
|
135
143
|
: inactiveBackgroundColor;
|
|
136
144
|
|
|
137
|
-
const iconNode =
|
|
145
|
+
const iconNode = React.useMemo(() => {
|
|
146
|
+
if (!icon) {
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const size = 24;
|
|
151
|
+
|
|
152
|
+
const iconValue =
|
|
153
|
+
typeof icon === 'function' ? icon({ size, focused, color }) : icon;
|
|
154
|
+
|
|
155
|
+
if (React.isValidElement(iconValue)) {
|
|
156
|
+
return iconValue;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (
|
|
160
|
+
typeof iconValue === 'object' &&
|
|
161
|
+
iconValue != null &&
|
|
162
|
+
'type' in iconValue
|
|
163
|
+
) {
|
|
164
|
+
return <PlatformIcon icon={iconValue} size={size} color={color} />;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return null;
|
|
168
|
+
}, [icon, focused, color]);
|
|
138
169
|
|
|
139
170
|
return (
|
|
140
171
|
<View
|
|
@@ -147,7 +178,10 @@ export function DrawerItem(props: Props) {
|
|
|
147
178
|
onPress={onPress}
|
|
148
179
|
role="button"
|
|
149
180
|
aria-label={accessibilityLabel}
|
|
150
|
-
aria-
|
|
181
|
+
aria-current={
|
|
182
|
+
Platform.OS === 'web' ? (focused ? 'page' : undefined) : undefined
|
|
183
|
+
}
|
|
184
|
+
aria-selected={Platform.OS === 'web' ? undefined : focused}
|
|
151
185
|
pressColor={pressColor}
|
|
152
186
|
pressOpacity={pressOpacity}
|
|
153
187
|
hoverEffect={typeof color === 'string' ? { color } : undefined}
|
|
@@ -23,8 +23,12 @@ export function DrawerItemList({ state, navigation, descriptors }: Props) {
|
|
|
23
23
|
const { buildHref } = useLinkBuilder();
|
|
24
24
|
|
|
25
25
|
const focusedRoute = state.routes[state.index];
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
|
|
27
|
+
if (focusedRoute == null) {
|
|
28
|
+
throw new Error(`Couldn't find a route at index ${state.index}.`);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const focusedOptions = descriptors[focusedRoute.key]?.options ?? {};
|
|
28
32
|
|
|
29
33
|
const {
|
|
30
34
|
drawerActiveTintColor,
|
|
@@ -34,6 +38,12 @@ export function DrawerItemList({ state, navigation, descriptors }: Props) {
|
|
|
34
38
|
} = focusedOptions;
|
|
35
39
|
|
|
36
40
|
return state.routes.map((route, i) => {
|
|
41
|
+
const descriptor = descriptors[route.key];
|
|
42
|
+
|
|
43
|
+
if (descriptor == null) {
|
|
44
|
+
throw new Error(`Couldn't find a descriptor for route '${route.key}'.`);
|
|
45
|
+
}
|
|
46
|
+
|
|
37
47
|
const focused = i === state.index;
|
|
38
48
|
|
|
39
49
|
const onPress = () => {
|
|
@@ -44,11 +54,13 @@ export function DrawerItemList({ state, navigation, descriptors }: Props) {
|
|
|
44
54
|
});
|
|
45
55
|
|
|
46
56
|
if (!event.defaultPrevented) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
57
|
+
React.startTransition(() => {
|
|
58
|
+
navigation.dispatch({
|
|
59
|
+
...(focused
|
|
60
|
+
? DrawerActions.closeDrawer()
|
|
61
|
+
: CommonActions.navigate(route.name, route.params)),
|
|
62
|
+
target: state.key,
|
|
63
|
+
});
|
|
52
64
|
});
|
|
53
65
|
}
|
|
54
66
|
};
|
|
@@ -59,8 +71,9 @@ export function DrawerItemList({ state, navigation, descriptors }: Props) {
|
|
|
59
71
|
drawerIcon,
|
|
60
72
|
drawerLabelStyle,
|
|
61
73
|
drawerItemStyle,
|
|
74
|
+
drawerItemTestID,
|
|
62
75
|
drawerAllowFontScaling,
|
|
63
|
-
} =
|
|
76
|
+
} = descriptor.options;
|
|
64
77
|
|
|
65
78
|
return (
|
|
66
79
|
<DrawerItem
|
|
@@ -84,6 +97,7 @@ export function DrawerItemList({ state, navigation, descriptors }: Props) {
|
|
|
84
97
|
labelStyle={drawerLabelStyle}
|
|
85
98
|
style={drawerItemStyle}
|
|
86
99
|
onPress={onPress}
|
|
100
|
+
testID={drawerItemTestID}
|
|
87
101
|
/>
|
|
88
102
|
);
|
|
89
103
|
}) as React.ReactNode as React.ReactElement;
|
|
@@ -1,51 +1,77 @@
|
|
|
1
|
-
import { HeaderButton } from '@react-navigation/elements';
|
|
2
|
-
import { DrawerActions, useNavigation } from '@react-navigation/native';
|
|
3
1
|
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
} from 'react-native';
|
|
2
|
+
HeaderButton,
|
|
3
|
+
type Icon,
|
|
4
|
+
PlatformIcon,
|
|
5
|
+
} from '@react-navigation/elements';
|
|
6
|
+
import { DrawerActions, useNavigation } from '@react-navigation/native';
|
|
7
|
+
import * as React from 'react';
|
|
8
|
+
import { type ColorValue, Platform, StyleSheet } from 'react-native';
|
|
9
9
|
|
|
10
10
|
import toggleDrawerIcon from './assets/toggle-drawer-icon.png';
|
|
11
11
|
|
|
12
12
|
type Props = {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
icon?:
|
|
14
|
+
| Icon
|
|
15
|
+
| ((props: { tintColor: ColorValue | undefined }) => React.ReactNode)
|
|
16
|
+
| undefined;
|
|
17
|
+
accessibilityLabel?: string | undefined;
|
|
18
|
+
pressColor?: ColorValue | undefined;
|
|
19
|
+
pressOpacity?: number | undefined;
|
|
20
|
+
tintColor?: ColorValue | undefined;
|
|
21
|
+
testID?: string | undefined;
|
|
18
22
|
};
|
|
19
23
|
|
|
20
24
|
export function DrawerToggleButton({
|
|
25
|
+
icon,
|
|
21
26
|
tintColor,
|
|
22
27
|
accessibilityLabel = 'Show navigation menu',
|
|
23
|
-
imageSource = toggleDrawerIcon,
|
|
24
28
|
...rest
|
|
25
29
|
}: Props) {
|
|
26
30
|
const navigation = useNavigation();
|
|
27
31
|
|
|
32
|
+
const drawerIcon =
|
|
33
|
+
icon ??
|
|
34
|
+
Platform.select<Icon>({
|
|
35
|
+
ios: {
|
|
36
|
+
type: 'sfSymbol',
|
|
37
|
+
name: 'line.3.horizontal',
|
|
38
|
+
},
|
|
39
|
+
android: {
|
|
40
|
+
type: 'materialSymbol',
|
|
41
|
+
name: 'menu',
|
|
42
|
+
},
|
|
43
|
+
default: {
|
|
44
|
+
type: 'image',
|
|
45
|
+
source: toggleDrawerIcon,
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
|
|
28
49
|
return (
|
|
29
50
|
<HeaderButton
|
|
30
51
|
{...rest}
|
|
31
52
|
accessibilityLabel={accessibilityLabel}
|
|
32
53
|
onPress={() => navigation.dispatch(DrawerActions.toggleDrawer())}
|
|
33
54
|
>
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
55
|
+
{typeof drawerIcon === 'function' ? (
|
|
56
|
+
drawerIcon({ tintColor })
|
|
57
|
+
) : (
|
|
58
|
+
<PlatformIcon
|
|
59
|
+
icon={drawerIcon}
|
|
60
|
+
size={ICON_SIZE}
|
|
61
|
+
color={tintColor}
|
|
62
|
+
style={styles.icon}
|
|
63
|
+
/>
|
|
64
|
+
)}
|
|
41
65
|
</HeaderButton>
|
|
42
66
|
);
|
|
43
67
|
}
|
|
44
68
|
|
|
69
|
+
const ICON_SIZE = 24;
|
|
70
|
+
|
|
45
71
|
const styles = StyleSheet.create({
|
|
46
72
|
icon: {
|
|
47
|
-
height:
|
|
48
|
-
width:
|
|
73
|
+
height: ICON_SIZE,
|
|
74
|
+
width: ICON_SIZE,
|
|
49
75
|
marginVertical: 8,
|
|
50
76
|
marginHorizontal: 5,
|
|
51
77
|
},
|