@sigmela/router 0.3.7 → 0.5.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 +38 -0
- package/LICENSE +2 -1
- package/README.md +127 -471
- 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 +56 -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 +3696 -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 +975 -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 +73 -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 -80
- 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
package/dist/index.js
ADDED
|
@@ -0,0 +1,3696 @@
|
|
|
1
|
+
import { createContext, memo, useMemo, Suspense, useCallback, useLayoutEffect, createElement, useState, useRef, useEffect, useContext, Children, isValidElement, Fragment as Fragment$1 } from 'react';
|
|
2
|
+
import { useTransitionMap } from 'react-transition-state';
|
|
3
|
+
import { Router as Router$1, useLocation, useSearch, useRouter as useRouter$1, matchRoute } from 'wouter';
|
|
4
|
+
import { navigate, useHistoryState as useHistoryState$1 } from 'wouter/use-browser-location';
|
|
5
|
+
import { useMotionValue, animate, motion } from 'motion/react';
|
|
6
|
+
import { disableScroll, enableScroll } from '@fluejs/noscroll';
|
|
7
|
+
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
8
|
+
import './router.css';
|
|
9
|
+
|
|
10
|
+
// src/Router.tsx
|
|
11
|
+
var pageScrollLockCount = 0;
|
|
12
|
+
function getPageScrollElement() {
|
|
13
|
+
return document.querySelector(
|
|
14
|
+
".screen-stack > .screen-stack-item.phase-active > .stack-screen-container"
|
|
15
|
+
) ?? document.getElementById("root");
|
|
16
|
+
}
|
|
17
|
+
function usePageScrollLock(active) {
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
const scrollEl = getPageScrollElement();
|
|
20
|
+
if (!scrollEl) return;
|
|
21
|
+
pageScrollLockCount += 1;
|
|
22
|
+
if (pageScrollLockCount === 1) {
|
|
23
|
+
disableScroll(scrollEl);
|
|
24
|
+
}
|
|
25
|
+
return () => {
|
|
26
|
+
pageScrollLockCount = Math.max(0, pageScrollLockCount - 1);
|
|
27
|
+
if (pageScrollLockCount === 0) {
|
|
28
|
+
enableScroll(scrollEl);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
}, [active]);
|
|
32
|
+
}
|
|
33
|
+
var SHEET_DRAG_EPS = 0.5;
|
|
34
|
+
var SHEET_DRAG_START_DISTANCE = 2;
|
|
35
|
+
function sheetScrollAtTop(el) {
|
|
36
|
+
return !el || el.scrollTop <= SHEET_DRAG_EPS;
|
|
37
|
+
}
|
|
38
|
+
function sheetDragStartsInInteractiveControl(target) {
|
|
39
|
+
if (!(target instanceof Element)) return false;
|
|
40
|
+
return Boolean(
|
|
41
|
+
target.closest(
|
|
42
|
+
'button,a,input,textarea,select,[role="button"],[data-sheet-drag-ignore="true"]'
|
|
43
|
+
)
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
function sheetDragStartsInTextInput(target) {
|
|
47
|
+
if (!(target instanceof Element)) return false;
|
|
48
|
+
return Boolean(
|
|
49
|
+
target.closest(
|
|
50
|
+
'input,textarea,select,[contenteditable="true"],[data-sheet-drag-ignore="true"]'
|
|
51
|
+
)
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
function useSheetDragEngine({
|
|
55
|
+
targetRef,
|
|
56
|
+
enabled,
|
|
57
|
+
minDragDistance = SHEET_DRAG_START_DISTANCE,
|
|
58
|
+
ignoreStartTarget,
|
|
59
|
+
shouldStart,
|
|
60
|
+
onStart,
|
|
61
|
+
onMove,
|
|
62
|
+
onEnd,
|
|
63
|
+
suppressClickOnDrag = false
|
|
64
|
+
}) {
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
if (!enabled) return;
|
|
67
|
+
const target = targetRef.current;
|
|
68
|
+
if (!target) return;
|
|
69
|
+
const drag = {
|
|
70
|
+
active: false,
|
|
71
|
+
tracking: false,
|
|
72
|
+
pointerId: -1,
|
|
73
|
+
startY: 0,
|
|
74
|
+
lastY: 0,
|
|
75
|
+
lastT: 0,
|
|
76
|
+
velocityY: 0,
|
|
77
|
+
lastClientY: 0,
|
|
78
|
+
lastTotalY: 0
|
|
79
|
+
};
|
|
80
|
+
let suppressNextClick = false;
|
|
81
|
+
let clearSuppressClickTimer = 0;
|
|
82
|
+
const clearSuppressNextClick = () => {
|
|
83
|
+
suppressNextClick = false;
|
|
84
|
+
if (clearSuppressClickTimer) {
|
|
85
|
+
window.clearTimeout(clearSuppressClickTimer);
|
|
86
|
+
clearSuppressClickTimer = 0;
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
const scheduleSuppressClickClear = () => {
|
|
90
|
+
if (!suppressClickOnDrag) return;
|
|
91
|
+
if (clearSuppressClickTimer) window.clearTimeout(clearSuppressClickTimer);
|
|
92
|
+
clearSuppressClickTimer = window.setTimeout(() => {
|
|
93
|
+
suppressNextClick = false;
|
|
94
|
+
clearSuppressClickTimer = 0;
|
|
95
|
+
}, 350);
|
|
96
|
+
};
|
|
97
|
+
const beginTracking = (clientY) => {
|
|
98
|
+
drag.active = false;
|
|
99
|
+
drag.tracking = true;
|
|
100
|
+
drag.pointerId = -1;
|
|
101
|
+
drag.startY = clientY;
|
|
102
|
+
drag.lastY = clientY;
|
|
103
|
+
drag.lastT = performance.now();
|
|
104
|
+
drag.velocityY = 0;
|
|
105
|
+
drag.lastClientY = clientY;
|
|
106
|
+
drag.lastTotalY = 0;
|
|
107
|
+
};
|
|
108
|
+
const resetTracking = () => {
|
|
109
|
+
drag.active = false;
|
|
110
|
+
drag.tracking = false;
|
|
111
|
+
drag.pointerId = -1;
|
|
112
|
+
drag.velocityY = 0;
|
|
113
|
+
drag.lastTotalY = 0;
|
|
114
|
+
};
|
|
115
|
+
const makeUpdate = (clientY, event, now) => {
|
|
116
|
+
const deltaY = clientY - drag.lastY;
|
|
117
|
+
const totalY = clientY - drag.startY;
|
|
118
|
+
const dt = Math.max(1, now - drag.lastT);
|
|
119
|
+
const velocityY = deltaY / dt * 1e3;
|
|
120
|
+
return { clientY, deltaY, totalY, velocityY, event };
|
|
121
|
+
};
|
|
122
|
+
const updateTracking = (clientY, event) => {
|
|
123
|
+
if (!drag.tracking) return;
|
|
124
|
+
const now = performance.now();
|
|
125
|
+
const update = makeUpdate(clientY, event, now);
|
|
126
|
+
drag.lastClientY = clientY;
|
|
127
|
+
drag.lastTotalY = update.totalY;
|
|
128
|
+
if (!drag.active) {
|
|
129
|
+
if (Math.abs(update.totalY) <= minDragDistance) {
|
|
130
|
+
drag.lastY = clientY;
|
|
131
|
+
drag.lastT = now;
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
if (!shouldStart(update)) {
|
|
135
|
+
drag.lastY = clientY;
|
|
136
|
+
drag.lastT = now;
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
drag.active = true;
|
|
140
|
+
if (suppressClickOnDrag) suppressNextClick = true;
|
|
141
|
+
if (event instanceof PointerEvent) {
|
|
142
|
+
try {
|
|
143
|
+
target.setPointerCapture(event.pointerId);
|
|
144
|
+
} catch {
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
onStart(update);
|
|
148
|
+
}
|
|
149
|
+
if (event.cancelable) event.preventDefault();
|
|
150
|
+
drag.velocityY = update.velocityY;
|
|
151
|
+
onMove(update);
|
|
152
|
+
drag.lastY = clientY;
|
|
153
|
+
drag.lastT = now;
|
|
154
|
+
};
|
|
155
|
+
const finishTracking = (event) => {
|
|
156
|
+
if (!drag.tracking) return;
|
|
157
|
+
const now = performance.now();
|
|
158
|
+
const update = makeUpdate(drag.lastClientY, event, now);
|
|
159
|
+
const wasActive = drag.active;
|
|
160
|
+
if (event instanceof PointerEvent) {
|
|
161
|
+
try {
|
|
162
|
+
target.releasePointerCapture(event.pointerId);
|
|
163
|
+
} catch {
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
const velocityY = drag.velocityY || update.velocityY;
|
|
167
|
+
resetTracking();
|
|
168
|
+
if (!wasActive) return;
|
|
169
|
+
if (event.cancelable) event.preventDefault();
|
|
170
|
+
scheduleSuppressClickClear();
|
|
171
|
+
onEnd({ ...update, velocityY });
|
|
172
|
+
};
|
|
173
|
+
const onTouchStart = (event) => {
|
|
174
|
+
if (event.touches.length !== 1 || ignoreStartTarget?.(event.target)) {
|
|
175
|
+
resetTracking();
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
beginTracking(event.touches[0]?.clientY ?? 0);
|
|
179
|
+
};
|
|
180
|
+
const onTouchMove = (event) => {
|
|
181
|
+
if (event.touches.length !== 1) return;
|
|
182
|
+
updateTracking(event.touches[0]?.clientY ?? drag.lastY, event);
|
|
183
|
+
};
|
|
184
|
+
const onPointerDown = (event) => {
|
|
185
|
+
if (event.pointerType === "touch" || !event.isPrimary || event.button !== 0 || ignoreStartTarget?.(event.target)) {
|
|
186
|
+
resetTracking();
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
beginTracking(event.clientY);
|
|
190
|
+
drag.pointerId = event.pointerId;
|
|
191
|
+
};
|
|
192
|
+
const onPointerMove = (event) => {
|
|
193
|
+
if (!drag.tracking || drag.pointerId !== event.pointerId) return;
|
|
194
|
+
updateTracking(event.clientY, event);
|
|
195
|
+
};
|
|
196
|
+
const onPointerEnd = (event) => {
|
|
197
|
+
if (!drag.tracking || drag.pointerId !== event.pointerId) return;
|
|
198
|
+
finishTracking(event);
|
|
199
|
+
};
|
|
200
|
+
const onClickCapture = (event) => {
|
|
201
|
+
if (!suppressNextClick) return;
|
|
202
|
+
clearSuppressNextClick();
|
|
203
|
+
event.preventDefault();
|
|
204
|
+
event.stopPropagation();
|
|
205
|
+
};
|
|
206
|
+
target.addEventListener("touchstart", onTouchStart, { passive: true });
|
|
207
|
+
target.addEventListener("touchmove", onTouchMove, { passive: false });
|
|
208
|
+
target.addEventListener("touchend", finishTracking, { passive: false });
|
|
209
|
+
target.addEventListener("touchcancel", finishTracking, { passive: false });
|
|
210
|
+
target.addEventListener("pointerdown", onPointerDown);
|
|
211
|
+
target.addEventListener("pointermove", onPointerMove, { passive: false });
|
|
212
|
+
target.addEventListener("pointerup", onPointerEnd);
|
|
213
|
+
target.addEventListener("pointercancel", onPointerEnd);
|
|
214
|
+
if (suppressClickOnDrag) target.addEventListener("click", onClickCapture, true);
|
|
215
|
+
return () => {
|
|
216
|
+
target.removeEventListener("touchstart", onTouchStart);
|
|
217
|
+
target.removeEventListener("touchmove", onTouchMove);
|
|
218
|
+
target.removeEventListener("touchend", finishTracking);
|
|
219
|
+
target.removeEventListener("touchcancel", finishTracking);
|
|
220
|
+
target.removeEventListener("pointerdown", onPointerDown);
|
|
221
|
+
target.removeEventListener("pointermove", onPointerMove);
|
|
222
|
+
target.removeEventListener("pointerup", onPointerEnd);
|
|
223
|
+
target.removeEventListener("pointercancel", onPointerEnd);
|
|
224
|
+
if (suppressClickOnDrag) target.removeEventListener("click", onClickCapture, true);
|
|
225
|
+
if (clearSuppressClickTimer) window.clearTimeout(clearSuppressClickTimer);
|
|
226
|
+
};
|
|
227
|
+
}, [
|
|
228
|
+
enabled,
|
|
229
|
+
ignoreStartTarget,
|
|
230
|
+
minDragDistance,
|
|
231
|
+
onEnd,
|
|
232
|
+
onMove,
|
|
233
|
+
onStart,
|
|
234
|
+
shouldStart,
|
|
235
|
+
suppressClickOnDrag,
|
|
236
|
+
targetRef
|
|
237
|
+
]);
|
|
238
|
+
}
|
|
239
|
+
var SHEET_SPRING = { type: "spring", bounce: 0, duration: 0.38 };
|
|
240
|
+
var CLOSE_DISTANCE = 112;
|
|
241
|
+
var CLOSE_VELOCITY = 850;
|
|
242
|
+
var DRAG_START_DISTANCE = 6;
|
|
243
|
+
var PROJECT_VELOCITY_FACTOR = 0.18;
|
|
244
|
+
function closeTargetY(surface, target) {
|
|
245
|
+
if (target === "viewport") return window.innerHeight + 32;
|
|
246
|
+
return (surface?.getBoundingClientRect().height || window.innerHeight) + 32;
|
|
247
|
+
}
|
|
248
|
+
function SheetSurface({
|
|
249
|
+
children,
|
|
250
|
+
open,
|
|
251
|
+
onRequestClose,
|
|
252
|
+
onExitComplete,
|
|
253
|
+
zIndex,
|
|
254
|
+
mode,
|
|
255
|
+
canDismiss = true,
|
|
256
|
+
swipeToClose = true,
|
|
257
|
+
backdrop = false,
|
|
258
|
+
backdropClassName,
|
|
259
|
+
backdropStyle,
|
|
260
|
+
shellClassName,
|
|
261
|
+
surfaceClassName,
|
|
262
|
+
surfaceStyle,
|
|
263
|
+
scrollElement,
|
|
264
|
+
ariaLabel,
|
|
265
|
+
shell = "mobile-contained",
|
|
266
|
+
closeTarget = "surface"
|
|
267
|
+
}) {
|
|
268
|
+
const surfaceRef = useRef(null);
|
|
269
|
+
const removeRef = useRef(onExitComplete);
|
|
270
|
+
const requestCloseRef = useRef(onRequestClose);
|
|
271
|
+
const closingOffsetRef = useRef(0);
|
|
272
|
+
const closingRef = useRef(false);
|
|
273
|
+
const y = useMotionValue(window.innerHeight);
|
|
274
|
+
removeRef.current = onExitComplete;
|
|
275
|
+
requestCloseRef.current = onRequestClose;
|
|
276
|
+
usePageScrollLock(true);
|
|
277
|
+
const requestClose = useCallback(
|
|
278
|
+
(offset = 0) => {
|
|
279
|
+
if (!canDismiss || closingRef.current) return;
|
|
280
|
+
closingOffsetRef.current = offset;
|
|
281
|
+
requestCloseRef.current();
|
|
282
|
+
},
|
|
283
|
+
[canDismiss]
|
|
284
|
+
);
|
|
285
|
+
const closeWithAnimation = useCallback(
|
|
286
|
+
(offset = 0) => {
|
|
287
|
+
if (closingRef.current) return;
|
|
288
|
+
closingRef.current = true;
|
|
289
|
+
const target = closeTargetY(surfaceRef.current, closeTarget);
|
|
290
|
+
y.stop();
|
|
291
|
+
y.set(Math.max(0, offset));
|
|
292
|
+
const controls = animate(y, target, SHEET_SPRING);
|
|
293
|
+
void controls.finished.then(
|
|
294
|
+
() => {
|
|
295
|
+
removeRef.current();
|
|
296
|
+
},
|
|
297
|
+
() => {
|
|
298
|
+
closingRef.current = false;
|
|
299
|
+
}
|
|
300
|
+
);
|
|
301
|
+
},
|
|
302
|
+
[closeTarget, y]
|
|
303
|
+
);
|
|
304
|
+
useEffect(() => {
|
|
305
|
+
if (!open) {
|
|
306
|
+
closeWithAnimation(closingOffsetRef.current);
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
y.set(window.innerHeight);
|
|
310
|
+
const controls = animate(y, 0, SHEET_SPRING);
|
|
311
|
+
return () => controls.stop();
|
|
312
|
+
}, [closeWithAnimation, open, y]);
|
|
313
|
+
useEffect(() => {
|
|
314
|
+
if (!canDismiss) return;
|
|
315
|
+
const handler = (event) => {
|
|
316
|
+
if (event.key === "Escape") requestClose();
|
|
317
|
+
};
|
|
318
|
+
document.addEventListener("keydown", handler);
|
|
319
|
+
return () => document.removeEventListener("keydown", handler);
|
|
320
|
+
}, [canDismiss, requestClose]);
|
|
321
|
+
const shouldStartDrag = useCallback(
|
|
322
|
+
(update) => update.totalY > 0 && sheetScrollAtTop(scrollElement ?? null),
|
|
323
|
+
[scrollElement]
|
|
324
|
+
);
|
|
325
|
+
const handleDragStart = useCallback(() => {
|
|
326
|
+
y.stop();
|
|
327
|
+
}, [y]);
|
|
328
|
+
const handleDragMove = useCallback(
|
|
329
|
+
(update) => {
|
|
330
|
+
y.set(Math.max(0, y.get() + update.deltaY));
|
|
331
|
+
},
|
|
332
|
+
[y]
|
|
333
|
+
);
|
|
334
|
+
const handleDragEnd = useCallback(
|
|
335
|
+
(update) => {
|
|
336
|
+
const offset = y.get();
|
|
337
|
+
const projected = offset + update.velocityY * PROJECT_VELOCITY_FACTOR;
|
|
338
|
+
if (projected > CLOSE_DISTANCE || update.velocityY > CLOSE_VELOCITY) {
|
|
339
|
+
requestClose(offset);
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
y.stop();
|
|
343
|
+
void animate(y, 0, SHEET_SPRING).finished.catch(() => {
|
|
344
|
+
});
|
|
345
|
+
},
|
|
346
|
+
[requestClose, y]
|
|
347
|
+
);
|
|
348
|
+
useSheetDragEngine({
|
|
349
|
+
targetRef: surfaceRef,
|
|
350
|
+
enabled: swipeToClose && canDismiss,
|
|
351
|
+
minDragDistance: DRAG_START_DISTANCE,
|
|
352
|
+
ignoreStartTarget: sheetDragStartsInTextInput,
|
|
353
|
+
shouldStart: shouldStartDrag,
|
|
354
|
+
onStart: handleDragStart,
|
|
355
|
+
onMove: handleDragMove,
|
|
356
|
+
onEnd: handleDragEnd,
|
|
357
|
+
suppressClickOnDrag: true
|
|
358
|
+
});
|
|
359
|
+
const baseShellClassName = mode === "fullscreen" ? "router-overlay-shell router-overlay-shell--fullscreen" : "router-overlay-shell router-overlay-shell--content";
|
|
360
|
+
const overlayShellClassName = shellClassName ? `${baseShellClassName} ${shellClassName}` : baseShellClassName;
|
|
361
|
+
const shellStyle = useMemo(
|
|
362
|
+
() => ({
|
|
363
|
+
zIndex
|
|
364
|
+
}),
|
|
365
|
+
[zIndex]
|
|
366
|
+
);
|
|
367
|
+
const node = /* @__PURE__ */ jsxs("div", { className: overlayShellClassName, "data-router-shell": shell, style: shellStyle, children: [
|
|
368
|
+
backdrop ? /* @__PURE__ */ jsx(
|
|
369
|
+
motion.button,
|
|
370
|
+
{
|
|
371
|
+
type: "button",
|
|
372
|
+
"aria-label": "Close",
|
|
373
|
+
className: `pointer-events-auto absolute inset-0 border-0 p-0 ${backdropClassName ?? ""}`,
|
|
374
|
+
style: backdropStyle,
|
|
375
|
+
initial: { opacity: 0 },
|
|
376
|
+
animate: { opacity: open ? 1 : 0 },
|
|
377
|
+
transition: { duration: 0.2, ease: "easeOut" },
|
|
378
|
+
onClick: () => requestClose()
|
|
379
|
+
}
|
|
380
|
+
) : null,
|
|
381
|
+
/* @__PURE__ */ jsx(
|
|
382
|
+
motion.div,
|
|
383
|
+
{
|
|
384
|
+
ref: surfaceRef,
|
|
385
|
+
className: surfaceClassName,
|
|
386
|
+
style: { ...surfaceStyle, y },
|
|
387
|
+
role: "dialog",
|
|
388
|
+
"aria-modal": "true",
|
|
389
|
+
"aria-label": ariaLabel,
|
|
390
|
+
children
|
|
391
|
+
}
|
|
392
|
+
)
|
|
393
|
+
] });
|
|
394
|
+
return node;
|
|
395
|
+
}
|
|
396
|
+
function CloseIcon() {
|
|
397
|
+
return /* @__PURE__ */ jsx("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx(
|
|
398
|
+
"path",
|
|
399
|
+
{
|
|
400
|
+
d: "M4.75 4.75L13.25 13.25M13.25 4.75L4.75 13.25",
|
|
401
|
+
stroke: "currentColor",
|
|
402
|
+
strokeLinecap: "round",
|
|
403
|
+
strokeWidth: "2.2"
|
|
404
|
+
}
|
|
405
|
+
) });
|
|
406
|
+
}
|
|
407
|
+
function RouterCloseButton({
|
|
408
|
+
onPress,
|
|
409
|
+
disabled,
|
|
410
|
+
tone = "default",
|
|
411
|
+
ariaLabel = "Close"
|
|
412
|
+
}) {
|
|
413
|
+
const toneClass = tone === "light" ? " router-close-button--light" : "";
|
|
414
|
+
return /* @__PURE__ */ jsxs(
|
|
415
|
+
"button",
|
|
416
|
+
{
|
|
417
|
+
type: "button",
|
|
418
|
+
"aria-label": ariaLabel,
|
|
419
|
+
className: `router-close-button router-close-button-circle${toneClass}`,
|
|
420
|
+
disabled,
|
|
421
|
+
onClick: onPress,
|
|
422
|
+
children: [
|
|
423
|
+
/* @__PURE__ */ jsx("div", { className: `router-close-button-inner router-close-button-circle${toneClass}`, children: /* @__PURE__ */ jsx(CloseIcon, {}) }),
|
|
424
|
+
/* @__PURE__ */ jsxs("div", { className: "router-close-button-blur router-close-button-circle", children: [
|
|
425
|
+
/* @__PURE__ */ jsx("div", { className: "router-close-mask-1", "aria-hidden": "true" }),
|
|
426
|
+
/* @__PURE__ */ jsx("div", { className: "router-close-mask-2", "aria-hidden": "true" }),
|
|
427
|
+
/* @__PURE__ */ jsx("div", { className: "router-close-mask-3", "aria-hidden": "true" })
|
|
428
|
+
] })
|
|
429
|
+
]
|
|
430
|
+
}
|
|
431
|
+
);
|
|
432
|
+
}
|
|
433
|
+
var DEFAULT_OVERLAY_CONTENT_KEY = "router-overlay-content:default";
|
|
434
|
+
var OverlayContentKeyContext = createContext(DEFAULT_OVERLAY_CONTENT_KEY);
|
|
435
|
+
function OverlayContentScope({
|
|
436
|
+
contentKey,
|
|
437
|
+
children
|
|
438
|
+
}) {
|
|
439
|
+
return /* @__PURE__ */ jsx(OverlayContentKeyContext.Provider, { value: contentKey, children });
|
|
440
|
+
}
|
|
441
|
+
function useOverlayContentKey() {
|
|
442
|
+
return useContext(OverlayContentKeyContext);
|
|
443
|
+
}
|
|
444
|
+
var ModalContext = createContext(null);
|
|
445
|
+
function useModalContext() {
|
|
446
|
+
const ctx = useContext(ModalContext);
|
|
447
|
+
if (!ctx) {
|
|
448
|
+
throw new Error("Modal sub-components must be rendered inside <Modal>");
|
|
449
|
+
}
|
|
450
|
+
return ctx;
|
|
451
|
+
}
|
|
452
|
+
function useModalSwipeTarget() {
|
|
453
|
+
const { setSwipeTarget } = useModalContext();
|
|
454
|
+
const contentKey = useOverlayContentKey();
|
|
455
|
+
return useCallback(
|
|
456
|
+
(el) => setSwipeTarget(contentKey, el),
|
|
457
|
+
[contentKey, setSwipeTarget]
|
|
458
|
+
);
|
|
459
|
+
}
|
|
460
|
+
function ModalFrame({
|
|
461
|
+
children,
|
|
462
|
+
open,
|
|
463
|
+
onRequestClose,
|
|
464
|
+
onExitComplete,
|
|
465
|
+
zIndex,
|
|
466
|
+
shell = "mobile-contained",
|
|
467
|
+
contentSized = false,
|
|
468
|
+
activeContentKey = DEFAULT_OVERLAY_CONTENT_KEY
|
|
469
|
+
}) {
|
|
470
|
+
const [registrations, setRegistrations] = useState(() => /* @__PURE__ */ new Map());
|
|
471
|
+
const setSwipeTarget = useCallback(
|
|
472
|
+
(contentKey, swipeTarget2) => {
|
|
473
|
+
setRegistrations((current) => {
|
|
474
|
+
const registration = current.get(contentKey);
|
|
475
|
+
if ((registration?.swipeTarget ?? null) === swipeTarget2) return current;
|
|
476
|
+
const next = new Map(current);
|
|
477
|
+
if (!swipeTarget2 && !registration?.options) {
|
|
478
|
+
next.delete(contentKey);
|
|
479
|
+
} else {
|
|
480
|
+
next.set(contentKey, { ...registration, swipeTarget: swipeTarget2 });
|
|
481
|
+
}
|
|
482
|
+
return next;
|
|
483
|
+
});
|
|
484
|
+
},
|
|
485
|
+
[]
|
|
486
|
+
);
|
|
487
|
+
const setOptions = useCallback((contentKey, options2) => {
|
|
488
|
+
setRegistrations((current) => {
|
|
489
|
+
const registration = current.get(contentKey);
|
|
490
|
+
if (registration?.options === options2) return current;
|
|
491
|
+
const next = new Map(current);
|
|
492
|
+
if (!options2 && !registration?.swipeTarget) {
|
|
493
|
+
next.delete(contentKey);
|
|
494
|
+
} else {
|
|
495
|
+
next.set(contentKey, {
|
|
496
|
+
...registration,
|
|
497
|
+
options: options2 ?? void 0
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
return next;
|
|
501
|
+
});
|
|
502
|
+
}, []);
|
|
503
|
+
const activeRegistration = registrations.get(activeContentKey);
|
|
504
|
+
const swipeTarget = activeRegistration?.swipeTarget ?? null;
|
|
505
|
+
const options = activeRegistration?.options;
|
|
506
|
+
const swipeToClose = options?.swipeToClose ?? true;
|
|
507
|
+
const ariaLabel = options?.ariaLabel;
|
|
508
|
+
const isContentSized = contentSized || options?.presentation === "content";
|
|
509
|
+
const requestClose = useCallback(() => {
|
|
510
|
+
onRequestClose();
|
|
511
|
+
}, [onRequestClose]);
|
|
512
|
+
const contextValue = useMemo(
|
|
513
|
+
() => ({ setSwipeTarget, requestClose, setOptions }),
|
|
514
|
+
[requestClose, setOptions, setSwipeTarget]
|
|
515
|
+
);
|
|
516
|
+
return /* @__PURE__ */ jsx(ModalContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(
|
|
517
|
+
SheetSurface,
|
|
518
|
+
{
|
|
519
|
+
open,
|
|
520
|
+
onRequestClose: requestClose,
|
|
521
|
+
onExitComplete,
|
|
522
|
+
zIndex,
|
|
523
|
+
mode: "fullscreen",
|
|
524
|
+
swipeToClose,
|
|
525
|
+
shell,
|
|
526
|
+
backdrop: true,
|
|
527
|
+
backdropClassName: `router-modal-backdrop${isContentSized ? " router-modal-backdrop--transparent" : ""}`,
|
|
528
|
+
shellClassName: "router-modal-shell",
|
|
529
|
+
surfaceClassName: `router-modal-surface${isContentSized ? " router-modal-surface--content-sized" : ""}${options?.size === "wide" ? " router-modal-surface--wide" : ""}`,
|
|
530
|
+
scrollElement: swipeTarget,
|
|
531
|
+
ariaLabel,
|
|
532
|
+
closeTarget: isContentSized ? "surface" : "viewport",
|
|
533
|
+
children
|
|
534
|
+
}
|
|
535
|
+
) });
|
|
536
|
+
}
|
|
537
|
+
function ModalRoot({
|
|
538
|
+
children,
|
|
539
|
+
swipeToClose = true,
|
|
540
|
+
ariaLabel,
|
|
541
|
+
size = "regular",
|
|
542
|
+
presentation = "fullscreen"
|
|
543
|
+
}) {
|
|
544
|
+
const { setOptions } = useModalContext();
|
|
545
|
+
const contentKey = useOverlayContentKey();
|
|
546
|
+
useLayoutEffect(() => {
|
|
547
|
+
setOptions(contentKey, { swipeToClose, ariaLabel, size, presentation });
|
|
548
|
+
return () => setOptions(contentKey, null);
|
|
549
|
+
}, [ariaLabel, contentKey, presentation, setOptions, size, swipeToClose]);
|
|
550
|
+
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
551
|
+
}
|
|
552
|
+
function ModalHeader({
|
|
553
|
+
title,
|
|
554
|
+
leftAction,
|
|
555
|
+
rightAction,
|
|
556
|
+
hideCloseButton,
|
|
557
|
+
sticky = true
|
|
558
|
+
}) {
|
|
559
|
+
const { requestClose } = useModalContext();
|
|
560
|
+
const headerClassName = `router-modal-header${sticky ? " router-modal-header--sticky" : ""}`;
|
|
561
|
+
return /* @__PURE__ */ jsxs("div", { className: headerClassName, children: [
|
|
562
|
+
/* @__PURE__ */ jsx("div", { className: "router-modal-header-side", children: leftAction }),
|
|
563
|
+
/* @__PURE__ */ jsx("h2", { className: "router-modal-title", children: title }),
|
|
564
|
+
/* @__PURE__ */ jsx("div", { className: "router-modal-header-side router-modal-header-side--trailing", children: rightAction ?? (hideCloseButton ? null : /* @__PURE__ */ jsx(RouterCloseButton, { onPress: requestClose })) })
|
|
565
|
+
] });
|
|
566
|
+
}
|
|
567
|
+
function ModalContent({ children, className }) {
|
|
568
|
+
return /* @__PURE__ */ jsx("div", { className: `router-modal-content ${className ?? ""}`, children });
|
|
569
|
+
}
|
|
570
|
+
function ModalScrollView({ children, className, style }) {
|
|
571
|
+
const setSwipeTarget = useModalSwipeTarget();
|
|
572
|
+
return /* @__PURE__ */ jsx(
|
|
573
|
+
"div",
|
|
574
|
+
{
|
|
575
|
+
ref: setSwipeTarget,
|
|
576
|
+
className: `router-scroll router-modal-scroll-view ${className ?? ""}`,
|
|
577
|
+
style,
|
|
578
|
+
children
|
|
579
|
+
}
|
|
580
|
+
);
|
|
581
|
+
}
|
|
582
|
+
function ModalFooter({ children, className }) {
|
|
583
|
+
return /* @__PURE__ */ jsx(
|
|
584
|
+
"div",
|
|
585
|
+
{
|
|
586
|
+
className: `router-modal-footer ${className ?? ""}`,
|
|
587
|
+
children: /* @__PURE__ */ jsx("div", { className: "router-modal-footer-content", children })
|
|
588
|
+
}
|
|
589
|
+
);
|
|
590
|
+
}
|
|
591
|
+
var Modal = Object.assign(ModalRoot, {
|
|
592
|
+
Header: ModalHeader,
|
|
593
|
+
Content: ModalContent,
|
|
594
|
+
ScrollView: ModalScrollView,
|
|
595
|
+
Footer: ModalFooter
|
|
596
|
+
});
|
|
597
|
+
var SheetContext = createContext(null);
|
|
598
|
+
function useSheetContext() {
|
|
599
|
+
const ctx = useContext(SheetContext);
|
|
600
|
+
if (!ctx) {
|
|
601
|
+
throw new Error("Sheet sub-components must be rendered inside <Sheet>");
|
|
602
|
+
}
|
|
603
|
+
return ctx;
|
|
604
|
+
}
|
|
605
|
+
function SheetFrame({
|
|
606
|
+
children,
|
|
607
|
+
open,
|
|
608
|
+
onRequestClose,
|
|
609
|
+
onExitComplete,
|
|
610
|
+
zIndex,
|
|
611
|
+
shell = "mobile-contained",
|
|
612
|
+
activeContentKey = DEFAULT_OVERLAY_CONTENT_KEY
|
|
613
|
+
}) {
|
|
614
|
+
const [frameScrollElement, setFrameScrollElement] = useState(null);
|
|
615
|
+
const [registrations, setRegistrations] = useState(() => /* @__PURE__ */ new Map());
|
|
616
|
+
const setScrollElement = useCallback(
|
|
617
|
+
(contentKey, scrollElement2) => {
|
|
618
|
+
setRegistrations((current) => {
|
|
619
|
+
const registration = current.get(contentKey);
|
|
620
|
+
if ((registration?.scrollElement ?? null) === scrollElement2) return current;
|
|
621
|
+
const next = new Map(current);
|
|
622
|
+
if (!scrollElement2 && !registration?.options) {
|
|
623
|
+
next.delete(contentKey);
|
|
624
|
+
} else {
|
|
625
|
+
next.set(contentKey, { ...registration, scrollElement: scrollElement2 });
|
|
626
|
+
}
|
|
627
|
+
return next;
|
|
628
|
+
});
|
|
629
|
+
},
|
|
630
|
+
[]
|
|
631
|
+
);
|
|
632
|
+
const setOptions = useCallback((contentKey, options2) => {
|
|
633
|
+
setRegistrations((current) => {
|
|
634
|
+
const registration = current.get(contentKey);
|
|
635
|
+
if (registration?.options === options2) return current;
|
|
636
|
+
const next = new Map(current);
|
|
637
|
+
if (!options2 && !registration?.scrollElement) {
|
|
638
|
+
next.delete(contentKey);
|
|
639
|
+
} else {
|
|
640
|
+
next.set(contentKey, {
|
|
641
|
+
...registration,
|
|
642
|
+
options: options2 ?? void 0
|
|
643
|
+
});
|
|
644
|
+
}
|
|
645
|
+
return next;
|
|
646
|
+
});
|
|
647
|
+
}, []);
|
|
648
|
+
const activeRegistration = registrations.get(activeContentKey);
|
|
649
|
+
const scrollElement = activeRegistration?.scrollElement ?? frameScrollElement;
|
|
650
|
+
const options = activeRegistration?.options;
|
|
651
|
+
const disableDismiss = options?.disableDismiss ?? false;
|
|
652
|
+
const customRequestClose = options?.onRequestClose;
|
|
653
|
+
const variant = options?.variant ?? "detached";
|
|
654
|
+
const presentation = options?.presentation ?? "content";
|
|
655
|
+
const fullscreen = presentation === "fullscreen";
|
|
656
|
+
const requestClose = useCallback(() => {
|
|
657
|
+
if (disableDismiss) return;
|
|
658
|
+
if (customRequestClose) {
|
|
659
|
+
customRequestClose();
|
|
660
|
+
return;
|
|
661
|
+
}
|
|
662
|
+
onRequestClose();
|
|
663
|
+
}, [customRequestClose, disableDismiss, onRequestClose]);
|
|
664
|
+
const contextValue = useMemo(
|
|
665
|
+
() => ({
|
|
666
|
+
setScrollElement,
|
|
667
|
+
close: requestClose,
|
|
668
|
+
canClose: !disableDismiss,
|
|
669
|
+
variant,
|
|
670
|
+
presentation,
|
|
671
|
+
setOptions
|
|
672
|
+
}),
|
|
673
|
+
[
|
|
674
|
+
requestClose,
|
|
675
|
+
disableDismiss,
|
|
676
|
+
presentation,
|
|
677
|
+
setScrollElement,
|
|
678
|
+
setOptions,
|
|
679
|
+
variant
|
|
680
|
+
]
|
|
681
|
+
);
|
|
682
|
+
const surfaceStyle = useMemo(
|
|
683
|
+
() => fullscreen ? {
|
|
684
|
+
backgroundColor: "var(--router-bg)",
|
|
685
|
+
borderRadius: "33px 33px 0 0",
|
|
686
|
+
boxShadow: "var(--router-card-shadow)",
|
|
687
|
+
color: "var(--router-text)",
|
|
688
|
+
overflow: "hidden",
|
|
689
|
+
bottom: 0,
|
|
690
|
+
left: 0,
|
|
691
|
+
right: 0,
|
|
692
|
+
width: "100%",
|
|
693
|
+
maxWidth: "var(--router-container)",
|
|
694
|
+
height: "calc(100dvh - env(safe-area-inset-top, 0px))",
|
|
695
|
+
maxHeight: "none",
|
|
696
|
+
marginInline: "auto"
|
|
697
|
+
} : variant === "detached" ? {
|
|
698
|
+
backgroundColor: "var(--router-bg)",
|
|
699
|
+
borderRadius: "28px 28px 32px 32px",
|
|
700
|
+
boxShadow: "var(--router-card-shadow)",
|
|
701
|
+
color: "var(--router-text)",
|
|
702
|
+
overflow: "hidden",
|
|
703
|
+
// Centered onto the app column with the same 8px gutter on every detached edge.
|
|
704
|
+
bottom: 8,
|
|
705
|
+
left: 8,
|
|
706
|
+
right: 8,
|
|
707
|
+
width: "auto",
|
|
708
|
+
maxWidth: "calc(var(--router-container) - 16px)",
|
|
709
|
+
marginInline: "auto",
|
|
710
|
+
maxHeight: "calc(100dvh - 32px - env(safe-area-inset-top, 0px))"
|
|
711
|
+
} : {
|
|
712
|
+
backgroundColor: "var(--router-bg)",
|
|
713
|
+
borderTop: "1px solid var(--router-line)",
|
|
714
|
+
borderRadius: "28px 28px 0 0",
|
|
715
|
+
boxShadow: "var(--router-card-shadow)",
|
|
716
|
+
color: "var(--router-text)",
|
|
717
|
+
// Centered onto the app column, full column width.
|
|
718
|
+
left: 0,
|
|
719
|
+
right: 0,
|
|
720
|
+
maxWidth: "var(--router-container)",
|
|
721
|
+
marginInline: "auto",
|
|
722
|
+
bottom: 0,
|
|
723
|
+
maxHeight: "calc(100dvh - env(safe-area-inset-top, 0px))"
|
|
724
|
+
},
|
|
725
|
+
[fullscreen, variant]
|
|
726
|
+
);
|
|
727
|
+
const backdropStyle = useMemo(
|
|
728
|
+
() => shell === "desktop-fullscreen" ? {
|
|
729
|
+
background: "var(--router-scrim)",
|
|
730
|
+
left: 0,
|
|
731
|
+
right: 0
|
|
732
|
+
} : {
|
|
733
|
+
background: "var(--router-scrim)",
|
|
734
|
+
left: 0,
|
|
735
|
+
right: 0,
|
|
736
|
+
maxWidth: "var(--router-container)",
|
|
737
|
+
marginInline: "auto"
|
|
738
|
+
},
|
|
739
|
+
[shell]
|
|
740
|
+
);
|
|
741
|
+
return /* @__PURE__ */ jsx(SheetContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(
|
|
742
|
+
SheetSurface,
|
|
743
|
+
{
|
|
744
|
+
open,
|
|
745
|
+
onRequestClose: requestClose,
|
|
746
|
+
onExitComplete,
|
|
747
|
+
zIndex,
|
|
748
|
+
mode: "content",
|
|
749
|
+
canDismiss: !disableDismiss,
|
|
750
|
+
shell,
|
|
751
|
+
backdrop: true,
|
|
752
|
+
backdropStyle,
|
|
753
|
+
surfaceClassName: "router-sheet-surface",
|
|
754
|
+
surfaceStyle,
|
|
755
|
+
scrollElement,
|
|
756
|
+
closeTarget: fullscreen ? "viewport" : "surface",
|
|
757
|
+
children: /* @__PURE__ */ jsx(
|
|
758
|
+
"div",
|
|
759
|
+
{
|
|
760
|
+
ref: setFrameScrollElement,
|
|
761
|
+
className: `router-scroll router-sheet-frame-scroll${fullscreen ? " router-sheet-frame-scroll--fullscreen" : ""}`,
|
|
762
|
+
children
|
|
763
|
+
}
|
|
764
|
+
)
|
|
765
|
+
}
|
|
766
|
+
) });
|
|
767
|
+
}
|
|
768
|
+
function SheetRoot({
|
|
769
|
+
children,
|
|
770
|
+
disableDismiss,
|
|
771
|
+
onRequestClose,
|
|
772
|
+
variant = "detached",
|
|
773
|
+
presentation = "content"
|
|
774
|
+
}) {
|
|
775
|
+
const { setOptions } = useSheetContext();
|
|
776
|
+
const contentKey = useOverlayContentKey();
|
|
777
|
+
useLayoutEffect(() => {
|
|
778
|
+
setOptions(contentKey, {
|
|
779
|
+
disableDismiss,
|
|
780
|
+
onRequestClose,
|
|
781
|
+
variant,
|
|
782
|
+
presentation
|
|
783
|
+
});
|
|
784
|
+
return () => setOptions(contentKey, null);
|
|
785
|
+
}, [
|
|
786
|
+
contentKey,
|
|
787
|
+
disableDismiss,
|
|
788
|
+
onRequestClose,
|
|
789
|
+
presentation,
|
|
790
|
+
setOptions,
|
|
791
|
+
variant
|
|
792
|
+
]);
|
|
793
|
+
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
794
|
+
}
|
|
795
|
+
function SheetHeader({
|
|
796
|
+
title,
|
|
797
|
+
leftAction,
|
|
798
|
+
rightAction,
|
|
799
|
+
hideCloseButton,
|
|
800
|
+
sticky = true,
|
|
801
|
+
align = "start"
|
|
802
|
+
}) {
|
|
803
|
+
const { close, canClose, presentation } = useSheetContext();
|
|
804
|
+
const headerBaseClassName = presentation === "fullscreen" ? "router-modal-header" : "router-sheet-header";
|
|
805
|
+
const headerClassName = `${headerBaseClassName}${sticky ? ` ${headerBaseClassName}--sticky` : ""}`;
|
|
806
|
+
const titleClassName = `router-sheet-title${align === "center" ? " router-sheet-title--center" : ""}`;
|
|
807
|
+
return /* @__PURE__ */ jsxs("div", { className: headerClassName, children: [
|
|
808
|
+
leftAction != null && /* @__PURE__ */ jsx("div", { className: "router-sheet-header-side", children: leftAction }),
|
|
809
|
+
title && /* @__PURE__ */ jsx("h2", { className: titleClassName, children: title }),
|
|
810
|
+
!title && /* @__PURE__ */ jsx("div", { className: "router-sheet-header-spacer" }),
|
|
811
|
+
/* @__PURE__ */ jsx("div", { className: "router-sheet-header-side router-sheet-header-side--trailing", children: rightAction ?? (hideCloseButton ? null : /* @__PURE__ */ jsx(RouterCloseButton, { onPress: close, disabled: !canClose })) })
|
|
812
|
+
] });
|
|
813
|
+
}
|
|
814
|
+
function SheetContent({ children, className }) {
|
|
815
|
+
return /* @__PURE__ */ jsx("div", { className: `router-sheet-content ${className ?? ""}`, children });
|
|
816
|
+
}
|
|
817
|
+
function SheetScrollView({ children, className, style }) {
|
|
818
|
+
const { setScrollElement } = useSheetContext();
|
|
819
|
+
const contentKey = useOverlayContentKey();
|
|
820
|
+
const setScopedScrollElement = useCallback(
|
|
821
|
+
(el) => setScrollElement(contentKey, el),
|
|
822
|
+
[contentKey, setScrollElement]
|
|
823
|
+
);
|
|
824
|
+
return /* @__PURE__ */ jsx(
|
|
825
|
+
"div",
|
|
826
|
+
{
|
|
827
|
+
ref: setScopedScrollElement,
|
|
828
|
+
className: `router-scroll router-sheet-scroll-view ${className ?? ""}`,
|
|
829
|
+
style,
|
|
830
|
+
children
|
|
831
|
+
}
|
|
832
|
+
);
|
|
833
|
+
}
|
|
834
|
+
function SheetFooter({ children, className }) {
|
|
835
|
+
const { variant } = useSheetContext();
|
|
836
|
+
const variantClassName = variant === "detached" ? "router-sheet-footer--detached" : "router-sheet-footer--attached";
|
|
837
|
+
return /* @__PURE__ */ jsx(
|
|
838
|
+
"div",
|
|
839
|
+
{
|
|
840
|
+
className: `router-sheet-footer ${variantClassName} ${className ?? ""}`,
|
|
841
|
+
children
|
|
842
|
+
}
|
|
843
|
+
);
|
|
844
|
+
}
|
|
845
|
+
var Sheet = Object.assign(SheetRoot, {
|
|
846
|
+
Header: SheetHeader,
|
|
847
|
+
Content: SheetContent,
|
|
848
|
+
ScrollView: SheetScrollView,
|
|
849
|
+
Footer: SheetFooter
|
|
850
|
+
});
|
|
851
|
+
|
|
852
|
+
// src/navigationHistory.ts
|
|
853
|
+
var MAX_HISTORY_LENGTH = 64;
|
|
854
|
+
function sameLocation(left, right) {
|
|
855
|
+
return left.stackKey === right.stackKey && left.pathname === right.pathname;
|
|
856
|
+
}
|
|
857
|
+
function sameScreenRoute(left, right) {
|
|
858
|
+
return left.stackKey === right.stackKey && left.route.id === right.route.id && left.presentation === right.presentation;
|
|
859
|
+
}
|
|
860
|
+
function latestSnapshots(history) {
|
|
861
|
+
return history.length > MAX_HISTORY_LENGTH ? history.slice(history.length - MAX_HISTORY_LENGTH) : history;
|
|
862
|
+
}
|
|
863
|
+
function updateSnapshotHistory(history, snapshot) {
|
|
864
|
+
const browserIndex = history.findIndex(
|
|
865
|
+
(entry) => entry.historyIndex === snapshot.historyIndex
|
|
866
|
+
);
|
|
867
|
+
const locationIndex = history.findIndex((entry) => sameLocation(entry, snapshot));
|
|
868
|
+
if (snapshot.historyCommit === "replace" && browserIndex !== -1) {
|
|
869
|
+
return latestSnapshots([...history.slice(0, browserIndex), snapshot]);
|
|
870
|
+
}
|
|
871
|
+
if (locationIndex !== -1 && locationIndex !== browserIndex) {
|
|
872
|
+
return latestSnapshots([...history.slice(0, locationIndex), snapshot]);
|
|
873
|
+
}
|
|
874
|
+
if (browserIndex !== -1) {
|
|
875
|
+
return latestSnapshots([...history.slice(0, browserIndex), snapshot]);
|
|
876
|
+
}
|
|
877
|
+
const active = history[history.length - 1];
|
|
878
|
+
if (active && sameScreenRoute(active, snapshot) && snapshot.splitNavigation?.operation !== "push") {
|
|
879
|
+
return latestSnapshots([...history.slice(0, -1), snapshot]);
|
|
880
|
+
}
|
|
881
|
+
const insertIndex = history.findIndex(
|
|
882
|
+
(entry) => entry.historyIndex > snapshot.historyIndex
|
|
883
|
+
);
|
|
884
|
+
const next = insertIndex === -1 ? [...history, snapshot] : [...history.slice(0, insertIndex), snapshot];
|
|
885
|
+
return latestSnapshots(next);
|
|
886
|
+
}
|
|
887
|
+
function previousSnapshotFromHistory(history, snapshot) {
|
|
888
|
+
if (!snapshot) return void 0;
|
|
889
|
+
const currentIndex = history.findIndex(
|
|
890
|
+
(entry) => entry.historyIndex === snapshot.historyIndex
|
|
891
|
+
);
|
|
892
|
+
if (currentIndex <= 0) return void 0;
|
|
893
|
+
return history[currentIndex - 1];
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
// src/utils/id.ts
|
|
897
|
+
function createRouterId() {
|
|
898
|
+
if (typeof globalThis.crypto !== "undefined" && typeof globalThis.crypto.randomUUID === "function") {
|
|
899
|
+
return globalThis.crypto.randomUUID();
|
|
900
|
+
}
|
|
901
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (char) => {
|
|
902
|
+
const value = Math.floor(Math.random() * 16);
|
|
903
|
+
const nibble = char === "x" ? value : value & 3 | 8;
|
|
904
|
+
return nibble.toString(16);
|
|
905
|
+
});
|
|
906
|
+
}
|
|
907
|
+
var STACK_ROUTE_KIND = /* @__PURE__ */ Symbol.for("sigmela.stack.route.kind");
|
|
908
|
+
var HISTORY_INDEX_KEY = "__sigmela_idx";
|
|
909
|
+
var SPLIT_NAVIGATION_KEY = "__sigmela_split_navigation";
|
|
910
|
+
var SPLIT_NAVIGATION_ORIGIN_KEY = "__sigmela_split_navigation_origin";
|
|
911
|
+
var ROUTE_TRANSITION_MS = 300;
|
|
912
|
+
var OVERLAY_STACK_BASE_Z = 60;
|
|
913
|
+
var DEFAULT_SPLIT_MIN_WIDTH = 640;
|
|
914
|
+
var DEFAULT_SPLIT_PRIMARY_MAX_WIDTH = 390;
|
|
915
|
+
var DEFAULT_SPLIT_SECONDARY_MIN_WIDTH = 360;
|
|
916
|
+
var RouterRouteContext = createContext(null);
|
|
917
|
+
var RouterActionsContext = createContext(null);
|
|
918
|
+
var SplitPaneNavigationContext = createContext(null);
|
|
919
|
+
var RouterDrawerContext = createContext(null);
|
|
920
|
+
var CurrentModalContext = createContext(null);
|
|
921
|
+
var REACT_COMPONENT_TYPE_SYMBOLS = /* @__PURE__ */ new Set([
|
|
922
|
+
/* @__PURE__ */ Symbol.for("react.forward_ref"),
|
|
923
|
+
/* @__PURE__ */ Symbol.for("react.lazy"),
|
|
924
|
+
/* @__PURE__ */ Symbol.for("react.memo")
|
|
925
|
+
]);
|
|
926
|
+
var HISTORY_NAVIGATION_KEY = "__sigmela_nav";
|
|
927
|
+
var HISTORY_COMMIT_KEY = "__sigmela_commit";
|
|
928
|
+
var DEFAULT_SHEET_FALLBACK = /* @__PURE__ */ jsx("div", { className: "min-h-[160px]" });
|
|
929
|
+
function splitViewWideMinWidth(minWidth, primaryMaxWidth, secondaryMinWidth = DEFAULT_SPLIT_SECONDARY_MIN_WIDTH) {
|
|
930
|
+
return Math.max(minWidth, primaryMaxWidth + secondaryMinWidth);
|
|
931
|
+
}
|
|
932
|
+
function isRecord(value) {
|
|
933
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
934
|
+
}
|
|
935
|
+
function mutableHistoryState(state) {
|
|
936
|
+
if (isRecord(state)) return { ...state };
|
|
937
|
+
if (state == null) return {};
|
|
938
|
+
return { value: state };
|
|
939
|
+
}
|
|
940
|
+
function splitNavigationFromState(state) {
|
|
941
|
+
if (!isRecord(state)) return void 0;
|
|
942
|
+
const value = state[SPLIT_NAVIGATION_KEY];
|
|
943
|
+
if (!isRecord(value)) return void 0;
|
|
944
|
+
if (typeof value.splitViewId !== "string" || typeof value.detailPathId !== "string" || typeof value.detailDepth !== "number" || value.operation !== "selection" && value.operation !== "push" && value.operation !== "replace") {
|
|
945
|
+
return void 0;
|
|
946
|
+
}
|
|
947
|
+
return {
|
|
948
|
+
splitViewId: value.splitViewId,
|
|
949
|
+
detailPathId: value.detailPathId,
|
|
950
|
+
detailDepth: value.detailDepth,
|
|
951
|
+
operation: value.operation
|
|
952
|
+
};
|
|
953
|
+
}
|
|
954
|
+
function splitNavigationOriginFromState(state) {
|
|
955
|
+
if (!isRecord(state)) return void 0;
|
|
956
|
+
const value = state[SPLIT_NAVIGATION_ORIGIN_KEY];
|
|
957
|
+
if (!isRecord(value)) return void 0;
|
|
958
|
+
if (typeof value.splitViewId !== "string" || value.pane !== "primary" && value.pane !== "secondary" || typeof value.detailPathId !== "string" || typeof value.detailDepth !== "number") {
|
|
959
|
+
return void 0;
|
|
960
|
+
}
|
|
961
|
+
return {
|
|
962
|
+
splitViewId: value.splitViewId,
|
|
963
|
+
pane: value.pane,
|
|
964
|
+
detailPathId: value.detailPathId,
|
|
965
|
+
detailDepth: value.detailDepth
|
|
966
|
+
};
|
|
967
|
+
}
|
|
968
|
+
function stateWithSplitNavigationOrigin(state, origin) {
|
|
969
|
+
const next = mutableHistoryState(state);
|
|
970
|
+
next[SPLIT_NAVIGATION_ORIGIN_KEY] = origin;
|
|
971
|
+
return next;
|
|
972
|
+
}
|
|
973
|
+
function stateWithoutSplitNavigation(state) {
|
|
974
|
+
const next = mutableHistoryState(state);
|
|
975
|
+
delete next[SPLIT_NAVIGATION_KEY];
|
|
976
|
+
delete next[SPLIT_NAVIGATION_ORIGIN_KEY];
|
|
977
|
+
return next;
|
|
978
|
+
}
|
|
979
|
+
function historyIndexFromState(state) {
|
|
980
|
+
if (isRecord(state) && typeof state[HISTORY_INDEX_KEY] === "number") {
|
|
981
|
+
return state[HISTORY_INDEX_KEY];
|
|
982
|
+
}
|
|
983
|
+
if (isRecord(state) && typeof state.idx === "number") {
|
|
984
|
+
return state.idx;
|
|
985
|
+
}
|
|
986
|
+
return 0;
|
|
987
|
+
}
|
|
988
|
+
function historyNavigationKeyFromState(state) {
|
|
989
|
+
if (isRecord(state) && typeof state[HISTORY_NAVIGATION_KEY] === "string") {
|
|
990
|
+
return state[HISTORY_NAVIGATION_KEY];
|
|
991
|
+
}
|
|
992
|
+
return null;
|
|
993
|
+
}
|
|
994
|
+
function historyCommitFromState(state) {
|
|
995
|
+
if (isRecord(state)) {
|
|
996
|
+
const commit = state[HISTORY_COMMIT_KEY];
|
|
997
|
+
if (commit === "sync" || commit === "replace") return commit;
|
|
998
|
+
}
|
|
999
|
+
return "push";
|
|
1000
|
+
}
|
|
1001
|
+
function stateWithHistoryIndex(state, index, navigationKey = createRouterId(), commit = "push") {
|
|
1002
|
+
const next = isRecord(state) ? { ...state } : state == null ? {} : { value: state };
|
|
1003
|
+
next[HISTORY_INDEX_KEY] = index;
|
|
1004
|
+
next[HISTORY_NAVIGATION_KEY] = navigationKey;
|
|
1005
|
+
next[HISTORY_COMMIT_KEY] = commit;
|
|
1006
|
+
return next;
|
|
1007
|
+
}
|
|
1008
|
+
function navigateWithHistoryIndex(to, options = {}) {
|
|
1009
|
+
const { commit = "push", ...navigationOptions } = options;
|
|
1010
|
+
const currentState = window.history.state;
|
|
1011
|
+
const currentIndex = historyIndexFromState(currentState);
|
|
1012
|
+
const isSyncCommit = commit === "sync";
|
|
1013
|
+
const replacesBrowserEntry = commit !== "push";
|
|
1014
|
+
const nextIndex = replacesBrowserEntry ? currentIndex : currentIndex + 1;
|
|
1015
|
+
const currentNavigationKey = historyNavigationKeyFromState(currentState);
|
|
1016
|
+
const nextNavigationKey = isSyncCommit ? historyNavigationKeyFromState(options.state) ?? currentNavigationKey ?? createRouterId() : replacesBrowserEntry ? currentNavigationKey ?? createRouterId() : createRouterId();
|
|
1017
|
+
navigate(to, {
|
|
1018
|
+
...navigationOptions,
|
|
1019
|
+
replace: replacesBrowserEntry,
|
|
1020
|
+
state: stateWithHistoryIndex(options.state, nextIndex, nextNavigationKey, commit)
|
|
1021
|
+
});
|
|
1022
|
+
}
|
|
1023
|
+
function ensureInitialHistoryIndex() {
|
|
1024
|
+
const currentState = window.history.state;
|
|
1025
|
+
const hasIndex = isRecord(currentState) && typeof currentState[HISTORY_INDEX_KEY] === "number";
|
|
1026
|
+
const currentNavigationKey = historyNavigationKeyFromState(currentState);
|
|
1027
|
+
if (hasIndex && currentNavigationKey) return;
|
|
1028
|
+
window.history.replaceState(
|
|
1029
|
+
stateWithHistoryIndex(
|
|
1030
|
+
currentState,
|
|
1031
|
+
historyIndexFromState(currentState),
|
|
1032
|
+
currentNavigationKey ?? createRouterId()
|
|
1033
|
+
),
|
|
1034
|
+
"",
|
|
1035
|
+
window.location.href
|
|
1036
|
+
);
|
|
1037
|
+
}
|
|
1038
|
+
function normalizedPath(pathname) {
|
|
1039
|
+
if (pathname === "/") return "/";
|
|
1040
|
+
return pathname.replace(/\/+$/, "") || "/";
|
|
1041
|
+
}
|
|
1042
|
+
function routeDepth(pathname) {
|
|
1043
|
+
const path = normalizedPath(pathname);
|
|
1044
|
+
if (path === "/") return 0;
|
|
1045
|
+
return path.split("/").filter(Boolean).length;
|
|
1046
|
+
}
|
|
1047
|
+
function joinRoutePath(parentPath, childPath) {
|
|
1048
|
+
if (childPath == null || childPath === "") return parentPath;
|
|
1049
|
+
if (childPath === "*") return "*";
|
|
1050
|
+
if (childPath.startsWith("/")) return normalizedPath(childPath);
|
|
1051
|
+
if (!parentPath || parentPath === "/") return normalizedPath(`/${childPath}`);
|
|
1052
|
+
return normalizedPath(`${parentPath}/${childPath}`);
|
|
1053
|
+
}
|
|
1054
|
+
function routeComponent(presentation, container) {
|
|
1055
|
+
return Object.assign(
|
|
1056
|
+
function RouterRouteComponent(_props) {
|
|
1057
|
+
return null;
|
|
1058
|
+
},
|
|
1059
|
+
{ [STACK_ROUTE_KIND]: { presentation, container } }
|
|
1060
|
+
);
|
|
1061
|
+
}
|
|
1062
|
+
function routeDescriptorFromElement(element) {
|
|
1063
|
+
const type = element.type;
|
|
1064
|
+
const descriptor = type[STACK_ROUTE_KIND];
|
|
1065
|
+
if (!descriptor) return null;
|
|
1066
|
+
if (typeof descriptor === "string") return { presentation: descriptor };
|
|
1067
|
+
return descriptor;
|
|
1068
|
+
}
|
|
1069
|
+
function isStackRouteElement(node) {
|
|
1070
|
+
return isValidElement(node) && routeDescriptorFromElement(node) != null;
|
|
1071
|
+
}
|
|
1072
|
+
function isTabBarItemElement(node) {
|
|
1073
|
+
return isValidElement(node) && routeDescriptorFromElement(node)?.container === "tabbar-item";
|
|
1074
|
+
}
|
|
1075
|
+
function isDrawerItemElement(node) {
|
|
1076
|
+
return isValidElement(node) && routeDescriptorFromElement(node)?.container === "drawer-item";
|
|
1077
|
+
}
|
|
1078
|
+
function isDrawerGroupElement(node) {
|
|
1079
|
+
return isValidElement(node) && routeDescriptorFromElement(node)?.container === "drawer-group";
|
|
1080
|
+
}
|
|
1081
|
+
function isDrawerSectionElement(node) {
|
|
1082
|
+
return isValidElement(node) && routeDescriptorFromElement(node)?.container === "drawer-section";
|
|
1083
|
+
}
|
|
1084
|
+
function isSplitPrimaryElement(node) {
|
|
1085
|
+
return isValidElement(node) && routeDescriptorFromElement(node)?.container === "split-primary";
|
|
1086
|
+
}
|
|
1087
|
+
function isSplitSecondaryElement(node) {
|
|
1088
|
+
return isValidElement(node) && routeDescriptorFromElement(node)?.container === "split-secondary";
|
|
1089
|
+
}
|
|
1090
|
+
function isProtectedElement(node) {
|
|
1091
|
+
return isValidElement(node) && routeDescriptorFromElement(node)?.container === "protected";
|
|
1092
|
+
}
|
|
1093
|
+
function isRedirectElement(node) {
|
|
1094
|
+
return isValidElement(node) && routeDescriptorFromElement(node)?.container === "redirect";
|
|
1095
|
+
}
|
|
1096
|
+
function isElementType(value) {
|
|
1097
|
+
if (isValidElement(value)) return false;
|
|
1098
|
+
if (typeof value === "function") return true;
|
|
1099
|
+
if (typeof value !== "object" || value === null) return false;
|
|
1100
|
+
const reactType = value.$$typeof;
|
|
1101
|
+
return reactType ? REACT_COMPONENT_TYPE_SYMBOLS.has(reactType) : false;
|
|
1102
|
+
}
|
|
1103
|
+
function flattenRouteNodes(children) {
|
|
1104
|
+
const result = [];
|
|
1105
|
+
Children.forEach(children, (child) => {
|
|
1106
|
+
if (isValidElement(child) && child.type === Fragment$1) {
|
|
1107
|
+
result.push(...flattenRouteNodes(child.props.children));
|
|
1108
|
+
return;
|
|
1109
|
+
}
|
|
1110
|
+
result.push(child);
|
|
1111
|
+
});
|
|
1112
|
+
return result;
|
|
1113
|
+
}
|
|
1114
|
+
function splitRouteChildren(children) {
|
|
1115
|
+
if (typeof children === "function") {
|
|
1116
|
+
return { routeChildren: [], renderChildren: children };
|
|
1117
|
+
}
|
|
1118
|
+
const childArray = flattenRouteNodes(children);
|
|
1119
|
+
const routeChildren = [];
|
|
1120
|
+
const nonRouteChildren = [];
|
|
1121
|
+
for (const child of childArray) {
|
|
1122
|
+
if (isStackRouteElement(child)) {
|
|
1123
|
+
routeChildren.push(child);
|
|
1124
|
+
} else {
|
|
1125
|
+
nonRouteChildren.push(child);
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
1128
|
+
if (routeChildren.length === 0) {
|
|
1129
|
+
return { routeChildren, renderChildren: children };
|
|
1130
|
+
}
|
|
1131
|
+
return {
|
|
1132
|
+
routeChildren,
|
|
1133
|
+
renderChildren: nonRouteChildren.length > 0 ? nonRouteChildren : void 0
|
|
1134
|
+
};
|
|
1135
|
+
}
|
|
1136
|
+
function drawerItemFromElement(element, parentPath) {
|
|
1137
|
+
const itemPath = joinRoutePath(parentPath, element.props.path) ?? "/";
|
|
1138
|
+
return {
|
|
1139
|
+
type: "item",
|
|
1140
|
+
id: element.props.id ?? normalizedPath(itemPath),
|
|
1141
|
+
path: itemPath,
|
|
1142
|
+
label: element.props.label,
|
|
1143
|
+
icon: element.props.icon,
|
|
1144
|
+
badge: element.props.badge,
|
|
1145
|
+
hidden: element.props.hidden
|
|
1146
|
+
};
|
|
1147
|
+
}
|
|
1148
|
+
function collectDrawerNavigation(routeChildren, parentPath, parentId) {
|
|
1149
|
+
const nodes = [];
|
|
1150
|
+
const entries = [];
|
|
1151
|
+
routeChildren.forEach((child, index) => {
|
|
1152
|
+
if (isDrawerSectionElement(child)) {
|
|
1153
|
+
nodes.push({
|
|
1154
|
+
type: "section",
|
|
1155
|
+
id: child.props.id ?? `${parentId}/drawer-section-${index}`,
|
|
1156
|
+
title: child.props.title,
|
|
1157
|
+
hidden: child.props.hidden
|
|
1158
|
+
});
|
|
1159
|
+
return;
|
|
1160
|
+
}
|
|
1161
|
+
if (isDrawerItemElement(child)) {
|
|
1162
|
+
const item = drawerItemFromElement(child, parentPath);
|
|
1163
|
+
nodes.push(item);
|
|
1164
|
+
entries.push({ element: child, item });
|
|
1165
|
+
return;
|
|
1166
|
+
}
|
|
1167
|
+
if (!isDrawerGroupElement(child)) return;
|
|
1168
|
+
const groupChildren = splitRouteChildren(child.props.children).routeChildren;
|
|
1169
|
+
const groupEntries = groupChildren.filter(isDrawerItemElement).map((element) => {
|
|
1170
|
+
const item = drawerItemFromElement(element, parentPath);
|
|
1171
|
+
return { element, item };
|
|
1172
|
+
});
|
|
1173
|
+
if (groupEntries.length === 0) return;
|
|
1174
|
+
nodes.push({
|
|
1175
|
+
type: "group",
|
|
1176
|
+
id: child.props.id ?? `${parentId}/drawer-group-${index}`,
|
|
1177
|
+
label: child.props.label,
|
|
1178
|
+
icon: child.props.icon,
|
|
1179
|
+
chevron: child.props.chevron,
|
|
1180
|
+
hidden: child.props.hidden,
|
|
1181
|
+
items: groupEntries.map((entry) => entry.item)
|
|
1182
|
+
});
|
|
1183
|
+
entries.push(...groupEntries);
|
|
1184
|
+
});
|
|
1185
|
+
return { nodes, entries };
|
|
1186
|
+
}
|
|
1187
|
+
function compiledRouteFromProps(props, path, routeId, presentation, animation, renderChildren, inheritedGuards) {
|
|
1188
|
+
const elementType = props.element !== void 0 && isElementType(props.element) ? props.element : void 0;
|
|
1189
|
+
const elementNode = props.element !== void 0 && !elementType ? props.element : void 0;
|
|
1190
|
+
const hasRenderable = props.element !== void 0 || props.component !== void 0 || renderChildren !== void 0;
|
|
1191
|
+
if (!hasRenderable) return null;
|
|
1192
|
+
return {
|
|
1193
|
+
id: routeId,
|
|
1194
|
+
path,
|
|
1195
|
+
presentation,
|
|
1196
|
+
animation,
|
|
1197
|
+
overlayLayout: props.overlayLayout,
|
|
1198
|
+
guards: inheritedGuards,
|
|
1199
|
+
stackKey: props.stackKey,
|
|
1200
|
+
fallback: props.fallback,
|
|
1201
|
+
element: elementNode,
|
|
1202
|
+
elementType,
|
|
1203
|
+
component: props.component,
|
|
1204
|
+
layout: props.layout,
|
|
1205
|
+
render: typeof renderChildren === "function" ? renderChildren : void 0,
|
|
1206
|
+
childrenNode: typeof renderChildren === "function" ? void 0 : renderChildren
|
|
1207
|
+
};
|
|
1208
|
+
}
|
|
1209
|
+
function compileStackRoutes(children, parentPath, parentId = "root", inheritedGuards = []) {
|
|
1210
|
+
const routes = [];
|
|
1211
|
+
flattenRouteNodes(children).forEach((child, index) => {
|
|
1212
|
+
if (!isStackRouteElement(child)) return;
|
|
1213
|
+
const descriptor = routeDescriptorFromElement(child) ?? { presentation: "push" };
|
|
1214
|
+
const presentation = descriptor.presentation;
|
|
1215
|
+
const props = child.props;
|
|
1216
|
+
const animation = props.animation ?? "push";
|
|
1217
|
+
const path = joinRoutePath(parentPath, props.path);
|
|
1218
|
+
const { routeChildren, renderChildren } = splitRouteChildren(props.children);
|
|
1219
|
+
const routeId = props.id ?? `${parentId}/${index}:${path ?? "*"}:${presentation}`;
|
|
1220
|
+
if (isRedirectElement(child)) {
|
|
1221
|
+
routes.push({
|
|
1222
|
+
id: routeId,
|
|
1223
|
+
path,
|
|
1224
|
+
presentation,
|
|
1225
|
+
animation,
|
|
1226
|
+
overlayLayout: props.overlayLayout,
|
|
1227
|
+
redirectTo: child.props.to,
|
|
1228
|
+
guards: inheritedGuards,
|
|
1229
|
+
stackKey: props.stackKey,
|
|
1230
|
+
fallback: props.fallback
|
|
1231
|
+
});
|
|
1232
|
+
return;
|
|
1233
|
+
}
|
|
1234
|
+
if (isProtectedElement(child)) {
|
|
1235
|
+
const guard = {
|
|
1236
|
+
id: props.id ?? routeId,
|
|
1237
|
+
when: child.props.when,
|
|
1238
|
+
redirectTo: child.props.redirectTo
|
|
1239
|
+
};
|
|
1240
|
+
if (routeChildren.length > 0) {
|
|
1241
|
+
routes.push(
|
|
1242
|
+
...compileStackRoutes(routeChildren, path, routeId, [
|
|
1243
|
+
...inheritedGuards,
|
|
1244
|
+
guard
|
|
1245
|
+
])
|
|
1246
|
+
);
|
|
1247
|
+
}
|
|
1248
|
+
return;
|
|
1249
|
+
}
|
|
1250
|
+
const elementType = props.element !== void 0 && isElementType(props.element) ? props.element : void 0;
|
|
1251
|
+
const elementNode = props.element !== void 0 && !elementType ? props.element : void 0;
|
|
1252
|
+
const hasRenderable = props.element !== void 0 || props.component !== void 0 || renderChildren !== void 0;
|
|
1253
|
+
if (isModalLikePresentation(presentation) && routeChildren.length > 0) {
|
|
1254
|
+
const compiledChildren2 = compileStackRoutes(
|
|
1255
|
+
routeChildren,
|
|
1256
|
+
path,
|
|
1257
|
+
routeId,
|
|
1258
|
+
inheritedGuards
|
|
1259
|
+
);
|
|
1260
|
+
const nestedOverlays = compiledChildren2.filter(
|
|
1261
|
+
(route) => route.presentation !== "push"
|
|
1262
|
+
);
|
|
1263
|
+
const flowRoutes = [];
|
|
1264
|
+
const rootRoute = compiledRouteFromProps(
|
|
1265
|
+
props,
|
|
1266
|
+
path,
|
|
1267
|
+
`${routeId}/overlay-root`,
|
|
1268
|
+
"push",
|
|
1269
|
+
animation,
|
|
1270
|
+
renderChildren,
|
|
1271
|
+
inheritedGuards
|
|
1272
|
+
);
|
|
1273
|
+
if (rootRoute) flowRoutes.push(rootRoute);
|
|
1274
|
+
flowRoutes.push(
|
|
1275
|
+
...compiledChildren2.filter((route) => route.presentation === "push")
|
|
1276
|
+
);
|
|
1277
|
+
routes.push(...nestedOverlays);
|
|
1278
|
+
if (flowRoutes.length === 0) return;
|
|
1279
|
+
const overlayFlow = {
|
|
1280
|
+
id: `${routeId}/overlay-flow`,
|
|
1281
|
+
kind: presentation,
|
|
1282
|
+
routes: flowRoutes
|
|
1283
|
+
};
|
|
1284
|
+
for (const flowRoute of flowRoutes) {
|
|
1285
|
+
routes.push({
|
|
1286
|
+
id: `${overlayFlow.id}:${flowRoute.id}`,
|
|
1287
|
+
path: flowRoute.path,
|
|
1288
|
+
presentation,
|
|
1289
|
+
animation,
|
|
1290
|
+
overlayLayout: props.overlayLayout,
|
|
1291
|
+
redirectTo: flowRoute.redirectTo,
|
|
1292
|
+
guards: flowRoute.guards,
|
|
1293
|
+
stackKey: props.stackKey ?? routeId,
|
|
1294
|
+
fallback: flowRoute.fallback ?? props.fallback,
|
|
1295
|
+
childRoute: flowRoute,
|
|
1296
|
+
overlayFlow
|
|
1297
|
+
});
|
|
1298
|
+
}
|
|
1299
|
+
return;
|
|
1300
|
+
}
|
|
1301
|
+
if (descriptor.container === "splitview") {
|
|
1302
|
+
const primarySlot = routeChildren.find(isSplitPrimaryElement);
|
|
1303
|
+
const secondarySlot = routeChildren.find(isSplitSecondaryElement);
|
|
1304
|
+
const compileSplitSlot = (slot, slotName) => {
|
|
1305
|
+
if (!slot) return [];
|
|
1306
|
+
const slotProps = slot.props;
|
|
1307
|
+
const slotPath = joinRoutePath(path, slotProps.path);
|
|
1308
|
+
const { routeChildren: slotRouteChildren, renderChildren: slotRenderChildren } = splitRouteChildren(slotProps.children);
|
|
1309
|
+
const slotRouteId = slotProps.id ?? `${routeId}/${slotName}`;
|
|
1310
|
+
const slotAnimation = slotProps.animation ?? "push";
|
|
1311
|
+
const slotRoutes = [];
|
|
1312
|
+
const slotOwnRoute = compiledRouteFromProps(
|
|
1313
|
+
slotProps,
|
|
1314
|
+
slotPath,
|
|
1315
|
+
slotRouteId,
|
|
1316
|
+
presentation,
|
|
1317
|
+
slotAnimation,
|
|
1318
|
+
slotRenderChildren,
|
|
1319
|
+
inheritedGuards
|
|
1320
|
+
);
|
|
1321
|
+
if (slotOwnRoute) {
|
|
1322
|
+
slotRoutes.push(slotOwnRoute);
|
|
1323
|
+
}
|
|
1324
|
+
if (slotRouteChildren.length > 0) {
|
|
1325
|
+
slotRoutes.push(
|
|
1326
|
+
...compileStackRoutes(
|
|
1327
|
+
slotRouteChildren,
|
|
1328
|
+
slotPath,
|
|
1329
|
+
slotRouteId,
|
|
1330
|
+
inheritedGuards
|
|
1331
|
+
)
|
|
1332
|
+
);
|
|
1333
|
+
}
|
|
1334
|
+
return slotRoutes;
|
|
1335
|
+
};
|
|
1336
|
+
const primaryRoutes = compileSplitSlot(primarySlot, "primary");
|
|
1337
|
+
const secondaryRoutes = compileSplitSlot(secondarySlot, "secondary");
|
|
1338
|
+
for (const splitChildRoute of [...primaryRoutes, ...secondaryRoutes]) {
|
|
1339
|
+
if (splitChildRoute.presentation !== "push") {
|
|
1340
|
+
routes.push(splitChildRoute);
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
const primaryPushRoutes = primaryRoutes.filter(
|
|
1344
|
+
(route) => route.presentation === "push"
|
|
1345
|
+
);
|
|
1346
|
+
const secondaryPushRoutes = secondaryRoutes.filter(
|
|
1347
|
+
(route) => route.presentation === "push"
|
|
1348
|
+
);
|
|
1349
|
+
const defaultPrimaryRoute = primaryPushRoutes[0];
|
|
1350
|
+
if (!defaultPrimaryRoute) {
|
|
1351
|
+
return;
|
|
1352
|
+
}
|
|
1353
|
+
const minWidth = props.minWidth ?? DEFAULT_SPLIT_MIN_WIDTH;
|
|
1354
|
+
const primaryMaxWidth = props.primaryMaxWidth ?? DEFAULT_SPLIT_PRIMARY_MAX_WIDTH;
|
|
1355
|
+
const secondaryMinWidth = props.secondaryMinWidth ?? DEFAULT_SPLIT_SECONDARY_MIN_WIDTH;
|
|
1356
|
+
const wideMinWidth = splitViewWideMinWidth(
|
|
1357
|
+
minWidth,
|
|
1358
|
+
primaryMaxWidth,
|
|
1359
|
+
secondaryMinWidth
|
|
1360
|
+
);
|
|
1361
|
+
const splitViewLayoutId = `${routeId}/splitview`;
|
|
1362
|
+
for (const primaryRoute of primaryPushRoutes) {
|
|
1363
|
+
routes.push({
|
|
1364
|
+
id: `${routeId}/splitview:primary:${primaryRoute.id}`,
|
|
1365
|
+
path: primaryRoute.path,
|
|
1366
|
+
presentation: primaryRoute.presentation,
|
|
1367
|
+
animation: primaryRoute.animation,
|
|
1368
|
+
overlayLayout: primaryRoute.overlayLayout,
|
|
1369
|
+
guards: primaryRoute.guards,
|
|
1370
|
+
stackKey: props.stackKey ?? routeId,
|
|
1371
|
+
fallback: primaryRoute.fallback ?? props.fallback,
|
|
1372
|
+
element: elementNode,
|
|
1373
|
+
elementType,
|
|
1374
|
+
component: props.component,
|
|
1375
|
+
layout: props.layout,
|
|
1376
|
+
render: typeof renderChildren === "function" ? renderChildren : void 0,
|
|
1377
|
+
childrenNode: typeof renderChildren === "function" ? void 0 : renderChildren,
|
|
1378
|
+
container: descriptor.container,
|
|
1379
|
+
childRoute: primaryRoute,
|
|
1380
|
+
splitView: {
|
|
1381
|
+
primaryRoute,
|
|
1382
|
+
secondaryRoutes: secondaryPushRoutes,
|
|
1383
|
+
activePane: "primary",
|
|
1384
|
+
minWidth,
|
|
1385
|
+
primaryMaxWidth,
|
|
1386
|
+
secondaryMinWidth,
|
|
1387
|
+
wideMinWidth,
|
|
1388
|
+
layoutId: splitViewLayoutId
|
|
1389
|
+
}
|
|
1390
|
+
});
|
|
1391
|
+
}
|
|
1392
|
+
for (const secondaryRoute of secondaryPushRoutes) {
|
|
1393
|
+
routes.push({
|
|
1394
|
+
id: `${routeId}/splitview:secondary:${secondaryRoute.id}`,
|
|
1395
|
+
path: secondaryRoute.path,
|
|
1396
|
+
presentation: secondaryRoute.presentation,
|
|
1397
|
+
animation: secondaryRoute.animation,
|
|
1398
|
+
overlayLayout: secondaryRoute.overlayLayout,
|
|
1399
|
+
guards: secondaryRoute.guards,
|
|
1400
|
+
stackKey: props.stackKey ?? routeId,
|
|
1401
|
+
fallback: secondaryRoute.fallback ?? props.fallback,
|
|
1402
|
+
element: elementNode,
|
|
1403
|
+
elementType,
|
|
1404
|
+
component: props.component,
|
|
1405
|
+
layout: props.layout,
|
|
1406
|
+
render: typeof renderChildren === "function" ? renderChildren : void 0,
|
|
1407
|
+
childrenNode: typeof renderChildren === "function" ? void 0 : renderChildren,
|
|
1408
|
+
container: descriptor.container,
|
|
1409
|
+
childRoute: secondaryRoute,
|
|
1410
|
+
splitView: {
|
|
1411
|
+
primaryRoute: defaultPrimaryRoute,
|
|
1412
|
+
secondaryRoute,
|
|
1413
|
+
secondaryRoutes: secondaryPushRoutes,
|
|
1414
|
+
activePane: "secondary",
|
|
1415
|
+
minWidth,
|
|
1416
|
+
primaryMaxWidth,
|
|
1417
|
+
secondaryMinWidth,
|
|
1418
|
+
wideMinWidth,
|
|
1419
|
+
layoutId: splitViewLayoutId
|
|
1420
|
+
}
|
|
1421
|
+
});
|
|
1422
|
+
}
|
|
1423
|
+
return;
|
|
1424
|
+
}
|
|
1425
|
+
if (descriptor.container === "tabbar" || descriptor.container === "drawer") {
|
|
1426
|
+
const isTabBar = descriptor.container === "tabbar";
|
|
1427
|
+
const drawerNavigation = isTabBar ? null : collectDrawerNavigation(routeChildren, path, routeId);
|
|
1428
|
+
const navigationItems = isTabBar ? routeChildren.filter(isTabBarItemElement) : drawerNavigation.entries.map((entry) => entry.element);
|
|
1429
|
+
if (navigationItems.length > 0) {
|
|
1430
|
+
const tabs = isTabBar ? navigationItems.map((item) => {
|
|
1431
|
+
const itemPath = joinRoutePath(path, item.props.path) ?? "/";
|
|
1432
|
+
return {
|
|
1433
|
+
id: item.props.id ?? normalizedPath(itemPath),
|
|
1434
|
+
path: itemPath,
|
|
1435
|
+
label: item.props.label,
|
|
1436
|
+
icon: item.props.icon
|
|
1437
|
+
};
|
|
1438
|
+
}) : void 0;
|
|
1439
|
+
const drawerItems = drawerNavigation?.nodes;
|
|
1440
|
+
navigationItems.forEach((item, itemIndex) => {
|
|
1441
|
+
const itemProps = item.props;
|
|
1442
|
+
const itemPath = joinRoutePath(path, itemProps.path);
|
|
1443
|
+
const navigationItem = isTabBar ? tabs?.[itemIndex] : drawerNavigation?.entries[itemIndex]?.item;
|
|
1444
|
+
if (!navigationItem) return;
|
|
1445
|
+
const { routeChildren: itemRouteChildren, renderChildren: itemRenderChildren } = splitRouteChildren(itemProps.children);
|
|
1446
|
+
const itemRouteId = itemProps.id ?? `${routeId}/${descriptor.container}-${itemIndex}:${itemPath ?? "*"}:push`;
|
|
1447
|
+
const itemAnimation = itemProps.animation ?? "push";
|
|
1448
|
+
const itemElementType = itemProps.element !== void 0 && isElementType(itemProps.element) ? itemProps.element : void 0;
|
|
1449
|
+
const itemElementNode = itemProps.element !== void 0 && !itemElementType ? itemProps.element : void 0;
|
|
1450
|
+
const itemHasRenderable = itemProps.element !== void 0 || itemProps.component !== void 0 || itemRenderChildren !== void 0;
|
|
1451
|
+
const itemChildRoutes = [];
|
|
1452
|
+
if (itemHasRenderable) {
|
|
1453
|
+
itemChildRoutes.push({
|
|
1454
|
+
id: itemRouteId,
|
|
1455
|
+
path: itemPath,
|
|
1456
|
+
presentation,
|
|
1457
|
+
animation: itemAnimation,
|
|
1458
|
+
overlayLayout: itemProps.overlayLayout,
|
|
1459
|
+
guards: inheritedGuards,
|
|
1460
|
+
stackKey: itemProps.stackKey,
|
|
1461
|
+
fallback: itemProps.fallback,
|
|
1462
|
+
element: itemElementNode,
|
|
1463
|
+
elementType: itemElementType,
|
|
1464
|
+
component: itemProps.component,
|
|
1465
|
+
layout: itemProps.layout,
|
|
1466
|
+
render: typeof itemRenderChildren === "function" ? itemRenderChildren : void 0,
|
|
1467
|
+
childrenNode: typeof itemRenderChildren === "function" ? void 0 : itemRenderChildren
|
|
1468
|
+
});
|
|
1469
|
+
}
|
|
1470
|
+
if (itemRouteChildren.length > 0) {
|
|
1471
|
+
itemChildRoutes.push(
|
|
1472
|
+
...compileStackRoutes(
|
|
1473
|
+
itemRouteChildren,
|
|
1474
|
+
itemPath,
|
|
1475
|
+
itemRouteId,
|
|
1476
|
+
inheritedGuards
|
|
1477
|
+
)
|
|
1478
|
+
);
|
|
1479
|
+
}
|
|
1480
|
+
for (const childRoute of itemChildRoutes) {
|
|
1481
|
+
if (childRoute.presentation !== "push") {
|
|
1482
|
+
routes.push(childRoute);
|
|
1483
|
+
continue;
|
|
1484
|
+
}
|
|
1485
|
+
const containerRoute = {
|
|
1486
|
+
id: `${routeId}/${descriptor.container}:${navigationItem.id}:${childRoute.id}`,
|
|
1487
|
+
path: childRoute.path,
|
|
1488
|
+
presentation: childRoute.presentation,
|
|
1489
|
+
animation: childRoute.animation,
|
|
1490
|
+
overlayLayout: childRoute.overlayLayout,
|
|
1491
|
+
guards: childRoute.guards,
|
|
1492
|
+
stackKey: props.stackKey ?? routeId,
|
|
1493
|
+
fallback: childRoute.fallback ?? props.fallback,
|
|
1494
|
+
element: elementNode,
|
|
1495
|
+
elementType,
|
|
1496
|
+
component: props.component,
|
|
1497
|
+
layout: props.layout,
|
|
1498
|
+
render: typeof renderChildren === "function" ? renderChildren : void 0,
|
|
1499
|
+
childrenNode: typeof renderChildren === "function" ? void 0 : renderChildren,
|
|
1500
|
+
container: descriptor.container,
|
|
1501
|
+
childRoute,
|
|
1502
|
+
drawerAside: isTabBar ? void 0 : props.aside,
|
|
1503
|
+
drawerFooter: isTabBar ? void 0 : props.footer
|
|
1504
|
+
};
|
|
1505
|
+
if (isTabBar && tabs) {
|
|
1506
|
+
containerRoute.tabBar = {
|
|
1507
|
+
tabs,
|
|
1508
|
+
activeTab: navigationItem.id
|
|
1509
|
+
};
|
|
1510
|
+
} else if (!isTabBar && drawerItems) {
|
|
1511
|
+
containerRoute.drawer = {
|
|
1512
|
+
items: drawerItems,
|
|
1513
|
+
activeItem: navigationItem.id
|
|
1514
|
+
};
|
|
1515
|
+
}
|
|
1516
|
+
routes.push(containerRoute);
|
|
1517
|
+
}
|
|
1518
|
+
});
|
|
1519
|
+
return;
|
|
1520
|
+
}
|
|
1521
|
+
const compiledChildren2 = routeChildren.length > 0 ? compileStackRoutes(routeChildren, path, routeId, inheritedGuards) : [];
|
|
1522
|
+
for (const childRoute of compiledChildren2) {
|
|
1523
|
+
if (childRoute.presentation !== "push") {
|
|
1524
|
+
routes.push(childRoute);
|
|
1525
|
+
continue;
|
|
1526
|
+
}
|
|
1527
|
+
routes.push({
|
|
1528
|
+
id: routeId,
|
|
1529
|
+
path: childRoute.path,
|
|
1530
|
+
presentation,
|
|
1531
|
+
animation: childRoute.animation,
|
|
1532
|
+
overlayLayout: childRoute.overlayLayout,
|
|
1533
|
+
guards: childRoute.guards,
|
|
1534
|
+
stackKey: props.stackKey ?? routeId,
|
|
1535
|
+
fallback: childRoute.fallback ?? props.fallback,
|
|
1536
|
+
element: elementNode,
|
|
1537
|
+
elementType,
|
|
1538
|
+
component: props.component,
|
|
1539
|
+
layout: props.layout,
|
|
1540
|
+
render: typeof renderChildren === "function" ? renderChildren : void 0,
|
|
1541
|
+
childrenNode: typeof renderChildren === "function" ? void 0 : renderChildren,
|
|
1542
|
+
container: descriptor.container,
|
|
1543
|
+
childRoute
|
|
1544
|
+
});
|
|
1545
|
+
}
|
|
1546
|
+
return;
|
|
1547
|
+
}
|
|
1548
|
+
if (descriptor.container === "tabbar-item" || descriptor.container === "drawer-group" || descriptor.container === "drawer-section" || descriptor.container === "drawer-item" || descriptor.container === "split-primary" || descriptor.container === "split-secondary") {
|
|
1549
|
+
return;
|
|
1550
|
+
}
|
|
1551
|
+
const compiledChildren = routeChildren.length > 0 ? compileStackRoutes(routeChildren, path, routeId, inheritedGuards) : [];
|
|
1552
|
+
if (hasRenderable) {
|
|
1553
|
+
routes.push({
|
|
1554
|
+
id: routeId,
|
|
1555
|
+
path,
|
|
1556
|
+
presentation,
|
|
1557
|
+
animation,
|
|
1558
|
+
overlayLayout: props.overlayLayout,
|
|
1559
|
+
guards: inheritedGuards,
|
|
1560
|
+
stackKey: props.stackKey,
|
|
1561
|
+
fallback: props.fallback,
|
|
1562
|
+
element: elementNode,
|
|
1563
|
+
elementType,
|
|
1564
|
+
component: props.component,
|
|
1565
|
+
layout: props.layout,
|
|
1566
|
+
render: typeof renderChildren === "function" ? renderChildren : void 0,
|
|
1567
|
+
childrenNode: typeof renderChildren === "function" ? void 0 : renderChildren
|
|
1568
|
+
});
|
|
1569
|
+
}
|
|
1570
|
+
if (compiledChildren.length > 0) {
|
|
1571
|
+
routes.push(...compiledChildren);
|
|
1572
|
+
}
|
|
1573
|
+
});
|
|
1574
|
+
return routes;
|
|
1575
|
+
}
|
|
1576
|
+
function matchStackRouteByPresentation(routes, parser, pathname, presentations) {
|
|
1577
|
+
for (const route of routes) {
|
|
1578
|
+
if (!presentations.has(route.presentation)) continue;
|
|
1579
|
+
const [matches, params] = matchRoute(parser, route.path ?? "*", pathname);
|
|
1580
|
+
if (matches) {
|
|
1581
|
+
return {
|
|
1582
|
+
route,
|
|
1583
|
+
params: { ...params }
|
|
1584
|
+
};
|
|
1585
|
+
}
|
|
1586
|
+
}
|
|
1587
|
+
return null;
|
|
1588
|
+
}
|
|
1589
|
+
function splitViewRouteForCompiledRoute(route) {
|
|
1590
|
+
if (route?.container === "splitview" && route.splitView) return route;
|
|
1591
|
+
if (route?.childRoute?.container === "splitview" && route.childRoute.splitView) {
|
|
1592
|
+
return route.childRoute;
|
|
1593
|
+
}
|
|
1594
|
+
return void 0;
|
|
1595
|
+
}
|
|
1596
|
+
function stateForSplitNavigationTarget(state, targetMatch, action) {
|
|
1597
|
+
const origin = splitNavigationOriginFromState(state);
|
|
1598
|
+
if (!origin) return state;
|
|
1599
|
+
const next = mutableHistoryState(state);
|
|
1600
|
+
delete next[SPLIT_NAVIGATION_ORIGIN_KEY];
|
|
1601
|
+
const targetSplitRoute = splitViewRouteForCompiledRoute(targetMatch?.route);
|
|
1602
|
+
const targetSplit = targetSplitRoute?.splitView;
|
|
1603
|
+
if (!targetSplit || targetSplit.layoutId !== origin.splitViewId || targetSplit.activePane !== "secondary") {
|
|
1604
|
+
delete next[SPLIT_NAVIGATION_KEY];
|
|
1605
|
+
return next;
|
|
1606
|
+
}
|
|
1607
|
+
const metadata = (
|
|
1608
|
+
// A primary selection establishes a new detail root. Navigation initiated
|
|
1609
|
+
// inside secondary continues (or explicitly replaces) that detail path.
|
|
1610
|
+
origin.pane === "primary" ? {
|
|
1611
|
+
splitViewId: origin.splitViewId,
|
|
1612
|
+
detailPathId: createRouterId(),
|
|
1613
|
+
detailDepth: 0,
|
|
1614
|
+
operation: "selection"
|
|
1615
|
+
} : {
|
|
1616
|
+
splitViewId: origin.splitViewId,
|
|
1617
|
+
detailPathId: origin.detailPathId,
|
|
1618
|
+
detailDepth: action === "navigate" ? origin.detailDepth + 1 : origin.detailDepth,
|
|
1619
|
+
operation: action === "navigate" ? "push" : "replace"
|
|
1620
|
+
}
|
|
1621
|
+
);
|
|
1622
|
+
next[SPLIT_NAVIGATION_KEY] = metadata;
|
|
1623
|
+
return next;
|
|
1624
|
+
}
|
|
1625
|
+
function routeRenderPropsForMatch(pathname, search, historyState, match) {
|
|
1626
|
+
return {
|
|
1627
|
+
params: match.params,
|
|
1628
|
+
pathname: normalizedPath(pathname),
|
|
1629
|
+
search,
|
|
1630
|
+
historyState,
|
|
1631
|
+
presentation: match.route.presentation
|
|
1632
|
+
};
|
|
1633
|
+
}
|
|
1634
|
+
function resolveGuardValue(value, props) {
|
|
1635
|
+
return typeof value === "function" ? value(props) : value;
|
|
1636
|
+
}
|
|
1637
|
+
function guardRedirectForMatch(match, pathname, search, historyState) {
|
|
1638
|
+
const props = routeRenderPropsForMatch(pathname, search, historyState, match);
|
|
1639
|
+
for (const guard of match.route.guards) {
|
|
1640
|
+
if (resolveGuardValue(guard.when, props)) continue;
|
|
1641
|
+
return resolveGuardValue(guard.redirectTo, props);
|
|
1642
|
+
}
|
|
1643
|
+
if (match.route.redirectTo) {
|
|
1644
|
+
return resolveGuardValue(match.route.redirectTo, props);
|
|
1645
|
+
}
|
|
1646
|
+
return null;
|
|
1647
|
+
}
|
|
1648
|
+
var PUSH_PRESENTATIONS = /* @__PURE__ */ new Set(["push"]);
|
|
1649
|
+
var OVERLAY_PRESENTATIONS = /* @__PURE__ */ new Set(["modal", "sheet"]);
|
|
1650
|
+
function parseNavigationTarget(to, currentPathname) {
|
|
1651
|
+
const base = `${window.location.origin}${currentPathname.startsWith("/") ? currentPathname : `/${currentPathname}`}`;
|
|
1652
|
+
const url = new URL(to, base);
|
|
1653
|
+
return {
|
|
1654
|
+
pathname: normalizedPath(url.pathname),
|
|
1655
|
+
search: url.search
|
|
1656
|
+
};
|
|
1657
|
+
}
|
|
1658
|
+
function pathForRoutePattern(pattern, params) {
|
|
1659
|
+
if (!pattern || pattern === "*") return null;
|
|
1660
|
+
let missingParam = false;
|
|
1661
|
+
const pathname = pattern.replace(/:([A-Za-z0-9_]+)/g, (_match, key) => {
|
|
1662
|
+
const value = params[key];
|
|
1663
|
+
if (value == null) {
|
|
1664
|
+
missingParam = true;
|
|
1665
|
+
return "";
|
|
1666
|
+
}
|
|
1667
|
+
return encodeURIComponent(String(value));
|
|
1668
|
+
});
|
|
1669
|
+
if (missingParam || pathname.includes("*")) return null;
|
|
1670
|
+
return normalizedPath(pathname);
|
|
1671
|
+
}
|
|
1672
|
+
function resolveStackKey(match, props) {
|
|
1673
|
+
const { route } = match;
|
|
1674
|
+
if (typeof route.stackKey === "function") return route.stackKey(props);
|
|
1675
|
+
if (typeof route.stackKey === "string") return route.stackKey;
|
|
1676
|
+
return normalizedPath(props.pathname);
|
|
1677
|
+
}
|
|
1678
|
+
function stackSnapshot(pathname, search, historyState, match) {
|
|
1679
|
+
const normalized = normalizedPath(pathname);
|
|
1680
|
+
const historyIndex = historyIndexFromState(historyState);
|
|
1681
|
+
const historyNavigationKey = historyNavigationKeyFromState(historyState) ?? `navigation-${historyIndex}`;
|
|
1682
|
+
const props = routeRenderPropsForMatch(normalized, search, historyState, match);
|
|
1683
|
+
const stackKey = resolveStackKey(match, props);
|
|
1684
|
+
const splitNavigation = splitNavigationFromState(historyState);
|
|
1685
|
+
return {
|
|
1686
|
+
...match,
|
|
1687
|
+
stackKey,
|
|
1688
|
+
locationKey: `${normalized}${search}:${historyIndex}:${historyNavigationKey}`,
|
|
1689
|
+
historyNavigationKey,
|
|
1690
|
+
pathname: normalized,
|
|
1691
|
+
search,
|
|
1692
|
+
historyState,
|
|
1693
|
+
historyIndex,
|
|
1694
|
+
historyCommit: historyCommitFromState(historyState),
|
|
1695
|
+
depth: routeDepth(normalized),
|
|
1696
|
+
presentation: match.route.presentation,
|
|
1697
|
+
splitNavigation
|
|
1698
|
+
};
|
|
1699
|
+
}
|
|
1700
|
+
function resolveDirection(previous, current) {
|
|
1701
|
+
if (!previous) return "forward";
|
|
1702
|
+
if (current.historyIndex < previous.historyIndex) return "back";
|
|
1703
|
+
if (current.historyIndex > previous.historyIndex) return "forward";
|
|
1704
|
+
if (current.depth < previous.depth) return "back";
|
|
1705
|
+
return "forward";
|
|
1706
|
+
}
|
|
1707
|
+
function createEntry(snapshot, enterDirection, animateEnter) {
|
|
1708
|
+
const transitionKey = animateEnter ? `${snapshot.stackKey}:${snapshot.locationKey}:${createRouterId()}` : `${snapshot.stackKey}:${snapshot.locationKey}`;
|
|
1709
|
+
return {
|
|
1710
|
+
...snapshot,
|
|
1711
|
+
id: transitionKey,
|
|
1712
|
+
transitionKey,
|
|
1713
|
+
enterDirection,
|
|
1714
|
+
exitDirection: "back",
|
|
1715
|
+
animateEnter
|
|
1716
|
+
};
|
|
1717
|
+
}
|
|
1718
|
+
function markCommitted(entry) {
|
|
1719
|
+
return entry.animateEnter ? { ...entry, animateEnter: false } : entry;
|
|
1720
|
+
}
|
|
1721
|
+
function mergeEntrySnapshot(entry, snapshot) {
|
|
1722
|
+
return {
|
|
1723
|
+
...entry,
|
|
1724
|
+
...snapshot,
|
|
1725
|
+
id: entry.id,
|
|
1726
|
+
transitionKey: entry.transitionKey,
|
|
1727
|
+
animateEnter: entry.animateEnter
|
|
1728
|
+
};
|
|
1729
|
+
}
|
|
1730
|
+
function isModalLikePresentation(presentation) {
|
|
1731
|
+
return presentation === "modal" || presentation === "sheet";
|
|
1732
|
+
}
|
|
1733
|
+
function isTabBarStackEntry(entry) {
|
|
1734
|
+
return entry.route.container === "tabbar";
|
|
1735
|
+
}
|
|
1736
|
+
function isDrawerContainerUpdate(previous, current) {
|
|
1737
|
+
return previous.stackKey === current.stackKey && previous.route.container === "drawer" && current.route.container === "drawer";
|
|
1738
|
+
}
|
|
1739
|
+
function canNavigateBackWithinDrawer(previous, current) {
|
|
1740
|
+
if (!previous || !current) return false;
|
|
1741
|
+
return previous.stackKey === current.stackKey && previous.route.container === "drawer" && current.route.container === "drawer" && previous.route.drawer?.activeItem === current.route.drawer?.activeItem && previous.pathname !== current.pathname;
|
|
1742
|
+
}
|
|
1743
|
+
function isTabBarContainerUpdate(previous, current) {
|
|
1744
|
+
return previous.stackKey === current.stackKey && (isTabBarStackEntry(previous) || isTabBarStackEntry(current));
|
|
1745
|
+
}
|
|
1746
|
+
function stackEntryContentContainer(entry) {
|
|
1747
|
+
return entry.route.childRoute?.container ?? entry.route.container;
|
|
1748
|
+
}
|
|
1749
|
+
function splitViewRouteForSnapshot(snapshot) {
|
|
1750
|
+
return splitViewRouteForCompiledRoute(snapshot.route);
|
|
1751
|
+
}
|
|
1752
|
+
function activeSplitViewLayout(layoutId) {
|
|
1753
|
+
if (typeof document === "undefined") return null;
|
|
1754
|
+
const splitViews = document.querySelectorAll(
|
|
1755
|
+
".sigmela-split-view[data-router-split-view-id]"
|
|
1756
|
+
);
|
|
1757
|
+
for (const splitView of splitViews) {
|
|
1758
|
+
if (splitView.dataset.routerSplitViewId !== layoutId) continue;
|
|
1759
|
+
const stackScreen = splitView.closest(
|
|
1760
|
+
'[data-route-stack-screen="true"]'
|
|
1761
|
+
);
|
|
1762
|
+
if (stackScreen?.dataset.routeStackPhase !== "active") continue;
|
|
1763
|
+
const layout = splitView.dataset.layout;
|
|
1764
|
+
if (layout === "wide") return true;
|
|
1765
|
+
if (layout === "narrow") return false;
|
|
1766
|
+
}
|
|
1767
|
+
return null;
|
|
1768
|
+
}
|
|
1769
|
+
function isWideSplitViewRoute(route) {
|
|
1770
|
+
const splitView = route?.splitView;
|
|
1771
|
+
if (!splitView || typeof window === "undefined" || typeof window.matchMedia !== "function") {
|
|
1772
|
+
return false;
|
|
1773
|
+
}
|
|
1774
|
+
const activeLayout = activeSplitViewLayout(splitView.layoutId);
|
|
1775
|
+
if (activeLayout !== null) return activeLayout;
|
|
1776
|
+
return window.matchMedia(`(min-width: ${splitView.wideMinWidth}px)`).matches;
|
|
1777
|
+
}
|
|
1778
|
+
function secondarySplitBackTarget(snapshot) {
|
|
1779
|
+
if (!snapshot) return null;
|
|
1780
|
+
const splitRoute = splitViewRouteForSnapshot(snapshot);
|
|
1781
|
+
const splitView = splitRoute?.splitView;
|
|
1782
|
+
if (!splitView || splitView.activePane !== "secondary") return null;
|
|
1783
|
+
if (!isWideSplitViewRoute(splitRoute)) return null;
|
|
1784
|
+
const currentPath = normalizedPath(snapshot.pathname);
|
|
1785
|
+
const parentSecondaryRoute = (splitView.secondaryRoutes ?? []).map((route) => pathForRoutePattern(route.path, snapshot.params)).filter(
|
|
1786
|
+
(path) => Boolean(path && path !== currentPath && currentPath.startsWith(`${path}/`))
|
|
1787
|
+
).sort((a, b) => routeDepth(b) - routeDepth(a))[0];
|
|
1788
|
+
if (parentSecondaryRoute) return parentSecondaryRoute;
|
|
1789
|
+
const target = pathForRoutePattern(splitView.primaryRoute.path, snapshot.params);
|
|
1790
|
+
if (!target || target === snapshot.pathname) return null;
|
|
1791
|
+
return target;
|
|
1792
|
+
}
|
|
1793
|
+
function canNavigateBackWithinSplit(previous, current) {
|
|
1794
|
+
if (!previous || !current) return false;
|
|
1795
|
+
const currentRoute = splitViewRouteForSnapshot(current);
|
|
1796
|
+
const previousRoute = splitViewRouteForSnapshot(previous);
|
|
1797
|
+
const currentSplit = currentRoute?.splitView;
|
|
1798
|
+
const previousSplit = previousRoute?.splitView;
|
|
1799
|
+
if (!currentSplit || currentSplit.activePane !== "secondary") return false;
|
|
1800
|
+
if (!previousSplit) return false;
|
|
1801
|
+
if (!isWideSplitViewRoute(currentRoute)) return false;
|
|
1802
|
+
return previous.stackKey === current.stackKey && previousSplit.primaryRoute.id === currentSplit.primaryRoute.id;
|
|
1803
|
+
}
|
|
1804
|
+
function existingStackEntryIndexForSnapshot(entries, snapshot) {
|
|
1805
|
+
const locationIndex = entries.findIndex(
|
|
1806
|
+
(entry) => entry.locationKey === snapshot.locationKey
|
|
1807
|
+
);
|
|
1808
|
+
if (locationIndex !== -1) return locationIndex;
|
|
1809
|
+
for (let i = entries.length - 1; i >= 0; i--) {
|
|
1810
|
+
const entry = entries[i];
|
|
1811
|
+
if (entry.stackKey === snapshot.stackKey && entry.pathname === snapshot.pathname && entry.search === snapshot.search) {
|
|
1812
|
+
return i;
|
|
1813
|
+
}
|
|
1814
|
+
}
|
|
1815
|
+
return -1;
|
|
1816
|
+
}
|
|
1817
|
+
function syncTargetEntryIndex(entries, snapshot) {
|
|
1818
|
+
if (snapshot.historyCommit !== "sync") return -1;
|
|
1819
|
+
return entries.findIndex(
|
|
1820
|
+
(entry) => entry.historyNavigationKey === snapshot.historyNavigationKey
|
|
1821
|
+
);
|
|
1822
|
+
}
|
|
1823
|
+
function entriesRevealingSnapshot(entries, existingIndex, snapshot) {
|
|
1824
|
+
const revealed = entries[existingIndex];
|
|
1825
|
+
const base = entries.slice(0, existingIndex).map(markCommitted);
|
|
1826
|
+
return [
|
|
1827
|
+
...base,
|
|
1828
|
+
{
|
|
1829
|
+
...revealed,
|
|
1830
|
+
...snapshot,
|
|
1831
|
+
id: revealed.id,
|
|
1832
|
+
animateEnter: false,
|
|
1833
|
+
enterDirection: "back"
|
|
1834
|
+
}
|
|
1835
|
+
];
|
|
1836
|
+
}
|
|
1837
|
+
function previousStackEntry(entries, active) {
|
|
1838
|
+
if (!active) return void 0;
|
|
1839
|
+
const activeIndex = entries.findIndex((entry) => entry.id === active.id);
|
|
1840
|
+
if (activeIndex <= 0) return void 0;
|
|
1841
|
+
return entries[activeIndex - 1];
|
|
1842
|
+
}
|
|
1843
|
+
function previousSnapshotInDetailPath(history, current) {
|
|
1844
|
+
const navigation = current.splitNavigation;
|
|
1845
|
+
if (!navigation || navigation.detailDepth <= 0) return void 0;
|
|
1846
|
+
const currentIndex = history.findIndex(
|
|
1847
|
+
(entry) => entry.historyIndex === current.historyIndex
|
|
1848
|
+
);
|
|
1849
|
+
if (currentIndex <= 0) return void 0;
|
|
1850
|
+
for (let index = currentIndex - 1; index >= 0; index -= 1) {
|
|
1851
|
+
const candidate = history[index];
|
|
1852
|
+
const candidateNavigation = candidate.splitNavigation;
|
|
1853
|
+
if (candidateNavigation?.splitViewId === navigation.splitViewId && candidateNavigation.detailPathId === navigation.detailPathId && candidateNavigation.detailDepth === navigation.detailDepth - 1) {
|
|
1854
|
+
return candidate;
|
|
1855
|
+
}
|
|
1856
|
+
}
|
|
1857
|
+
return void 0;
|
|
1858
|
+
}
|
|
1859
|
+
function navigateToSnapshot(snapshot) {
|
|
1860
|
+
if (!snapshot) return false;
|
|
1861
|
+
navigateWithHistoryIndex(`${snapshot.pathname}${snapshot.search}`, {
|
|
1862
|
+
commit: "sync",
|
|
1863
|
+
state: snapshot.historyState
|
|
1864
|
+
});
|
|
1865
|
+
return true;
|
|
1866
|
+
}
|
|
1867
|
+
function isWideSplitInternalUpdate(previous, current) {
|
|
1868
|
+
const previousRoute = splitViewRouteForSnapshot(previous);
|
|
1869
|
+
const currentRoute = splitViewRouteForSnapshot(current);
|
|
1870
|
+
const previousSplit = previousRoute?.splitView;
|
|
1871
|
+
const currentSplit = currentRoute?.splitView;
|
|
1872
|
+
if (!previousSplit || !currentSplit) return false;
|
|
1873
|
+
return previous.stackKey === current.stackKey && (previousSplit.activePane === "secondary" || currentSplit.activePane === "secondary") && previousSplit.primaryRoute.id === currentSplit.primaryRoute.id && isWideSplitViewRoute(currentRoute);
|
|
1874
|
+
}
|
|
1875
|
+
function isSameScreenRouteUpdate(previous, current) {
|
|
1876
|
+
return previous.stackKey === current.stackKey && previous.route.id === current.route.id && previous.presentation === current.presentation;
|
|
1877
|
+
}
|
|
1878
|
+
function shouldReplaceActiveStackEntry(previous, current) {
|
|
1879
|
+
const isSecondaryPush = current.splitPane === "secondary" && current.splitNavigation?.operation === "push";
|
|
1880
|
+
return !current.forcePushRouteChanges && !isSecondaryPush && isSameScreenRouteUpdate(previous, current) || isWideSplitInternalUpdate(previous, current) || isDrawerContainerUpdate(previous, current) || isTabBarContainerUpdate(previous, current);
|
|
1881
|
+
}
|
|
1882
|
+
function isExplicitStackReplace(previous, current) {
|
|
1883
|
+
return current.historyCommit === "replace" && previous.historyIndex === current.historyIndex;
|
|
1884
|
+
}
|
|
1885
|
+
function replaceActiveStackEntry(entries, activeId, snapshot, direction, commitInactive) {
|
|
1886
|
+
return entries.map((entry) => {
|
|
1887
|
+
if (entry.id === activeId) {
|
|
1888
|
+
return {
|
|
1889
|
+
...mergeEntrySnapshot(entry, snapshot),
|
|
1890
|
+
enterDirection: direction
|
|
1891
|
+
};
|
|
1892
|
+
}
|
|
1893
|
+
return commitInactive ? markCommitted(entry) : entry;
|
|
1894
|
+
});
|
|
1895
|
+
}
|
|
1896
|
+
function presentationClass(presentation) {
|
|
1897
|
+
return presentation;
|
|
1898
|
+
}
|
|
1899
|
+
function activeAnimationClass(entry) {
|
|
1900
|
+
if (entry.presentation !== "push") return "none";
|
|
1901
|
+
if (entry.route.animation === "slide_from_bottom" && entry.enterDirection !== "back") {
|
|
1902
|
+
return "slide-from-bottom-enter";
|
|
1903
|
+
}
|
|
1904
|
+
return entry.enterDirection === "back" ? "pop-enter" : "push-enter";
|
|
1905
|
+
}
|
|
1906
|
+
function exitingAnimationClass(entry) {
|
|
1907
|
+
if (entry.presentation !== "push") return "none";
|
|
1908
|
+
if (entry.route.animation === "slide_from_bottom" && entry.exitDirection === "back") {
|
|
1909
|
+
return "slide-from-bottom-exit";
|
|
1910
|
+
}
|
|
1911
|
+
return entry.exitDirection === "back" ? "pop-exit" : "push-exit";
|
|
1912
|
+
}
|
|
1913
|
+
function inactiveAnimationClass(entry, activeEntry, direction) {
|
|
1914
|
+
if (entry.presentation !== "push" || activeEntry?.presentation !== "push") {
|
|
1915
|
+
return "none";
|
|
1916
|
+
}
|
|
1917
|
+
if (activeEntry.route.animation === "slide_from_bottom") {
|
|
1918
|
+
return "none";
|
|
1919
|
+
}
|
|
1920
|
+
return direction === "back" ? "pop-background" : "push-background";
|
|
1921
|
+
}
|
|
1922
|
+
function transitionStatusForEntry(entry, status) {
|
|
1923
|
+
if (status) return status;
|
|
1924
|
+
return entry.animateEnter ? "preEnter" : "entered";
|
|
1925
|
+
}
|
|
1926
|
+
function phaseForEntry(entry, activeIds, activeId) {
|
|
1927
|
+
if (!activeIds.has(entry.id)) return "exiting";
|
|
1928
|
+
return entry.id === activeId ? "active" : "inactive";
|
|
1929
|
+
}
|
|
1930
|
+
function animationClassForEntry(entry, phase, activeEntry, direction) {
|
|
1931
|
+
if (phase === "exiting") return exitingAnimationClass(entry);
|
|
1932
|
+
if (phase === "active") return activeAnimationClass(entry);
|
|
1933
|
+
return inactiveAnimationClass(entry, activeEntry, direction);
|
|
1934
|
+
}
|
|
1935
|
+
function screenClassName(entry, phase, transitionStatus, animationType) {
|
|
1936
|
+
return [
|
|
1937
|
+
"screen-stack-item",
|
|
1938
|
+
presentationClass(entry.presentation),
|
|
1939
|
+
animationType,
|
|
1940
|
+
`transition-${transitionStatus}`,
|
|
1941
|
+
`phase-${phase}`
|
|
1942
|
+
].join(" ");
|
|
1943
|
+
}
|
|
1944
|
+
function frozenLocationHook(pathname) {
|
|
1945
|
+
return () => [pathname, navigateWithHistoryIndex];
|
|
1946
|
+
}
|
|
1947
|
+
function searchParamsForSearch(search) {
|
|
1948
|
+
return new URLSearchParams(search.startsWith("?") ? search.slice(1) : search);
|
|
1949
|
+
}
|
|
1950
|
+
function routeContextValue(entry) {
|
|
1951
|
+
return {
|
|
1952
|
+
params: entry.params,
|
|
1953
|
+
pathname: entry.pathname,
|
|
1954
|
+
search: entry.search,
|
|
1955
|
+
searchParams: searchParamsForSearch(entry.search),
|
|
1956
|
+
historyState: entry.historyState,
|
|
1957
|
+
presentation: entry.presentation,
|
|
1958
|
+
splitPane: entry.splitPane
|
|
1959
|
+
};
|
|
1960
|
+
}
|
|
1961
|
+
function routeContextValueFromProps(props) {
|
|
1962
|
+
return {
|
|
1963
|
+
...props,
|
|
1964
|
+
searchParams: searchParamsForSearch(props.search)
|
|
1965
|
+
};
|
|
1966
|
+
}
|
|
1967
|
+
function pathnameForRouteContext(route, fallbackPathname) {
|
|
1968
|
+
const routePath = route.path;
|
|
1969
|
+
if (!routePath || routePath.includes(":") || routePath.includes("*")) {
|
|
1970
|
+
return fallbackPathname;
|
|
1971
|
+
}
|
|
1972
|
+
return normalizedPath(routePath);
|
|
1973
|
+
}
|
|
1974
|
+
function useMinWidth(minWidth) {
|
|
1975
|
+
const [matches, setMatches] = useState(() => {
|
|
1976
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function") {
|
|
1977
|
+
return false;
|
|
1978
|
+
}
|
|
1979
|
+
return window.matchMedia(`(min-width: ${minWidth}px)`).matches;
|
|
1980
|
+
});
|
|
1981
|
+
useEffect(() => {
|
|
1982
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function") {
|
|
1983
|
+
return;
|
|
1984
|
+
}
|
|
1985
|
+
const mediaQuery = window.matchMedia(`(min-width: ${minWidth}px)`);
|
|
1986
|
+
const handleChange = (event) => setMatches(event.matches);
|
|
1987
|
+
setMatches(mediaQuery.matches);
|
|
1988
|
+
if (typeof mediaQuery.addEventListener === "function") {
|
|
1989
|
+
mediaQuery.addEventListener("change", handleChange);
|
|
1990
|
+
return () => mediaQuery.removeEventListener("change", handleChange);
|
|
1991
|
+
}
|
|
1992
|
+
const mediaQueryWithListener = mediaQuery;
|
|
1993
|
+
mediaQueryWithListener.addListener?.(handleChange);
|
|
1994
|
+
return () => mediaQueryWithListener.removeListener?.(handleChange);
|
|
1995
|
+
}, [minWidth]);
|
|
1996
|
+
return matches;
|
|
1997
|
+
}
|
|
1998
|
+
function measuredElementWidth(element) {
|
|
1999
|
+
return element.getBoundingClientRect().width || element.clientWidth || 0;
|
|
2000
|
+
}
|
|
2001
|
+
function widthMatchesMinWidth(width, minWidth) {
|
|
2002
|
+
if (width <= 0) return null;
|
|
2003
|
+
return width >= minWidth;
|
|
2004
|
+
}
|
|
2005
|
+
function useElementMinWidth(minWidth) {
|
|
2006
|
+
const ref = useRef(null);
|
|
2007
|
+
const viewportMatches = useMinWidth(minWidth);
|
|
2008
|
+
const [elementMatches, setElementMatches] = useState(null);
|
|
2009
|
+
useLayoutEffect(() => {
|
|
2010
|
+
const element = ref.current;
|
|
2011
|
+
if (!element) {
|
|
2012
|
+
setElementMatches(null);
|
|
2013
|
+
return;
|
|
2014
|
+
}
|
|
2015
|
+
const updateWidth = (width) => {
|
|
2016
|
+
const nextMatches = widthMatchesMinWidth(width, minWidth);
|
|
2017
|
+
setElementMatches(
|
|
2018
|
+
(currentMatches) => currentMatches === nextMatches ? currentMatches : nextMatches
|
|
2019
|
+
);
|
|
2020
|
+
};
|
|
2021
|
+
const measure = () => updateWidth(measuredElementWidth(element));
|
|
2022
|
+
measure();
|
|
2023
|
+
let observer = null;
|
|
2024
|
+
if (typeof window !== "undefined" && typeof window.ResizeObserver === "function") {
|
|
2025
|
+
observer = new window.ResizeObserver((entries) => {
|
|
2026
|
+
updateWidth(entries[0]?.contentRect.width ?? measuredElementWidth(element));
|
|
2027
|
+
});
|
|
2028
|
+
observer.observe(element);
|
|
2029
|
+
}
|
|
2030
|
+
if (typeof window !== "undefined") {
|
|
2031
|
+
window.addEventListener("resize", measure);
|
|
2032
|
+
}
|
|
2033
|
+
return () => {
|
|
2034
|
+
observer?.disconnect();
|
|
2035
|
+
if (typeof window !== "undefined") {
|
|
2036
|
+
window.removeEventListener("resize", measure);
|
|
2037
|
+
}
|
|
2038
|
+
};
|
|
2039
|
+
}, [minWidth]);
|
|
2040
|
+
return [ref, elementMatches ?? viewportMatches];
|
|
2041
|
+
}
|
|
2042
|
+
function useRoute() {
|
|
2043
|
+
const route = useContext(RouterRouteContext);
|
|
2044
|
+
if (!route) {
|
|
2045
|
+
throw new Error("Router route hooks must be used inside <Router>");
|
|
2046
|
+
}
|
|
2047
|
+
return route;
|
|
2048
|
+
}
|
|
2049
|
+
function useCurrentRoute() {
|
|
2050
|
+
return useRoute();
|
|
2051
|
+
}
|
|
2052
|
+
function useParams() {
|
|
2053
|
+
return useRoute().params;
|
|
2054
|
+
}
|
|
2055
|
+
function useSearchParams() {
|
|
2056
|
+
return useRoute().searchParams;
|
|
2057
|
+
}
|
|
2058
|
+
function useHistoryState() {
|
|
2059
|
+
return useRoute().historyState;
|
|
2060
|
+
}
|
|
2061
|
+
function useRouter() {
|
|
2062
|
+
const router = useContext(RouterActionsContext);
|
|
2063
|
+
const splitPaneOrigin = useContext(SplitPaneNavigationContext);
|
|
2064
|
+
if (!router) {
|
|
2065
|
+
throw new Error("useRouter must be used inside <Router>");
|
|
2066
|
+
}
|
|
2067
|
+
return useMemo(() => {
|
|
2068
|
+
if (!splitPaneOrigin) return router;
|
|
2069
|
+
return {
|
|
2070
|
+
...router,
|
|
2071
|
+
navigate: (to, options = {}) => {
|
|
2072
|
+
if (typeof to === "number") {
|
|
2073
|
+
router.navigate(to, options);
|
|
2074
|
+
return;
|
|
2075
|
+
}
|
|
2076
|
+
router.navigate(to, {
|
|
2077
|
+
...options,
|
|
2078
|
+
state: stateWithSplitNavigationOrigin(options.state, splitPaneOrigin)
|
|
2079
|
+
});
|
|
2080
|
+
},
|
|
2081
|
+
replace: (to, options = {}) => {
|
|
2082
|
+
router.replace(to, {
|
|
2083
|
+
...options,
|
|
2084
|
+
state: stateWithSplitNavigationOrigin(options.state, splitPaneOrigin)
|
|
2085
|
+
});
|
|
2086
|
+
}
|
|
2087
|
+
};
|
|
2088
|
+
}, [router, splitPaneOrigin]);
|
|
2089
|
+
}
|
|
2090
|
+
function useDrawer() {
|
|
2091
|
+
const drawer = useContext(RouterDrawerContext);
|
|
2092
|
+
if (!drawer) {
|
|
2093
|
+
throw new Error("useDrawer must be used inside <Router.Drawer>");
|
|
2094
|
+
}
|
|
2095
|
+
return drawer;
|
|
2096
|
+
}
|
|
2097
|
+
function useCurrentModal() {
|
|
2098
|
+
const current = useContext(CurrentModalContext);
|
|
2099
|
+
if (!current) {
|
|
2100
|
+
throw new Error("useCurrentModal called outside a Router modal/sheet entry");
|
|
2101
|
+
}
|
|
2102
|
+
return current;
|
|
2103
|
+
}
|
|
2104
|
+
function DefaultSplitViewLayout({
|
|
2105
|
+
children,
|
|
2106
|
+
primary,
|
|
2107
|
+
secondary,
|
|
2108
|
+
isWide,
|
|
2109
|
+
primaryMaxWidth = DEFAULT_SPLIT_PRIMARY_MAX_WIDTH,
|
|
2110
|
+
splitViewRef,
|
|
2111
|
+
splitViewLayoutId
|
|
2112
|
+
}) {
|
|
2113
|
+
return /* @__PURE__ */ jsxs(
|
|
2114
|
+
"div",
|
|
2115
|
+
{
|
|
2116
|
+
ref: splitViewRef,
|
|
2117
|
+
className: "sigmela-split-view",
|
|
2118
|
+
"data-layout": isWide ? "wide" : "narrow",
|
|
2119
|
+
"data-router-split-view-id": splitViewLayoutId,
|
|
2120
|
+
style: { "--sigmela-split-primary-max-width": `${primaryMaxWidth}px` },
|
|
2121
|
+
children: [
|
|
2122
|
+
/* @__PURE__ */ jsx("div", { className: "sigmela-split-view__primary", children: isWide ? primary : children }),
|
|
2123
|
+
isWide ? /* @__PURE__ */ jsx("div", { className: "sigmela-split-view__secondary", children: secondary }) : null
|
|
2124
|
+
]
|
|
2125
|
+
}
|
|
2126
|
+
);
|
|
2127
|
+
}
|
|
2128
|
+
function DefaultDrawerLayout({
|
|
2129
|
+
children,
|
|
2130
|
+
aside,
|
|
2131
|
+
footer,
|
|
2132
|
+
items = [],
|
|
2133
|
+
activeItem,
|
|
2134
|
+
onItemChange,
|
|
2135
|
+
drawer
|
|
2136
|
+
}) {
|
|
2137
|
+
const [expandedGroups, setExpandedGroups] = useState(
|
|
2138
|
+
() => /* @__PURE__ */ new Set()
|
|
2139
|
+
);
|
|
2140
|
+
const toggleGroup = useCallback((id) => {
|
|
2141
|
+
setExpandedGroups((current) => {
|
|
2142
|
+
const next = new Set(current);
|
|
2143
|
+
if (next.has(id)) next.delete(id);
|
|
2144
|
+
else next.add(id);
|
|
2145
|
+
return next;
|
|
2146
|
+
});
|
|
2147
|
+
}, []);
|
|
2148
|
+
return /* @__PURE__ */ jsxs("div", { className: "sigmela-drawer", "data-drawer-open": drawer?.isOpen ? "true" : "false", children: [
|
|
2149
|
+
/* @__PURE__ */ jsxs("aside", { className: "sigmela-drawer__sidebar", children: [
|
|
2150
|
+
/* @__PURE__ */ jsx("div", { className: "sigmela-drawer__sidebar-content", children: items.filter((node) => !node.hidden).map((node) => {
|
|
2151
|
+
if (node.type === "item") {
|
|
2152
|
+
return /* @__PURE__ */ jsxs(
|
|
2153
|
+
"button",
|
|
2154
|
+
{
|
|
2155
|
+
type: "button",
|
|
2156
|
+
className: "sigmela-drawer__item",
|
|
2157
|
+
"data-active": node.id === activeItem ? "true" : void 0,
|
|
2158
|
+
onClick: () => onItemChange?.(node.id),
|
|
2159
|
+
children: [
|
|
2160
|
+
node.icon ? /* @__PURE__ */ jsx("span", { className: "sigmela-drawer__item-icon", children: node.icon }) : null,
|
|
2161
|
+
/* @__PURE__ */ jsx("span", { className: "sigmela-drawer__item-label", children: node.label }),
|
|
2162
|
+
node.badge ? /* @__PURE__ */ jsx("span", { className: "sigmela-drawer__item-badge", children: node.badge }) : null
|
|
2163
|
+
]
|
|
2164
|
+
},
|
|
2165
|
+
node.id
|
|
2166
|
+
);
|
|
2167
|
+
}
|
|
2168
|
+
if (node.type === "section") {
|
|
2169
|
+
return /* @__PURE__ */ jsx("div", { className: "sigmela-drawer__section-label", children: node.title }, node.id);
|
|
2170
|
+
}
|
|
2171
|
+
const visibleItems = node.items.filter((item) => !item.hidden);
|
|
2172
|
+
if (visibleItems.length === 0) return null;
|
|
2173
|
+
const isExpanded = expandedGroups.has(node.id);
|
|
2174
|
+
const itemsId = `${node.id}-drawer-items`;
|
|
2175
|
+
return /* @__PURE__ */ jsxs("div", { className: "sigmela-drawer__group-container", children: [
|
|
2176
|
+
/* @__PURE__ */ jsxs(
|
|
2177
|
+
"button",
|
|
2178
|
+
{
|
|
2179
|
+
type: "button",
|
|
2180
|
+
className: "sigmela-drawer__item sigmela-drawer__group-label",
|
|
2181
|
+
"aria-controls": itemsId,
|
|
2182
|
+
"aria-expanded": isExpanded,
|
|
2183
|
+
onClick: () => toggleGroup(node.id),
|
|
2184
|
+
children: [
|
|
2185
|
+
node.icon ? /* @__PURE__ */ jsx("span", { className: "sigmela-drawer__item-icon", children: node.icon }) : null,
|
|
2186
|
+
/* @__PURE__ */ jsx("span", { className: "sigmela-drawer__item-label", children: node.label }),
|
|
2187
|
+
node.chevron ? /* @__PURE__ */ jsx(
|
|
2188
|
+
"span",
|
|
2189
|
+
{
|
|
2190
|
+
className: "sigmela-drawer__group-chevron",
|
|
2191
|
+
"data-expanded": isExpanded ? "true" : void 0,
|
|
2192
|
+
"aria-hidden": "true",
|
|
2193
|
+
children: node.chevron
|
|
2194
|
+
}
|
|
2195
|
+
) : null
|
|
2196
|
+
]
|
|
2197
|
+
}
|
|
2198
|
+
),
|
|
2199
|
+
isExpanded ? /* @__PURE__ */ jsx("div", { id: itemsId, className: "sigmela-drawer__group-items", children: visibleItems.map((item) => /* @__PURE__ */ jsxs(
|
|
2200
|
+
"button",
|
|
2201
|
+
{
|
|
2202
|
+
type: "button",
|
|
2203
|
+
className: "sigmela-drawer__item sigmela-drawer__subitem",
|
|
2204
|
+
"data-active": item.id === activeItem ? "true" : void 0,
|
|
2205
|
+
onClick: () => onItemChange?.(item.id),
|
|
2206
|
+
children: [
|
|
2207
|
+
item.icon ? /* @__PURE__ */ jsx("span", { className: "sigmela-drawer__item-icon", children: item.icon }) : null,
|
|
2208
|
+
/* @__PURE__ */ jsx("span", { className: "sigmela-drawer__item-label", children: item.label }),
|
|
2209
|
+
item.badge ? /* @__PURE__ */ jsx("span", { className: "sigmela-drawer__item-badge", children: item.badge }) : null
|
|
2210
|
+
]
|
|
2211
|
+
},
|
|
2212
|
+
item.id
|
|
2213
|
+
)) }) : null
|
|
2214
|
+
] }, node.id);
|
|
2215
|
+
}) }),
|
|
2216
|
+
footer ? /* @__PURE__ */ jsx("div", { className: "sigmela-drawer__footer", children: footer }) : null
|
|
2217
|
+
] }),
|
|
2218
|
+
/* @__PURE__ */ jsx(
|
|
2219
|
+
"button",
|
|
2220
|
+
{
|
|
2221
|
+
type: "button",
|
|
2222
|
+
className: "sigmela-drawer__overlay",
|
|
2223
|
+
"aria-label": "Close navigation",
|
|
2224
|
+
onClick: drawer?.close
|
|
2225
|
+
}
|
|
2226
|
+
),
|
|
2227
|
+
/* @__PURE__ */ jsx("main", { className: "sigmela-drawer__main", children }),
|
|
2228
|
+
aside ? /* @__PURE__ */ jsx("aside", { className: "sigmela-drawer__assistant", children: aside }) : null
|
|
2229
|
+
] });
|
|
2230
|
+
}
|
|
2231
|
+
function FrozenPaneRouteContent({
|
|
2232
|
+
route,
|
|
2233
|
+
props,
|
|
2234
|
+
fallback
|
|
2235
|
+
}) {
|
|
2236
|
+
const hook = useMemo(() => frozenLocationHook(props.pathname), [props.pathname]);
|
|
2237
|
+
const searchHook = useMemo(() => () => props.search, [props.search]);
|
|
2238
|
+
const routeContext = useMemo(() => routeContextValueFromProps(props), [props]);
|
|
2239
|
+
return /* @__PURE__ */ jsx(Router$1, { hook, searchHook, children: /* @__PURE__ */ jsx(RouterRouteContext.Provider, { value: routeContext, children: /* @__PURE__ */ jsx(Suspense, { fallback, children: renderRouteContent(route, props) }) }) });
|
|
2240
|
+
}
|
|
2241
|
+
function stackSnapshotForRouteProps(route, props, stackKey, forcePushRouteChanges = false) {
|
|
2242
|
+
const normalized = normalizedPath(props.pathname);
|
|
2243
|
+
const historyIndex = historyIndexFromState(props.historyState);
|
|
2244
|
+
const historyNavigationKey = historyNavigationKeyFromState(props.historyState) ?? `navigation-${historyIndex}`;
|
|
2245
|
+
const splitNavigation = splitNavigationFromState(props.historyState);
|
|
2246
|
+
return {
|
|
2247
|
+
route,
|
|
2248
|
+
params: props.params,
|
|
2249
|
+
stackKey,
|
|
2250
|
+
locationKey: `${normalized}${props.search}:${historyIndex}:${historyNavigationKey}`,
|
|
2251
|
+
historyNavigationKey,
|
|
2252
|
+
pathname: normalized,
|
|
2253
|
+
search: props.search,
|
|
2254
|
+
historyState: props.historyState,
|
|
2255
|
+
historyIndex,
|
|
2256
|
+
historyCommit: historyCommitFromState(props.historyState),
|
|
2257
|
+
depth: routeDepth(normalized),
|
|
2258
|
+
presentation: route.presentation,
|
|
2259
|
+
forcePushRouteChanges,
|
|
2260
|
+
splitPane: props.splitPane,
|
|
2261
|
+
splitNavigation
|
|
2262
|
+
};
|
|
2263
|
+
}
|
|
2264
|
+
function propsForStackEntry(entry) {
|
|
2265
|
+
return {
|
|
2266
|
+
params: entry.params,
|
|
2267
|
+
pathname: entry.pathname,
|
|
2268
|
+
search: entry.search,
|
|
2269
|
+
historyState: entry.historyState,
|
|
2270
|
+
presentation: entry.presentation,
|
|
2271
|
+
splitPane: entry.splitPane
|
|
2272
|
+
};
|
|
2273
|
+
}
|
|
2274
|
+
function RouteStackViewport({
|
|
2275
|
+
route,
|
|
2276
|
+
props,
|
|
2277
|
+
fallback,
|
|
2278
|
+
stackKey,
|
|
2279
|
+
className = "sigmela-split-pane-stack",
|
|
2280
|
+
contentClassName,
|
|
2281
|
+
scopeOverlayContent = false,
|
|
2282
|
+
forcePushRouteChanges = false
|
|
2283
|
+
}) {
|
|
2284
|
+
const snapshot = useMemo(
|
|
2285
|
+
() => stackSnapshotForRouteProps(
|
|
2286
|
+
route,
|
|
2287
|
+
props,
|
|
2288
|
+
stackKey,
|
|
2289
|
+
forcePushRouteChanges
|
|
2290
|
+
),
|
|
2291
|
+
[
|
|
2292
|
+
props.historyState,
|
|
2293
|
+
props.params,
|
|
2294
|
+
props.pathname,
|
|
2295
|
+
props.search,
|
|
2296
|
+
props.splitPane,
|
|
2297
|
+
forcePushRouteChanges,
|
|
2298
|
+
route,
|
|
2299
|
+
stackKey
|
|
2300
|
+
]
|
|
2301
|
+
);
|
|
2302
|
+
const [entries, setEntries] = useState(() => [
|
|
2303
|
+
createEntry(snapshot, "forward", false)
|
|
2304
|
+
]);
|
|
2305
|
+
const [heldEnterIds, setHeldEnterIds] = useState(() => /* @__PURE__ */ new Set());
|
|
2306
|
+
const heldEnterIdsRef = useRef(heldEnterIds);
|
|
2307
|
+
const enterHoldCleanupRef = useRef(/* @__PURE__ */ new Map());
|
|
2308
|
+
const entryArchiveRef = useRef(
|
|
2309
|
+
new Map(entries.map((entry) => [entry.id, entry]))
|
|
2310
|
+
);
|
|
2311
|
+
const { stateMap, setItem, toggle, deleteItem } = useTransitionMap({
|
|
2312
|
+
timeout: ROUTE_TRANSITION_MS,
|
|
2313
|
+
preEnter: true,
|
|
2314
|
+
preExit: true,
|
|
2315
|
+
mountOnEnter: true,
|
|
2316
|
+
unmountOnExit: true,
|
|
2317
|
+
allowMultiple: true
|
|
2318
|
+
});
|
|
2319
|
+
for (const entry of entries) {
|
|
2320
|
+
entryArchiveRef.current.set(entry.id, entry);
|
|
2321
|
+
}
|
|
2322
|
+
heldEnterIdsRef.current = heldEnterIds;
|
|
2323
|
+
const releaseHeldEnter = useCallback((id) => {
|
|
2324
|
+
const cleanup = enterHoldCleanupRef.current.get(id);
|
|
2325
|
+
if (cleanup) cleanup();
|
|
2326
|
+
enterHoldCleanupRef.current.delete(id);
|
|
2327
|
+
setHeldEnterIds((prev) => {
|
|
2328
|
+
if (!prev.has(id)) return prev;
|
|
2329
|
+
const next = new Set(prev);
|
|
2330
|
+
next.delete(id);
|
|
2331
|
+
return next;
|
|
2332
|
+
});
|
|
2333
|
+
}, []);
|
|
2334
|
+
const holdEnterUntilPainted = useCallback((id, onRelease) => {
|
|
2335
|
+
if (heldEnterIdsRef.current.has(id) || enterHoldCleanupRef.current.has(id)) return;
|
|
2336
|
+
setHeldEnterIds((prev) => {
|
|
2337
|
+
if (prev.has(id)) return prev;
|
|
2338
|
+
const next = new Set(prev);
|
|
2339
|
+
next.add(id);
|
|
2340
|
+
return next;
|
|
2341
|
+
});
|
|
2342
|
+
let frame = 0;
|
|
2343
|
+
let timeout = 0;
|
|
2344
|
+
const cleanup = () => {
|
|
2345
|
+
if (frame) window.cancelAnimationFrame(frame);
|
|
2346
|
+
if (timeout) window.clearTimeout(timeout);
|
|
2347
|
+
};
|
|
2348
|
+
frame = window.requestAnimationFrame(() => {
|
|
2349
|
+
timeout = window.setTimeout(() => {
|
|
2350
|
+
enterHoldCleanupRef.current.delete(id);
|
|
2351
|
+
setHeldEnterIds((prev) => {
|
|
2352
|
+
if (!prev.has(id)) return prev;
|
|
2353
|
+
const next = new Set(prev);
|
|
2354
|
+
next.delete(id);
|
|
2355
|
+
return next;
|
|
2356
|
+
});
|
|
2357
|
+
onRelease();
|
|
2358
|
+
}, 0);
|
|
2359
|
+
});
|
|
2360
|
+
enterHoldCleanupRef.current.set(id, cleanup);
|
|
2361
|
+
}, []);
|
|
2362
|
+
useEffect(() => {
|
|
2363
|
+
return () => {
|
|
2364
|
+
for (const cleanup of enterHoldCleanupRef.current.values()) cleanup();
|
|
2365
|
+
enterHoldCleanupRef.current.clear();
|
|
2366
|
+
};
|
|
2367
|
+
}, []);
|
|
2368
|
+
useLayoutEffect(() => {
|
|
2369
|
+
setEntries((prev) => {
|
|
2370
|
+
const change = resolveStackChange(prev, snapshot);
|
|
2371
|
+
const nextIds = new Set(change.entries.map((entry) => entry.id));
|
|
2372
|
+
for (const entry of prev) {
|
|
2373
|
+
if (!nextIds.has(entry.id)) {
|
|
2374
|
+
entryArchiveRef.current.set(entry.id, {
|
|
2375
|
+
...entry,
|
|
2376
|
+
animateEnter: false,
|
|
2377
|
+
exitDirection: change.direction
|
|
2378
|
+
});
|
|
2379
|
+
}
|
|
2380
|
+
}
|
|
2381
|
+
for (const entry of change.entries) {
|
|
2382
|
+
entryArchiveRef.current.set(entry.id, entry);
|
|
2383
|
+
}
|
|
2384
|
+
return change.entries;
|
|
2385
|
+
});
|
|
2386
|
+
}, [snapshot]);
|
|
2387
|
+
const visibleEntries = useMemo(
|
|
2388
|
+
() => visibleEntriesForSnapshot(entries, snapshot),
|
|
2389
|
+
[entries, snapshot]
|
|
2390
|
+
);
|
|
2391
|
+
const activeIds = useMemo(() => new Set(entries.map((entry) => entry.id)), [entries]);
|
|
2392
|
+
const visibleActiveIds = useMemo(
|
|
2393
|
+
() => new Set(visibleEntries.map((entry) => entry.id)),
|
|
2394
|
+
[visibleEntries]
|
|
2395
|
+
);
|
|
2396
|
+
const visibleActiveId = visibleEntries[visibleEntries.length - 1]?.id ?? null;
|
|
2397
|
+
const visibleActiveEntry = visibleEntries[visibleEntries.length - 1];
|
|
2398
|
+
const visibleStackDirection = visibleActiveEntry?.enterDirection ?? "forward";
|
|
2399
|
+
const activeIdKey = useMemo(
|
|
2400
|
+
() => entries.map((entry) => entry.id).join("|"),
|
|
2401
|
+
[entries]
|
|
2402
|
+
);
|
|
2403
|
+
const mountedTransitionEntries = useMemo(
|
|
2404
|
+
() => Array.from(stateMap.entries()).filter(([, state]) => state.isMounted),
|
|
2405
|
+
[stateMap]
|
|
2406
|
+
);
|
|
2407
|
+
const isTransitionSettled = mountedTransitionEntries.every(
|
|
2408
|
+
([, state]) => state.isResolved
|
|
2409
|
+
);
|
|
2410
|
+
useLayoutEffect(() => {
|
|
2411
|
+
for (const entry of entries) {
|
|
2412
|
+
const state = stateMap.get(entry.id);
|
|
2413
|
+
if (!state) {
|
|
2414
|
+
setItem(entry.id, { initialEntered: !entry.animateEnter });
|
|
2415
|
+
if (entry.animateEnter) {
|
|
2416
|
+
holdEnterUntilPainted(entry.id, () => toggle(entry.id, true));
|
|
2417
|
+
}
|
|
2418
|
+
continue;
|
|
2419
|
+
}
|
|
2420
|
+
if (heldEnterIds.has(entry.id)) {
|
|
2421
|
+
continue;
|
|
2422
|
+
}
|
|
2423
|
+
if (!state.isEnter) {
|
|
2424
|
+
toggle(entry.id, true);
|
|
2425
|
+
}
|
|
2426
|
+
}
|
|
2427
|
+
for (const [id, state] of stateMap) {
|
|
2428
|
+
if (!activeIds.has(id) && state.isEnter) {
|
|
2429
|
+
releaseHeldEnter(id);
|
|
2430
|
+
toggle(id, false);
|
|
2431
|
+
}
|
|
2432
|
+
}
|
|
2433
|
+
}, [
|
|
2434
|
+
activeIdKey,
|
|
2435
|
+
activeIds,
|
|
2436
|
+
entries,
|
|
2437
|
+
heldEnterIds,
|
|
2438
|
+
holdEnterUntilPainted,
|
|
2439
|
+
releaseHeldEnter,
|
|
2440
|
+
setItem,
|
|
2441
|
+
stateMap,
|
|
2442
|
+
toggle
|
|
2443
|
+
]);
|
|
2444
|
+
useEffect(() => {
|
|
2445
|
+
const unmountedIds = Array.from(stateMap.entries()).filter(([, state]) => !state.isMounted).map(([id]) => id);
|
|
2446
|
+
for (const id of unmountedIds) {
|
|
2447
|
+
if (activeIds.has(id)) continue;
|
|
2448
|
+
entryArchiveRef.current.delete(id);
|
|
2449
|
+
releaseHeldEnter(id);
|
|
2450
|
+
deleteItem(id);
|
|
2451
|
+
}
|
|
2452
|
+
}, [activeIds, deleteItem, releaseHeldEnter, stateMap]);
|
|
2453
|
+
const renderEntries = useMemo(() => {
|
|
2454
|
+
const result = [...visibleEntries];
|
|
2455
|
+
const visibleIds = new Set(visibleEntries.map((entry) => entry.id));
|
|
2456
|
+
for (const [id] of mountedTransitionEntries) {
|
|
2457
|
+
if (visibleIds.has(id)) continue;
|
|
2458
|
+
const entry = entryArchiveRef.current.get(id);
|
|
2459
|
+
if (!entry) continue;
|
|
2460
|
+
result.push(entry);
|
|
2461
|
+
}
|
|
2462
|
+
return result;
|
|
2463
|
+
}, [mountedTransitionEntries, visibleEntries]);
|
|
2464
|
+
return /* @__PURE__ */ jsx(
|
|
2465
|
+
"div",
|
|
2466
|
+
{
|
|
2467
|
+
className: `screen-stack ${className}`,
|
|
2468
|
+
"data-animation": !isTransitionSettled ? "true" : void 0,
|
|
2469
|
+
style: { "--stack-transition-time": `${ROUTE_TRANSITION_MS}ms` },
|
|
2470
|
+
children: renderEntries.map((entry, index) => {
|
|
2471
|
+
const phase = phaseForEntry(entry, visibleActiveIds, visibleActiveId);
|
|
2472
|
+
const transitionStatus = heldEnterIds.has(entry.id) ? "preEnter" : transitionStatusForEntry(entry, stateMap.get(entry.id)?.status);
|
|
2473
|
+
const animationType = animationClassForEntry(
|
|
2474
|
+
entry,
|
|
2475
|
+
phase,
|
|
2476
|
+
visibleActiveEntry,
|
|
2477
|
+
visibleStackDirection
|
|
2478
|
+
);
|
|
2479
|
+
const zIndex = phase === "exiting" ? renderEntries.length + index + 1 : index + 1;
|
|
2480
|
+
const routeContent = /* @__PURE__ */ jsx(
|
|
2481
|
+
FrozenPaneRouteContent,
|
|
2482
|
+
{
|
|
2483
|
+
route: entry.route,
|
|
2484
|
+
props: propsForStackEntry(entry),
|
|
2485
|
+
fallback: entry.route.fallback ?? fallback
|
|
2486
|
+
}
|
|
2487
|
+
);
|
|
2488
|
+
const scopedContent = scopeOverlayContent ? /* @__PURE__ */ jsx(OverlayContentScope, { contentKey: entry.historyNavigationKey, children: routeContent }) : routeContent;
|
|
2489
|
+
return /* @__PURE__ */ jsx(
|
|
2490
|
+
"div",
|
|
2491
|
+
{
|
|
2492
|
+
"data-route-stack-screen": "true",
|
|
2493
|
+
"data-route-stack-key": entry.stackKey,
|
|
2494
|
+
"data-route-stack-route-id": entry.route.id,
|
|
2495
|
+
"data-route-stack-container": entry.route.container,
|
|
2496
|
+
"data-route-stack-presentation": entry.presentation,
|
|
2497
|
+
"data-route-stack-phase": phase,
|
|
2498
|
+
"data-route-stack-transition": transitionStatus,
|
|
2499
|
+
className: screenClassName(entry, phase, transitionStatus, animationType),
|
|
2500
|
+
"aria-hidden": phase === "active" ? void 0 : true,
|
|
2501
|
+
inert: phase === "active" ? void 0 : true,
|
|
2502
|
+
style: { zIndex },
|
|
2503
|
+
children: /* @__PURE__ */ jsx("div", { className: "stack-screen-container", children: contentClassName ? /* @__PURE__ */ jsx("div", { className: contentClassName, children: scopedContent }) : scopedContent })
|
|
2504
|
+
},
|
|
2505
|
+
entry.id
|
|
2506
|
+
);
|
|
2507
|
+
})
|
|
2508
|
+
}
|
|
2509
|
+
);
|
|
2510
|
+
}
|
|
2511
|
+
function SplitViewRouteContent({
|
|
2512
|
+
route,
|
|
2513
|
+
props,
|
|
2514
|
+
fallback
|
|
2515
|
+
}) {
|
|
2516
|
+
const splitView = route.splitView;
|
|
2517
|
+
const [splitViewRef, isWide] = useElementMinWidth(
|
|
2518
|
+
splitView?.wideMinWidth ?? splitViewWideMinWidth(DEFAULT_SPLIT_MIN_WIDTH, DEFAULT_SPLIT_PRIMARY_MAX_WIDTH)
|
|
2519
|
+
);
|
|
2520
|
+
if (!splitView) {
|
|
2521
|
+
return route.childRoute ? renderRouteContent(route.childRoute, props) : null;
|
|
2522
|
+
}
|
|
2523
|
+
const storedSplitNavigation = splitNavigationFromState(props.historyState);
|
|
2524
|
+
const detailPathId = storedSplitNavigation?.splitViewId === splitView.layoutId ? storedSplitNavigation.detailPathId : `${splitView.layoutId}:default`;
|
|
2525
|
+
const detailDepth = storedSplitNavigation?.splitViewId === splitView.layoutId ? storedSplitNavigation.detailDepth : 0;
|
|
2526
|
+
const primaryNavigationOrigin = {
|
|
2527
|
+
splitViewId: splitView.layoutId,
|
|
2528
|
+
pane: "primary",
|
|
2529
|
+
detailPathId,
|
|
2530
|
+
detailDepth
|
|
2531
|
+
};
|
|
2532
|
+
const secondaryNavigationOrigin = {
|
|
2533
|
+
splitViewId: splitView.layoutId,
|
|
2534
|
+
pane: "secondary",
|
|
2535
|
+
detailPathId,
|
|
2536
|
+
detailDepth
|
|
2537
|
+
};
|
|
2538
|
+
const primaryProps = {
|
|
2539
|
+
...props,
|
|
2540
|
+
splitPane: "primary"
|
|
2541
|
+
};
|
|
2542
|
+
const secondaryProps = splitView.secondaryRoute ? {
|
|
2543
|
+
...props,
|
|
2544
|
+
pathname: pathnameForRouteContext(splitView.secondaryRoute, props.pathname),
|
|
2545
|
+
splitPane: "secondary"
|
|
2546
|
+
} : props;
|
|
2547
|
+
const primary = /* @__PURE__ */ jsx(SplitPaneNavigationContext.Provider, { value: primaryNavigationOrigin, children: /* @__PURE__ */ jsx(
|
|
2548
|
+
FrozenPaneRouteContent,
|
|
2549
|
+
{
|
|
2550
|
+
route: splitView.primaryRoute,
|
|
2551
|
+
props: primaryProps,
|
|
2552
|
+
fallback: splitView.primaryRoute.fallback ?? fallback
|
|
2553
|
+
}
|
|
2554
|
+
) });
|
|
2555
|
+
const secondary = splitView.secondaryRoute ? /* @__PURE__ */ jsx(SplitPaneNavigationContext.Provider, { value: secondaryNavigationOrigin, children: isWide ? /* @__PURE__ */ jsx(
|
|
2556
|
+
RouteStackViewport,
|
|
2557
|
+
{
|
|
2558
|
+
route: splitView.secondaryRoute,
|
|
2559
|
+
props: secondaryProps,
|
|
2560
|
+
fallback: splitView.secondaryRoute.fallback ?? fallback,
|
|
2561
|
+
stackKey: `${route.id}:secondary`
|
|
2562
|
+
},
|
|
2563
|
+
detailPathId
|
|
2564
|
+
) : /* @__PURE__ */ jsx(
|
|
2565
|
+
FrozenPaneRouteContent,
|
|
2566
|
+
{
|
|
2567
|
+
route: splitView.secondaryRoute,
|
|
2568
|
+
props: secondaryProps,
|
|
2569
|
+
fallback: splitView.secondaryRoute.fallback ?? fallback
|
|
2570
|
+
}
|
|
2571
|
+
) }) : null;
|
|
2572
|
+
const activeContent = splitView.activePane === "secondary" && secondary ? secondary : primary;
|
|
2573
|
+
const layoutProps = {
|
|
2574
|
+
children: isWide ? primary : activeContent,
|
|
2575
|
+
primary,
|
|
2576
|
+
secondary,
|
|
2577
|
+
isWide,
|
|
2578
|
+
hasSecondary: Boolean(splitView.secondaryRoute),
|
|
2579
|
+
minWidth: splitView.minWidth,
|
|
2580
|
+
primaryMaxWidth: splitView.primaryMaxWidth,
|
|
2581
|
+
secondaryMinWidth: splitView.secondaryMinWidth,
|
|
2582
|
+
splitViewRef,
|
|
2583
|
+
splitViewLayoutId: splitView.layoutId
|
|
2584
|
+
};
|
|
2585
|
+
if (route.layout) {
|
|
2586
|
+
return createElement(route.layout, layoutProps);
|
|
2587
|
+
}
|
|
2588
|
+
if (route.component) {
|
|
2589
|
+
return createElement(route.component, { ...props, ...layoutProps });
|
|
2590
|
+
}
|
|
2591
|
+
if (route.elementType) {
|
|
2592
|
+
return createElement(route.elementType, { ...props, ...layoutProps });
|
|
2593
|
+
}
|
|
2594
|
+
if (route.render) return route.render(props);
|
|
2595
|
+
return /* @__PURE__ */ jsx(DefaultSplitViewLayout, { ...layoutProps });
|
|
2596
|
+
}
|
|
2597
|
+
function DrawerRouteContent({
|
|
2598
|
+
route,
|
|
2599
|
+
props
|
|
2600
|
+
}) {
|
|
2601
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
2602
|
+
const open = useCallback(() => setIsOpen(true), []);
|
|
2603
|
+
const close = useCallback(() => setIsOpen(false), []);
|
|
2604
|
+
const toggle = useCallback(() => setIsOpen((value) => !value), []);
|
|
2605
|
+
const drawerApi = useMemo(
|
|
2606
|
+
() => ({ isOpen, open, close, toggle }),
|
|
2607
|
+
[close, isOpen, open, toggle]
|
|
2608
|
+
);
|
|
2609
|
+
const childFallback = route.childRoute?.fallback ?? route.fallback ?? null;
|
|
2610
|
+
const drawer = route.drawer;
|
|
2611
|
+
const activeItem = drawer?.activeItem;
|
|
2612
|
+
const content = route.childRoute ? /* @__PURE__ */ jsx(
|
|
2613
|
+
RouteStackViewport,
|
|
2614
|
+
{
|
|
2615
|
+
route: route.childRoute,
|
|
2616
|
+
props,
|
|
2617
|
+
fallback: childFallback,
|
|
2618
|
+
stackKey: `${route.stackKey ?? route.id}:drawer:${activeItem ?? "content"}`
|
|
2619
|
+
},
|
|
2620
|
+
activeItem
|
|
2621
|
+
) : null;
|
|
2622
|
+
const onItemChange = drawer ? (id) => {
|
|
2623
|
+
const item = findDrawerItem(drawer.items, id);
|
|
2624
|
+
if (item && normalizedPath(item.path) !== props.pathname) {
|
|
2625
|
+
navigateWithHistoryIndex(item.path);
|
|
2626
|
+
}
|
|
2627
|
+
close();
|
|
2628
|
+
} : void 0;
|
|
2629
|
+
const layoutProps = {
|
|
2630
|
+
children: content,
|
|
2631
|
+
aside: route.drawerAside,
|
|
2632
|
+
footer: route.drawerFooter,
|
|
2633
|
+
portal: false,
|
|
2634
|
+
items: drawer?.items,
|
|
2635
|
+
activeItem: drawer?.activeItem,
|
|
2636
|
+
onItemChange,
|
|
2637
|
+
drawer: drawerApi
|
|
2638
|
+
};
|
|
2639
|
+
let rendered;
|
|
2640
|
+
if (route.layout) {
|
|
2641
|
+
rendered = createElement(route.layout, layoutProps);
|
|
2642
|
+
} else if (route.component) {
|
|
2643
|
+
rendered = createElement(route.component, { ...props, ...layoutProps });
|
|
2644
|
+
} else if (route.elementType) {
|
|
2645
|
+
rendered = createElement(route.elementType, { ...props, ...layoutProps });
|
|
2646
|
+
} else if (route.render) {
|
|
2647
|
+
rendered = route.render(props);
|
|
2648
|
+
} else {
|
|
2649
|
+
rendered = /* @__PURE__ */ jsx(DefaultDrawerLayout, { ...layoutProps });
|
|
2650
|
+
}
|
|
2651
|
+
return /* @__PURE__ */ jsx(RouterDrawerContext.Provider, { value: drawerApi, children: rendered });
|
|
2652
|
+
}
|
|
2653
|
+
function findDrawerItem(nodes, id) {
|
|
2654
|
+
for (const node of nodes) {
|
|
2655
|
+
if (node.type === "item") {
|
|
2656
|
+
if (node.id === id) return node;
|
|
2657
|
+
continue;
|
|
2658
|
+
}
|
|
2659
|
+
if (node.type === "section") continue;
|
|
2660
|
+
const item = node.items.find((entry) => entry.id === id);
|
|
2661
|
+
if (item) return item;
|
|
2662
|
+
}
|
|
2663
|
+
return void 0;
|
|
2664
|
+
}
|
|
2665
|
+
function renderRouteContent(route, props) {
|
|
2666
|
+
if (route.container === "splitview" && route.splitView) {
|
|
2667
|
+
return /* @__PURE__ */ jsx(
|
|
2668
|
+
SplitViewRouteContent,
|
|
2669
|
+
{
|
|
2670
|
+
route,
|
|
2671
|
+
props,
|
|
2672
|
+
fallback: route.fallback ?? null
|
|
2673
|
+
}
|
|
2674
|
+
);
|
|
2675
|
+
}
|
|
2676
|
+
if (route.component) {
|
|
2677
|
+
return createElement(route.component, props);
|
|
2678
|
+
}
|
|
2679
|
+
let content;
|
|
2680
|
+
if (route.elementType) {
|
|
2681
|
+
content = createElement(route.elementType, props);
|
|
2682
|
+
} else if (route.render) {
|
|
2683
|
+
content = route.render(props);
|
|
2684
|
+
} else if (route.childrenNode !== void 0) {
|
|
2685
|
+
content = route.childrenNode;
|
|
2686
|
+
} else {
|
|
2687
|
+
content = route.element;
|
|
2688
|
+
}
|
|
2689
|
+
if (!route.layout) return content;
|
|
2690
|
+
return createElement(route.layout, { children: content });
|
|
2691
|
+
}
|
|
2692
|
+
function renderCompiledRoute(entry) {
|
|
2693
|
+
const props = {
|
|
2694
|
+
params: entry.params,
|
|
2695
|
+
pathname: entry.pathname,
|
|
2696
|
+
search: entry.search,
|
|
2697
|
+
historyState: entry.historyState,
|
|
2698
|
+
presentation: entry.presentation
|
|
2699
|
+
};
|
|
2700
|
+
if (entry.route.container === "drawer" && entry.route.childRoute) {
|
|
2701
|
+
return /* @__PURE__ */ jsx(DrawerRouteContent, { route: entry.route, props });
|
|
2702
|
+
}
|
|
2703
|
+
if (entry.route.container === "tabbar" && entry.route.childRoute) {
|
|
2704
|
+
const childFallback = entry.route.childRoute.fallback ?? entry.route.fallback ?? null;
|
|
2705
|
+
const content = /* @__PURE__ */ jsx(Suspense, { fallback: childFallback, children: renderRouteContent(entry.route.childRoute, props) });
|
|
2706
|
+
const tabBar = entry.route.tabBar;
|
|
2707
|
+
const onTabChange = tabBar ? (id) => {
|
|
2708
|
+
const tab = tabBar.tabs.find((item) => item.id === id);
|
|
2709
|
+
if (tab && normalizedPath(tab.path) !== entry.pathname) {
|
|
2710
|
+
navigateWithHistoryIndex(tab.path);
|
|
2711
|
+
}
|
|
2712
|
+
} : void 0;
|
|
2713
|
+
const layoutProps = {
|
|
2714
|
+
children: content,
|
|
2715
|
+
portal: false,
|
|
2716
|
+
tabs: tabBar?.tabs,
|
|
2717
|
+
activeTab: tabBar?.activeTab,
|
|
2718
|
+
onTabChange
|
|
2719
|
+
};
|
|
2720
|
+
if (entry.route.layout) {
|
|
2721
|
+
return createElement(entry.route.layout, layoutProps);
|
|
2722
|
+
}
|
|
2723
|
+
if (entry.route.component) {
|
|
2724
|
+
return createElement(entry.route.component, { ...props, ...layoutProps });
|
|
2725
|
+
}
|
|
2726
|
+
if (entry.route.elementType) {
|
|
2727
|
+
return createElement(entry.route.elementType, { ...props, ...layoutProps });
|
|
2728
|
+
}
|
|
2729
|
+
if (entry.route.render) return entry.route.render(props);
|
|
2730
|
+
return content;
|
|
2731
|
+
}
|
|
2732
|
+
return renderRouteContent(entry.route, props);
|
|
2733
|
+
}
|
|
2734
|
+
var FrozenStackEntry = memo(function FrozenStackEntry2({
|
|
2735
|
+
entry,
|
|
2736
|
+
fallback
|
|
2737
|
+
}) {
|
|
2738
|
+
const hook = useMemo(() => frozenLocationHook(entry.pathname), [entry.pathname]);
|
|
2739
|
+
const searchHook = useMemo(() => () => entry.search, [entry.search]);
|
|
2740
|
+
const routeContext = useMemo(() => routeContextValue(entry), [entry]);
|
|
2741
|
+
const suspenseFallback = entry.route.fallback ?? fallback;
|
|
2742
|
+
return /* @__PURE__ */ jsx(Router$1, { hook, searchHook, children: /* @__PURE__ */ jsx(RouterRouteContext.Provider, { value: routeContext, children: /* @__PURE__ */ jsx(Suspense, { fallback: suspenseFallback, children: renderCompiledRoute(entry) }) }) });
|
|
2743
|
+
});
|
|
2744
|
+
var FrozenModalRouteEntry = memo(function FrozenModalRouteEntry2({
|
|
2745
|
+
entry,
|
|
2746
|
+
fallback
|
|
2747
|
+
}) {
|
|
2748
|
+
const activeScreen = entry.flowScreens?.[entry.flowScreens.length - 1];
|
|
2749
|
+
if (activeScreen) {
|
|
2750
|
+
const props = {
|
|
2751
|
+
params: activeScreen.params,
|
|
2752
|
+
pathname: activeScreen.pathname,
|
|
2753
|
+
search: activeScreen.search,
|
|
2754
|
+
historyState: activeScreen.historyState,
|
|
2755
|
+
presentation: "push"
|
|
2756
|
+
};
|
|
2757
|
+
return /* @__PURE__ */ jsx(
|
|
2758
|
+
RouteStackViewport,
|
|
2759
|
+
{
|
|
2760
|
+
route: activeScreen.route,
|
|
2761
|
+
props,
|
|
2762
|
+
fallback: activeScreen.route.fallback ?? fallback,
|
|
2763
|
+
stackKey: `${entry.id}:overlay-flow`,
|
|
2764
|
+
className: `router-overlay-flow-stack router-overlay-flow-stack--${entry.kind}`,
|
|
2765
|
+
contentClassName: "router-overlay-flow-screen",
|
|
2766
|
+
scopeOverlayContent: true,
|
|
2767
|
+
forcePushRouteChanges: true
|
|
2768
|
+
}
|
|
2769
|
+
);
|
|
2770
|
+
}
|
|
2771
|
+
return /* @__PURE__ */ jsx(
|
|
2772
|
+
FrozenModalCompiledRouteEntry,
|
|
2773
|
+
{
|
|
2774
|
+
entry,
|
|
2775
|
+
route: entry.route,
|
|
2776
|
+
fallback
|
|
2777
|
+
}
|
|
2778
|
+
);
|
|
2779
|
+
});
|
|
2780
|
+
var FrozenModalCompiledRouteEntry = memo(function FrozenModalCompiledRouteEntry2({
|
|
2781
|
+
entry,
|
|
2782
|
+
route,
|
|
2783
|
+
fallback
|
|
2784
|
+
}) {
|
|
2785
|
+
const hook = useMemo(() => frozenLocationHook(entry.pathname), [entry.pathname]);
|
|
2786
|
+
const searchHook = useMemo(() => () => entry.search, [entry.search]);
|
|
2787
|
+
const routeContext = useMemo(
|
|
2788
|
+
() => ({
|
|
2789
|
+
params: entry.params,
|
|
2790
|
+
pathname: entry.pathname,
|
|
2791
|
+
search: entry.search,
|
|
2792
|
+
searchParams: searchParamsForSearch(entry.search),
|
|
2793
|
+
historyState: entry.historyState,
|
|
2794
|
+
presentation: entry.kind
|
|
2795
|
+
}),
|
|
2796
|
+
[entry]
|
|
2797
|
+
);
|
|
2798
|
+
const props = useMemo(
|
|
2799
|
+
() => ({
|
|
2800
|
+
params: entry.params,
|
|
2801
|
+
pathname: entry.pathname,
|
|
2802
|
+
search: entry.search,
|
|
2803
|
+
historyState: entry.historyState,
|
|
2804
|
+
presentation: entry.kind
|
|
2805
|
+
}),
|
|
2806
|
+
[entry]
|
|
2807
|
+
);
|
|
2808
|
+
const suspenseFallback = route.fallback ?? fallback;
|
|
2809
|
+
const modalFallback = suspenseFallback ?? (entry.kind === "sheet" ? DEFAULT_SHEET_FALLBACK : null);
|
|
2810
|
+
return /* @__PURE__ */ jsx(Router$1, { hook, searchHook, children: /* @__PURE__ */ jsx(RouterRouteContext.Provider, { value: routeContext, children: /* @__PURE__ */ jsx(Suspense, { fallback: modalFallback, children: renderRouteContent(route, props) }) }) });
|
|
2811
|
+
});
|
|
2812
|
+
function RouterModalStackHost({
|
|
2813
|
+
entries,
|
|
2814
|
+
close,
|
|
2815
|
+
remove,
|
|
2816
|
+
fallback,
|
|
2817
|
+
shell
|
|
2818
|
+
}) {
|
|
2819
|
+
return /* @__PURE__ */ jsx(Fragment, { children: entries.map((entry, index) => /* @__PURE__ */ jsx(
|
|
2820
|
+
RouterModalEntryHost,
|
|
2821
|
+
{
|
|
2822
|
+
entry,
|
|
2823
|
+
index,
|
|
2824
|
+
close,
|
|
2825
|
+
remove,
|
|
2826
|
+
fallback,
|
|
2827
|
+
shell
|
|
2828
|
+
},
|
|
2829
|
+
entry.id
|
|
2830
|
+
)) });
|
|
2831
|
+
}
|
|
2832
|
+
var RouterModalEntryHost = memo(function RouterModalEntryHost2({
|
|
2833
|
+
entry,
|
|
2834
|
+
index,
|
|
2835
|
+
close,
|
|
2836
|
+
remove,
|
|
2837
|
+
fallback,
|
|
2838
|
+
shell
|
|
2839
|
+
}) {
|
|
2840
|
+
const closeSelf = useCallback(() => close(entry.id), [close, entry.id]);
|
|
2841
|
+
const removeSelf = useCallback(() => remove(entry.id), [remove, entry.id]);
|
|
2842
|
+
const current = useMemo(
|
|
2843
|
+
() => ({
|
|
2844
|
+
id: entry.id,
|
|
2845
|
+
index,
|
|
2846
|
+
exiting: entry.exiting,
|
|
2847
|
+
close: closeSelf,
|
|
2848
|
+
remove: removeSelf
|
|
2849
|
+
}),
|
|
2850
|
+
[entry.id, entry.exiting, index, closeSelf, removeSelf]
|
|
2851
|
+
);
|
|
2852
|
+
const zIndex = OVERLAY_STACK_BASE_Z + index;
|
|
2853
|
+
const overlayShell = entry.route.overlayLayout ?? shell;
|
|
2854
|
+
const activeContentKey = entry.flowScreens ? historyNavigationKeyFromState(entry.historyState) ?? void 0 : void 0;
|
|
2855
|
+
return /* @__PURE__ */ jsx(CurrentModalContext.Provider, { value: current, children: entry.kind === "sheet" ? /* @__PURE__ */ jsx(
|
|
2856
|
+
SheetFrame,
|
|
2857
|
+
{
|
|
2858
|
+
open: !entry.exiting,
|
|
2859
|
+
onRequestClose: closeSelf,
|
|
2860
|
+
onExitComplete: removeSelf,
|
|
2861
|
+
zIndex,
|
|
2862
|
+
shell: overlayShell,
|
|
2863
|
+
activeContentKey,
|
|
2864
|
+
children: /* @__PURE__ */ jsx(FrozenModalRouteEntry, { entry, fallback })
|
|
2865
|
+
}
|
|
2866
|
+
) : /* @__PURE__ */ jsx(
|
|
2867
|
+
ModalFrame,
|
|
2868
|
+
{
|
|
2869
|
+
open: !entry.exiting,
|
|
2870
|
+
onRequestClose: closeSelf,
|
|
2871
|
+
onExitComplete: removeSelf,
|
|
2872
|
+
zIndex,
|
|
2873
|
+
shell: overlayShell,
|
|
2874
|
+
activeContentKey,
|
|
2875
|
+
children: /* @__PURE__ */ jsx(FrozenModalRouteEntry, { entry, fallback })
|
|
2876
|
+
}
|
|
2877
|
+
) });
|
|
2878
|
+
});
|
|
2879
|
+
function resolveStackChange(prev, snapshot) {
|
|
2880
|
+
const top = prev[prev.length - 1];
|
|
2881
|
+
if (!top) {
|
|
2882
|
+
return {
|
|
2883
|
+
entries: [createEntry(snapshot, "forward", false)],
|
|
2884
|
+
direction: "forward"
|
|
2885
|
+
};
|
|
2886
|
+
}
|
|
2887
|
+
if (top.locationKey === snapshot.locationKey) {
|
|
2888
|
+
return {
|
|
2889
|
+
entries: prev.map(
|
|
2890
|
+
(entry) => entry.id === top.id ? mergeEntrySnapshot(entry, snapshot) : markCommitted(entry)
|
|
2891
|
+
),
|
|
2892
|
+
direction: "forward"
|
|
2893
|
+
};
|
|
2894
|
+
}
|
|
2895
|
+
const direction = resolveDirection(top, snapshot);
|
|
2896
|
+
if (isExplicitStackReplace(top, snapshot)) {
|
|
2897
|
+
return {
|
|
2898
|
+
entries: replaceActiveStackEntry(prev, top.id, snapshot, direction, true),
|
|
2899
|
+
direction
|
|
2900
|
+
};
|
|
2901
|
+
}
|
|
2902
|
+
const syncTargetIndex = syncTargetEntryIndex(prev, snapshot);
|
|
2903
|
+
if (syncTargetIndex !== -1 && syncTargetIndex !== prev.length - 1) {
|
|
2904
|
+
return {
|
|
2905
|
+
entries: entriesRevealingSnapshot(prev, syncTargetIndex, snapshot),
|
|
2906
|
+
direction: "back"
|
|
2907
|
+
};
|
|
2908
|
+
}
|
|
2909
|
+
if (shouldReplaceActiveStackEntry(top, snapshot)) {
|
|
2910
|
+
return {
|
|
2911
|
+
entries: replaceActiveStackEntry(prev, top.id, snapshot, direction, true),
|
|
2912
|
+
direction
|
|
2913
|
+
};
|
|
2914
|
+
}
|
|
2915
|
+
const existingIndex = existingStackEntryIndexForSnapshot(prev, snapshot);
|
|
2916
|
+
const revealsExistingEntry = existingIndex !== -1;
|
|
2917
|
+
const isBack = direction === "back";
|
|
2918
|
+
if (isBack || revealsExistingEntry) {
|
|
2919
|
+
if (!revealsExistingEntry) {
|
|
2920
|
+
return {
|
|
2921
|
+
entries: [createEntry(snapshot, "back", false)],
|
|
2922
|
+
direction: "back"
|
|
2923
|
+
};
|
|
2924
|
+
}
|
|
2925
|
+
const revealed = prev[existingIndex];
|
|
2926
|
+
const base = prev.slice(0, existingIndex).map(markCommitted);
|
|
2927
|
+
return {
|
|
2928
|
+
entries: [
|
|
2929
|
+
...base,
|
|
2930
|
+
{
|
|
2931
|
+
...revealed,
|
|
2932
|
+
...snapshot,
|
|
2933
|
+
id: revealed.id,
|
|
2934
|
+
animateEnter: false,
|
|
2935
|
+
enterDirection: "back"
|
|
2936
|
+
}
|
|
2937
|
+
],
|
|
2938
|
+
direction: "back"
|
|
2939
|
+
};
|
|
2940
|
+
}
|
|
2941
|
+
return {
|
|
2942
|
+
entries: [...prev.map(markCommitted), createEntry(snapshot, "forward", true)],
|
|
2943
|
+
direction: "forward"
|
|
2944
|
+
};
|
|
2945
|
+
}
|
|
2946
|
+
function visibleEntriesForSnapshot(entries, snapshot) {
|
|
2947
|
+
if (!snapshot) return entries;
|
|
2948
|
+
const top = entries[entries.length - 1];
|
|
2949
|
+
if (!top) {
|
|
2950
|
+
return [createEntry(snapshot, "forward", false)];
|
|
2951
|
+
}
|
|
2952
|
+
if (top.locationKey === snapshot.locationKey) {
|
|
2953
|
+
return entries.map(
|
|
2954
|
+
(entry) => entry.id === top.id ? mergeEntrySnapshot(entry, snapshot) : entry
|
|
2955
|
+
);
|
|
2956
|
+
}
|
|
2957
|
+
if (isExplicitStackReplace(top, snapshot)) {
|
|
2958
|
+
return replaceActiveStackEntry(
|
|
2959
|
+
entries,
|
|
2960
|
+
top.id,
|
|
2961
|
+
snapshot,
|
|
2962
|
+
resolveDirection(top, snapshot),
|
|
2963
|
+
false
|
|
2964
|
+
);
|
|
2965
|
+
}
|
|
2966
|
+
const syncTargetIndex = syncTargetEntryIndex(entries, snapshot);
|
|
2967
|
+
if (syncTargetIndex !== -1 && syncTargetIndex !== entries.length - 1) {
|
|
2968
|
+
return entriesRevealingSnapshot(entries, syncTargetIndex, snapshot);
|
|
2969
|
+
}
|
|
2970
|
+
if (shouldReplaceActiveStackEntry(top, snapshot)) {
|
|
2971
|
+
return replaceActiveStackEntry(
|
|
2972
|
+
entries,
|
|
2973
|
+
top.id,
|
|
2974
|
+
snapshot,
|
|
2975
|
+
resolveDirection(top, snapshot),
|
|
2976
|
+
false
|
|
2977
|
+
);
|
|
2978
|
+
}
|
|
2979
|
+
const direction = resolveDirection(top, snapshot);
|
|
2980
|
+
const existingIndex = existingStackEntryIndexForSnapshot(entries, snapshot);
|
|
2981
|
+
if (direction === "back" || existingIndex !== -1) {
|
|
2982
|
+
if (existingIndex === -1) {
|
|
2983
|
+
return [createEntry(snapshot, "back", false)];
|
|
2984
|
+
}
|
|
2985
|
+
const revealed = entries[existingIndex];
|
|
2986
|
+
const base = entries.slice(0, existingIndex).map(markCommitted);
|
|
2987
|
+
return [
|
|
2988
|
+
...base,
|
|
2989
|
+
{
|
|
2990
|
+
...revealed,
|
|
2991
|
+
...snapshot,
|
|
2992
|
+
id: revealed.id,
|
|
2993
|
+
animateEnter: false,
|
|
2994
|
+
enterDirection: "back"
|
|
2995
|
+
}
|
|
2996
|
+
];
|
|
2997
|
+
}
|
|
2998
|
+
return entries;
|
|
2999
|
+
}
|
|
3000
|
+
function activeModalEntry(entries) {
|
|
3001
|
+
for (let index = entries.length - 1; index >= 0; index -= 1) {
|
|
3002
|
+
if (!entries[index].exiting) return entries[index];
|
|
3003
|
+
}
|
|
3004
|
+
return void 0;
|
|
3005
|
+
}
|
|
3006
|
+
function modalFlowScreenFromMatch(match, pathname, search, state, historyIndex, commit) {
|
|
3007
|
+
const route = match.route.childRoute;
|
|
3008
|
+
if (!match.route.overlayFlow || !route) return null;
|
|
3009
|
+
return {
|
|
3010
|
+
overlayRoute: match.route,
|
|
3011
|
+
route,
|
|
3012
|
+
params: match.params,
|
|
3013
|
+
pathname,
|
|
3014
|
+
search,
|
|
3015
|
+
historyState: stateWithHistoryIndex(
|
|
3016
|
+
state,
|
|
3017
|
+
historyIndex,
|
|
3018
|
+
createRouterId(),
|
|
3019
|
+
commit
|
|
3020
|
+
)
|
|
3021
|
+
};
|
|
3022
|
+
}
|
|
3023
|
+
function RouterRuntime({
|
|
3024
|
+
children,
|
|
3025
|
+
fallback,
|
|
3026
|
+
shell = "mobile-contained"
|
|
3027
|
+
}) {
|
|
3028
|
+
const [pathname] = useLocation();
|
|
3029
|
+
const search = useSearch();
|
|
3030
|
+
const historyState = useHistoryState$1();
|
|
3031
|
+
const wouterRouter = useRouter$1();
|
|
3032
|
+
const compiledRoutes = useMemo(() => compileStackRoutes(children), [children]);
|
|
3033
|
+
const runtimeChildren = useMemo(
|
|
3034
|
+
() => flattenRouteNodes(children).filter((child) => !isStackRouteElement(child)),
|
|
3035
|
+
[children]
|
|
3036
|
+
);
|
|
3037
|
+
const rawMatch = useMemo(
|
|
3038
|
+
() => matchStackRouteByPresentation(
|
|
3039
|
+
compiledRoutes,
|
|
3040
|
+
wouterRouter.parser,
|
|
3041
|
+
pathname,
|
|
3042
|
+
PUSH_PRESENTATIONS
|
|
3043
|
+
),
|
|
3044
|
+
[compiledRoutes, pathname, wouterRouter.parser]
|
|
3045
|
+
);
|
|
3046
|
+
const fallbackNode = fallback ?? null;
|
|
3047
|
+
const [modalEntries, setModalEntries] = useState([]);
|
|
3048
|
+
const modalEntriesRef = useRef(modalEntries);
|
|
3049
|
+
const modalSeqRef = useRef(0);
|
|
3050
|
+
modalEntriesRef.current = modalEntries;
|
|
3051
|
+
useLayoutEffect(() => {
|
|
3052
|
+
ensureInitialHistoryIndex();
|
|
3053
|
+
}, []);
|
|
3054
|
+
useEffect(() => {
|
|
3055
|
+
document.documentElement.setAttribute("data-router-shell", shell);
|
|
3056
|
+
return () => {
|
|
3057
|
+
document.documentElement.removeAttribute("data-router-shell");
|
|
3058
|
+
};
|
|
3059
|
+
}, [shell]);
|
|
3060
|
+
const searchPath = search ? `?${search}` : "";
|
|
3061
|
+
const guardRedirect = useMemo(
|
|
3062
|
+
() => rawMatch ? guardRedirectForMatch(rawMatch, pathname, searchPath, historyState) : null,
|
|
3063
|
+
[historyState, pathname, rawMatch, searchPath]
|
|
3064
|
+
);
|
|
3065
|
+
const match = guardRedirect ? null : rawMatch;
|
|
3066
|
+
useLayoutEffect(() => {
|
|
3067
|
+
if (!guardRedirect) return;
|
|
3068
|
+
const target = parseNavigationTarget(guardRedirect, pathname);
|
|
3069
|
+
if (target.pathname === normalizedPath(pathname) && target.search === searchPath) {
|
|
3070
|
+
return;
|
|
3071
|
+
}
|
|
3072
|
+
navigateWithHistoryIndex(`${target.pathname}${target.search}`, { commit: "sync" });
|
|
3073
|
+
}, [guardRedirect, pathname, searchPath]);
|
|
3074
|
+
const snapshot = useMemo(() => {
|
|
3075
|
+
if (!match) return null;
|
|
3076
|
+
return stackSnapshot(pathname, searchPath, historyState, match);
|
|
3077
|
+
}, [historyState, match, pathname, searchPath]);
|
|
3078
|
+
const snapshotHistoryRef = useRef([]);
|
|
3079
|
+
const [entries, setEntries] = useState(
|
|
3080
|
+
() => snapshot ? [createEntry(snapshot, "forward", false)] : []
|
|
3081
|
+
);
|
|
3082
|
+
const [heldEnterIds, setHeldEnterIds] = useState(() => /* @__PURE__ */ new Set());
|
|
3083
|
+
const heldEnterIdsRef = useRef(heldEnterIds);
|
|
3084
|
+
const enterHoldCleanupRef = useRef(/* @__PURE__ */ new Map());
|
|
3085
|
+
const entryArchiveRef = useRef(
|
|
3086
|
+
new Map(entries.map((entry) => [entry.id, entry]))
|
|
3087
|
+
);
|
|
3088
|
+
const { stateMap, setItem, toggle, deleteItem } = useTransitionMap({
|
|
3089
|
+
timeout: ROUTE_TRANSITION_MS,
|
|
3090
|
+
preEnter: true,
|
|
3091
|
+
preExit: true,
|
|
3092
|
+
mountOnEnter: true,
|
|
3093
|
+
unmountOnExit: true,
|
|
3094
|
+
allowMultiple: true
|
|
3095
|
+
});
|
|
3096
|
+
for (const entry of entries) {
|
|
3097
|
+
entryArchiveRef.current.set(entry.id, entry);
|
|
3098
|
+
}
|
|
3099
|
+
const entriesRef = useRef(entries);
|
|
3100
|
+
entriesRef.current = entries;
|
|
3101
|
+
heldEnterIdsRef.current = heldEnterIds;
|
|
3102
|
+
const releaseHeldEnter = useCallback((id) => {
|
|
3103
|
+
const cleanup = enterHoldCleanupRef.current.get(id);
|
|
3104
|
+
if (cleanup) cleanup();
|
|
3105
|
+
enterHoldCleanupRef.current.delete(id);
|
|
3106
|
+
setHeldEnterIds((prev) => {
|
|
3107
|
+
if (!prev.has(id)) return prev;
|
|
3108
|
+
const next = new Set(prev);
|
|
3109
|
+
next.delete(id);
|
|
3110
|
+
return next;
|
|
3111
|
+
});
|
|
3112
|
+
}, []);
|
|
3113
|
+
const holdEnterUntilPainted = useCallback((id, onRelease) => {
|
|
3114
|
+
if (heldEnterIdsRef.current.has(id) || enterHoldCleanupRef.current.has(id)) return;
|
|
3115
|
+
setHeldEnterIds((prev) => {
|
|
3116
|
+
if (prev.has(id)) return prev;
|
|
3117
|
+
const next = new Set(prev);
|
|
3118
|
+
next.add(id);
|
|
3119
|
+
return next;
|
|
3120
|
+
});
|
|
3121
|
+
let frame = 0;
|
|
3122
|
+
let timeout = 0;
|
|
3123
|
+
const cleanup = () => {
|
|
3124
|
+
if (frame) window.cancelAnimationFrame(frame);
|
|
3125
|
+
if (timeout) window.clearTimeout(timeout);
|
|
3126
|
+
};
|
|
3127
|
+
frame = window.requestAnimationFrame(() => {
|
|
3128
|
+
timeout = window.setTimeout(() => {
|
|
3129
|
+
enterHoldCleanupRef.current.delete(id);
|
|
3130
|
+
setHeldEnterIds((prev) => {
|
|
3131
|
+
if (!prev.has(id)) return prev;
|
|
3132
|
+
const next = new Set(prev);
|
|
3133
|
+
next.delete(id);
|
|
3134
|
+
return next;
|
|
3135
|
+
});
|
|
3136
|
+
onRelease();
|
|
3137
|
+
}, 0);
|
|
3138
|
+
});
|
|
3139
|
+
enterHoldCleanupRef.current.set(id, cleanup);
|
|
3140
|
+
}, []);
|
|
3141
|
+
useEffect(() => {
|
|
3142
|
+
return () => {
|
|
3143
|
+
for (const cleanup of enterHoldCleanupRef.current.values()) cleanup();
|
|
3144
|
+
enterHoldCleanupRef.current.clear();
|
|
3145
|
+
};
|
|
3146
|
+
}, []);
|
|
3147
|
+
useLayoutEffect(() => {
|
|
3148
|
+
if (!snapshot) return;
|
|
3149
|
+
snapshotHistoryRef.current = updateSnapshotHistory(
|
|
3150
|
+
snapshotHistoryRef.current,
|
|
3151
|
+
snapshot
|
|
3152
|
+
);
|
|
3153
|
+
setEntries((prev) => {
|
|
3154
|
+
const change = resolveStackChange(prev, snapshot);
|
|
3155
|
+
const nextIds = new Set(change.entries.map((entry) => entry.id));
|
|
3156
|
+
for (const entry of prev) {
|
|
3157
|
+
if (!nextIds.has(entry.id)) {
|
|
3158
|
+
entryArchiveRef.current.set(entry.id, {
|
|
3159
|
+
...entry,
|
|
3160
|
+
animateEnter: false,
|
|
3161
|
+
exitDirection: change.direction
|
|
3162
|
+
});
|
|
3163
|
+
}
|
|
3164
|
+
}
|
|
3165
|
+
for (const entry of change.entries) {
|
|
3166
|
+
entryArchiveRef.current.set(entry.id, entry);
|
|
3167
|
+
}
|
|
3168
|
+
return change.entries;
|
|
3169
|
+
});
|
|
3170
|
+
}, [snapshot]);
|
|
3171
|
+
const visibleEntries = useMemo(
|
|
3172
|
+
() => visibleEntriesForSnapshot(entries, snapshot),
|
|
3173
|
+
[entries, snapshot]
|
|
3174
|
+
);
|
|
3175
|
+
const activeIds = useMemo(() => new Set(entries.map((entry) => entry.id)), [entries]);
|
|
3176
|
+
const visibleActiveIds = useMemo(
|
|
3177
|
+
() => new Set(visibleEntries.map((entry) => entry.id)),
|
|
3178
|
+
[visibleEntries]
|
|
3179
|
+
);
|
|
3180
|
+
const visibleActiveId = visibleEntries[visibleEntries.length - 1]?.id ?? null;
|
|
3181
|
+
const visibleActiveEntry = visibleEntries[visibleEntries.length - 1];
|
|
3182
|
+
const visibleActiveEntryRef = useRef(void 0);
|
|
3183
|
+
visibleActiveEntryRef.current = visibleActiveEntry;
|
|
3184
|
+
const visibleStackDirection = visibleActiveEntry?.enterDirection ?? "forward";
|
|
3185
|
+
const activeIdKey = useMemo(
|
|
3186
|
+
() => entries.map((entry) => entry.id).join("|"),
|
|
3187
|
+
[entries]
|
|
3188
|
+
);
|
|
3189
|
+
const mountedTransitionEntries = useMemo(
|
|
3190
|
+
() => Array.from(stateMap.entries()).filter(([, state]) => state.isMounted),
|
|
3191
|
+
[stateMap]
|
|
3192
|
+
);
|
|
3193
|
+
const isTransitionSettled = mountedTransitionEntries.every(
|
|
3194
|
+
([, state]) => state.isResolved
|
|
3195
|
+
);
|
|
3196
|
+
useLayoutEffect(() => {
|
|
3197
|
+
for (const entry of entries) {
|
|
3198
|
+
const state = stateMap.get(entry.id);
|
|
3199
|
+
if (!state) {
|
|
3200
|
+
setItem(entry.id, { initialEntered: !entry.animateEnter });
|
|
3201
|
+
if (entry.animateEnter) {
|
|
3202
|
+
holdEnterUntilPainted(entry.id, () => toggle(entry.id, true));
|
|
3203
|
+
}
|
|
3204
|
+
continue;
|
|
3205
|
+
}
|
|
3206
|
+
if (heldEnterIds.has(entry.id)) {
|
|
3207
|
+
continue;
|
|
3208
|
+
}
|
|
3209
|
+
if (!state.isEnter) {
|
|
3210
|
+
toggle(entry.id, true);
|
|
3211
|
+
}
|
|
3212
|
+
}
|
|
3213
|
+
for (const [id, state] of stateMap) {
|
|
3214
|
+
if (!activeIds.has(id) && state.isEnter) {
|
|
3215
|
+
releaseHeldEnter(id);
|
|
3216
|
+
toggle(id, false);
|
|
3217
|
+
}
|
|
3218
|
+
}
|
|
3219
|
+
}, [
|
|
3220
|
+
activeIdKey,
|
|
3221
|
+
activeIds,
|
|
3222
|
+
entries,
|
|
3223
|
+
heldEnterIds,
|
|
3224
|
+
holdEnterUntilPainted,
|
|
3225
|
+
releaseHeldEnter,
|
|
3226
|
+
setItem,
|
|
3227
|
+
stateMap,
|
|
3228
|
+
toggle
|
|
3229
|
+
]);
|
|
3230
|
+
useEffect(() => {
|
|
3231
|
+
const unmountedIds = Array.from(stateMap.entries()).filter(([, state]) => !state.isMounted).map(([id]) => id);
|
|
3232
|
+
for (const id of unmountedIds) {
|
|
3233
|
+
if (activeIds.has(id)) continue;
|
|
3234
|
+
entryArchiveRef.current.delete(id);
|
|
3235
|
+
releaseHeldEnter(id);
|
|
3236
|
+
deleteItem(id);
|
|
3237
|
+
}
|
|
3238
|
+
}, [activeIds, deleteItem, releaseHeldEnter, stateMap]);
|
|
3239
|
+
const renderEntries = useMemo(() => {
|
|
3240
|
+
const result = [...visibleEntries];
|
|
3241
|
+
for (const [id] of mountedTransitionEntries) {
|
|
3242
|
+
if (visibleActiveIds.has(id)) continue;
|
|
3243
|
+
const entry = entryArchiveRef.current.get(id);
|
|
3244
|
+
if (!entry) continue;
|
|
3245
|
+
result.push(entry);
|
|
3246
|
+
}
|
|
3247
|
+
return result;
|
|
3248
|
+
}, [visibleActiveIds, visibleEntries, mountedTransitionEntries]);
|
|
3249
|
+
const removeModal = useCallback((id) => {
|
|
3250
|
+
setModalEntries((prev) => prev.filter((entry) => entry.id !== id));
|
|
3251
|
+
}, []);
|
|
3252
|
+
const closeModal = useCallback((id) => {
|
|
3253
|
+
setModalEntries((prev) => {
|
|
3254
|
+
let changed = false;
|
|
3255
|
+
const next = prev.map((entry) => {
|
|
3256
|
+
if (entry.id !== id || entry.exiting) return entry;
|
|
3257
|
+
changed = true;
|
|
3258
|
+
return { ...entry, exiting: true };
|
|
3259
|
+
});
|
|
3260
|
+
return changed ? next : prev;
|
|
3261
|
+
});
|
|
3262
|
+
}, []);
|
|
3263
|
+
const closeAllModals = useCallback(() => {
|
|
3264
|
+
setModalEntries((prev) => {
|
|
3265
|
+
let changed = false;
|
|
3266
|
+
const next = prev.map((entry) => {
|
|
3267
|
+
if (entry.exiting) return entry;
|
|
3268
|
+
changed = true;
|
|
3269
|
+
return { ...entry, exiting: true };
|
|
3270
|
+
});
|
|
3271
|
+
return changed ? next : prev;
|
|
3272
|
+
});
|
|
3273
|
+
}, []);
|
|
3274
|
+
const goBackTopModal = useCallback(() => {
|
|
3275
|
+
const entry = activeModalEntry(modalEntriesRef.current);
|
|
3276
|
+
if (!entry) return false;
|
|
3277
|
+
if (entry.flowScreens && entry.flowScreens.length > 1) {
|
|
3278
|
+
setModalEntries(
|
|
3279
|
+
(current) => current.map((candidate) => {
|
|
3280
|
+
if (candidate.id !== entry.id || !candidate.flowScreens) return candidate;
|
|
3281
|
+
const flowScreens = candidate.flowScreens.slice(0, -1);
|
|
3282
|
+
const activeScreen = flowScreens[flowScreens.length - 1];
|
|
3283
|
+
if (!activeScreen) return candidate;
|
|
3284
|
+
return {
|
|
3285
|
+
...candidate,
|
|
3286
|
+
route: activeScreen.overlayRoute,
|
|
3287
|
+
params: activeScreen.params,
|
|
3288
|
+
pathname: activeScreen.pathname,
|
|
3289
|
+
search: activeScreen.search,
|
|
3290
|
+
historyState: activeScreen.historyState,
|
|
3291
|
+
flowScreens
|
|
3292
|
+
};
|
|
3293
|
+
})
|
|
3294
|
+
);
|
|
3295
|
+
return true;
|
|
3296
|
+
}
|
|
3297
|
+
closeModal(entry.id);
|
|
3298
|
+
return true;
|
|
3299
|
+
}, [closeModal]);
|
|
3300
|
+
const updateActiveModalFlow = useCallback(
|
|
3301
|
+
(match2, target, state, operation) => {
|
|
3302
|
+
const entry = activeModalEntry(modalEntriesRef.current);
|
|
3303
|
+
const flow = match2.route.overlayFlow;
|
|
3304
|
+
if (!entry?.flowScreens || !flow || entry.route.overlayFlow?.id !== flow.id) {
|
|
3305
|
+
return false;
|
|
3306
|
+
}
|
|
3307
|
+
const historyIndex = operation === "replace" ? Math.max(0, entry.flowScreens.length - 1) : entry.flowScreens.length;
|
|
3308
|
+
const screen = modalFlowScreenFromMatch(
|
|
3309
|
+
match2,
|
|
3310
|
+
target.pathname,
|
|
3311
|
+
target.search,
|
|
3312
|
+
state,
|
|
3313
|
+
historyIndex,
|
|
3314
|
+
operation
|
|
3315
|
+
);
|
|
3316
|
+
if (!screen) return false;
|
|
3317
|
+
setModalEntries(
|
|
3318
|
+
(current) => current.map((candidate) => {
|
|
3319
|
+
if (candidate.id !== entry.id || !candidate.flowScreens) return candidate;
|
|
3320
|
+
const flowScreens = operation === "replace" ? [...candidate.flowScreens.slice(0, -1), screen] : [...candidate.flowScreens, screen];
|
|
3321
|
+
return {
|
|
3322
|
+
...candidate,
|
|
3323
|
+
route: screen.overlayRoute,
|
|
3324
|
+
params: screen.params,
|
|
3325
|
+
pathname: screen.pathname,
|
|
3326
|
+
search: screen.search,
|
|
3327
|
+
historyState: screen.historyState,
|
|
3328
|
+
flowScreens
|
|
3329
|
+
};
|
|
3330
|
+
})
|
|
3331
|
+
);
|
|
3332
|
+
return true;
|
|
3333
|
+
},
|
|
3334
|
+
[]
|
|
3335
|
+
);
|
|
3336
|
+
const pushModalEntry = useCallback(
|
|
3337
|
+
(entry, replace2 = false) => {
|
|
3338
|
+
modalSeqRef.current += 1;
|
|
3339
|
+
const id = `${entry.kind}:${modalSeqRef.current}-${createRouterId()}`;
|
|
3340
|
+
const nextEntry = { ...entry, id, exiting: false };
|
|
3341
|
+
setModalEntries((prev) => {
|
|
3342
|
+
if (replace2 && prev.length > 0) {
|
|
3343
|
+
return [...prev.slice(0, -1), nextEntry];
|
|
3344
|
+
}
|
|
3345
|
+
return [...prev, nextEntry];
|
|
3346
|
+
});
|
|
3347
|
+
return id;
|
|
3348
|
+
},
|
|
3349
|
+
[]
|
|
3350
|
+
);
|
|
3351
|
+
const navigate = useCallback(
|
|
3352
|
+
(to, options = {}) => {
|
|
3353
|
+
if (typeof to === "number") {
|
|
3354
|
+
if (to < 0 && goBackTopModal()) return;
|
|
3355
|
+
window.history.go(to);
|
|
3356
|
+
return;
|
|
3357
|
+
}
|
|
3358
|
+
const target = parseNavigationTarget(to, pathname);
|
|
3359
|
+
const overlayMatch = matchStackRouteByPresentation(
|
|
3360
|
+
compiledRoutes,
|
|
3361
|
+
wouterRouter.parser,
|
|
3362
|
+
target.pathname,
|
|
3363
|
+
OVERLAY_PRESENTATIONS
|
|
3364
|
+
);
|
|
3365
|
+
if (overlayMatch && isModalLikePresentation(overlayMatch.route.presentation)) {
|
|
3366
|
+
const overlayState = stateForSplitNavigationTarget(
|
|
3367
|
+
options.state,
|
|
3368
|
+
null,
|
|
3369
|
+
"navigate"
|
|
3370
|
+
);
|
|
3371
|
+
const overlayRedirect = guardRedirectForMatch(
|
|
3372
|
+
overlayMatch,
|
|
3373
|
+
target.pathname,
|
|
3374
|
+
target.search,
|
|
3375
|
+
overlayState
|
|
3376
|
+
);
|
|
3377
|
+
if (overlayRedirect) {
|
|
3378
|
+
navigateWithHistoryIndex(overlayRedirect, { commit: "sync" });
|
|
3379
|
+
return;
|
|
3380
|
+
}
|
|
3381
|
+
if (updateActiveModalFlow(overlayMatch, target, overlayState, "push")) {
|
|
3382
|
+
return;
|
|
3383
|
+
}
|
|
3384
|
+
const initialFlowScreen = modalFlowScreenFromMatch(
|
|
3385
|
+
overlayMatch,
|
|
3386
|
+
target.pathname,
|
|
3387
|
+
target.search,
|
|
3388
|
+
overlayState,
|
|
3389
|
+
0,
|
|
3390
|
+
"push"
|
|
3391
|
+
);
|
|
3392
|
+
pushModalEntry({
|
|
3393
|
+
kind: overlayMatch.route.presentation,
|
|
3394
|
+
route: overlayMatch.route,
|
|
3395
|
+
params: overlayMatch.params,
|
|
3396
|
+
pathname: target.pathname,
|
|
3397
|
+
search: target.search,
|
|
3398
|
+
historyState: initialFlowScreen?.historyState ?? overlayState,
|
|
3399
|
+
flowScreens: initialFlowScreen ? [initialFlowScreen] : void 0
|
|
3400
|
+
});
|
|
3401
|
+
return;
|
|
3402
|
+
}
|
|
3403
|
+
const pushMatch = matchStackRouteByPresentation(
|
|
3404
|
+
compiledRoutes,
|
|
3405
|
+
wouterRouter.parser,
|
|
3406
|
+
target.pathname,
|
|
3407
|
+
PUSH_PRESENTATIONS
|
|
3408
|
+
);
|
|
3409
|
+
navigateWithHistoryIndex(to, {
|
|
3410
|
+
...options,
|
|
3411
|
+
state: stateForSplitNavigationTarget(options.state, pushMatch, "navigate")
|
|
3412
|
+
});
|
|
3413
|
+
},
|
|
3414
|
+
[
|
|
3415
|
+
compiledRoutes,
|
|
3416
|
+
goBackTopModal,
|
|
3417
|
+
pathname,
|
|
3418
|
+
pushModalEntry,
|
|
3419
|
+
updateActiveModalFlow,
|
|
3420
|
+
wouterRouter.parser
|
|
3421
|
+
]
|
|
3422
|
+
);
|
|
3423
|
+
const replace = useCallback(
|
|
3424
|
+
(to, options = {}) => {
|
|
3425
|
+
const target = parseNavigationTarget(to, pathname);
|
|
3426
|
+
const overlayMatch = matchStackRouteByPresentation(
|
|
3427
|
+
compiledRoutes,
|
|
3428
|
+
wouterRouter.parser,
|
|
3429
|
+
target.pathname,
|
|
3430
|
+
OVERLAY_PRESENTATIONS
|
|
3431
|
+
);
|
|
3432
|
+
if (overlayMatch && isModalLikePresentation(overlayMatch.route.presentation)) {
|
|
3433
|
+
const overlayState = stateForSplitNavigationTarget(
|
|
3434
|
+
options.state,
|
|
3435
|
+
null,
|
|
3436
|
+
"replace"
|
|
3437
|
+
);
|
|
3438
|
+
const overlayRedirect = guardRedirectForMatch(
|
|
3439
|
+
overlayMatch,
|
|
3440
|
+
target.pathname,
|
|
3441
|
+
target.search,
|
|
3442
|
+
overlayState
|
|
3443
|
+
);
|
|
3444
|
+
if (overlayRedirect) {
|
|
3445
|
+
navigateWithHistoryIndex(overlayRedirect, {
|
|
3446
|
+
commit: "replace",
|
|
3447
|
+
state: options.state
|
|
3448
|
+
});
|
|
3449
|
+
return;
|
|
3450
|
+
}
|
|
3451
|
+
if (updateActiveModalFlow(overlayMatch, target, overlayState, "replace")) {
|
|
3452
|
+
return;
|
|
3453
|
+
}
|
|
3454
|
+
const initialFlowScreen = modalFlowScreenFromMatch(
|
|
3455
|
+
overlayMatch,
|
|
3456
|
+
target.pathname,
|
|
3457
|
+
target.search,
|
|
3458
|
+
overlayState,
|
|
3459
|
+
0,
|
|
3460
|
+
"replace"
|
|
3461
|
+
);
|
|
3462
|
+
pushModalEntry(
|
|
3463
|
+
{
|
|
3464
|
+
kind: overlayMatch.route.presentation,
|
|
3465
|
+
route: overlayMatch.route,
|
|
3466
|
+
params: overlayMatch.params,
|
|
3467
|
+
pathname: target.pathname,
|
|
3468
|
+
search: target.search,
|
|
3469
|
+
historyState: initialFlowScreen?.historyState ?? overlayState,
|
|
3470
|
+
flowScreens: initialFlowScreen ? [initialFlowScreen] : void 0
|
|
3471
|
+
},
|
|
3472
|
+
true
|
|
3473
|
+
);
|
|
3474
|
+
return;
|
|
3475
|
+
}
|
|
3476
|
+
const pushMatch = matchStackRouteByPresentation(
|
|
3477
|
+
compiledRoutes,
|
|
3478
|
+
wouterRouter.parser,
|
|
3479
|
+
target.pathname,
|
|
3480
|
+
PUSH_PRESENTATIONS
|
|
3481
|
+
);
|
|
3482
|
+
navigateWithHistoryIndex(to, {
|
|
3483
|
+
commit: "replace",
|
|
3484
|
+
state: stateForSplitNavigationTarget(options.state, pushMatch, "replace")
|
|
3485
|
+
});
|
|
3486
|
+
},
|
|
3487
|
+
[
|
|
3488
|
+
compiledRoutes,
|
|
3489
|
+
pathname,
|
|
3490
|
+
pushModalEntry,
|
|
3491
|
+
updateActiveModalFlow,
|
|
3492
|
+
wouterRouter.parser
|
|
3493
|
+
]
|
|
3494
|
+
);
|
|
3495
|
+
const goBack = useCallback(() => {
|
|
3496
|
+
if (goBackTopModal()) return true;
|
|
3497
|
+
const activeEntry = visibleActiveEntryRef.current;
|
|
3498
|
+
const activeSplitRoute = activeEntry ? splitViewRouteForSnapshot(activeEntry) : void 0;
|
|
3499
|
+
const activeSplitNavigation = activeEntry?.splitNavigation;
|
|
3500
|
+
if (activeEntry && activeSplitRoute?.splitView?.activePane === "secondary" && activeSplitNavigation) {
|
|
3501
|
+
const previousDetailSnapshot = previousSnapshotInDetailPath(
|
|
3502
|
+
snapshotHistoryRef.current,
|
|
3503
|
+
activeEntry
|
|
3504
|
+
);
|
|
3505
|
+
if (navigateToSnapshot(previousDetailSnapshot)) return true;
|
|
3506
|
+
const splitRootTarget = secondarySplitBackTarget(activeEntry);
|
|
3507
|
+
if (splitRootTarget) {
|
|
3508
|
+
navigateWithHistoryIndex(`${splitRootTarget}${activeEntry.search}`, {
|
|
3509
|
+
commit: "sync",
|
|
3510
|
+
state: stateWithoutSplitNavigation(activeEntry.historyState)
|
|
3511
|
+
});
|
|
3512
|
+
return true;
|
|
3513
|
+
}
|
|
3514
|
+
}
|
|
3515
|
+
const previousSnapshot = previousSnapshotFromHistory(
|
|
3516
|
+
snapshotHistoryRef.current,
|
|
3517
|
+
activeEntry
|
|
3518
|
+
);
|
|
3519
|
+
if (canNavigateBackWithinDrawer(previousSnapshot, activeEntry)) {
|
|
3520
|
+
return navigateToSnapshot(previousSnapshot);
|
|
3521
|
+
}
|
|
3522
|
+
const previousEntry = previousStackEntry(entriesRef.current, activeEntry);
|
|
3523
|
+
if (navigateToSnapshot(previousEntry)) return true;
|
|
3524
|
+
if (canNavigateBackWithinSplit(previousSnapshot, activeEntry)) {
|
|
3525
|
+
return navigateToSnapshot(previousSnapshot);
|
|
3526
|
+
}
|
|
3527
|
+
const splitBackTarget = secondarySplitBackTarget(activeEntry);
|
|
3528
|
+
if (splitBackTarget) {
|
|
3529
|
+
navigateWithHistoryIndex(`${splitBackTarget}${activeEntry?.search ?? ""}`, {
|
|
3530
|
+
commit: "sync",
|
|
3531
|
+
state: activeEntry?.historyState
|
|
3532
|
+
});
|
|
3533
|
+
return true;
|
|
3534
|
+
}
|
|
3535
|
+
return false;
|
|
3536
|
+
}, [goBackTopModal]);
|
|
3537
|
+
const router = useMemo(
|
|
3538
|
+
() => ({
|
|
3539
|
+
navigate,
|
|
3540
|
+
replace,
|
|
3541
|
+
close: closeModal,
|
|
3542
|
+
closeAll: closeAllModals,
|
|
3543
|
+
goBack
|
|
3544
|
+
}),
|
|
3545
|
+
[closeAllModals, closeModal, goBack, navigate, replace]
|
|
3546
|
+
);
|
|
3547
|
+
useEffect(() => {
|
|
3548
|
+
if (visibleActiveEntry) {
|
|
3549
|
+
document.documentElement.setAttribute(
|
|
3550
|
+
"data-route-stack-active-key",
|
|
3551
|
+
visibleActiveEntry.stackKey
|
|
3552
|
+
);
|
|
3553
|
+
document.documentElement.setAttribute(
|
|
3554
|
+
"data-route-stack-active-presentation",
|
|
3555
|
+
visibleActiveEntry.presentation
|
|
3556
|
+
);
|
|
3557
|
+
}
|
|
3558
|
+
return () => {
|
|
3559
|
+
document.documentElement.removeAttribute("data-route-stack-active-key");
|
|
3560
|
+
document.documentElement.removeAttribute("data-route-stack-active-presentation");
|
|
3561
|
+
};
|
|
3562
|
+
}, [visibleActiveEntry]);
|
|
3563
|
+
if (guardRedirect) {
|
|
3564
|
+
return /* @__PURE__ */ jsxs(RouterActionsContext.Provider, { value: router, children: [
|
|
3565
|
+
runtimeChildren,
|
|
3566
|
+
fallbackNode
|
|
3567
|
+
] });
|
|
3568
|
+
}
|
|
3569
|
+
if (!snapshot && entries.length === 0) {
|
|
3570
|
+
return /* @__PURE__ */ jsxs(RouterActionsContext.Provider, { value: router, children: [
|
|
3571
|
+
runtimeChildren,
|
|
3572
|
+
fallbackNode,
|
|
3573
|
+
/* @__PURE__ */ jsx(
|
|
3574
|
+
RouterModalStackHost,
|
|
3575
|
+
{
|
|
3576
|
+
entries: modalEntries,
|
|
3577
|
+
close: closeModal,
|
|
3578
|
+
remove: removeModal,
|
|
3579
|
+
fallback: fallbackNode,
|
|
3580
|
+
shell
|
|
3581
|
+
}
|
|
3582
|
+
)
|
|
3583
|
+
] });
|
|
3584
|
+
}
|
|
3585
|
+
return /* @__PURE__ */ jsxs(RouterActionsContext.Provider, { value: router, children: [
|
|
3586
|
+
runtimeChildren,
|
|
3587
|
+
/* @__PURE__ */ jsx(
|
|
3588
|
+
"div",
|
|
3589
|
+
{
|
|
3590
|
+
className: "screen-stack",
|
|
3591
|
+
"data-router-shell": shell,
|
|
3592
|
+
"data-animation": !isTransitionSettled ? "true" : void 0,
|
|
3593
|
+
style: { "--stack-transition-time": `${ROUTE_TRANSITION_MS}ms` },
|
|
3594
|
+
children: renderEntries.map((entry, index) => {
|
|
3595
|
+
const phase = phaseForEntry(entry, visibleActiveIds, visibleActiveId);
|
|
3596
|
+
const transitionStatus = heldEnterIds.has(entry.id) ? "preEnter" : transitionStatusForEntry(entry, stateMap.get(entry.id)?.status);
|
|
3597
|
+
const animationType = animationClassForEntry(
|
|
3598
|
+
entry,
|
|
3599
|
+
phase,
|
|
3600
|
+
visibleActiveEntry,
|
|
3601
|
+
visibleStackDirection
|
|
3602
|
+
);
|
|
3603
|
+
const zIndex = phase === "exiting" ? renderEntries.length + index + 1 : index + 1;
|
|
3604
|
+
const contentContainer = stackEntryContentContainer(entry);
|
|
3605
|
+
return /* @__PURE__ */ jsx(
|
|
3606
|
+
"div",
|
|
3607
|
+
{
|
|
3608
|
+
"data-route-stack-screen": "true",
|
|
3609
|
+
"data-route-stack-key": entry.stackKey,
|
|
3610
|
+
"data-route-stack-route-id": entry.route.id,
|
|
3611
|
+
"data-route-stack-container": entry.route.container,
|
|
3612
|
+
"data-route-stack-content-container": contentContainer,
|
|
3613
|
+
"data-route-stack-presentation": entry.presentation,
|
|
3614
|
+
"data-route-stack-phase": phase,
|
|
3615
|
+
"data-route-stack-transition": transitionStatus,
|
|
3616
|
+
className: screenClassName(entry, phase, transitionStatus, animationType),
|
|
3617
|
+
style: { zIndex },
|
|
3618
|
+
children: /* @__PURE__ */ jsx("div", { className: "stack-screen-container", children: /* @__PURE__ */ jsx(FrozenStackEntry, { entry, fallback: fallbackNode }) })
|
|
3619
|
+
},
|
|
3620
|
+
entry.id
|
|
3621
|
+
);
|
|
3622
|
+
})
|
|
3623
|
+
}
|
|
3624
|
+
),
|
|
3625
|
+
/* @__PURE__ */ jsx(
|
|
3626
|
+
RouterModalStackHost,
|
|
3627
|
+
{
|
|
3628
|
+
entries: modalEntries,
|
|
3629
|
+
close: closeModal,
|
|
3630
|
+
remove: removeModal,
|
|
3631
|
+
fallback: fallbackNode,
|
|
3632
|
+
shell
|
|
3633
|
+
}
|
|
3634
|
+
)
|
|
3635
|
+
] });
|
|
3636
|
+
}
|
|
3637
|
+
function RouterRoot(props) {
|
|
3638
|
+
return /* @__PURE__ */ jsx(
|
|
3639
|
+
Router$1,
|
|
3640
|
+
{
|
|
3641
|
+
aroundNav: (_navigate, to, options) => {
|
|
3642
|
+
navigateWithHistoryIndex(to, options);
|
|
3643
|
+
},
|
|
3644
|
+
children: /* @__PURE__ */ jsx(RouterRuntime, { ...props })
|
|
3645
|
+
}
|
|
3646
|
+
);
|
|
3647
|
+
}
|
|
3648
|
+
var RouterScreen = routeComponent("push");
|
|
3649
|
+
var RouterStack = routeComponent("push");
|
|
3650
|
+
var RouterModal = routeComponent("modal");
|
|
3651
|
+
var RouterSheet = routeComponent("sheet");
|
|
3652
|
+
var RouterTabBar = routeComponent("push", "tabbar");
|
|
3653
|
+
var RouterTabBarItem = routeComponent("push", "tabbar-item");
|
|
3654
|
+
var RouterDrawer = routeComponent("push", "drawer");
|
|
3655
|
+
var RouterDrawerGroup = routeComponent("push", "drawer-group");
|
|
3656
|
+
var RouterDrawerSection = routeComponent(
|
|
3657
|
+
"push",
|
|
3658
|
+
"drawer-section"
|
|
3659
|
+
);
|
|
3660
|
+
var RouterDrawerItem = routeComponent("push", "drawer-item");
|
|
3661
|
+
var RouterSplitViewPrimary = routeComponent(
|
|
3662
|
+
"push",
|
|
3663
|
+
"split-primary"
|
|
3664
|
+
);
|
|
3665
|
+
var RouterSplitViewSecondary = routeComponent(
|
|
3666
|
+
"push",
|
|
3667
|
+
"split-secondary"
|
|
3668
|
+
);
|
|
3669
|
+
var RouterSplitView = Object.assign(
|
|
3670
|
+
routeComponent("push", "splitview"),
|
|
3671
|
+
{
|
|
3672
|
+
Primary: RouterSplitViewPrimary,
|
|
3673
|
+
Secondary: RouterSplitViewSecondary
|
|
3674
|
+
}
|
|
3675
|
+
);
|
|
3676
|
+
var RouterProtected = routeComponent("push", "protected");
|
|
3677
|
+
var RouterRedirect = routeComponent("push", "redirect");
|
|
3678
|
+
var Router = Object.assign(RouterRoot, {
|
|
3679
|
+
Screen: RouterScreen,
|
|
3680
|
+
Stack: RouterStack,
|
|
3681
|
+
Redirect: RouterRedirect,
|
|
3682
|
+
Modal: RouterModal,
|
|
3683
|
+
Sheet: RouterSheet,
|
|
3684
|
+
TabBar: RouterTabBar,
|
|
3685
|
+
TabBarItem: RouterTabBarItem,
|
|
3686
|
+
Drawer: RouterDrawer,
|
|
3687
|
+
DrawerGroup: RouterDrawerGroup,
|
|
3688
|
+
DrawerSection: RouterDrawerSection,
|
|
3689
|
+
DrawerItem: RouterDrawerItem,
|
|
3690
|
+
SplitView: RouterSplitView,
|
|
3691
|
+
Protected: RouterProtected
|
|
3692
|
+
});
|
|
3693
|
+
|
|
3694
|
+
export { Modal, ModalFrame, Router, Sheet, SheetFrame, sheetDragStartsInInteractiveControl, sheetScrollAtTop, useCurrentModal, useCurrentRoute, useDrawer, useHistoryState, useModalSwipeTarget, useParams, useRoute, useRouter, useSearchParams, useSheetDragEngine };
|
|
3695
|
+
//# sourceMappingURL=index.js.map
|
|
3696
|
+
//# sourceMappingURL=index.js.map
|