@sigmela/router 0.3.6 → 0.4.0
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/CHANGELOG.md +23 -0
- package/LICENSE +2 -1
- package/README.md +108 -479
- package/dist/Router.d.ts +190 -0
- package/dist/Router.d.ts.map +1 -0
- package/dist/components/Modal.d.ts +56 -0
- package/dist/components/Modal.d.ts.map +1 -0
- package/dist/components/OverlayContentScope.d.ts +8 -0
- package/dist/components/OverlayContentScope.d.ts.map +1 -0
- package/dist/components/RouterCloseButton.d.ts +9 -0
- package/dist/components/RouterCloseButton.d.ts.map +1 -0
- package/dist/components/Sheet.d.ts +53 -0
- package/dist/components/Sheet.d.ts.map +1 -0
- package/dist/components/SheetSurface.d.ts +27 -0
- package/dist/components/SheetSurface.d.ts.map +1 -0
- package/dist/components/index.d.ts +4 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/pageScrollLock.d.ts +3 -0
- package/dist/components/pageScrollLock.d.ts.map +1 -0
- package/dist/components/sheetDragEngine.d.ts +27 -0
- package/dist/components/sheetDragEngine.d.ts.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3649 -0
- package/dist/index.js.map +1 -0
- package/dist/navigationHistory.d.ts +17 -0
- package/dist/navigationHistory.d.ts.map +1 -0
- package/dist/router.css +971 -0
- package/dist/types.d.ts +3 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/utils/id.d.ts +2 -0
- package/dist/utils/id.d.ts.map +1 -0
- package/package.json +69 -174
- package/lib/module/Drawer/Drawer.js +0 -250
- package/lib/module/Drawer/DrawerContext.js +0 -4
- package/lib/module/Drawer/DrawerIcon.web.js +0 -47
- package/lib/module/Drawer/RenderDrawer.native.js +0 -248
- package/lib/module/Drawer/RenderDrawer.web.js +0 -197
- package/lib/module/Drawer/useDrawer.js +0 -11
- package/lib/module/Navigation.js +0 -79
- package/lib/module/NavigationStack.js +0 -254
- package/lib/module/Router.js +0 -2171
- package/lib/module/RouterContext.js +0 -33
- package/lib/module/ScreenStack/ScreenStack.native.js +0 -3
- package/lib/module/ScreenStack/ScreenStack.web.js +0 -561
- package/lib/module/ScreenStack/ScreenStackContext.js +0 -21
- package/lib/module/ScreenStack/animationHelpers.js +0 -87
- package/lib/module/ScreenStack/index.js +0 -3
- package/lib/module/ScreenStackItem/ScreenStackItem.js +0 -70
- package/lib/module/ScreenStackItem/ScreenStackItem.types.js +0 -3
- package/lib/module/ScreenStackItem/ScreenStackItem.web.js +0 -171
- package/lib/module/ScreenStackItem/index.js +0 -3
- package/lib/module/ScreenStackSheetItem/ScreenStackSheetItem.native.js +0 -70
- package/lib/module/ScreenStackSheetItem/ScreenStackSheetItem.web.js +0 -5
- package/lib/module/ScreenStackSheetItem/index.js +0 -3
- package/lib/module/SplitView/RenderSplitView.native.js +0 -101
- package/lib/module/SplitView/RenderSplitView.web.js +0 -107
- package/lib/module/SplitView/SplitView.js +0 -97
- package/lib/module/SplitView/SplitViewContext.js +0 -4
- package/lib/module/SplitView/index.js +0 -5
- package/lib/module/SplitView/useSplitView.js +0 -11
- package/lib/module/StackRenderer.js +0 -42
- package/lib/module/TabBar/RenderTabBar.native.js +0 -418
- package/lib/module/TabBar/RenderTabBar.web.js +0 -218
- package/lib/module/TabBar/TabBar.js +0 -208
- package/lib/module/TabBar/TabBarContext.js +0 -4
- package/lib/module/TabBar/TabIcon.web.js +0 -47
- package/lib/module/TabBar/index.js +0 -6
- package/lib/module/TabBar/useTabBar.js +0 -11
- package/lib/module/TabBar/useTabBarHeight.js +0 -22
- package/lib/module/createController.js +0 -5
- package/lib/module/index.js +0 -15
- package/lib/module/navigationNode.js +0 -3
- package/lib/module/package.json +0 -1
- package/lib/module/styles.css +0 -1111
- package/lib/module/types.js +0 -13
- package/lib/typescript/package.json +0 -1
- package/lib/typescript/src/Drawer/Drawer.d.ts +0 -100
- package/lib/typescript/src/Drawer/DrawerContext.d.ts +0 -3
- package/lib/typescript/src/Drawer/DrawerIcon.web.d.ts +0 -7
- package/lib/typescript/src/Drawer/RenderDrawer.native.d.ts +0 -8
- package/lib/typescript/src/Drawer/RenderDrawer.web.d.ts +0 -8
- package/lib/typescript/src/Drawer/useDrawer.d.ts +0 -2
- package/lib/typescript/src/Navigation.d.ts +0 -17
- package/lib/typescript/src/NavigationStack.d.ts +0 -46
- package/lib/typescript/src/Router.d.ts +0 -232
- package/lib/typescript/src/RouterContext.d.ts +0 -18
- package/lib/typescript/src/ScreenStack/ScreenStack.native.d.ts +0 -2
- package/lib/typescript/src/ScreenStack/ScreenStack.web.d.ts +0 -9
- package/lib/typescript/src/ScreenStack/ScreenStackContext.d.ts +0 -31
- package/lib/typescript/src/ScreenStack/animationHelpers.d.ts +0 -6
- package/lib/typescript/src/ScreenStack/index.d.ts +0 -2
- package/lib/typescript/src/ScreenStackItem/ScreenStackItem.d.ts +0 -3
- package/lib/typescript/src/ScreenStackItem/ScreenStackItem.types.d.ts +0 -14
- package/lib/typescript/src/ScreenStackItem/ScreenStackItem.web.d.ts +0 -3
- package/lib/typescript/src/ScreenStackItem/index.d.ts +0 -3
- package/lib/typescript/src/ScreenStackSheetItem/ScreenStackSheetItem.native.d.ts +0 -11
- package/lib/typescript/src/ScreenStackSheetItem/ScreenStackSheetItem.web.d.ts +0 -2
- package/lib/typescript/src/ScreenStackSheetItem/index.d.ts +0 -2
- package/lib/typescript/src/SplitView/RenderSplitView.native.d.ts +0 -19
- package/lib/typescript/src/SplitView/RenderSplitView.web.d.ts +0 -8
- package/lib/typescript/src/SplitView/SplitView.d.ts +0 -33
- package/lib/typescript/src/SplitView/SplitViewContext.d.ts +0 -3
- package/lib/typescript/src/SplitView/index.d.ts +0 -5
- package/lib/typescript/src/SplitView/useSplitView.d.ts +0 -2
- package/lib/typescript/src/StackRenderer.d.ts +0 -8
- package/lib/typescript/src/TabBar/RenderTabBar.native.d.ts +0 -8
- package/lib/typescript/src/TabBar/RenderTabBar.web.d.ts +0 -8
- package/lib/typescript/src/TabBar/TabBar.d.ts +0 -112
- package/lib/typescript/src/TabBar/TabBarContext.d.ts +0 -3
- package/lib/typescript/src/TabBar/TabIcon.web.d.ts +0 -7
- package/lib/typescript/src/TabBar/index.d.ts +0 -5
- package/lib/typescript/src/TabBar/useTabBar.d.ts +0 -2
- package/lib/typescript/src/TabBar/useTabBarHeight.d.ts +0 -18
- package/lib/typescript/src/createController.d.ts +0 -15
- package/lib/typescript/src/index.d.ts +0 -21
- package/lib/typescript/src/navigationNode.d.ts +0 -41
- package/lib/typescript/src/types.d.ts +0 -140
|
@@ -1,248 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
import { StackRenderer } from "../StackRenderer.js";
|
|
4
|
-
import { DrawerContext } from "./DrawerContext.js";
|
|
5
|
-
import { useRouter } from "../RouterContext.js";
|
|
6
|
-
import { Pressable, StyleSheet, View, Text } from 'react-native';
|
|
7
|
-
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
8
|
-
import { useCallback, useSyncExternalStore, memo, useEffect, useState, useMemo, startTransition } from 'react';
|
|
9
|
-
const EMPTY_HISTORY = [];
|
|
10
|
-
import Animated, { useSharedValue, useAnimatedStyle, withTiming, Easing } from 'react-native-reanimated';
|
|
11
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
12
|
-
const TIMING_CONFIG = {
|
|
13
|
-
duration: 300,
|
|
14
|
-
easing: Easing.bezier(0.22, 0.61, 0.36, 1)
|
|
15
|
-
};
|
|
16
|
-
const DrawerStackRenderer = /*#__PURE__*/memo(({
|
|
17
|
-
stack,
|
|
18
|
-
appearance
|
|
19
|
-
}) => {
|
|
20
|
-
const router = useRouter();
|
|
21
|
-
const stackId = stack.getId();
|
|
22
|
-
|
|
23
|
-
// Start with empty history — useEffect populates via startTransition.
|
|
24
|
-
const [history, setHistory] = useState(EMPTY_HISTORY);
|
|
25
|
-
useEffect(() => {
|
|
26
|
-
const update = () => {
|
|
27
|
-
startTransition(() => {
|
|
28
|
-
setHistory(router.getStackHistory(stackId));
|
|
29
|
-
});
|
|
30
|
-
};
|
|
31
|
-
const unsub = router.subscribeStack(stackId, update);
|
|
32
|
-
update();
|
|
33
|
-
return unsub;
|
|
34
|
-
}, [router, stackId]);
|
|
35
|
-
return /*#__PURE__*/_jsx(StackRenderer, {
|
|
36
|
-
appearance: appearance,
|
|
37
|
-
stackId: stackId,
|
|
38
|
-
history: history
|
|
39
|
-
});
|
|
40
|
-
});
|
|
41
|
-
DrawerStackRenderer.displayName = 'DrawerStackRenderer';
|
|
42
|
-
const DrawerNodeRenderer = /*#__PURE__*/memo(({
|
|
43
|
-
node,
|
|
44
|
-
appearance
|
|
45
|
-
}) => {
|
|
46
|
-
const Renderer = useMemo(() => node.getRenderer(), [node]);
|
|
47
|
-
return /*#__PURE__*/_jsx(Renderer, {
|
|
48
|
-
appearance: appearance
|
|
49
|
-
});
|
|
50
|
-
});
|
|
51
|
-
DrawerNodeRenderer.displayName = 'DrawerNodeRenderer';
|
|
52
|
-
export const RenderDrawer = /*#__PURE__*/memo(({
|
|
53
|
-
drawer,
|
|
54
|
-
appearance = {}
|
|
55
|
-
}) => {
|
|
56
|
-
const router = useRouter();
|
|
57
|
-
const insets = useSafeAreaInsets();
|
|
58
|
-
const drawerWidth = drawer.width;
|
|
59
|
-
const subscribe = useCallback(cb => drawer.subscribe(cb), [drawer]);
|
|
60
|
-
const snapshot = useSyncExternalStore(subscribe, drawer.getState, drawer.getState);
|
|
61
|
-
const {
|
|
62
|
-
tabs,
|
|
63
|
-
index,
|
|
64
|
-
config,
|
|
65
|
-
isOpen
|
|
66
|
-
} = snapshot;
|
|
67
|
-
|
|
68
|
-
// Reanimated shared value for drawer position
|
|
69
|
-
const translateX = useSharedValue(0);
|
|
70
|
-
const overlayOpacity = useSharedValue(0);
|
|
71
|
-
useEffect(() => {
|
|
72
|
-
translateX.value = withTiming(isOpen ? drawerWidth : 0, TIMING_CONFIG);
|
|
73
|
-
overlayOpacity.value = withTiming(isOpen ? 0.3 : 0, TIMING_CONFIG);
|
|
74
|
-
}, [isOpen, drawerWidth, translateX, overlayOpacity]);
|
|
75
|
-
const drawerStyle = useAnimatedStyle(() => ({
|
|
76
|
-
transform: [{
|
|
77
|
-
translateX: translateX.value - drawerWidth
|
|
78
|
-
}]
|
|
79
|
-
}));
|
|
80
|
-
const mainStyle = useAnimatedStyle(() => ({
|
|
81
|
-
transform: [{
|
|
82
|
-
translateX: translateX.value
|
|
83
|
-
}]
|
|
84
|
-
}));
|
|
85
|
-
const overlayStyle = useAnimatedStyle(() => ({
|
|
86
|
-
opacity: overlayOpacity.value,
|
|
87
|
-
pointerEvents: isOpen ? 'auto' : 'none'
|
|
88
|
-
}));
|
|
89
|
-
const onItemPress = useCallback(nextIndex => {
|
|
90
|
-
const targetTab = tabs[nextIndex];
|
|
91
|
-
if (!targetTab) return;
|
|
92
|
-
const targetStack = drawer.stacks[targetTab.tabKey];
|
|
93
|
-
const targetNode = drawer.nodes[targetTab.tabKey];
|
|
94
|
-
if (nextIndex !== index) {
|
|
95
|
-
drawer.onIndexChange(nextIndex);
|
|
96
|
-
}
|
|
97
|
-
if (targetStack) {
|
|
98
|
-
const stackId = targetStack.getId();
|
|
99
|
-
const stackHistory = router.getStackHistory(stackId);
|
|
100
|
-
if (stackHistory.length === 0) {
|
|
101
|
-
const firstRoute = targetStack.getFirstRoute();
|
|
102
|
-
if (firstRoute?.path) {
|
|
103
|
-
router.navigate(firstRoute.path);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
} else if (targetNode) {
|
|
107
|
-
const nodeId = targetNode.getId?.();
|
|
108
|
-
if (nodeId) {
|
|
109
|
-
const nodeHistory = router.getStackHistory(nodeId);
|
|
110
|
-
if (nodeHistory.length === 0) {
|
|
111
|
-
const seed = targetNode.seed?.();
|
|
112
|
-
if (seed?.path) {
|
|
113
|
-
const prefix = targetTab.tabPrefix ?? '';
|
|
114
|
-
const fullPath = prefix && !seed.path.startsWith(prefix) ? `${prefix}${seed.path.startsWith('/') ? '' : '/'}${seed.path}` : seed.path;
|
|
115
|
-
router.navigate(fullPath);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
drawer.close();
|
|
121
|
-
}, [tabs, drawer, index, router]);
|
|
122
|
-
const handleOverlayPress = useCallback(() => {
|
|
123
|
-
drawer.close();
|
|
124
|
-
}, [drawer]);
|
|
125
|
-
const [visited, setVisited] = useState({});
|
|
126
|
-
useEffect(() => {
|
|
127
|
-
const key = tabs[index]?.tabKey;
|
|
128
|
-
if (key) {
|
|
129
|
-
startTransition(() => {
|
|
130
|
-
setVisited(prev => prev[key] ? prev : {
|
|
131
|
-
...prev,
|
|
132
|
-
[key]: true
|
|
133
|
-
});
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
}, [tabs, index]);
|
|
137
|
-
const CustomDrawer = config.component;
|
|
138
|
-
return /*#__PURE__*/_jsx(DrawerContext.Provider, {
|
|
139
|
-
value: drawer,
|
|
140
|
-
children: /*#__PURE__*/_jsxs(View, {
|
|
141
|
-
style: styles.container,
|
|
142
|
-
children: [/*#__PURE__*/_jsx(Animated.View, {
|
|
143
|
-
style: [styles.sidebar, {
|
|
144
|
-
width: drawerWidth
|
|
145
|
-
}, drawerStyle],
|
|
146
|
-
children: CustomDrawer ? /*#__PURE__*/_jsx(CustomDrawer, {
|
|
147
|
-
onItemPress: onItemPress,
|
|
148
|
-
activeIndex: index,
|
|
149
|
-
items: tabs,
|
|
150
|
-
isOpen: isOpen,
|
|
151
|
-
onClose: handleOverlayPress
|
|
152
|
-
}) : /*#__PURE__*/_jsx(View, {
|
|
153
|
-
style: [styles.sidebarContent, {
|
|
154
|
-
paddingTop: insets.top + 12
|
|
155
|
-
}],
|
|
156
|
-
children: tabs.map((tab, i) => {
|
|
157
|
-
const isActive = i === index;
|
|
158
|
-
return /*#__PURE__*/_jsx(Pressable, {
|
|
159
|
-
onPress: () => onItemPress(i),
|
|
160
|
-
style: [styles.item, isActive && styles.itemActive],
|
|
161
|
-
children: /*#__PURE__*/_jsx(Text, {
|
|
162
|
-
style: [styles.itemText, isActive && styles.itemTextActive],
|
|
163
|
-
children: tab.title
|
|
164
|
-
})
|
|
165
|
-
}, tab.tabKey);
|
|
166
|
-
})
|
|
167
|
-
})
|
|
168
|
-
}), /*#__PURE__*/_jsx(Animated.View, {
|
|
169
|
-
style: [styles.overlay, overlayStyle],
|
|
170
|
-
children: /*#__PURE__*/_jsx(Pressable, {
|
|
171
|
-
style: StyleSheet.absoluteFill,
|
|
172
|
-
onPress: handleOverlayPress
|
|
173
|
-
})
|
|
174
|
-
}), /*#__PURE__*/_jsx(Animated.View, {
|
|
175
|
-
style: [styles.main, mainStyle],
|
|
176
|
-
children: tabs.filter(t => visited[t.tabKey]).map(tab => {
|
|
177
|
-
const isActive = tab.tabKey === tabs[index]?.tabKey;
|
|
178
|
-
const stackForTab = drawer.stacks[tab.tabKey];
|
|
179
|
-
const nodeForTab = drawer.nodes[tab.tabKey];
|
|
180
|
-
const ScreenForTab = drawer.screens[tab.tabKey];
|
|
181
|
-
return /*#__PURE__*/_jsx(View, {
|
|
182
|
-
style: [styles.flex, !isActive && styles.hidden],
|
|
183
|
-
children: stackForTab ? /*#__PURE__*/_jsx(DrawerStackRenderer, {
|
|
184
|
-
appearance: appearance,
|
|
185
|
-
stack: stackForTab
|
|
186
|
-
}) : nodeForTab ? /*#__PURE__*/_jsx(DrawerNodeRenderer, {
|
|
187
|
-
appearance: appearance,
|
|
188
|
-
node: nodeForTab
|
|
189
|
-
}) : ScreenForTab ? /*#__PURE__*/_jsx(ScreenForTab, {}) : null
|
|
190
|
-
}, `drawer-content-${tab.tabKey}`);
|
|
191
|
-
})
|
|
192
|
-
})]
|
|
193
|
-
})
|
|
194
|
-
});
|
|
195
|
-
});
|
|
196
|
-
const styles = StyleSheet.create({
|
|
197
|
-
container: {
|
|
198
|
-
flex: 1,
|
|
199
|
-
flexDirection: 'row',
|
|
200
|
-
overflow: 'hidden'
|
|
201
|
-
},
|
|
202
|
-
sidebar: {
|
|
203
|
-
position: 'absolute',
|
|
204
|
-
top: 0,
|
|
205
|
-
bottom: 0,
|
|
206
|
-
left: 0,
|
|
207
|
-
zIndex: 10,
|
|
208
|
-
backgroundColor: '#ffffff'
|
|
209
|
-
},
|
|
210
|
-
sidebarContent: {
|
|
211
|
-
flex: 1
|
|
212
|
-
},
|
|
213
|
-
main: {
|
|
214
|
-
flex: 1,
|
|
215
|
-
width: '100%'
|
|
216
|
-
},
|
|
217
|
-
overlay: {
|
|
218
|
-
...StyleSheet.absoluteFillObject,
|
|
219
|
-
zIndex: 5,
|
|
220
|
-
backgroundColor: '#000000'
|
|
221
|
-
},
|
|
222
|
-
item: {
|
|
223
|
-
height: 44,
|
|
224
|
-
flexDirection: 'row',
|
|
225
|
-
alignItems: 'center',
|
|
226
|
-
paddingHorizontal: 12,
|
|
227
|
-
marginHorizontal: 12,
|
|
228
|
-
marginBottom: 4,
|
|
229
|
-
borderRadius: 10
|
|
230
|
-
},
|
|
231
|
-
itemActive: {
|
|
232
|
-
backgroundColor: 'rgba(201, 204, 209, 0.32)'
|
|
233
|
-
},
|
|
234
|
-
itemText: {
|
|
235
|
-
flex: 1,
|
|
236
|
-
fontSize: 14,
|
|
237
|
-
fontWeight: '600'
|
|
238
|
-
},
|
|
239
|
-
itemTextActive: {
|
|
240
|
-
fontWeight: '700'
|
|
241
|
-
},
|
|
242
|
-
flex: {
|
|
243
|
-
flex: 1
|
|
244
|
-
},
|
|
245
|
-
hidden: {
|
|
246
|
-
display: 'none'
|
|
247
|
-
}
|
|
248
|
-
});
|
|
@@ -1,197 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
import { StackRenderer } from "../StackRenderer.js";
|
|
4
|
-
import { DrawerContext } from "./DrawerContext.js";
|
|
5
|
-
import { useRouter } from "../RouterContext.js";
|
|
6
|
-
import { DrawerIcon } from './DrawerIcon';
|
|
7
|
-
import { useCallback, useSyncExternalStore, memo, useMemo } from 'react';
|
|
8
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
9
|
-
const isImageSource = value => {
|
|
10
|
-
if (value == null) return false;
|
|
11
|
-
const valueType = typeof value;
|
|
12
|
-
if (valueType === 'number') return true;
|
|
13
|
-
if (Array.isArray(value)) return value.length > 0;
|
|
14
|
-
if (valueType === 'object') {
|
|
15
|
-
const v = value;
|
|
16
|
-
if ('uri' in v || 'width' in v || 'height' in v) return true;
|
|
17
|
-
}
|
|
18
|
-
return false;
|
|
19
|
-
};
|
|
20
|
-
const toColorString = c => typeof c === 'string' ? c : undefined;
|
|
21
|
-
const DrawerStackRenderer = /*#__PURE__*/memo(({
|
|
22
|
-
stack,
|
|
23
|
-
appearance
|
|
24
|
-
}) => {
|
|
25
|
-
const router = useRouter();
|
|
26
|
-
const stackId = stack.getId();
|
|
27
|
-
const subscribe = useCallback(cb => router.subscribeStack(stackId, cb), [router, stackId]);
|
|
28
|
-
const get = useCallback(() => router.getStackHistory(stackId), [router, stackId]);
|
|
29
|
-
const history = useSyncExternalStore(subscribe, get, get);
|
|
30
|
-
return /*#__PURE__*/_jsx(StackRenderer, {
|
|
31
|
-
appearance: appearance,
|
|
32
|
-
stackId: stackId,
|
|
33
|
-
history: history
|
|
34
|
-
});
|
|
35
|
-
});
|
|
36
|
-
DrawerStackRenderer.displayName = 'DrawerStackRenderer';
|
|
37
|
-
const DrawerNodeRenderer = /*#__PURE__*/memo(({
|
|
38
|
-
node,
|
|
39
|
-
appearance
|
|
40
|
-
}) => {
|
|
41
|
-
const Renderer = useMemo(() => node.getRenderer(), [node]);
|
|
42
|
-
return /*#__PURE__*/_jsx(Renderer, {
|
|
43
|
-
appearance: appearance
|
|
44
|
-
});
|
|
45
|
-
});
|
|
46
|
-
DrawerNodeRenderer.displayName = 'DrawerNodeRenderer';
|
|
47
|
-
const joinPrefixAndPath = (prefix, path) => {
|
|
48
|
-
const base = (prefix ?? '').trim();
|
|
49
|
-
const child = (path || '/').trim();
|
|
50
|
-
if (!base) return child || '/';
|
|
51
|
-
const baseNorm = base === '/' ? '' : base.endsWith('/') ? base.slice(0, -1) : base;
|
|
52
|
-
if (!child || child === '/') {
|
|
53
|
-
return baseNorm || '/';
|
|
54
|
-
}
|
|
55
|
-
if (child.startsWith('/')) {
|
|
56
|
-
return `${baseNorm}${child}`;
|
|
57
|
-
}
|
|
58
|
-
return `${baseNorm}/${child}`;
|
|
59
|
-
};
|
|
60
|
-
export const RenderDrawer = /*#__PURE__*/memo(({
|
|
61
|
-
drawer,
|
|
62
|
-
appearance
|
|
63
|
-
}) => {
|
|
64
|
-
const router = useRouter();
|
|
65
|
-
const subscribe = useCallback(cb => drawer.subscribe(cb), [drawer]);
|
|
66
|
-
const snapshot = useSyncExternalStore(subscribe, drawer.getState, drawer.getState);
|
|
67
|
-
const {
|
|
68
|
-
tabs,
|
|
69
|
-
index,
|
|
70
|
-
config,
|
|
71
|
-
isOpen
|
|
72
|
-
} = snapshot;
|
|
73
|
-
const focusedTab = tabs[index];
|
|
74
|
-
const stack = focusedTab ? drawer.stacks[focusedTab.tabKey] : undefined;
|
|
75
|
-
const node = focusedTab ? drawer.nodes[focusedTab.tabKey] : undefined;
|
|
76
|
-
const Screen = focusedTab ? drawer.screens[focusedTab.tabKey] : undefined;
|
|
77
|
-
const onItemClick = useCallback(nextIndex => {
|
|
78
|
-
const targetTab = tabs[nextIndex];
|
|
79
|
-
if (!targetTab) return;
|
|
80
|
-
const targetStack = drawer.stacks[targetTab.tabKey];
|
|
81
|
-
const targetNode = drawer.nodes[targetTab.tabKey];
|
|
82
|
-
if (targetStack) {
|
|
83
|
-
if (nextIndex !== index) {
|
|
84
|
-
drawer.onIndexChange(nextIndex);
|
|
85
|
-
}
|
|
86
|
-
const firstRoutePath = targetStack.getFirstRoute()?.path;
|
|
87
|
-
if (firstRoutePath) {
|
|
88
|
-
router.reset(firstRoutePath);
|
|
89
|
-
}
|
|
90
|
-
} else if (targetNode) {
|
|
91
|
-
if (nextIndex !== index) {
|
|
92
|
-
drawer.onIndexChange(nextIndex);
|
|
93
|
-
}
|
|
94
|
-
const seedPath = targetNode.seed?.()?.path;
|
|
95
|
-
const fallbackFirstPath = targetNode.getNodeRoutes()?.[0]?.path;
|
|
96
|
-
const path = seedPath ?? fallbackFirstPath ?? '/';
|
|
97
|
-
const fullPath = joinPrefixAndPath(targetTab.tabPrefix, path);
|
|
98
|
-
router.reset(fullPath);
|
|
99
|
-
} else {
|
|
100
|
-
if (nextIndex !== index) {
|
|
101
|
-
drawer.onIndexChange(nextIndex);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// Close drawer on mobile after navigation
|
|
106
|
-
drawer.close();
|
|
107
|
-
}, [router, drawer, tabs, index]);
|
|
108
|
-
const handleItemClick = useCallback(e => {
|
|
109
|
-
const idx = Number(e.currentTarget.dataset.index);
|
|
110
|
-
onItemClick(idx);
|
|
111
|
-
}, [onItemClick]);
|
|
112
|
-
const handleOverlayClick = useCallback(() => {
|
|
113
|
-
drawer.close();
|
|
114
|
-
}, [drawer]);
|
|
115
|
-
const drawerStyle = useMemo(() => {
|
|
116
|
-
const bg = toColorString(appearance?.tabBar?.backgroundColor);
|
|
117
|
-
const style = {};
|
|
118
|
-
if (bg) {
|
|
119
|
-
style['--drawer-bg'] = bg;
|
|
120
|
-
}
|
|
121
|
-
if (drawer.width !== 280) {
|
|
122
|
-
style['--drawer-width'] = `${drawer.width}px`;
|
|
123
|
-
}
|
|
124
|
-
return Object.keys(style).length ? style : undefined;
|
|
125
|
-
}, [appearance?.tabBar?.backgroundColor, drawer.width]);
|
|
126
|
-
const titleBaseStyle = useMemo(() => ({
|
|
127
|
-
fontFamily: appearance?.tabBar?.title?.fontFamily,
|
|
128
|
-
fontSize: appearance?.tabBar?.title?.fontSize,
|
|
129
|
-
fontWeight: appearance?.tabBar?.title?.fontWeight,
|
|
130
|
-
fontStyle: appearance?.tabBar?.title?.fontStyle
|
|
131
|
-
}), [appearance?.tabBar?.title?.fontFamily, appearance?.tabBar?.title?.fontSize, appearance?.tabBar?.title?.fontWeight, appearance?.tabBar?.title?.fontStyle]);
|
|
132
|
-
const CustomDrawer = config.component;
|
|
133
|
-
return /*#__PURE__*/_jsx(DrawerContext.Provider, {
|
|
134
|
-
value: drawer,
|
|
135
|
-
children: /*#__PURE__*/_jsxs("div", {
|
|
136
|
-
className: "drawer-container",
|
|
137
|
-
"data-drawer-open": isOpen ? 'true' : 'false',
|
|
138
|
-
style: drawerStyle,
|
|
139
|
-
children: [CustomDrawer ? /*#__PURE__*/_jsx(CustomDrawer, {
|
|
140
|
-
onItemPress: onItemClick,
|
|
141
|
-
activeIndex: index,
|
|
142
|
-
items: tabs,
|
|
143
|
-
isOpen: isOpen,
|
|
144
|
-
onClose: handleOverlayClick
|
|
145
|
-
}) : /*#__PURE__*/_jsx("div", {
|
|
146
|
-
className: "drawer-sidebar",
|
|
147
|
-
children: /*#__PURE__*/_jsx("div", {
|
|
148
|
-
className: "drawer-sidebar-content",
|
|
149
|
-
children: tabs.map((tab, i) => {
|
|
150
|
-
const isActive = i === index;
|
|
151
|
-
const iconTint = toColorString(isActive ? appearance?.tabBar?.iconColorActive : appearance?.tabBar?.iconColor);
|
|
152
|
-
const title = appearance?.tabBar?.title;
|
|
153
|
-
const labelColor = isActive ? toColorString(title?.activeColor) ?? toColorString(title?.color) : toColorString(title?.color);
|
|
154
|
-
const labelStyle = {
|
|
155
|
-
...titleBaseStyle,
|
|
156
|
-
color: labelColor
|
|
157
|
-
};
|
|
158
|
-
return /*#__PURE__*/_jsxs("button", {
|
|
159
|
-
type: "button",
|
|
160
|
-
"data-index": i,
|
|
161
|
-
"data-active": isActive ? 'true' : 'false',
|
|
162
|
-
"aria-current": isActive ? 'page' : undefined,
|
|
163
|
-
className: `drawer-item${isActive ? ' active' : ''}`,
|
|
164
|
-
onClick: handleItemClick,
|
|
165
|
-
children: [/*#__PURE__*/_jsx("div", {
|
|
166
|
-
className: "drawer-item-icon",
|
|
167
|
-
children: isImageSource(tab.icon) ? /*#__PURE__*/_jsx(DrawerIcon, {
|
|
168
|
-
source: tab.icon,
|
|
169
|
-
tintColor: iconTint
|
|
170
|
-
}) : null
|
|
171
|
-
}), /*#__PURE__*/_jsx("div", {
|
|
172
|
-
className: "drawer-item-label",
|
|
173
|
-
style: labelStyle,
|
|
174
|
-
children: tab.title
|
|
175
|
-
}), tab.badgeValue ? /*#__PURE__*/_jsx("span", {
|
|
176
|
-
className: "drawer-item-badge",
|
|
177
|
-
children: tab.badgeValue
|
|
178
|
-
}) : null]
|
|
179
|
-
}, tab.tabKey);
|
|
180
|
-
})
|
|
181
|
-
})
|
|
182
|
-
}), /*#__PURE__*/_jsx("div", {
|
|
183
|
-
className: "drawer-overlay",
|
|
184
|
-
onClick: handleOverlayClick
|
|
185
|
-
}), /*#__PURE__*/_jsx("div", {
|
|
186
|
-
className: "drawer-main",
|
|
187
|
-
children: stack ? /*#__PURE__*/_jsx(DrawerStackRenderer, {
|
|
188
|
-
appearance: appearance,
|
|
189
|
-
stack: stack
|
|
190
|
-
}) : node ? /*#__PURE__*/_jsx(DrawerNodeRenderer, {
|
|
191
|
-
appearance: appearance,
|
|
192
|
-
node: node
|
|
193
|
-
}) : Screen ? /*#__PURE__*/_jsx(Screen, {}) : null
|
|
194
|
-
})]
|
|
195
|
-
})
|
|
196
|
-
});
|
|
197
|
-
});
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
import { useContext } from 'react';
|
|
4
|
-
import { DrawerContext } from "./DrawerContext.js";
|
|
5
|
-
export const useDrawer = () => {
|
|
6
|
-
const drawer = useContext(DrawerContext);
|
|
7
|
-
if (!drawer) {
|
|
8
|
-
throw new Error('useDrawer must be used within a DrawerProvider');
|
|
9
|
-
}
|
|
10
|
-
return drawer;
|
|
11
|
-
};
|
package/lib/module/Navigation.js
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
import { ScreenStackItem } from "./ScreenStackItem/index.js";
|
|
4
|
-
import { RouterContext } from "./RouterContext.js";
|
|
5
|
-
import { ScreenStack } from "./ScreenStack/index.js";
|
|
6
|
-
import { StyleSheet } from 'react-native';
|
|
7
|
-
import { memo, useEffect, useRef, useState, startTransition } from 'react';
|
|
8
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
9
|
-
const EMPTY_HISTORY = [];
|
|
10
|
-
function useStackHistory(router, stackId) {
|
|
11
|
-
const [history, setHistory] = useState(EMPTY_HISTORY);
|
|
12
|
-
useEffect(() => {
|
|
13
|
-
if (!stackId) {
|
|
14
|
-
startTransition(() => {
|
|
15
|
-
setHistory(EMPTY_HISTORY);
|
|
16
|
-
});
|
|
17
|
-
return;
|
|
18
|
-
}
|
|
19
|
-
const update = () => {
|
|
20
|
-
startTransition(() => {
|
|
21
|
-
setHistory(router.getStackHistory(stackId));
|
|
22
|
-
});
|
|
23
|
-
};
|
|
24
|
-
const unsub = router.subscribeStack(stackId, update);
|
|
25
|
-
update();
|
|
26
|
-
return unsub;
|
|
27
|
-
}, [router, stackId]);
|
|
28
|
-
return history;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Navigation component renders the root and global stacks.
|
|
33
|
-
*
|
|
34
|
-
* Modal stacks (NavigationStack added via addModal) are rendered as regular ScreenStackItems
|
|
35
|
-
* with their component being the StackRenderer that subscribes to its own stack history.
|
|
36
|
-
* This creates a clean recursive structure: stacks render their items, nested stacks
|
|
37
|
-
* (via childNode) render their own items through StackRenderer.
|
|
38
|
-
*/
|
|
39
|
-
export const Navigation = /*#__PURE__*/memo(({
|
|
40
|
-
router,
|
|
41
|
-
appearance
|
|
42
|
-
}) => {
|
|
43
|
-
const [root, setRoot] = useState(() => ({
|
|
44
|
-
rootId: router.getRootStackId()
|
|
45
|
-
}));
|
|
46
|
-
useEffect(() => {
|
|
47
|
-
return router.subscribeRoot(() => {
|
|
48
|
-
startTransition(() => {
|
|
49
|
-
setRoot({
|
|
50
|
-
rootId: router.getRootStackId()
|
|
51
|
-
});
|
|
52
|
-
});
|
|
53
|
-
});
|
|
54
|
-
}, [router]);
|
|
55
|
-
const {
|
|
56
|
-
rootId
|
|
57
|
-
} = root;
|
|
58
|
-
const rootTransitionRef = useRef(undefined);
|
|
59
|
-
rootTransitionRef.current = router.getRootTransition();
|
|
60
|
-
const rootTransition = rootTransitionRef.current;
|
|
61
|
-
const rootItems = useStackHistory(router, rootId);
|
|
62
|
-
return /*#__PURE__*/_jsx(RouterContext.Provider, {
|
|
63
|
-
value: router,
|
|
64
|
-
children: /*#__PURE__*/_jsx(ScreenStack, {
|
|
65
|
-
style: styles.flex,
|
|
66
|
-
children: rootItems.map(item => /*#__PURE__*/_jsx(ScreenStackItem, {
|
|
67
|
-
stackId: rootId,
|
|
68
|
-
item: item,
|
|
69
|
-
stackAnimation: rootTransition,
|
|
70
|
-
appearance: appearance
|
|
71
|
-
}, `root-${item.key}`))
|
|
72
|
-
}, rootId ?? 'root')
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
const styles = StyleSheet.create({
|
|
76
|
-
flex: {
|
|
77
|
-
flex: 1
|
|
78
|
-
}
|
|
79
|
-
});
|