@sigmela/router 0.7.2 → 0.9.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 +45 -0
- package/README.md +70 -1
- package/dist/Router.d.ts +9 -0
- package/dist/Router.d.ts.map +1 -1
- package/dist/components/Modal.d.ts +10 -3
- package/dist/components/Modal.d.ts.map +1 -1
- package/dist/components/SheetSurface.d.ts +4 -1
- package/dist/components/SheetSurface.d.ts.map +1 -1
- package/dist/index.js +320 -151
- package/dist/index.js.map +1 -1
- package/dist/navigationHistory.d.ts +1 -1
- package/dist/navigationHistory.d.ts.map +1 -1
- package/dist/router.css +95 -9
- package/dist/utils/useMediaQuery.d.ts +5 -0
- package/dist/utils/useMediaQuery.d.ts.map +1 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -236,15 +236,52 @@ function useSheetDragEngine({
|
|
|
236
236
|
targetRef
|
|
237
237
|
]);
|
|
238
238
|
}
|
|
239
|
+
function useMediaQuery(query) {
|
|
240
|
+
const [matches, setMatches] = useState(() => {
|
|
241
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function") {
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
|
+
return window.matchMedia(query).matches;
|
|
245
|
+
});
|
|
246
|
+
useEffect(() => {
|
|
247
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function") {
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
const mediaQuery = window.matchMedia(query);
|
|
251
|
+
const handleChange = (event) => setMatches(event.matches);
|
|
252
|
+
setMatches(mediaQuery.matches);
|
|
253
|
+
if (typeof mediaQuery.addEventListener === "function") {
|
|
254
|
+
mediaQuery.addEventListener("change", handleChange);
|
|
255
|
+
return () => mediaQuery.removeEventListener("change", handleChange);
|
|
256
|
+
}
|
|
257
|
+
const mediaQueryWithListener = mediaQuery;
|
|
258
|
+
mediaQueryWithListener.addListener?.(handleChange);
|
|
259
|
+
return () => mediaQueryWithListener.removeListener?.(handleChange);
|
|
260
|
+
}, [query]);
|
|
261
|
+
return matches;
|
|
262
|
+
}
|
|
263
|
+
function useMinWidth(minWidth) {
|
|
264
|
+
return useMediaQuery(`(min-width: ${minWidth}px)`);
|
|
265
|
+
}
|
|
266
|
+
function prefersReducedMotion() {
|
|
267
|
+
return typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
268
|
+
}
|
|
239
269
|
var SHEET_SPRING = { type: "spring", bounce: 0, duration: 0.38 };
|
|
240
270
|
var CLOSE_DISTANCE = 112;
|
|
241
271
|
var CLOSE_VELOCITY = 850;
|
|
242
272
|
var DRAG_START_DISTANCE = 6;
|
|
243
273
|
var PROJECT_VELOCITY_FACTOR = 0.18;
|
|
274
|
+
var SIDE_PANEL_TWEEN = { duration: 0.3, ease: [0.22, 0.61, 0.36, 1] };
|
|
275
|
+
var INSTANT = { duration: 0 };
|
|
244
276
|
function closeTargetY(surface, target) {
|
|
245
277
|
if (target === "viewport") return window.innerHeight + 32;
|
|
246
278
|
return (surface?.getBoundingClientRect().height || window.innerHeight) + 32;
|
|
247
279
|
}
|
|
280
|
+
function closeTargetX(surface, currentX) {
|
|
281
|
+
if (!surface) return window.innerWidth;
|
|
282
|
+
const left = surface.getBoundingClientRect().left - currentX;
|
|
283
|
+
return Math.max(0, window.innerWidth - left) + 32;
|
|
284
|
+
}
|
|
248
285
|
function SheetSurface({
|
|
249
286
|
children,
|
|
250
287
|
open,
|
|
@@ -263,15 +300,20 @@ function SheetSurface({
|
|
|
263
300
|
scrollElement,
|
|
264
301
|
ariaLabel,
|
|
265
302
|
shell = "mobile-contained",
|
|
266
|
-
closeTarget = "surface"
|
|
303
|
+
closeTarget = "surface",
|
|
304
|
+
edge = "bottom"
|
|
267
305
|
}) {
|
|
268
306
|
const surfaceRef = useRef(null);
|
|
269
307
|
const removeRef = useRef(onExitComplete);
|
|
270
308
|
const requestCloseRef = useRef(onRequestClose);
|
|
271
309
|
const closingOffsetRef = useRef(0);
|
|
272
310
|
const closingRef = useRef(false);
|
|
273
|
-
const
|
|
311
|
+
const edgeRef = useRef(edge);
|
|
312
|
+
const enteredRef = useRef(false);
|
|
313
|
+
const y = useMotionValue(edge === "bottom" ? window.innerHeight : 0);
|
|
314
|
+
const x = useMotionValue(edge === "right" ? window.innerWidth : 0);
|
|
274
315
|
removeRef.current = onExitComplete;
|
|
316
|
+
edgeRef.current = edge;
|
|
275
317
|
requestCloseRef.current = onRequestClose;
|
|
276
318
|
usePageScrollLock(true);
|
|
277
319
|
const requestClose = useCallback(
|
|
@@ -286,10 +328,18 @@ function SheetSurface({
|
|
|
286
328
|
(offset = 0) => {
|
|
287
329
|
if (closingRef.current) return;
|
|
288
330
|
closingRef.current = true;
|
|
289
|
-
const
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
331
|
+
const reduced = prefersReducedMotion();
|
|
332
|
+
let controls;
|
|
333
|
+
if (edgeRef.current === "right") {
|
|
334
|
+
x.stop();
|
|
335
|
+
const target = closeTargetX(surfaceRef.current, x.get());
|
|
336
|
+
controls = animate(x, target, reduced ? INSTANT : SIDE_PANEL_TWEEN);
|
|
337
|
+
} else {
|
|
338
|
+
const target = closeTargetY(surfaceRef.current, closeTarget);
|
|
339
|
+
y.stop();
|
|
340
|
+
y.set(Math.max(0, offset));
|
|
341
|
+
controls = animate(y, target, SHEET_SPRING);
|
|
342
|
+
}
|
|
293
343
|
void controls.finished.then(
|
|
294
344
|
() => {
|
|
295
345
|
removeRef.current();
|
|
@@ -299,25 +349,55 @@ function SheetSurface({
|
|
|
299
349
|
}
|
|
300
350
|
);
|
|
301
351
|
},
|
|
302
|
-
[closeTarget, y]
|
|
352
|
+
[closeTarget, x, y]
|
|
303
353
|
);
|
|
304
354
|
useEffect(() => {
|
|
305
355
|
if (!open) {
|
|
306
356
|
closeWithAnimation(closingOffsetRef.current);
|
|
307
357
|
return;
|
|
308
358
|
}
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
359
|
+
if (enteredRef.current) {
|
|
360
|
+
x.stop();
|
|
361
|
+
y.stop();
|
|
362
|
+
x.set(0);
|
|
363
|
+
y.set(0);
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
let controls;
|
|
367
|
+
if (edge === "right") {
|
|
368
|
+
y.set(0);
|
|
369
|
+
x.set(closeTargetX(surfaceRef.current, 0));
|
|
370
|
+
controls = animate(x, 0, prefersReducedMotion() ? INSTANT : SIDE_PANEL_TWEEN);
|
|
371
|
+
} else {
|
|
372
|
+
x.set(0);
|
|
373
|
+
y.set(window.innerHeight);
|
|
374
|
+
controls = animate(y, 0, SHEET_SPRING);
|
|
375
|
+
}
|
|
376
|
+
let cancelled = false;
|
|
377
|
+
void controls.finished.then(
|
|
378
|
+
() => {
|
|
379
|
+
if (!cancelled) enteredRef.current = true;
|
|
380
|
+
},
|
|
381
|
+
() => {
|
|
382
|
+
}
|
|
383
|
+
);
|
|
384
|
+
return () => {
|
|
385
|
+
cancelled = true;
|
|
386
|
+
controls.stop();
|
|
387
|
+
};
|
|
388
|
+
}, [closeWithAnimation, edge, open, x, y]);
|
|
313
389
|
useEffect(() => {
|
|
314
|
-
if (!canDismiss) return;
|
|
390
|
+
if (!canDismiss || !open) return;
|
|
315
391
|
const handler = (event) => {
|
|
316
|
-
if (event.key
|
|
392
|
+
if (event.key !== "Escape") return;
|
|
393
|
+
const higherSurface = Array.from(
|
|
394
|
+
document.querySelectorAll(".router-overlay-shell")
|
|
395
|
+
).some((shell2) => Number(shell2.style.zIndex) > zIndex);
|
|
396
|
+
if (!higherSurface) requestClose();
|
|
317
397
|
};
|
|
318
398
|
document.addEventListener("keydown", handler);
|
|
319
399
|
return () => document.removeEventListener("keydown", handler);
|
|
320
|
-
}, [canDismiss, requestClose]);
|
|
400
|
+
}, [canDismiss, open, requestClose, zIndex]);
|
|
321
401
|
const shouldStartDrag = useCallback(
|
|
322
402
|
(update) => update.totalY > 0 && sheetScrollAtTop(scrollElement ?? null),
|
|
323
403
|
[scrollElement]
|
|
@@ -347,7 +427,7 @@ function SheetSurface({
|
|
|
347
427
|
);
|
|
348
428
|
useSheetDragEngine({
|
|
349
429
|
targetRef: surfaceRef,
|
|
350
|
-
enabled: swipeToClose && canDismiss,
|
|
430
|
+
enabled: swipeToClose && canDismiss && edge === "bottom",
|
|
351
431
|
minDragDistance: DRAG_START_DISTANCE,
|
|
352
432
|
ignoreStartTarget: sheetDragStartsInTextInput,
|
|
353
433
|
shouldStart: shouldStartDrag,
|
|
@@ -383,7 +463,7 @@ function SheetSurface({
|
|
|
383
463
|
{
|
|
384
464
|
ref: surfaceRef,
|
|
385
465
|
className: surfaceClassName,
|
|
386
|
-
style: { ...surfaceStyle, y },
|
|
466
|
+
style: { ...surfaceStyle, x, y },
|
|
387
467
|
role: "dialog",
|
|
388
468
|
"aria-modal": "true",
|
|
389
469
|
"aria-label": ariaLabel,
|
|
@@ -441,6 +521,7 @@ function OverlayContentScope({
|
|
|
441
521
|
function useOverlayContentKey() {
|
|
442
522
|
return useContext(OverlayContentKeyContext);
|
|
443
523
|
}
|
|
524
|
+
var DESKTOP_MIN_WIDTH = 640;
|
|
444
525
|
var ModalContext = createContext(null);
|
|
445
526
|
function useModalContext() {
|
|
446
527
|
const ctx = useContext(ModalContext);
|
|
@@ -505,7 +586,15 @@ function ModalFrame({
|
|
|
505
586
|
const options = activeRegistration?.options;
|
|
506
587
|
const swipeToClose = options?.swipeToClose ?? true;
|
|
507
588
|
const ariaLabel = options?.ariaLabel;
|
|
508
|
-
const
|
|
589
|
+
const isDesktop = useMinWidth(DESKTOP_MIN_WIDTH);
|
|
590
|
+
const isRightPanel = isDesktop && options?.presentation === "right";
|
|
591
|
+
const isContentSized = !isRightPanel && (contentSized || options?.presentation === "content");
|
|
592
|
+
const surfaceClassName = [
|
|
593
|
+
"router-modal-surface",
|
|
594
|
+
isContentSized && "router-modal-surface--content-sized",
|
|
595
|
+
isRightPanel && "router-modal-surface--right",
|
|
596
|
+
!isRightPanel && options?.size === "wide" && "router-modal-surface--wide"
|
|
597
|
+
].filter(Boolean).join(" ");
|
|
509
598
|
const requestClose = useCallback(() => {
|
|
510
599
|
onRequestClose();
|
|
511
600
|
}, [onRequestClose]);
|
|
@@ -525,11 +614,16 @@ function ModalFrame({
|
|
|
525
614
|
shell,
|
|
526
615
|
backdrop: true,
|
|
527
616
|
backdropClassName: `router-modal-backdrop${isContentSized ? " router-modal-backdrop--transparent" : ""}`,
|
|
528
|
-
shellClassName: "router-modal-shell"
|
|
529
|
-
surfaceClassName
|
|
617
|
+
shellClassName: `router-modal-shell${isRightPanel ? " router-modal-shell--right" : ""}`,
|
|
618
|
+
surfaceClassName,
|
|
619
|
+
surfaceStyle: {
|
|
620
|
+
"--router-modal-width": options?.width ? `${options.width}px` : void 0,
|
|
621
|
+
"--router-modal-height": options?.height ? `${options.height}px` : void 0
|
|
622
|
+
},
|
|
530
623
|
scrollElement: swipeTarget,
|
|
531
624
|
ariaLabel,
|
|
532
625
|
closeTarget: isContentSized ? "surface" : "viewport",
|
|
626
|
+
edge: isRightPanel ? "right" : "bottom",
|
|
533
627
|
children
|
|
534
628
|
}
|
|
535
629
|
) });
|
|
@@ -539,14 +633,16 @@ function ModalRoot({
|
|
|
539
633
|
swipeToClose = true,
|
|
540
634
|
ariaLabel,
|
|
541
635
|
size = "regular",
|
|
636
|
+
width,
|
|
637
|
+
height,
|
|
542
638
|
presentation = "fullscreen"
|
|
543
639
|
}) {
|
|
544
640
|
const { setOptions } = useModalContext();
|
|
545
641
|
const contentKey = useOverlayContentKey();
|
|
546
642
|
useLayoutEffect(() => {
|
|
547
|
-
setOptions(contentKey, { swipeToClose, ariaLabel, size, presentation });
|
|
643
|
+
setOptions(contentKey, { swipeToClose, ariaLabel, size, width, height, presentation });
|
|
548
644
|
return () => setOptions(contentKey, null);
|
|
549
|
-
}, [ariaLabel, contentKey, presentation, setOptions, size, swipeToClose]);
|
|
645
|
+
}, [ariaLabel, contentKey, height, presentation, setOptions, size, swipeToClose, width]);
|
|
550
646
|
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
551
647
|
}
|
|
552
648
|
function ModalHeader({
|
|
@@ -941,7 +1037,7 @@ function splitNavigationFromState(state) {
|
|
|
941
1037
|
if (!isRecord(state)) return void 0;
|
|
942
1038
|
const value = state[SPLIT_NAVIGATION_KEY];
|
|
943
1039
|
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") {
|
|
1040
|
+
if (typeof value.splitViewId !== "string" || typeof value.detailPathId !== "string" || typeof value.detailDepth !== "number" || value.operation !== "selection" && value.operation !== "push" && value.operation !== "replace" && value.operation !== "pop") {
|
|
945
1041
|
return void 0;
|
|
946
1042
|
}
|
|
947
1043
|
return {
|
|
@@ -994,7 +1090,7 @@ function historyNavigationKeyFromState(state) {
|
|
|
994
1090
|
function historyCommitFromState(state) {
|
|
995
1091
|
if (isRecord(state)) {
|
|
996
1092
|
const commit = state[HISTORY_COMMIT_KEY];
|
|
997
|
-
if (commit === "sync" || commit === "replace") return commit;
|
|
1093
|
+
if (commit === "sync" || commit === "replace" || commit === "pop") return commit;
|
|
998
1094
|
}
|
|
999
1095
|
return "push";
|
|
1000
1096
|
}
|
|
@@ -1119,6 +1215,7 @@ function splitRouteChildren(children) {
|
|
|
1119
1215
|
const routeChildren = [];
|
|
1120
1216
|
const nonRouteChildren = [];
|
|
1121
1217
|
for (const child of childArray) {
|
|
1218
|
+
if (child == null || typeof child === "boolean") continue;
|
|
1122
1219
|
if (isStackRouteElement(child)) {
|
|
1123
1220
|
routeChildren.push(child);
|
|
1124
1221
|
} else {
|
|
@@ -1506,7 +1603,8 @@ function compileStackRoutes(children, parentPath, parentId = "root", inheritedGu
|
|
|
1506
1603
|
container: descriptor.container,
|
|
1507
1604
|
childRoute,
|
|
1508
1605
|
drawerAside: isTabBar ? void 0 : props.aside,
|
|
1509
|
-
drawerFooter: isTabBar ? void 0 : props.footer
|
|
1606
|
+
drawerFooter: isTabBar ? void 0 : props.footer,
|
|
1607
|
+
drawerDesktopCollapsible: isTabBar ? void 0 : props.desktopCollapsible
|
|
1510
1608
|
};
|
|
1511
1609
|
if (isTabBar && tabs) {
|
|
1512
1610
|
containerRoute.tabBar = {
|
|
@@ -1622,8 +1720,8 @@ function stateForSplitNavigationTarget(state, targetMatch, action) {
|
|
|
1622
1720
|
} : {
|
|
1623
1721
|
splitViewId: origin.splitViewId,
|
|
1624
1722
|
detailPathId: origin.detailPathId,
|
|
1625
|
-
detailDepth: action === "navigate" ? origin.detailDepth + 1 : origin.detailDepth,
|
|
1626
|
-
operation: action === "navigate" ? "push" :
|
|
1723
|
+
detailDepth: action === "navigate" ? origin.detailDepth + 1 : action === "pop" ? Math.max(0, origin.detailDepth - 1) : origin.detailDepth,
|
|
1724
|
+
operation: action === "navigate" ? "push" : action
|
|
1627
1725
|
}
|
|
1628
1726
|
);
|
|
1629
1727
|
next[SPLIT_NAVIGATION_KEY] = metadata;
|
|
@@ -1987,30 +2085,6 @@ function pathnameForRouteContext(route, fallbackPathname) {
|
|
|
1987
2085
|
}
|
|
1988
2086
|
return normalizedPath(routePath);
|
|
1989
2087
|
}
|
|
1990
|
-
function useMinWidth(minWidth) {
|
|
1991
|
-
const [matches, setMatches] = useState(() => {
|
|
1992
|
-
if (typeof window === "undefined" || typeof window.matchMedia !== "function") {
|
|
1993
|
-
return false;
|
|
1994
|
-
}
|
|
1995
|
-
return window.matchMedia(`(min-width: ${minWidth}px)`).matches;
|
|
1996
|
-
});
|
|
1997
|
-
useEffect(() => {
|
|
1998
|
-
if (typeof window === "undefined" || typeof window.matchMedia !== "function") {
|
|
1999
|
-
return;
|
|
2000
|
-
}
|
|
2001
|
-
const mediaQuery = window.matchMedia(`(min-width: ${minWidth}px)`);
|
|
2002
|
-
const handleChange = (event) => setMatches(event.matches);
|
|
2003
|
-
setMatches(mediaQuery.matches);
|
|
2004
|
-
if (typeof mediaQuery.addEventListener === "function") {
|
|
2005
|
-
mediaQuery.addEventListener("change", handleChange);
|
|
2006
|
-
return () => mediaQuery.removeEventListener("change", handleChange);
|
|
2007
|
-
}
|
|
2008
|
-
const mediaQueryWithListener = mediaQuery;
|
|
2009
|
-
mediaQueryWithListener.addListener?.(handleChange);
|
|
2010
|
-
return () => mediaQueryWithListener.removeListener?.(handleChange);
|
|
2011
|
-
}, [minWidth]);
|
|
2012
|
-
return matches;
|
|
2013
|
-
}
|
|
2014
2088
|
function measuredElementWidth(element) {
|
|
2015
2089
|
return element.getBoundingClientRect().width || element.clientWidth || 0;
|
|
2016
2090
|
}
|
|
@@ -2099,6 +2173,12 @@ function useRouter() {
|
|
|
2099
2173
|
...options,
|
|
2100
2174
|
state: stateWithSplitNavigationOrigin(options.state, splitPaneOrigin)
|
|
2101
2175
|
});
|
|
2176
|
+
},
|
|
2177
|
+
popTo: (to, options = {}) => {
|
|
2178
|
+
router.popTo(to, {
|
|
2179
|
+
...options,
|
|
2180
|
+
state: stateWithSplitNavigationOrigin(options.state, splitPaneOrigin)
|
|
2181
|
+
});
|
|
2102
2182
|
}
|
|
2103
2183
|
};
|
|
2104
2184
|
}, [router, splitPaneOrigin]);
|
|
@@ -2118,7 +2198,6 @@ function useCurrentModal() {
|
|
|
2118
2198
|
return current;
|
|
2119
2199
|
}
|
|
2120
2200
|
function DefaultSplitViewLayout({
|
|
2121
|
-
children,
|
|
2122
2201
|
primary,
|
|
2123
2202
|
secondary,
|
|
2124
2203
|
isWide,
|
|
@@ -2135,8 +2214,15 @@ function DefaultSplitViewLayout({
|
|
|
2135
2214
|
"data-router-split-view-id": splitViewLayoutId,
|
|
2136
2215
|
style: { "--sigmela-split-primary-max-width": `${primaryMaxWidth}px` },
|
|
2137
2216
|
children: [
|
|
2138
|
-
/* @__PURE__ */ jsx(
|
|
2139
|
-
|
|
2217
|
+
/* @__PURE__ */ jsx(
|
|
2218
|
+
"div",
|
|
2219
|
+
{
|
|
2220
|
+
className: "sigmela-split-view__primary",
|
|
2221
|
+
style: !isWide && secondary ? { display: "none" } : void 0,
|
|
2222
|
+
children: primary
|
|
2223
|
+
}
|
|
2224
|
+
),
|
|
2225
|
+
/* @__PURE__ */ jsx("div", { className: "sigmela-split-view__secondary", children: secondary })
|
|
2140
2226
|
]
|
|
2141
2227
|
}
|
|
2142
2228
|
);
|
|
@@ -2161,88 +2247,119 @@ function DefaultDrawerLayout({
|
|
|
2161
2247
|
return next;
|
|
2162
2248
|
});
|
|
2163
2249
|
}, []);
|
|
2164
|
-
return /* @__PURE__ */ jsxs(
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
"
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2250
|
+
return /* @__PURE__ */ jsxs(
|
|
2251
|
+
"div",
|
|
2252
|
+
{
|
|
2253
|
+
className: "sigmela-drawer",
|
|
2254
|
+
"data-drawer-open": drawer?.isOpen ? "true" : "false",
|
|
2255
|
+
"data-drawer-collapsed": drawer?.isCollapsed ? "true" : "false",
|
|
2256
|
+
"data-drawer-desktop": drawer?.desktopCollapsible,
|
|
2257
|
+
children: [
|
|
2258
|
+
/* @__PURE__ */ jsxs(
|
|
2259
|
+
"aside",
|
|
2260
|
+
{
|
|
2261
|
+
className: "sigmela-drawer__sidebar",
|
|
2262
|
+
inert: drawer?.isMobile && !drawer.isOpen ? true : void 0,
|
|
2263
|
+
children: [
|
|
2264
|
+
/* @__PURE__ */ jsx("div", { className: "sigmela-drawer__sidebar-content", children: items.filter((node) => !node.hidden).map((node) => {
|
|
2265
|
+
if (node.type === "item") {
|
|
2266
|
+
return /* @__PURE__ */ jsxs(
|
|
2267
|
+
"button",
|
|
2268
|
+
{
|
|
2269
|
+
type: "button",
|
|
2270
|
+
className: "sigmela-drawer__item",
|
|
2271
|
+
"aria-label": node.label,
|
|
2272
|
+
title: drawer?.isCollapsed ? node.label : void 0,
|
|
2273
|
+
"data-active": node.id === activeItem ? "true" : void 0,
|
|
2274
|
+
onClick: () => onItemChange?.(node.id),
|
|
2275
|
+
children: [
|
|
2276
|
+
node.icon || drawer?.isCollapsed ? /* @__PURE__ */ jsx("span", { className: "sigmela-drawer__item-icon", "aria-hidden": "true", children: node.icon ?? node.label.slice(0, 1) }) : null,
|
|
2277
|
+
/* @__PURE__ */ jsx("span", { className: "sigmela-drawer__item-label", children: node.label }),
|
|
2278
|
+
node.badge ? /* @__PURE__ */ jsx("span", { className: "sigmela-drawer__item-badge", children: node.badge }) : null
|
|
2279
|
+
]
|
|
2280
|
+
},
|
|
2281
|
+
node.id
|
|
2282
|
+
);
|
|
2283
|
+
}
|
|
2284
|
+
if (node.type === "section") {
|
|
2285
|
+
return /* @__PURE__ */ jsx("div", { className: "sigmela-drawer__section-label", children: node.title }, node.id);
|
|
2286
|
+
}
|
|
2287
|
+
const visibleItems = node.items.filter((item) => !item.hidden);
|
|
2288
|
+
if (visibleItems.length === 0) return null;
|
|
2289
|
+
const isExpanded = expandedGroups.has(node.id);
|
|
2290
|
+
const itemsId = `${node.id}-drawer-items`;
|
|
2291
|
+
return /* @__PURE__ */ jsxs("div", { className: "sigmela-drawer__group-container", children: [
|
|
2292
|
+
/* @__PURE__ */ jsxs(
|
|
2293
|
+
"button",
|
|
2294
|
+
{
|
|
2295
|
+
type: "button",
|
|
2296
|
+
className: "sigmela-drawer__item sigmela-drawer__group-label",
|
|
2297
|
+
"aria-label": node.label,
|
|
2298
|
+
title: drawer?.isCollapsed ? node.label : void 0,
|
|
2299
|
+
"aria-controls": itemsId,
|
|
2300
|
+
"aria-expanded": isExpanded,
|
|
2301
|
+
onClick: () => {
|
|
2302
|
+
if (drawer?.isCollapsed) drawer.open();
|
|
2303
|
+
toggleGroup(node.id);
|
|
2304
|
+
},
|
|
2305
|
+
children: [
|
|
2306
|
+
node.icon || drawer?.isCollapsed ? /* @__PURE__ */ jsx("span", { className: "sigmela-drawer__item-icon", "aria-hidden": "true", children: node.icon ?? node.label.slice(0, 1) }) : null,
|
|
2307
|
+
/* @__PURE__ */ jsx("span", { className: "sigmela-drawer__item-label", children: node.label }),
|
|
2308
|
+
node.chevron ? /* @__PURE__ */ jsx(
|
|
2309
|
+
"span",
|
|
2310
|
+
{
|
|
2311
|
+
className: "sigmela-drawer__group-chevron",
|
|
2312
|
+
"data-expanded": isExpanded ? "true" : void 0,
|
|
2313
|
+
"aria-hidden": "true",
|
|
2314
|
+
children: node.chevron
|
|
2315
|
+
}
|
|
2316
|
+
) : null
|
|
2317
|
+
]
|
|
2318
|
+
}
|
|
2319
|
+
),
|
|
2320
|
+
isExpanded ? /* @__PURE__ */ jsx("div", { id: itemsId, className: "sigmela-drawer__group-items", children: visibleItems.map((item) => /* @__PURE__ */ jsxs(
|
|
2321
|
+
"button",
|
|
2322
|
+
{
|
|
2323
|
+
type: "button",
|
|
2324
|
+
className: "sigmela-drawer__item sigmela-drawer__subitem",
|
|
2325
|
+
"data-active": item.id === activeItem ? "true" : void 0,
|
|
2326
|
+
onClick: () => onItemChange?.(item.id),
|
|
2327
|
+
children: [
|
|
2328
|
+
item.icon ? /* @__PURE__ */ jsx("span", { className: "sigmela-drawer__item-icon", children: item.icon }) : null,
|
|
2329
|
+
/* @__PURE__ */ jsx("span", { className: "sigmela-drawer__item-label", children: item.label }),
|
|
2330
|
+
item.badge ? /* @__PURE__ */ jsx("span", { className: "sigmela-drawer__item-badge", children: item.badge }) : null
|
|
2331
|
+
]
|
|
2332
|
+
},
|
|
2333
|
+
item.id
|
|
2334
|
+
)) }) : null
|
|
2335
|
+
] }, node.id);
|
|
2336
|
+
}) }),
|
|
2337
|
+
footer ? /* @__PURE__ */ jsx("div", { className: "sigmela-drawer__footer", children: footer }) : null
|
|
2338
|
+
]
|
|
2339
|
+
}
|
|
2340
|
+
),
|
|
2341
|
+
/* @__PURE__ */ jsx(
|
|
2342
|
+
"button",
|
|
2343
|
+
{
|
|
2344
|
+
type: "button",
|
|
2345
|
+
className: "sigmela-drawer__overlay",
|
|
2346
|
+
"aria-label": "Close navigation",
|
|
2347
|
+
tabIndex: drawer?.isMobile && drawer.isOpen ? 0 : -1,
|
|
2348
|
+
onClick: drawer?.close
|
|
2349
|
+
}
|
|
2350
|
+
),
|
|
2351
|
+
/* @__PURE__ */ jsx(
|
|
2352
|
+
"main",
|
|
2353
|
+
{
|
|
2354
|
+
className: "sigmela-drawer__main",
|
|
2355
|
+
inert: drawer?.isMobile && drawer.isOpen ? true : void 0,
|
|
2356
|
+
children
|
|
2357
|
+
}
|
|
2358
|
+
),
|
|
2359
|
+
aside ? /* @__PURE__ */ jsx("aside", { className: "sigmela-drawer__assistant", children: aside }) : null
|
|
2360
|
+
]
|
|
2361
|
+
}
|
|
2362
|
+
);
|
|
2246
2363
|
}
|
|
2247
2364
|
function FrozenPaneRouteContent({
|
|
2248
2365
|
route,
|
|
@@ -2568,7 +2685,7 @@ function SplitViewRouteContent({
|
|
|
2568
2685
|
fallback: splitView.primaryRoute.fallback ?? fallback
|
|
2569
2686
|
}
|
|
2570
2687
|
) });
|
|
2571
|
-
const secondary = splitView.secondaryRoute ? /* @__PURE__ */ jsx(SplitPaneNavigationContext.Provider, { value: secondaryNavigationOrigin, children:
|
|
2688
|
+
const secondary = splitView.secondaryRoute ? /* @__PURE__ */ jsx(SplitPaneNavigationContext.Provider, { value: secondaryNavigationOrigin, children: /* @__PURE__ */ jsx(
|
|
2572
2689
|
RouteStackViewport,
|
|
2573
2690
|
{
|
|
2574
2691
|
route: splitView.secondaryRoute,
|
|
@@ -2577,13 +2694,6 @@ function SplitViewRouteContent({
|
|
|
2577
2694
|
stackKey: `${route.id}:secondary`
|
|
2578
2695
|
},
|
|
2579
2696
|
detailPathId
|
|
2580
|
-
) : /* @__PURE__ */ jsx(
|
|
2581
|
-
FrozenPaneRouteContent,
|
|
2582
|
-
{
|
|
2583
|
-
route: splitView.secondaryRoute,
|
|
2584
|
-
props: secondaryProps,
|
|
2585
|
-
fallback: splitView.secondaryRoute.fallback ?? fallback
|
|
2586
|
-
}
|
|
2587
2697
|
) }) : null;
|
|
2588
2698
|
const activeContent = splitView.activePane === "secondary" && secondary ? secondary : primary;
|
|
2589
2699
|
const layoutProps = {
|
|
@@ -2614,13 +2724,44 @@ function DrawerRouteContent({
|
|
|
2614
2724
|
route,
|
|
2615
2725
|
props
|
|
2616
2726
|
}) {
|
|
2617
|
-
const
|
|
2618
|
-
const
|
|
2619
|
-
const
|
|
2620
|
-
const
|
|
2727
|
+
const isMobile = !useMinWidth(641);
|
|
2728
|
+
const [mobileOpen, setMobileOpen] = useState(false);
|
|
2729
|
+
const [desktopCollapsed, setDesktopCollapsed] = useState(false);
|
|
2730
|
+
const desktopCollapsible = route.drawerDesktopCollapsible ?? "offcanvas";
|
|
2731
|
+
const isCollapsed = !isMobile && desktopCollapsed;
|
|
2732
|
+
const isOpen = isMobile ? mobileOpen : !desktopCollapsed;
|
|
2733
|
+
const open = useCallback(() => {
|
|
2734
|
+
if (isMobile) setMobileOpen(true);
|
|
2735
|
+
else setDesktopCollapsed(false);
|
|
2736
|
+
}, [isMobile]);
|
|
2737
|
+
const close = useCallback(() => {
|
|
2738
|
+
if (isMobile) setMobileOpen(false);
|
|
2739
|
+
else setDesktopCollapsed(true);
|
|
2740
|
+
}, [isMobile]);
|
|
2741
|
+
const toggle = useCallback(() => {
|
|
2742
|
+
if (isMobile) setMobileOpen((value) => !value);
|
|
2743
|
+
else setDesktopCollapsed((value) => !value);
|
|
2744
|
+
}, [isMobile]);
|
|
2745
|
+
useEffect(() => setMobileOpen(false), [isMobile, props.pathname]);
|
|
2746
|
+
useEffect(() => {
|
|
2747
|
+
if (!isMobile || !mobileOpen) return;
|
|
2748
|
+
const onKeyDown = (event) => {
|
|
2749
|
+
if (event.key === "Escape" && !event.defaultPrevented) setMobileOpen(false);
|
|
2750
|
+
};
|
|
2751
|
+
window.addEventListener("keydown", onKeyDown);
|
|
2752
|
+
return () => window.removeEventListener("keydown", onKeyDown);
|
|
2753
|
+
}, [isMobile, mobileOpen]);
|
|
2621
2754
|
const drawerApi = useMemo(
|
|
2622
|
-
() => ({
|
|
2623
|
-
|
|
2755
|
+
() => ({
|
|
2756
|
+
isOpen,
|
|
2757
|
+
isMobile,
|
|
2758
|
+
isCollapsed,
|
|
2759
|
+
desktopCollapsible,
|
|
2760
|
+
open,
|
|
2761
|
+
close,
|
|
2762
|
+
toggle
|
|
2763
|
+
}),
|
|
2764
|
+
[close, isOpen, isMobile, isCollapsed, desktopCollapsible, open, toggle]
|
|
2624
2765
|
);
|
|
2625
2766
|
const childFallback = route.childRoute?.fallback ?? route.fallback ?? null;
|
|
2626
2767
|
const drawer = route.drawer;
|
|
@@ -2640,7 +2781,7 @@ function DrawerRouteContent({
|
|
|
2640
2781
|
if (item && normalizedPath(item.path) !== props.pathname) {
|
|
2641
2782
|
navigateWithHistoryIndex(item.path);
|
|
2642
2783
|
}
|
|
2643
|
-
|
|
2784
|
+
setMobileOpen(false);
|
|
2644
2785
|
} : void 0;
|
|
2645
2786
|
const layoutProps = {
|
|
2646
2787
|
children: content,
|
|
@@ -2909,6 +3050,13 @@ function resolveStackChange(prev, snapshot) {
|
|
|
2909
3050
|
};
|
|
2910
3051
|
}
|
|
2911
3052
|
const direction = resolveDirection(top, snapshot);
|
|
3053
|
+
if (snapshot.historyCommit === "pop" && snapshot.splitPane === "secondary") {
|
|
3054
|
+
const existingIndex2 = existingStackEntryIndexForSnapshot(prev, snapshot);
|
|
3055
|
+
return {
|
|
3056
|
+
entries: existingIndex2 !== -1 && existingIndex2 < prev.length - 1 ? entriesRevealingSnapshot(prev, existingIndex2, snapshot) : [createEntry(snapshot, "back", true)],
|
|
3057
|
+
direction: "back"
|
|
3058
|
+
};
|
|
3059
|
+
}
|
|
2912
3060
|
if (isExplicitStackReplace(top, snapshot)) {
|
|
2913
3061
|
return {
|
|
2914
3062
|
entries: replaceActiveStackEntry(prev, top.id, snapshot, direction, true),
|
|
@@ -2970,6 +3118,10 @@ function visibleEntriesForSnapshot(entries, snapshot) {
|
|
|
2970
3118
|
(entry) => entry.id === top.id ? mergeEntrySnapshot(entry, snapshot) : entry
|
|
2971
3119
|
);
|
|
2972
3120
|
}
|
|
3121
|
+
if (snapshot.historyCommit === "pop" && snapshot.splitPane === "secondary") {
|
|
3122
|
+
const existingIndex2 = existingStackEntryIndexForSnapshot(entries, snapshot);
|
|
3123
|
+
return existingIndex2 !== -1 && existingIndex2 < entries.length - 1 ? entriesRevealingSnapshot(entries, existingIndex2, snapshot) : [createEntry(snapshot, "back", true)];
|
|
3124
|
+
}
|
|
2973
3125
|
if (isExplicitStackReplace(top, snapshot)) {
|
|
2974
3126
|
return replaceActiveStackEntry(
|
|
2975
3127
|
entries,
|
|
@@ -3640,6 +3792,20 @@ function RouterRuntime({
|
|
|
3640
3792
|
},
|
|
3641
3793
|
[pushModalEntry, updateActiveModalFlow]
|
|
3642
3794
|
);
|
|
3795
|
+
const popTo = useCallback((to, options = {}) => {
|
|
3796
|
+
const { compiledRoutes: compiledRoutes2, pathname: pathname2, parser } = navigationScopeRef.current;
|
|
3797
|
+
const target = parseNavigationTarget(to, pathname2);
|
|
3798
|
+
const pushMatch = matchStackRouteByPresentation(
|
|
3799
|
+
compiledRoutes2,
|
|
3800
|
+
parser,
|
|
3801
|
+
target.pathname,
|
|
3802
|
+
PUSH_PRESENTATIONS
|
|
3803
|
+
);
|
|
3804
|
+
navigateWithHistoryIndex(to, {
|
|
3805
|
+
commit: "pop",
|
|
3806
|
+
state: stateForSplitNavigationTarget(options.state, pushMatch, "pop")
|
|
3807
|
+
});
|
|
3808
|
+
}, []);
|
|
3643
3809
|
const goBack = useCallback(() => {
|
|
3644
3810
|
if (goBackTopModal()) return true;
|
|
3645
3811
|
const activeEntry = visibleActiveEntryRef.current;
|
|
@@ -3686,11 +3852,12 @@ function RouterRuntime({
|
|
|
3686
3852
|
() => ({
|
|
3687
3853
|
navigate,
|
|
3688
3854
|
replace,
|
|
3855
|
+
popTo,
|
|
3689
3856
|
close: closeModal,
|
|
3690
3857
|
closeAll: closeAllModals,
|
|
3691
3858
|
goBack
|
|
3692
3859
|
}),
|
|
3693
|
-
[closeAllModals, closeModal, goBack, navigate, replace]
|
|
3860
|
+
[closeAllModals, closeModal, goBack, navigate, popTo, replace]
|
|
3694
3861
|
);
|
|
3695
3862
|
useEffect(() => {
|
|
3696
3863
|
if (visibleActiveEntry) {
|
|
@@ -3762,6 +3929,8 @@ function RouterRuntime({
|
|
|
3762
3929
|
"data-route-stack-phase": phase,
|
|
3763
3930
|
"data-route-stack-transition": transitionStatus,
|
|
3764
3931
|
className: screenClassName(entry, phase, transitionStatus, animationType),
|
|
3932
|
+
"aria-hidden": phase === "active" ? void 0 : true,
|
|
3933
|
+
inert: phase === "active" ? void 0 : true,
|
|
3765
3934
|
style: { zIndex },
|
|
3766
3935
|
children: /* @__PURE__ */ jsx("div", { className: "stack-screen-container", children: /* @__PURE__ */ jsx(FrozenStackEntry, { entry, fallback: fallbackNode }) })
|
|
3767
3936
|
},
|