@terreno/ui 0.11.5 → 0.11.7
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/dist/Common.d.ts +13 -0
- package/dist/SidebarNavigation.native.d.ts +9 -17
- package/dist/SidebarNavigation.native.js +201 -107
- package/dist/SidebarNavigation.native.js.map +1 -1
- package/package.json +1 -1
- package/src/Common.ts +13 -0
- package/src/SidebarNavigation.native.tsx +340 -176
package/dist/Common.d.ts
CHANGED
|
@@ -2533,5 +2533,18 @@ export interface SidebarNavigationPanelProps {
|
|
|
2533
2533
|
* Additional styles applied to each navigation item.
|
|
2534
2534
|
*/
|
|
2535
2535
|
itemStyle?: StyleProp<ViewStyle>;
|
|
2536
|
+
/**
|
|
2537
|
+
* Controlled open state. When provided, the panel hides its internal hamburger
|
|
2538
|
+
* button and defers open/close to the caller.
|
|
2539
|
+
*
|
|
2540
|
+
* @platform mobile — the web sidebar is always visible; this prop is ignored on web.
|
|
2541
|
+
*/
|
|
2542
|
+
isOpen?: boolean;
|
|
2543
|
+
/**
|
|
2544
|
+
* Called when the panel requests an open or close (controlled mode only).
|
|
2545
|
+
*
|
|
2546
|
+
* @platform mobile — the web sidebar is always visible; this prop is ignored on web.
|
|
2547
|
+
*/
|
|
2548
|
+
onOpenChange?: (isOpen: boolean) => void;
|
|
2536
2549
|
}
|
|
2537
2550
|
export {};
|
|
@@ -1,22 +1,14 @@
|
|
|
1
|
+
import { Screen } from "expo-router/build/views/Screen";
|
|
1
2
|
import { type FC } from "react";
|
|
2
3
|
import type { SidebarNavigationPanelProps, SidebarNavigationProps } from "./Common";
|
|
3
4
|
/**
|
|
4
|
-
* Renders the
|
|
5
|
-
*/
|
|
6
|
-
export declare const SidebarNavigationPanel: FC<SidebarNavigationPanelProps>;
|
|
7
|
-
/**
|
|
8
|
-
* Custom expo-router navigator with a hamburger-triggered slide-in drawer.
|
|
9
|
-
* Use in _layout.tsx files:
|
|
5
|
+
* Renders the bottom sheet overlay and children. Works without expo-router Navigator context.
|
|
10
6
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* <SidebarNavigation
|
|
15
|
-
* topItems={[{label: "Home", route: "index", iconName: "house"}]}
|
|
16
|
-
* bottomItems={[{label: "Settings", route: "settings", iconName: "gear"}]}
|
|
17
|
-
* />
|
|
18
|
-
* );
|
|
19
|
-
* }
|
|
20
|
-
* ```
|
|
7
|
+
* Supports two modes:
|
|
8
|
+
* - Uncontrolled (default): manages open state internally and shows a floating hamburger button.
|
|
9
|
+
* - Controlled: caller provides isOpen + onOpenChange and owns the trigger (e.g. a header button).
|
|
21
10
|
*/
|
|
22
|
-
export declare const
|
|
11
|
+
export declare const SidebarNavigationPanel: FC<SidebarNavigationPanelProps>;
|
|
12
|
+
export declare const SidebarNavigation: FC<SidebarNavigationProps> & {
|
|
13
|
+
Screen: typeof Screen;
|
|
14
|
+
};
|
|
@@ -1,18 +1,51 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { TabRouter } from "@react-navigation/native";
|
|
3
3
|
import { Navigator, Slot } from "expo-router";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
import
|
|
7
|
-
|
|
4
|
+
// Screen is not exported from expo-router's public API (exports.d.ts only exposes ScreenProps).
|
|
5
|
+
// Stack.Screen and Tabs.Screen use this same internal path. If expo-router upgrades break this,
|
|
6
|
+
// update the import path here — this is the only place in the codebase that references it.
|
|
7
|
+
// eslint-disable-next-line import/no-internal-modules
|
|
8
|
+
import { Screen } from "expo-router/build/views/Screen";
|
|
9
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
10
|
+
import { Animated, Dimensions, PanResponder, Pressable, Text as RNText, View, } from "react-native";
|
|
11
|
+
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
8
12
|
import { Icon } from "./Icon";
|
|
9
13
|
import { Text } from "./Text";
|
|
10
14
|
import { useTheme } from "./Theme";
|
|
11
|
-
const
|
|
12
|
-
const ITEM_HEIGHT = 48;
|
|
13
|
-
const ICON_SIZE = 20;
|
|
15
|
+
const ITEM_HEIGHT = 44;
|
|
14
16
|
const BACKDROP_OPACITY = 0.5;
|
|
15
|
-
const
|
|
17
|
+
const SIDEBAR_BADGE_SURFACE = {
|
|
18
|
+
error: "error",
|
|
19
|
+
info: "secondaryDark",
|
|
20
|
+
neutral: "neutralDark",
|
|
21
|
+
success: "success",
|
|
22
|
+
warning: "warning",
|
|
23
|
+
};
|
|
24
|
+
const SidebarBadge = ({ badge, status }) => {
|
|
25
|
+
const { theme } = useTheme();
|
|
26
|
+
const backgroundColor = theme.surface[SIDEBAR_BADGE_SURFACE[status]];
|
|
27
|
+
const isDot = badge === true;
|
|
28
|
+
if (isDot) {
|
|
29
|
+
return _jsx(View, { style: { backgroundColor, borderRadius: 999, height: 18, width: 18 } });
|
|
30
|
+
}
|
|
31
|
+
const value = Number(badge) > 9 ? "9+" : String(badge);
|
|
32
|
+
return (_jsx(View, { style: {
|
|
33
|
+
alignItems: "center",
|
|
34
|
+
backgroundColor,
|
|
35
|
+
borderRadius: 999,
|
|
36
|
+
height: 18,
|
|
37
|
+
justifyContent: "center",
|
|
38
|
+
minWidth: 18,
|
|
39
|
+
paddingHorizontal: 4,
|
|
40
|
+
}, children: _jsx(RNText, { style: {
|
|
41
|
+
color: "#FFFFFF",
|
|
42
|
+
fontSize: 11,
|
|
43
|
+
fontWeight: "700",
|
|
44
|
+
lineHeight: 12,
|
|
45
|
+
}, children: value }) }));
|
|
46
|
+
};
|
|
47
|
+
const ANIMATION_DURATION = 300;
|
|
48
|
+
const DISMISS_THRESHOLD = 0.3;
|
|
16
49
|
const SidebarItem = ({ item, isActive, onPress, itemStyle }) => {
|
|
17
50
|
var _a;
|
|
18
51
|
const { theme } = useTheme();
|
|
@@ -22,136 +55,195 @@ const SidebarItem = ({ item, isActive, onPress, itemStyle }) => {
|
|
|
22
55
|
return (_jsxs(Pressable, { accessibilityLabel: item.label, accessibilityRole: "button", onPress: handlePress, style: [
|
|
23
56
|
{
|
|
24
57
|
alignItems: "center",
|
|
25
|
-
backgroundColor: isActive ? theme.surface.
|
|
58
|
+
backgroundColor: isActive ? theme.surface.neutralLight : "transparent",
|
|
26
59
|
borderRadius: theme.radius.default,
|
|
27
60
|
flexDirection: "row",
|
|
28
|
-
gap:
|
|
61
|
+
gap: 12,
|
|
29
62
|
height: ITEM_HEIGHT,
|
|
30
|
-
marginHorizontal:
|
|
31
|
-
paddingHorizontal:
|
|
63
|
+
marginHorizontal: 8,
|
|
64
|
+
paddingHorizontal: 12,
|
|
32
65
|
},
|
|
33
66
|
itemStyle,
|
|
34
|
-
], children: [_jsxs(View, { style: { alignItems: "center", justifyContent: "center", width:
|
|
35
|
-
bottom: item.badge === true ? -4 : undefined,
|
|
36
|
-
position: "absolute",
|
|
37
|
-
right: -6,
|
|
38
|
-
top: item.badge === true ? undefined : -4,
|
|
39
|
-
}, children: _jsx(Badge, { maxValue: 99, status: SIDEBAR_BADGE_STATUS_MAP[(_a = item.badgeStatus) !== null && _a !== void 0 ? _a : "error"], value: item.badge === true ? undefined : String(item.badge), variant: item.badge === true ? "iconOnly" : "numberOnly" }) }))] }), _jsx(Text, { bold: isActive, color: isActive ? "primary" : "secondaryDark", size: "md", children: item.label })] }));
|
|
67
|
+
], children: [_jsxs(View, { style: { alignItems: "center", height: 40, justifyContent: "center", width: 40 }, children: [_jsx(Icon, { color: isActive ? "primary" : "secondaryLight", iconName: item.iconName, size: "xl" }), item.badge !== undefined && item.badge !== false && (_jsx(View, { style: { bottom: 0, position: "absolute", right: 0 }, children: _jsx(SidebarBadge, { badge: item.badge, status: (_a = item.badgeStatus) !== null && _a !== void 0 ? _a : "success" }) }))] }), _jsx(Text, { bold: isActive, color: isActive ? "primary" : "secondaryLight", size: "lg", children: item.label })] }));
|
|
40
68
|
};
|
|
69
|
+
const SidebarHamburger = ({ onOpen }) => (_jsx(Pressable, { accessibilityLabel: "Open navigation menu", accessibilityRole: "button", onPress: onOpen, style: { alignItems: "center", height: 40, justifyContent: "center", width: 40 }, children: _jsx(Icon, { color: "primary", iconName: "bars", size: "md" }) }));
|
|
41
70
|
/**
|
|
42
|
-
* Renders the
|
|
71
|
+
* Renders the bottom sheet overlay and children. Works without expo-router Navigator context.
|
|
72
|
+
*
|
|
73
|
+
* Supports two modes:
|
|
74
|
+
* - Uncontrolled (default): manages open state internally and shows a floating hamburger button.
|
|
75
|
+
* - Controlled: caller provides isOpen + onOpenChange and owns the trigger (e.g. a header button).
|
|
43
76
|
*/
|
|
44
|
-
export const SidebarNavigationPanel = ({ topItems, bottomItems, activeRoute, onNavigate, children, panelStyle, itemStyle, }) => {
|
|
77
|
+
export const SidebarNavigationPanel = ({ topItems, bottomItems, activeRoute, onNavigate, children, panelStyle, itemStyle, isOpen: isOpenProp, onOpenChange, }) => {
|
|
45
78
|
const { theme } = useTheme();
|
|
46
|
-
const
|
|
47
|
-
const
|
|
79
|
+
const insets = useSafeAreaInsets();
|
|
80
|
+
const isControlled = isOpenProp !== undefined;
|
|
81
|
+
const [isOpenInternal, setIsOpenInternal] = useState(false);
|
|
82
|
+
const isOpen = isControlled ? isOpenProp : isOpenInternal;
|
|
83
|
+
const sheetHeight = useMemo(() => Dimensions.get("window").height * 0.65, []);
|
|
84
|
+
const slideAnim = useRef(new Animated.Value(sheetHeight)).current;
|
|
48
85
|
const backdropAnim = useRef(new Animated.Value(0)).current;
|
|
49
|
-
|
|
86
|
+
const capturedSlideValue = useRef(0);
|
|
87
|
+
// Play open animation whenever isOpen becomes true
|
|
50
88
|
useEffect(() => {
|
|
51
|
-
if (isOpen) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
89
|
+
if (!isOpen) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
slideAnim.setValue(sheetHeight);
|
|
93
|
+
backdropAnim.setValue(0);
|
|
94
|
+
Animated.parallel([
|
|
95
|
+
Animated.timing(slideAnim, {
|
|
96
|
+
duration: ANIMATION_DURATION,
|
|
97
|
+
toValue: 0,
|
|
98
|
+
useNativeDriver: true,
|
|
99
|
+
}),
|
|
100
|
+
Animated.timing(backdropAnim, {
|
|
101
|
+
duration: ANIMATION_DURATION,
|
|
102
|
+
toValue: BACKDROP_OPACITY,
|
|
103
|
+
useNativeDriver: true,
|
|
104
|
+
}),
|
|
105
|
+
]).start();
|
|
106
|
+
}, [isOpen, slideAnim, backdropAnim, sheetHeight]);
|
|
107
|
+
// Play close animation then update state
|
|
108
|
+
const handleClose = useCallback(() => {
|
|
109
|
+
Animated.parallel([
|
|
110
|
+
Animated.timing(slideAnim, {
|
|
111
|
+
duration: ANIMATION_DURATION,
|
|
112
|
+
toValue: sheetHeight,
|
|
113
|
+
useNativeDriver: true,
|
|
114
|
+
}),
|
|
115
|
+
Animated.timing(backdropAnim, {
|
|
116
|
+
duration: ANIMATION_DURATION,
|
|
117
|
+
toValue: 0,
|
|
118
|
+
useNativeDriver: true,
|
|
119
|
+
}),
|
|
120
|
+
]).start(() => {
|
|
121
|
+
if (isControlled) {
|
|
122
|
+
onOpenChange === null || onOpenChange === void 0 ? void 0 : onOpenChange(false);
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
setIsOpenInternal(false);
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
}, [isControlled, onOpenChange, slideAnim, backdropAnim, sheetHeight]);
|
|
129
|
+
const handleOpen = useCallback(() => {
|
|
130
|
+
if (isControlled) {
|
|
131
|
+
onOpenChange === null || onOpenChange === void 0 ? void 0 : onOpenChange(true);
|
|
64
132
|
}
|
|
65
133
|
else {
|
|
66
|
-
|
|
67
|
-
Animated.timing(slideAnim, {
|
|
68
|
-
duration: ANIMATION_DURATION,
|
|
69
|
-
toValue: -DRAWER_WIDTH,
|
|
70
|
-
useNativeDriver: true,
|
|
71
|
-
}),
|
|
72
|
-
Animated.timing(backdropAnim, {
|
|
73
|
-
duration: ANIMATION_DURATION,
|
|
74
|
-
toValue: 0,
|
|
75
|
-
useNativeDriver: true,
|
|
76
|
-
}),
|
|
77
|
-
]).start();
|
|
134
|
+
setIsOpenInternal(true);
|
|
78
135
|
}
|
|
79
|
-
}, [
|
|
80
|
-
const handleOpen = useCallback(() => setIsOpen(true), []);
|
|
81
|
-
const handleClose = useCallback(() => setIsOpen(false), []);
|
|
136
|
+
}, [isControlled, onOpenChange]);
|
|
82
137
|
const handleNavigate = useCallback((route) => {
|
|
83
|
-
|
|
138
|
+
handleClose();
|
|
84
139
|
onNavigate(route);
|
|
85
|
-
}, [onNavigate]);
|
|
86
|
-
const
|
|
87
|
-
|
|
140
|
+
}, [handleClose, onNavigate]);
|
|
141
|
+
const panResponder = useMemo(() => PanResponder.create({
|
|
142
|
+
onMoveShouldSetPanResponder: (_, { dx, dy }) => Math.abs(dy) > Math.abs(dx) && dy > 4,
|
|
143
|
+
onPanResponderGrant: () => {
|
|
144
|
+
slideAnim.stopAnimation((value) => {
|
|
145
|
+
capturedSlideValue.current = value;
|
|
146
|
+
});
|
|
147
|
+
backdropAnim.stopAnimation();
|
|
148
|
+
},
|
|
149
|
+
onPanResponderMove: (_, { dy }) => {
|
|
150
|
+
const next = capturedSlideValue.current + dy;
|
|
151
|
+
if (next < 0) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
slideAnim.setValue(next);
|
|
155
|
+
backdropAnim.setValue(BACKDROP_OPACITY * Math.max(0, 1 - next / sheetHeight));
|
|
156
|
+
},
|
|
157
|
+
onPanResponderRelease: (_, { dy, vy }) => {
|
|
158
|
+
if (dy > sheetHeight * DISMISS_THRESHOLD || vy > 0.5) {
|
|
159
|
+
handleClose();
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
Animated.parallel([
|
|
163
|
+
Animated.timing(slideAnim, {
|
|
164
|
+
duration: 200,
|
|
165
|
+
toValue: 0,
|
|
166
|
+
useNativeDriver: true,
|
|
167
|
+
}),
|
|
168
|
+
Animated.timing(backdropAnim, {
|
|
169
|
+
duration: 200,
|
|
170
|
+
toValue: BACKDROP_OPACITY,
|
|
171
|
+
useNativeDriver: true,
|
|
172
|
+
}),
|
|
173
|
+
]).start();
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
}), [slideAnim, backdropAnim, sheetHeight, handleClose]);
|
|
177
|
+
return (_jsxs(View, { style: { flex: 1 }, children: [children, !isControlled && (_jsx(Pressable, { accessibilityLabel: "Open navigation menu", accessibilityRole: "button", onPress: handleOpen, style: {
|
|
88
178
|
alignItems: "center",
|
|
89
|
-
backgroundColor: theme.surface.primary,
|
|
90
|
-
borderRadius: theme.radius.full,
|
|
91
|
-
elevation: 4,
|
|
92
179
|
height: 44,
|
|
93
180
|
justifyContent: "center",
|
|
94
181
|
left: 16,
|
|
95
182
|
position: "absolute",
|
|
96
|
-
|
|
97
|
-
shadowOffset: { height: 2, width: 0 },
|
|
98
|
-
shadowOpacity: 0.25,
|
|
99
|
-
shadowRadius: 4,
|
|
100
|
-
top: 16,
|
|
183
|
+
top: insets.top + 16,
|
|
101
184
|
width: 44,
|
|
102
185
|
zIndex: 10,
|
|
103
|
-
}, children: _jsx(Icon, { color: "
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
186
|
+
}, children: _jsx(Icon, { color: "primary", iconName: "bars", size: "md" }) })), isOpen && (_jsxs(_Fragment, { children: [_jsx(Pressable, { accessibilityElementsHidden: true, onPress: handleClose, style: { bottom: 0, left: 0, position: "absolute", right: 0, top: 0, zIndex: 100 }, children: _jsx(Animated.View, { style: { backgroundColor: "#000", flex: 1, opacity: backdropAnim } }) }), _jsxs(Animated.View, { style: [
|
|
187
|
+
{
|
|
188
|
+
backgroundColor: theme.surface.base,
|
|
189
|
+
borderTopLeftRadius: 16,
|
|
190
|
+
borderTopRightRadius: 16,
|
|
191
|
+
bottom: 0,
|
|
192
|
+
height: sheetHeight,
|
|
193
|
+
left: 0,
|
|
194
|
+
position: "absolute",
|
|
195
|
+
right: 0,
|
|
196
|
+
transform: [{ translateY: slideAnim }],
|
|
197
|
+
zIndex: 200,
|
|
198
|
+
},
|
|
199
|
+
panelStyle,
|
|
200
|
+
], children: [_jsx(View, Object.assign({}, panResponder.panHandlers, { accessibilityHint: "Drag down to close", accessibilityLabel: "Navigation menu drag handle", accessibilityRole: "adjustable", style: { alignItems: "center", paddingBottom: 8, paddingTop: 12 }, children: _jsx(View, { style: {
|
|
201
|
+
backgroundColor: theme.border.default,
|
|
202
|
+
borderRadius: 2,
|
|
203
|
+
height: 4,
|
|
204
|
+
width: 36,
|
|
205
|
+
} }) })), _jsx(View, { style: { gap: 4, paddingBottom: insets.bottom + 8 }, children: [...topItems, ...bottomItems].map((item) => (_jsx(SidebarItem, { isActive: activeRoute === item.route, item: item, itemStyle: itemStyle, onPress: handleNavigate }, item.label))) })] })] }))] }));
|
|
206
|
+
};
|
|
207
|
+
const SidebarHeader = ({ onOpen }) => {
|
|
208
|
+
var _a, _b;
|
|
209
|
+
const { theme } = useTheme();
|
|
210
|
+
const insets = useSafeAreaInsets();
|
|
211
|
+
const { state, descriptors } = Navigator.useContext();
|
|
212
|
+
const activeRoute = state.routes[state.index];
|
|
213
|
+
const { headerLeft, headerRight, title } = ((_b = (_a = descriptors[activeRoute === null || activeRoute === void 0 ? void 0 : activeRoute.key]) === null || _a === void 0 ? void 0 : _a.options) !== null && _b !== void 0 ? _b : {});
|
|
214
|
+
return (_jsx(View, { style: {
|
|
215
|
+
backgroundColor: theme.surface.base,
|
|
216
|
+
borderBottomColor: theme.border.default,
|
|
217
|
+
borderBottomWidth: 1,
|
|
218
|
+
paddingTop: insets.top,
|
|
219
|
+
}, children: _jsxs(View, { style: {
|
|
220
|
+
alignItems: "center",
|
|
221
|
+
flexDirection: "row",
|
|
222
|
+
height: 44,
|
|
223
|
+
justifyContent: "space-between",
|
|
224
|
+
paddingHorizontal: 16,
|
|
225
|
+
}, children: [_jsxs(View, { style: { alignItems: "center", flexDirection: "row", gap: 12 }, children: [_jsx(SidebarHamburger, { onOpen: onOpen }), headerLeft === null || headerLeft === void 0 ? void 0 : headerLeft({})] }), Boolean(title) && (_jsx(View, { pointerEvents: "none", style: {
|
|
226
|
+
alignItems: "center",
|
|
227
|
+
bottom: 0,
|
|
228
|
+
justifyContent: "center",
|
|
121
229
|
left: 0,
|
|
122
|
-
paddingBottom: 32,
|
|
123
|
-
paddingTop: 20,
|
|
124
230
|
position: "absolute",
|
|
231
|
+
right: 0,
|
|
125
232
|
top: 0,
|
|
126
|
-
|
|
127
|
-
width: DRAWER_WIDTH,
|
|
128
|
-
zIndex: 200,
|
|
129
|
-
},
|
|
130
|
-
panelStyle,
|
|
131
|
-
], children: [_jsxs(View, { children: [_jsx(Pressable, { accessibilityLabel: "Close navigation menu", accessibilityRole: "button", onPress: handleClose, style: {
|
|
132
|
-
alignItems: "center",
|
|
133
|
-
alignSelf: "flex-end",
|
|
134
|
-
height: 40,
|
|
135
|
-
justifyContent: "center",
|
|
136
|
-
marginRight: 12,
|
|
137
|
-
width: 40,
|
|
138
|
-
}, children: _jsx(Icon, { color: "secondaryDark", iconName: "xmark", size: "md" }) }), _jsx(View, { style: { gap: 4, marginTop: 8 }, children: topItems.map((item) => (_jsx(SidebarItem, { isActive: activeRoute === item.route, item: item, itemStyle: itemStyle, onPress: handleNavigate }, item.route))) })] }), _jsx(View, { style: { gap: 4 }, children: bottomItems.map((item) => (_jsx(SidebarItem, { isActive: activeRoute === item.route, item: item, onPress: handleNavigate }, item.route))) })] })] }));
|
|
233
|
+
}, children: _jsx(Text, { bold: true, size: "lg", children: title }) })), Boolean(headerRight) && _jsx(View, { style: { alignItems: "flex-end" }, children: headerRight === null || headerRight === void 0 ? void 0 : headerRight({}) })] }) }));
|
|
139
234
|
};
|
|
140
|
-
/**
|
|
141
|
-
|
|
142
|
-
*/
|
|
143
|
-
const SidebarNavigatorContent = ({ topItems, bottomItems, onNavigate, panelStyle, itemStyle }) => {
|
|
144
|
-
var _a;
|
|
235
|
+
/** Renders the content panel and bottom sheet for the active screen. */
|
|
236
|
+
const SidebarNavigatorContent = ({ topItems, bottomItems, isOpen, onOpenChange, onNavigate, panelStyle, itemStyle }) => {
|
|
145
237
|
const { state, navigation } = Navigator.useContext();
|
|
146
|
-
const activeRoute =
|
|
238
|
+
const activeRoute = state.routes[state.index];
|
|
147
239
|
const handleNavigate = useCallback((route) => {
|
|
148
240
|
navigation.navigate(route);
|
|
149
241
|
onNavigate === null || onNavigate === void 0 ? void 0 : onNavigate(route);
|
|
150
242
|
}, [navigation, onNavigate]);
|
|
151
|
-
return (_jsx(SidebarNavigationPanel, { activeRoute: activeRoute, bottomItems: bottomItems, itemStyle: itemStyle, onNavigate: handleNavigate, panelStyle: panelStyle, topItems: topItems, children: _jsx(Slot, {}) }));
|
|
243
|
+
return (_jsx(SidebarNavigationPanel, { activeRoute: activeRoute === null || activeRoute === void 0 ? void 0 : activeRoute.name, bottomItems: bottomItems, isOpen: isOpen, itemStyle: itemStyle, onNavigate: handleNavigate, onOpenChange: onOpenChange, panelStyle: panelStyle, topItems: topItems, children: _jsx(Slot, {}) }));
|
|
152
244
|
};
|
|
153
245
|
/**
|
|
154
|
-
* Custom expo-router navigator with a hamburger-triggered
|
|
246
|
+
* Custom expo-router navigator with a header bar and hamburger-triggered bottom sheet.
|
|
155
247
|
* Use in _layout.tsx files:
|
|
156
248
|
*
|
|
157
249
|
* ```tsx
|
|
@@ -165,7 +257,9 @@ const SidebarNavigatorContent = ({ topItems, bottomItems, onNavigate, panelStyle
|
|
|
165
257
|
* }
|
|
166
258
|
* ```
|
|
167
259
|
*/
|
|
168
|
-
|
|
169
|
-
|
|
260
|
+
const SidebarNavigationBase = ({ topItems, bottomItems, onNavigate, initialRouteName, screenOptions, panelStyle, itemStyle, children, }) => {
|
|
261
|
+
const [isSheetOpen, setIsSheetOpen] = useState(false);
|
|
262
|
+
return (_jsxs(Navigator, { initialRouteName: initialRouteName, router: TabRouter, screenOptions: screenOptions, children: [_jsxs(View, { style: { flex: 1 }, children: [_jsx(SidebarHeader, { onOpen: () => setIsSheetOpen(true) }), _jsx(SidebarNavigatorContent, { bottomItems: bottomItems, isOpen: isSheetOpen, itemStyle: itemStyle, onNavigate: onNavigate, onOpenChange: setIsSheetOpen, panelStyle: panelStyle, topItems: topItems })] }), children] }));
|
|
170
263
|
};
|
|
264
|
+
export const SidebarNavigation = Object.assign(SidebarNavigationBase, { Screen });
|
|
171
265
|
//# sourceMappingURL=SidebarNavigation.native.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SidebarNavigation.native.js","sourceRoot":"","sources":["../src/SidebarNavigation.native.tsx"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SidebarNavigation.native.js","sourceRoot":"","sources":["../src/SidebarNavigation.native.tsx"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/Common.ts
CHANGED
|
@@ -3044,4 +3044,17 @@ export interface SidebarNavigationPanelProps {
|
|
|
3044
3044
|
* Additional styles applied to each navigation item.
|
|
3045
3045
|
*/
|
|
3046
3046
|
itemStyle?: StyleProp<ViewStyle>;
|
|
3047
|
+
/**
|
|
3048
|
+
* Controlled open state. When provided, the panel hides its internal hamburger
|
|
3049
|
+
* button and defers open/close to the caller.
|
|
3050
|
+
*
|
|
3051
|
+
* @platform mobile — the web sidebar is always visible; this prop is ignored on web.
|
|
3052
|
+
*/
|
|
3053
|
+
isOpen?: boolean;
|
|
3054
|
+
/**
|
|
3055
|
+
* Called when the panel requests an open or close (controlled mode only).
|
|
3056
|
+
*
|
|
3057
|
+
* @platform mobile — the web sidebar is always visible; this prop is ignored on web.
|
|
3058
|
+
*/
|
|
3059
|
+
onOpenChange?: (isOpen: boolean) => void;
|
|
3047
3060
|
}
|
|
@@ -1,24 +1,84 @@
|
|
|
1
1
|
import {TabRouter} from "@react-navigation/native";
|
|
2
2
|
import {Navigator, Slot} from "expo-router";
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
// Screen is not exported from expo-router's public API (exports.d.ts only exposes ScreenProps).
|
|
4
|
+
// Stack.Screen and Tabs.Screen use this same internal path. If expo-router upgrades break this,
|
|
5
|
+
// update the import path here — this is the only place in the codebase that references it.
|
|
6
|
+
// eslint-disable-next-line import/no-internal-modules
|
|
7
|
+
import {Screen} from "expo-router/build/views/Screen";
|
|
8
|
+
import {type FC, useCallback, useEffect, useMemo, useRef, useState} from "react";
|
|
9
|
+
import {
|
|
10
|
+
Animated,
|
|
11
|
+
Dimensions,
|
|
12
|
+
PanResponder,
|
|
13
|
+
Pressable,
|
|
14
|
+
Text as RNText,
|
|
15
|
+
type StyleProp,
|
|
16
|
+
View,
|
|
17
|
+
type ViewStyle,
|
|
18
|
+
} from "react-native";
|
|
19
|
+
import {useSafeAreaInsets} from "react-native-safe-area-context";
|
|
5
20
|
|
|
6
|
-
import {Badge} from "./Badge";
|
|
7
21
|
import type {
|
|
22
|
+
SidebarBadgeStatus,
|
|
8
23
|
SidebarNavigationItem,
|
|
9
24
|
SidebarNavigationPanelProps,
|
|
10
25
|
SidebarNavigationProps,
|
|
26
|
+
SurfaceTheme,
|
|
11
27
|
} from "./Common";
|
|
12
|
-
import {SIDEBAR_BADGE_STATUS_MAP} from "./Common";
|
|
13
28
|
import {Icon} from "./Icon";
|
|
14
29
|
import {Text} from "./Text";
|
|
15
30
|
import {useTheme} from "./Theme";
|
|
16
31
|
|
|
17
|
-
const
|
|
18
|
-
const ITEM_HEIGHT = 48;
|
|
19
|
-
const ICON_SIZE = 20;
|
|
32
|
+
const ITEM_HEIGHT = 44;
|
|
20
33
|
const BACKDROP_OPACITY = 0.5;
|
|
21
|
-
|
|
34
|
+
|
|
35
|
+
const SIDEBAR_BADGE_SURFACE: Record<SidebarBadgeStatus, keyof SurfaceTheme> = {
|
|
36
|
+
error: "error",
|
|
37
|
+
info: "secondaryDark",
|
|
38
|
+
neutral: "neutralDark",
|
|
39
|
+
success: "success",
|
|
40
|
+
warning: "warning",
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const SidebarBadge: FC<{badge: number | true; status: SidebarBadgeStatus}> = ({badge, status}) => {
|
|
44
|
+
const {theme} = useTheme();
|
|
45
|
+
const backgroundColor = theme.surface[SIDEBAR_BADGE_SURFACE[status]];
|
|
46
|
+
const isDot = badge === true;
|
|
47
|
+
|
|
48
|
+
if (isDot) {
|
|
49
|
+
return <View style={{backgroundColor, borderRadius: 999, height: 18, width: 18}} />;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const value = Number(badge) > 9 ? "9+" : String(badge);
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<View
|
|
56
|
+
style={{
|
|
57
|
+
alignItems: "center",
|
|
58
|
+
backgroundColor,
|
|
59
|
+
borderRadius: 999,
|
|
60
|
+
height: 18,
|
|
61
|
+
justifyContent: "center",
|
|
62
|
+
minWidth: 18,
|
|
63
|
+
paddingHorizontal: 4,
|
|
64
|
+
}}
|
|
65
|
+
>
|
|
66
|
+
<RNText
|
|
67
|
+
style={{
|
|
68
|
+
color: "#FFFFFF",
|
|
69
|
+
fontSize: 11,
|
|
70
|
+
fontWeight: "700",
|
|
71
|
+
lineHeight: 12,
|
|
72
|
+
}}
|
|
73
|
+
>
|
|
74
|
+
{value}
|
|
75
|
+
</RNText>
|
|
76
|
+
</View>
|
|
77
|
+
);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const ANIMATION_DURATION = 300;
|
|
81
|
+
const DISMISS_THRESHOLD = 0.3;
|
|
22
82
|
|
|
23
83
|
const SidebarItem: FC<{
|
|
24
84
|
item: SidebarNavigationItem;
|
|
@@ -40,46 +100,49 @@ const SidebarItem: FC<{
|
|
|
40
100
|
style={[
|
|
41
101
|
{
|
|
42
102
|
alignItems: "center",
|
|
43
|
-
backgroundColor: isActive ? theme.surface.
|
|
103
|
+
backgroundColor: isActive ? theme.surface.neutralLight : "transparent",
|
|
44
104
|
borderRadius: theme.radius.default,
|
|
45
105
|
flexDirection: "row",
|
|
46
|
-
gap:
|
|
106
|
+
gap: 12,
|
|
47
107
|
height: ITEM_HEIGHT,
|
|
48
|
-
marginHorizontal:
|
|
49
|
-
paddingHorizontal:
|
|
108
|
+
marginHorizontal: 8,
|
|
109
|
+
paddingHorizontal: 12,
|
|
50
110
|
},
|
|
51
111
|
itemStyle,
|
|
52
112
|
]}
|
|
53
113
|
>
|
|
54
|
-
<View style={{alignItems: "center", justifyContent: "center", width:
|
|
55
|
-
<Icon color={isActive ? "primary" : "
|
|
56
|
-
{
|
|
57
|
-
<View
|
|
58
|
-
|
|
59
|
-
bottom: item.badge === true ? -4 : undefined,
|
|
60
|
-
position: "absolute",
|
|
61
|
-
right: -6,
|
|
62
|
-
top: item.badge === true ? undefined : -4,
|
|
63
|
-
}}
|
|
64
|
-
>
|
|
65
|
-
<Badge
|
|
66
|
-
maxValue={99}
|
|
67
|
-
status={SIDEBAR_BADGE_STATUS_MAP[item.badgeStatus ?? "error"]}
|
|
68
|
-
value={item.badge === true ? undefined : String(item.badge)}
|
|
69
|
-
variant={item.badge === true ? "iconOnly" : "numberOnly"}
|
|
70
|
-
/>
|
|
114
|
+
<View style={{alignItems: "center", height: 40, justifyContent: "center", width: 40}}>
|
|
115
|
+
<Icon color={isActive ? "primary" : "secondaryLight"} iconName={item.iconName} size="xl" />
|
|
116
|
+
{item.badge !== undefined && item.badge !== false && (
|
|
117
|
+
<View style={{bottom: 0, position: "absolute", right: 0}}>
|
|
118
|
+
<SidebarBadge badge={item.badge} status={item.badgeStatus ?? "success"} />
|
|
71
119
|
</View>
|
|
72
120
|
)}
|
|
73
121
|
</View>
|
|
74
|
-
<Text bold={isActive} color={isActive ? "primary" : "
|
|
122
|
+
<Text bold={isActive} color={isActive ? "primary" : "secondaryLight"} size="lg">
|
|
75
123
|
{item.label}
|
|
76
124
|
</Text>
|
|
77
125
|
</Pressable>
|
|
78
126
|
);
|
|
79
127
|
};
|
|
80
128
|
|
|
129
|
+
const SidebarHamburger: FC<{onOpen: () => void}> = ({onOpen}) => (
|
|
130
|
+
<Pressable
|
|
131
|
+
accessibilityLabel="Open navigation menu"
|
|
132
|
+
accessibilityRole="button"
|
|
133
|
+
onPress={onOpen}
|
|
134
|
+
style={{alignItems: "center", height: 40, justifyContent: "center", width: 40}}
|
|
135
|
+
>
|
|
136
|
+
<Icon color="primary" iconName="bars" size="md" />
|
|
137
|
+
</Pressable>
|
|
138
|
+
);
|
|
139
|
+
|
|
81
140
|
/**
|
|
82
|
-
* Renders the
|
|
141
|
+
* Renders the bottom sheet overlay and children. Works without expo-router Navigator context.
|
|
142
|
+
*
|
|
143
|
+
* Supports two modes:
|
|
144
|
+
* - Uncontrolled (default): manages open state internally and shows a floating hamburger button.
|
|
145
|
+
* - Controlled: caller provides isOpen + onOpenChange and owns the trigger (e.g. a header button).
|
|
83
146
|
*/
|
|
84
147
|
export const SidebarNavigationPanel: FC<SidebarNavigationPanelProps> = ({
|
|
85
148
|
topItems,
|
|
@@ -89,187 +152,275 @@ export const SidebarNavigationPanel: FC<SidebarNavigationPanelProps> = ({
|
|
|
89
152
|
children,
|
|
90
153
|
panelStyle,
|
|
91
154
|
itemStyle,
|
|
155
|
+
isOpen: isOpenProp,
|
|
156
|
+
onOpenChange,
|
|
92
157
|
}) => {
|
|
93
158
|
const {theme} = useTheme();
|
|
94
|
-
const
|
|
95
|
-
const
|
|
159
|
+
const insets = useSafeAreaInsets();
|
|
160
|
+
const isControlled = isOpenProp !== undefined;
|
|
161
|
+
const [isOpenInternal, setIsOpenInternal] = useState(false);
|
|
162
|
+
const isOpen = isControlled ? isOpenProp : isOpenInternal;
|
|
163
|
+
|
|
164
|
+
const sheetHeight = useMemo(() => Dimensions.get("window").height * 0.65, []);
|
|
165
|
+
const slideAnim = useRef(new Animated.Value(sheetHeight)).current;
|
|
96
166
|
const backdropAnim = useRef(new Animated.Value(0)).current;
|
|
167
|
+
const capturedSlideValue = useRef(0);
|
|
97
168
|
|
|
98
|
-
//
|
|
169
|
+
// Play open animation whenever isOpen becomes true
|
|
99
170
|
useEffect(() => {
|
|
100
|
-
if (isOpen) {
|
|
101
|
-
|
|
102
|
-
Animated.timing(slideAnim, {
|
|
103
|
-
duration: ANIMATION_DURATION,
|
|
104
|
-
toValue: 0,
|
|
105
|
-
useNativeDriver: true,
|
|
106
|
-
}),
|
|
107
|
-
Animated.timing(backdropAnim, {
|
|
108
|
-
duration: ANIMATION_DURATION,
|
|
109
|
-
toValue: BACKDROP_OPACITY,
|
|
110
|
-
useNativeDriver: true,
|
|
111
|
-
}),
|
|
112
|
-
]).start();
|
|
113
|
-
} else {
|
|
114
|
-
Animated.parallel([
|
|
115
|
-
Animated.timing(slideAnim, {
|
|
116
|
-
duration: ANIMATION_DURATION,
|
|
117
|
-
toValue: -DRAWER_WIDTH,
|
|
118
|
-
useNativeDriver: true,
|
|
119
|
-
}),
|
|
120
|
-
Animated.timing(backdropAnim, {
|
|
121
|
-
duration: ANIMATION_DURATION,
|
|
122
|
-
toValue: 0,
|
|
123
|
-
useNativeDriver: true,
|
|
124
|
-
}),
|
|
125
|
-
]).start();
|
|
171
|
+
if (!isOpen) {
|
|
172
|
+
return;
|
|
126
173
|
}
|
|
127
|
-
|
|
174
|
+
slideAnim.setValue(sheetHeight);
|
|
175
|
+
backdropAnim.setValue(0);
|
|
176
|
+
Animated.parallel([
|
|
177
|
+
Animated.timing(slideAnim, {
|
|
178
|
+
duration: ANIMATION_DURATION,
|
|
179
|
+
toValue: 0,
|
|
180
|
+
useNativeDriver: true,
|
|
181
|
+
}),
|
|
182
|
+
Animated.timing(backdropAnim, {
|
|
183
|
+
duration: ANIMATION_DURATION,
|
|
184
|
+
toValue: BACKDROP_OPACITY,
|
|
185
|
+
useNativeDriver: true,
|
|
186
|
+
}),
|
|
187
|
+
]).start();
|
|
188
|
+
}, [isOpen, slideAnim, backdropAnim, sheetHeight]);
|
|
128
189
|
|
|
129
|
-
|
|
130
|
-
const handleClose = useCallback(() =>
|
|
190
|
+
// Play close animation then update state
|
|
191
|
+
const handleClose = useCallback(() => {
|
|
192
|
+
Animated.parallel([
|
|
193
|
+
Animated.timing(slideAnim, {
|
|
194
|
+
duration: ANIMATION_DURATION,
|
|
195
|
+
toValue: sheetHeight,
|
|
196
|
+
useNativeDriver: true,
|
|
197
|
+
}),
|
|
198
|
+
Animated.timing(backdropAnim, {
|
|
199
|
+
duration: ANIMATION_DURATION,
|
|
200
|
+
toValue: 0,
|
|
201
|
+
useNativeDriver: true,
|
|
202
|
+
}),
|
|
203
|
+
]).start(() => {
|
|
204
|
+
if (isControlled) {
|
|
205
|
+
onOpenChange?.(false);
|
|
206
|
+
} else {
|
|
207
|
+
setIsOpenInternal(false);
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
}, [isControlled, onOpenChange, slideAnim, backdropAnim, sheetHeight]);
|
|
211
|
+
|
|
212
|
+
const handleOpen = useCallback(() => {
|
|
213
|
+
if (isControlled) {
|
|
214
|
+
onOpenChange?.(true);
|
|
215
|
+
} else {
|
|
216
|
+
setIsOpenInternal(true);
|
|
217
|
+
}
|
|
218
|
+
}, [isControlled, onOpenChange]);
|
|
131
219
|
|
|
132
220
|
const handleNavigate = useCallback(
|
|
133
221
|
(route: string) => {
|
|
134
|
-
|
|
222
|
+
handleClose();
|
|
135
223
|
onNavigate(route);
|
|
136
224
|
},
|
|
137
|
-
[onNavigate]
|
|
225
|
+
[handleClose, onNavigate]
|
|
138
226
|
);
|
|
139
227
|
|
|
140
|
-
const
|
|
228
|
+
const panResponder = useMemo(
|
|
229
|
+
() =>
|
|
230
|
+
PanResponder.create({
|
|
231
|
+
onMoveShouldSetPanResponder: (_, {dx, dy}) => Math.abs(dy) > Math.abs(dx) && dy > 4,
|
|
232
|
+
onPanResponderGrant: () => {
|
|
233
|
+
slideAnim.stopAnimation((value) => {
|
|
234
|
+
capturedSlideValue.current = value;
|
|
235
|
+
});
|
|
236
|
+
backdropAnim.stopAnimation();
|
|
237
|
+
},
|
|
238
|
+
onPanResponderMove: (_, {dy}) => {
|
|
239
|
+
const next = capturedSlideValue.current + dy;
|
|
240
|
+
if (next < 0) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
slideAnim.setValue(next);
|
|
244
|
+
backdropAnim.setValue(BACKDROP_OPACITY * Math.max(0, 1 - next / sheetHeight));
|
|
245
|
+
},
|
|
246
|
+
onPanResponderRelease: (_, {dy, vy}) => {
|
|
247
|
+
if (dy > sheetHeight * DISMISS_THRESHOLD || vy > 0.5) {
|
|
248
|
+
handleClose();
|
|
249
|
+
} else {
|
|
250
|
+
Animated.parallel([
|
|
251
|
+
Animated.timing(slideAnim, {
|
|
252
|
+
duration: 200,
|
|
253
|
+
toValue: 0,
|
|
254
|
+
useNativeDriver: true,
|
|
255
|
+
}),
|
|
256
|
+
Animated.timing(backdropAnim, {
|
|
257
|
+
duration: 200,
|
|
258
|
+
toValue: BACKDROP_OPACITY,
|
|
259
|
+
useNativeDriver: true,
|
|
260
|
+
}),
|
|
261
|
+
]).start();
|
|
262
|
+
}
|
|
263
|
+
},
|
|
264
|
+
}),
|
|
265
|
+
[slideAnim, backdropAnim, sheetHeight, handleClose]
|
|
266
|
+
);
|
|
141
267
|
|
|
142
268
|
return (
|
|
143
269
|
<View style={{flex: 1}}>
|
|
144
270
|
{children}
|
|
145
271
|
|
|
146
|
-
{/*
|
|
147
|
-
|
|
148
|
-
accessibilityLabel="Open navigation menu"
|
|
149
|
-
accessibilityRole="button"
|
|
150
|
-
onPress={handleOpen}
|
|
151
|
-
style={{
|
|
152
|
-
alignItems: "center",
|
|
153
|
-
backgroundColor: theme.surface.primary,
|
|
154
|
-
borderRadius: theme.radius.full,
|
|
155
|
-
elevation: 4,
|
|
156
|
-
height: 44,
|
|
157
|
-
justifyContent: "center",
|
|
158
|
-
left: 16,
|
|
159
|
-
position: "absolute",
|
|
160
|
-
shadowColor: "#000",
|
|
161
|
-
shadowOffset: {height: 2, width: 0},
|
|
162
|
-
shadowOpacity: 0.25,
|
|
163
|
-
shadowRadius: 4,
|
|
164
|
-
top: 16,
|
|
165
|
-
width: 44,
|
|
166
|
-
zIndex: 10,
|
|
167
|
-
}}
|
|
168
|
-
>
|
|
169
|
-
<Icon color="inverted" iconName="bars" size="md" />
|
|
170
|
-
</Pressable>
|
|
171
|
-
|
|
172
|
-
{/* Backdrop */}
|
|
173
|
-
{isOpen && (
|
|
272
|
+
{/* Floating hamburger — only shown in uncontrolled (standalone) mode */}
|
|
273
|
+
{!isControlled && (
|
|
174
274
|
<Pressable
|
|
175
|
-
|
|
275
|
+
accessibilityLabel="Open navigation menu"
|
|
276
|
+
accessibilityRole="button"
|
|
277
|
+
onPress={handleOpen}
|
|
176
278
|
style={{
|
|
177
|
-
|
|
178
|
-
|
|
279
|
+
alignItems: "center",
|
|
280
|
+
height: 44,
|
|
281
|
+
justifyContent: "center",
|
|
282
|
+
left: 16,
|
|
179
283
|
position: "absolute",
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
zIndex:
|
|
284
|
+
top: insets.top + 16,
|
|
285
|
+
width: 44,
|
|
286
|
+
zIndex: 10,
|
|
183
287
|
}}
|
|
184
288
|
>
|
|
185
|
-
<
|
|
186
|
-
style={{
|
|
187
|
-
backgroundColor: "#000",
|
|
188
|
-
flex: 1,
|
|
189
|
-
opacity: backdropAnim,
|
|
190
|
-
}}
|
|
191
|
-
/>
|
|
289
|
+
<Icon color="primary" iconName="bars" size="md" />
|
|
192
290
|
</Pressable>
|
|
193
291
|
)}
|
|
194
292
|
|
|
195
|
-
{
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
{
|
|
199
|
-
backgroundColor: theme.surface.base,
|
|
200
|
-
borderColor: theme.border.default,
|
|
201
|
-
borderRightWidth: 1,
|
|
202
|
-
height: screenHeight,
|
|
203
|
-
justifyContent: "space-between",
|
|
204
|
-
left: 0,
|
|
205
|
-
paddingBottom: 32,
|
|
206
|
-
paddingTop: 20,
|
|
207
|
-
position: "absolute",
|
|
208
|
-
top: 0,
|
|
209
|
-
transform: [{translateX: slideAnim}],
|
|
210
|
-
width: DRAWER_WIDTH,
|
|
211
|
-
zIndex: 200,
|
|
212
|
-
},
|
|
213
|
-
panelStyle,
|
|
214
|
-
]}
|
|
215
|
-
>
|
|
216
|
-
{/* Close button */}
|
|
217
|
-
<View>
|
|
293
|
+
{isOpen && (
|
|
294
|
+
<>
|
|
295
|
+
{/* Backdrop */}
|
|
218
296
|
<Pressable
|
|
219
|
-
|
|
220
|
-
accessibilityRole="button"
|
|
297
|
+
accessibilityElementsHidden
|
|
221
298
|
onPress={handleClose}
|
|
299
|
+
style={{bottom: 0, left: 0, position: "absolute", right: 0, top: 0, zIndex: 100}}
|
|
300
|
+
>
|
|
301
|
+
<Animated.View style={{backgroundColor: "#000", flex: 1, opacity: backdropAnim}} />
|
|
302
|
+
</Pressable>
|
|
303
|
+
|
|
304
|
+
{/* Bottom sheet */}
|
|
305
|
+
<Animated.View
|
|
306
|
+
style={[
|
|
307
|
+
{
|
|
308
|
+
backgroundColor: theme.surface.base,
|
|
309
|
+
borderTopLeftRadius: 16,
|
|
310
|
+
borderTopRightRadius: 16,
|
|
311
|
+
bottom: 0,
|
|
312
|
+
height: sheetHeight,
|
|
313
|
+
left: 0,
|
|
314
|
+
position: "absolute",
|
|
315
|
+
right: 0,
|
|
316
|
+
transform: [{translateY: slideAnim}],
|
|
317
|
+
zIndex: 200,
|
|
318
|
+
},
|
|
319
|
+
panelStyle,
|
|
320
|
+
]}
|
|
321
|
+
>
|
|
322
|
+
{/* Drag bar */}
|
|
323
|
+
<View
|
|
324
|
+
{...panResponder.panHandlers}
|
|
325
|
+
accessibilityHint="Drag down to close"
|
|
326
|
+
accessibilityLabel="Navigation menu drag handle"
|
|
327
|
+
accessibilityRole="adjustable"
|
|
328
|
+
style={{alignItems: "center", paddingBottom: 8, paddingTop: 12}}
|
|
329
|
+
>
|
|
330
|
+
<View
|
|
331
|
+
style={{
|
|
332
|
+
backgroundColor: theme.border.default,
|
|
333
|
+
borderRadius: 2,
|
|
334
|
+
height: 4,
|
|
335
|
+
width: 36,
|
|
336
|
+
}}
|
|
337
|
+
/>
|
|
338
|
+
</View>
|
|
339
|
+
|
|
340
|
+
{/* Nav items */}
|
|
341
|
+
<View style={{gap: 4, paddingBottom: insets.bottom + 8}}>
|
|
342
|
+
{[...topItems, ...bottomItems].map((item) => (
|
|
343
|
+
<SidebarItem
|
|
344
|
+
isActive={activeRoute === item.route}
|
|
345
|
+
item={item}
|
|
346
|
+
itemStyle={itemStyle}
|
|
347
|
+
key={item.label}
|
|
348
|
+
onPress={handleNavigate}
|
|
349
|
+
/>
|
|
350
|
+
))}
|
|
351
|
+
</View>
|
|
352
|
+
</Animated.View>
|
|
353
|
+
</>
|
|
354
|
+
)}
|
|
355
|
+
</View>
|
|
356
|
+
);
|
|
357
|
+
};
|
|
358
|
+
|
|
359
|
+
const SidebarHeader: FC<{onOpen: () => void}> = ({onOpen}) => {
|
|
360
|
+
const {theme} = useTheme();
|
|
361
|
+
const insets = useSafeAreaInsets();
|
|
362
|
+
const {state, descriptors} = Navigator.useContext();
|
|
363
|
+
const activeRoute = state.routes[state.index];
|
|
364
|
+
const {headerLeft, headerRight, title} = (descriptors[activeRoute?.key]?.options ?? {}) as any;
|
|
365
|
+
|
|
366
|
+
return (
|
|
367
|
+
<View
|
|
368
|
+
style={{
|
|
369
|
+
backgroundColor: theme.surface.base,
|
|
370
|
+
borderBottomColor: theme.border.default,
|
|
371
|
+
borderBottomWidth: 1,
|
|
372
|
+
paddingTop: insets.top,
|
|
373
|
+
}}
|
|
374
|
+
>
|
|
375
|
+
<View
|
|
376
|
+
style={{
|
|
377
|
+
alignItems: "center",
|
|
378
|
+
flexDirection: "row",
|
|
379
|
+
height: 44,
|
|
380
|
+
justifyContent: "space-between",
|
|
381
|
+
paddingHorizontal: 16,
|
|
382
|
+
}}
|
|
383
|
+
>
|
|
384
|
+
<View style={{alignItems: "center", flexDirection: "row", gap: 12}}>
|
|
385
|
+
<SidebarHamburger onOpen={onOpen} />
|
|
386
|
+
{headerLeft?.({})}
|
|
387
|
+
</View>
|
|
388
|
+
{Boolean(title) && (
|
|
389
|
+
<View
|
|
390
|
+
pointerEvents="none"
|
|
222
391
|
style={{
|
|
223
392
|
alignItems: "center",
|
|
224
|
-
|
|
225
|
-
height: 40,
|
|
393
|
+
bottom: 0,
|
|
226
394
|
justifyContent: "center",
|
|
227
|
-
|
|
228
|
-
|
|
395
|
+
left: 0,
|
|
396
|
+
position: "absolute",
|
|
397
|
+
right: 0,
|
|
398
|
+
top: 0,
|
|
229
399
|
}}
|
|
230
400
|
>
|
|
231
|
-
<
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
{topItems.map((item) => (
|
|
235
|
-
<SidebarItem
|
|
236
|
-
isActive={activeRoute === item.route}
|
|
237
|
-
item={item}
|
|
238
|
-
itemStyle={itemStyle}
|
|
239
|
-
key={item.route}
|
|
240
|
-
onPress={handleNavigate}
|
|
241
|
-
/>
|
|
242
|
-
))}
|
|
401
|
+
<Text bold size="lg">
|
|
402
|
+
{title}
|
|
403
|
+
</Text>
|
|
243
404
|
</View>
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
{bottomItems.map((item) => (
|
|
248
|
-
<SidebarItem
|
|
249
|
-
isActive={activeRoute === item.route}
|
|
250
|
-
item={item}
|
|
251
|
-
key={item.route}
|
|
252
|
-
onPress={handleNavigate}
|
|
253
|
-
/>
|
|
254
|
-
))}
|
|
255
|
-
</View>
|
|
256
|
-
</Animated.View>
|
|
405
|
+
)}
|
|
406
|
+
{Boolean(headerRight) && <View style={{alignItems: "flex-end"}}>{headerRight?.({})}</View>}
|
|
407
|
+
</View>
|
|
257
408
|
</View>
|
|
258
409
|
);
|
|
259
410
|
};
|
|
260
411
|
|
|
261
|
-
/**
|
|
262
|
-
* Reads active route from Navigator context and renders the drawer + Slot.
|
|
263
|
-
*/
|
|
412
|
+
/** Renders the content panel and bottom sheet for the active screen. */
|
|
264
413
|
const SidebarNavigatorContent: FC<{
|
|
265
414
|
topItems: SidebarNavigationItem[];
|
|
266
415
|
bottomItems: SidebarNavigationItem[];
|
|
416
|
+
isOpen: boolean;
|
|
417
|
+
onOpenChange: (isOpen: boolean) => void;
|
|
267
418
|
onNavigate?: (route: string) => void;
|
|
268
419
|
panelStyle?: StyleProp<ViewStyle>;
|
|
269
420
|
itemStyle?: StyleProp<ViewStyle>;
|
|
270
|
-
}> = ({topItems, bottomItems, onNavigate, panelStyle, itemStyle}) => {
|
|
421
|
+
}> = ({topItems, bottomItems, isOpen, onOpenChange, onNavigate, panelStyle, itemStyle}) => {
|
|
271
422
|
const {state, navigation} = Navigator.useContext();
|
|
272
|
-
const activeRoute = state.routes[state.index]
|
|
423
|
+
const activeRoute = state.routes[state.index];
|
|
273
424
|
|
|
274
425
|
const handleNavigate = useCallback(
|
|
275
426
|
(route: string) => {
|
|
@@ -281,10 +432,12 @@ const SidebarNavigatorContent: FC<{
|
|
|
281
432
|
|
|
282
433
|
return (
|
|
283
434
|
<SidebarNavigationPanel
|
|
284
|
-
activeRoute={activeRoute}
|
|
435
|
+
activeRoute={activeRoute?.name}
|
|
285
436
|
bottomItems={bottomItems}
|
|
437
|
+
isOpen={isOpen}
|
|
286
438
|
itemStyle={itemStyle}
|
|
287
439
|
onNavigate={handleNavigate}
|
|
440
|
+
onOpenChange={onOpenChange}
|
|
288
441
|
panelStyle={panelStyle}
|
|
289
442
|
topItems={topItems}
|
|
290
443
|
>
|
|
@@ -294,7 +447,7 @@ const SidebarNavigatorContent: FC<{
|
|
|
294
447
|
};
|
|
295
448
|
|
|
296
449
|
/**
|
|
297
|
-
* Custom expo-router navigator with a hamburger-triggered
|
|
450
|
+
* Custom expo-router navigator with a header bar and hamburger-triggered bottom sheet.
|
|
298
451
|
* Use in _layout.tsx files:
|
|
299
452
|
*
|
|
300
453
|
* ```tsx
|
|
@@ -308,7 +461,7 @@ const SidebarNavigatorContent: FC<{
|
|
|
308
461
|
* }
|
|
309
462
|
* ```
|
|
310
463
|
*/
|
|
311
|
-
|
|
464
|
+
const SidebarNavigationBase: FC<SidebarNavigationProps> = ({
|
|
312
465
|
topItems,
|
|
313
466
|
bottomItems,
|
|
314
467
|
onNavigate,
|
|
@@ -316,16 +469,27 @@ export const SidebarNavigation: FC<SidebarNavigationProps> = ({
|
|
|
316
469
|
screenOptions,
|
|
317
470
|
panelStyle,
|
|
318
471
|
itemStyle,
|
|
472
|
+
children,
|
|
319
473
|
}) => {
|
|
474
|
+
const [isSheetOpen, setIsSheetOpen] = useState(false);
|
|
475
|
+
|
|
320
476
|
return (
|
|
321
477
|
<Navigator initialRouteName={initialRouteName} router={TabRouter} screenOptions={screenOptions}>
|
|
322
|
-
<
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
478
|
+
<View style={{flex: 1}}>
|
|
479
|
+
<SidebarHeader onOpen={() => setIsSheetOpen(true)} />
|
|
480
|
+
<SidebarNavigatorContent
|
|
481
|
+
bottomItems={bottomItems}
|
|
482
|
+
isOpen={isSheetOpen}
|
|
483
|
+
itemStyle={itemStyle}
|
|
484
|
+
onNavigate={onNavigate}
|
|
485
|
+
onOpenChange={setIsSheetOpen}
|
|
486
|
+
panelStyle={panelStyle}
|
|
487
|
+
topItems={topItems}
|
|
488
|
+
/>
|
|
489
|
+
</View>
|
|
490
|
+
{children}
|
|
329
491
|
</Navigator>
|
|
330
492
|
);
|
|
331
493
|
};
|
|
494
|
+
|
|
495
|
+
export const SidebarNavigation = Object.assign(SidebarNavigationBase, {Screen});
|