@surdeddd/bottom-sheet 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +51 -21
- package/dist/{BottomSheetEngine-CIT9Htti.d.cts → BottomSheetEngine-BJrH7qY3.d.cts} +105 -3
- package/dist/{BottomSheetEngine-Df9MwBbm.d.ts → BottomSheetEngine-L05jGZvU.d.ts} +105 -3
- package/dist/element.cjs +1170 -196
- package/dist/element.d.cts +29 -5
- package/dist/element.d.ts +29 -5
- package/dist/element.iife.global.js +2 -2
- package/dist/element.js +1170 -196
- package/dist/index.cjs +1051 -220
- package/dist/index.d.cts +18 -3
- package/dist/index.d.ts +18 -3
- package/dist/index.js +1049 -221
- package/dist/integrations/formik.d.cts +1 -1
- package/dist/integrations/formik.d.ts +1 -1
- package/dist/integrations/react-hook-form.d.cts +1 -1
- package/dist/integrations/react-hook-form.d.ts +1 -1
- package/dist/overlay.cjs +181 -37
- package/dist/overlay.d.cts +13 -0
- package/dist/overlay.d.ts +13 -0
- package/dist/overlay.js +181 -37
- package/dist/preact.d.cts +1 -1
- package/dist/preact.d.ts +1 -1
- package/dist/qwik.cjs +966 -195
- package/dist/qwik.d.cts +4 -2
- package/dist/qwik.d.ts +4 -2
- package/dist/qwik.js +967 -196
- package/dist/react.cjs +1242 -272
- package/dist/react.d.cts +47 -5
- package/dist/react.d.ts +47 -5
- package/dist/react.js +1242 -272
- package/dist/solid.cjs +992 -236
- package/dist/solid.d.cts +299 -4
- package/dist/solid.d.ts +299 -4
- package/dist/solid.js +993 -237
- package/dist/solid.source.jsx +3476 -0
- package/dist/styles.css +67 -66
- package/dist/svelte-core.cjs +3415 -0
- package/dist/svelte-core.js +3413 -0
- package/dist/svelte-src/BottomSheet.svelte +308 -0
- package/dist/svelte-src/index.js +2 -0
- package/dist/svelte.cjs +1034 -207
- package/dist/svelte.d.cts +121 -0
- package/dist/svelte.d.ts +28 -3
- package/dist/svelte.js +1035 -208
- package/dist/vue.cjs +1191 -205
- package/dist/vue.d.cts +127 -0
- package/dist/vue.d.ts +57 -4
- package/dist/vue.js +1192 -206
- package/package.json +105 -45
package/dist/svelte.cjs
CHANGED
|
@@ -46,16 +46,52 @@ var SheetStack = class {
|
|
|
46
46
|
this.entries.splice(idx, 1);
|
|
47
47
|
this.recompute();
|
|
48
48
|
}
|
|
49
|
+
promote(id) {
|
|
50
|
+
const idx = this.entries.findIndex((e) => e.id === id);
|
|
51
|
+
if (idx === -1) return;
|
|
52
|
+
if (idx !== this.entries.length - 1) {
|
|
53
|
+
const [entry] = this.entries.splice(idx, 1);
|
|
54
|
+
this.entries.push(entry);
|
|
55
|
+
}
|
|
56
|
+
this.recompute();
|
|
57
|
+
}
|
|
58
|
+
update() {
|
|
59
|
+
this.recompute();
|
|
60
|
+
}
|
|
49
61
|
size() {
|
|
50
62
|
return this.entries.length;
|
|
51
63
|
}
|
|
64
|
+
depthOf(id) {
|
|
65
|
+
const open = [];
|
|
66
|
+
for (const entry of this.entries) {
|
|
67
|
+
if (!entry.isOpen || entry.isOpen()) open.push(entry);
|
|
68
|
+
}
|
|
69
|
+
const idx = open.findIndex((e) => e.id === id);
|
|
70
|
+
if (idx === -1) return 0;
|
|
71
|
+
return open.length - 1 - idx;
|
|
72
|
+
}
|
|
52
73
|
clear() {
|
|
53
74
|
this.entries = [];
|
|
54
75
|
}
|
|
55
76
|
recompute() {
|
|
77
|
+
let top = null;
|
|
78
|
+
const open = [];
|
|
79
|
+
for (const entry of this.entries) {
|
|
80
|
+
if (!entry.isOpen || entry.isOpen()) {
|
|
81
|
+
top = entry;
|
|
82
|
+
open.push(entry);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (!top && this.entries.length > 0) {
|
|
86
|
+
top = this.entries[this.entries.length - 1];
|
|
87
|
+
}
|
|
56
88
|
this.entries.forEach((entry, i) => {
|
|
57
89
|
entry.setZIndex(BASE_Z + i * STEP);
|
|
58
|
-
entry.setIsTop(
|
|
90
|
+
entry.setIsTop(entry === top);
|
|
91
|
+
if (entry.setDepth) {
|
|
92
|
+
const openIdx = open.indexOf(entry);
|
|
93
|
+
entry.setDepth(openIdx === -1 ? 0 : open.length - 1 - openIdx);
|
|
94
|
+
}
|
|
59
95
|
});
|
|
60
96
|
}
|
|
61
97
|
};
|
|
@@ -152,7 +188,9 @@ var PERCENT = /^(-?\d+(?:\.\d+)?)%$/;
|
|
|
152
188
|
var resolveSnap = (point, mode, measureFit) => {
|
|
153
189
|
if (typeof point === "number") return Math.max(0, point);
|
|
154
190
|
if (point === "full") return viewportSize(mode);
|
|
155
|
-
if (point === "fit"
|
|
191
|
+
if (point === "fit" || point === "content") {
|
|
192
|
+
return Math.max(0, measureFit?.() ?? 0);
|
|
193
|
+
}
|
|
156
194
|
const pctMatch = point.match(PERCENT);
|
|
157
195
|
if (pctMatch) {
|
|
158
196
|
const pct = parseFloat(pctMatch[1]) / 100;
|
|
@@ -340,14 +378,17 @@ function installAutoCollapse(deps) {
|
|
|
340
378
|
const fire = () => {
|
|
341
379
|
if (deps.isDestroyed()) return;
|
|
342
380
|
if (deps.isDragging()) return;
|
|
343
|
-
const
|
|
344
|
-
|
|
381
|
+
const active = deps.resolveSnap(deps.getActiveId());
|
|
382
|
+
if (!active || active.size === 0) return;
|
|
383
|
+
let target = null;
|
|
384
|
+
for (const id of deps.getAllowedIds()) {
|
|
345
385
|
const snap = deps.resolveSnap(id);
|
|
346
|
-
|
|
347
|
-
|
|
386
|
+
if (!snap || snap.size <= 0) continue;
|
|
387
|
+
if (!target || snap.size < target.size) target = snap;
|
|
388
|
+
}
|
|
348
389
|
if (!target) return;
|
|
349
|
-
if (target ===
|
|
350
|
-
deps.snapTo(target);
|
|
390
|
+
if (target.id === active.id || target.size >= active.size) return;
|
|
391
|
+
deps.snapTo(target.id);
|
|
351
392
|
};
|
|
352
393
|
const reset2 = () => {
|
|
353
394
|
clearTimer();
|
|
@@ -358,6 +399,7 @@ function installAutoCollapse(deps) {
|
|
|
358
399
|
}, ms);
|
|
359
400
|
};
|
|
360
401
|
const unsubscribe = deps.on("snap", () => reset2());
|
|
402
|
+
if ((deps.resolveSnap(deps.getActiveId())?.size ?? 0) > 0) reset2();
|
|
361
403
|
return () => {
|
|
362
404
|
clearTimer();
|
|
363
405
|
unsubscribe();
|
|
@@ -370,6 +412,7 @@ function notifyLinkedSheets(sheets, self) {
|
|
|
370
412
|
for (const linked of sheets) {
|
|
371
413
|
if (linked === self) continue;
|
|
372
414
|
try {
|
|
415
|
+
if (linked.state.size === 0) continue;
|
|
373
416
|
const ids = linked.getAllowedIds();
|
|
374
417
|
const target = ids.find((id) => id !== "closed");
|
|
375
418
|
if (target && target !== linked.state.activeId) {
|
|
@@ -384,6 +427,42 @@ function notifyLinkedSheets(sheets, self) {
|
|
|
384
427
|
}
|
|
385
428
|
|
|
386
429
|
// src/core/features/route.ts
|
|
430
|
+
var closers = [];
|
|
431
|
+
var handlerInstalled = false;
|
|
432
|
+
var suppress = 0;
|
|
433
|
+
var ensureHandler = () => {
|
|
434
|
+
if (handlerInstalled || typeof window === "undefined") return;
|
|
435
|
+
handlerInstalled = true;
|
|
436
|
+
window.addEventListener("popstate", () => {
|
|
437
|
+
if (suppress > 0) {
|
|
438
|
+
suppress -= 1;
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
let target = null;
|
|
442
|
+
for (let i = closers.length - 1; i >= 0; i -= 1) {
|
|
443
|
+
const c = closers[i];
|
|
444
|
+
if (!c.isOpen()) continue;
|
|
445
|
+
if (!target) target = c;
|
|
446
|
+
if (c.isTop()) {
|
|
447
|
+
target = c;
|
|
448
|
+
break;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
if (!target) return;
|
|
452
|
+
target.consumed = true;
|
|
453
|
+
const idx = closers.indexOf(target);
|
|
454
|
+
if (idx !== -1) closers.splice(idx, 1);
|
|
455
|
+
target.close();
|
|
456
|
+
});
|
|
457
|
+
};
|
|
458
|
+
var programmaticBack = () => {
|
|
459
|
+
suppress += 1;
|
|
460
|
+
try {
|
|
461
|
+
history.back();
|
|
462
|
+
} catch {
|
|
463
|
+
suppress = Math.max(0, suppress - 1);
|
|
464
|
+
}
|
|
465
|
+
};
|
|
387
466
|
function installRoute(deps) {
|
|
388
467
|
if (typeof window === "undefined") {
|
|
389
468
|
return () => {
|
|
@@ -393,82 +472,81 @@ function installRoute(deps) {
|
|
|
393
472
|
return () => {
|
|
394
473
|
};
|
|
395
474
|
}
|
|
396
|
-
let
|
|
397
|
-
let
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
475
|
+
let pushed = false;
|
|
476
|
+
let closer = null;
|
|
477
|
+
const teardownEntry = () => {
|
|
478
|
+
if (closer) {
|
|
479
|
+
const idx = closers.indexOf(closer);
|
|
480
|
+
if (idx !== -1) closers.splice(idx, 1);
|
|
481
|
+
}
|
|
482
|
+
const wasConsumed = closer?.consumed ?? false;
|
|
483
|
+
closer = null;
|
|
484
|
+
if (pushed && !wasConsumed) {
|
|
485
|
+
pushed = false;
|
|
486
|
+
programmaticBack();
|
|
487
|
+
} else {
|
|
488
|
+
pushed = false;
|
|
406
489
|
}
|
|
407
490
|
};
|
|
408
491
|
const onOpen = () => {
|
|
409
|
-
if (
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
}
|
|
423
|
-
};
|
|
424
|
-
window.addEventListener("popstate", onPop);
|
|
425
|
-
detachPopstate = () => window.removeEventListener("popstate", onPop);
|
|
426
|
-
} else if (deps.closeOnBack && !detachPopstate) {
|
|
427
|
-
try {
|
|
492
|
+
if (closer) return;
|
|
493
|
+
closer = {
|
|
494
|
+
isOpen: () => !deps.isDestroyed() && deps.getSize() > 0,
|
|
495
|
+
isTop: () => deps.isTopSheet(),
|
|
496
|
+
close: () => void deps.close(),
|
|
497
|
+
consumed: false
|
|
498
|
+
};
|
|
499
|
+
ensureHandler();
|
|
500
|
+
closers.push(closer);
|
|
501
|
+
try {
|
|
502
|
+
if (deps.routedTo !== void 0) {
|
|
503
|
+
history.pushState({ __bsRouted: deps.sheetId }, "", deps.routedTo);
|
|
504
|
+
} else {
|
|
428
505
|
history.pushState({ __bsSheet: deps.sheetId }, "");
|
|
429
|
-
closeOnBackPushed = true;
|
|
430
|
-
} catch {
|
|
431
506
|
}
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
const state2 = history.state;
|
|
436
|
-
if (state2?.__bsSheet !== deps.sheetId) closeOnBackPushed = false;
|
|
437
|
-
void deps.close();
|
|
438
|
-
}
|
|
439
|
-
};
|
|
440
|
-
window.addEventListener("popstate", onPop);
|
|
441
|
-
detachPopstate = () => window.removeEventListener("popstate", onPop);
|
|
442
|
-
}
|
|
443
|
-
};
|
|
444
|
-
const onClose = () => {
|
|
445
|
-
detachPopstate?.();
|
|
446
|
-
detachPopstate = null;
|
|
447
|
-
if (routePushed) {
|
|
448
|
-
routePushed = false;
|
|
449
|
-
if (deps.routedTo !== void 0) popOurMarker("__bsRouted", deps.routedTo);
|
|
450
|
-
}
|
|
451
|
-
if (closeOnBackPushed) {
|
|
452
|
-
closeOnBackPushed = false;
|
|
453
|
-
popOurMarker("__bsSheet", deps.sheetId);
|
|
507
|
+
pushed = true;
|
|
508
|
+
} catch {
|
|
509
|
+
pushed = false;
|
|
454
510
|
}
|
|
455
511
|
};
|
|
456
512
|
const unsubscribeOpen = deps.on("open", onOpen);
|
|
457
|
-
const unsubscribeClose = deps.on("close",
|
|
513
|
+
const unsubscribeClose = deps.on("close", teardownEntry);
|
|
458
514
|
if (deps.getSize() > 0) onOpen();
|
|
459
515
|
return () => {
|
|
460
516
|
unsubscribeOpen();
|
|
461
517
|
unsubscribeClose();
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
518
|
+
teardownEntry();
|
|
519
|
+
};
|
|
520
|
+
}
|
|
521
|
+
function installRouteChange(deps) {
|
|
522
|
+
if (typeof window === "undefined" || typeof history === "undefined") {
|
|
523
|
+
return () => {
|
|
524
|
+
};
|
|
525
|
+
}
|
|
526
|
+
const onChange = () => {
|
|
527
|
+
if (deps.isDestroyed() || deps.getSize() <= 0) return;
|
|
528
|
+
void deps.close();
|
|
529
|
+
};
|
|
530
|
+
const wrap = (key) => {
|
|
531
|
+
const original = history[key];
|
|
532
|
+
const patched = function(...args) {
|
|
533
|
+
original.apply(this, args);
|
|
534
|
+
onChange();
|
|
535
|
+
};
|
|
536
|
+
history[key] = patched;
|
|
537
|
+
return () => {
|
|
538
|
+
if (history[key] === patched) {
|
|
539
|
+
history[key] = original;
|
|
540
|
+
}
|
|
541
|
+
};
|
|
542
|
+
};
|
|
543
|
+
window.addEventListener("popstate", onChange);
|
|
544
|
+
const restorePush = wrap("pushState");
|
|
545
|
+
const restoreReplace = wrap("replaceState");
|
|
546
|
+
return () => {
|
|
547
|
+
window.removeEventListener("popstate", onChange);
|
|
548
|
+
restorePush();
|
|
549
|
+
restoreReplace();
|
|
472
550
|
};
|
|
473
551
|
}
|
|
474
552
|
|
|
@@ -570,13 +648,17 @@ function installResizeObserver(deps) {
|
|
|
570
648
|
if (viewportSize2 > 0 && viewportSize2 < max) {
|
|
571
649
|
deps.setMaxAxisSize(viewportSize2);
|
|
572
650
|
}
|
|
651
|
+
const wasAnimating = deps.isAnimating?.() ?? false;
|
|
573
652
|
deps.cancelInFlight();
|
|
574
653
|
deps.newCycle();
|
|
575
654
|
const current = deps.resolveActiveSnap();
|
|
576
655
|
const newMax = deps.getMaxAxisSize();
|
|
577
656
|
const targetSize = current ? Math.min(current.size, newMax) : Math.min(deps.getSize(), newMax);
|
|
578
657
|
deps.setSize(targetSize);
|
|
579
|
-
if (current && !deps.isDragging())
|
|
658
|
+
if (current && !deps.isDragging()) {
|
|
659
|
+
deps.applySize(targetSize);
|
|
660
|
+
if (wasAnimating) deps.resyncAfterCancel?.();
|
|
661
|
+
}
|
|
580
662
|
};
|
|
581
663
|
let resizeObserver = null;
|
|
582
664
|
if (typeof ResizeObserver !== "undefined") {
|
|
@@ -691,8 +773,88 @@ function devWarn(...args) {
|
|
|
691
773
|
}
|
|
692
774
|
}
|
|
693
775
|
|
|
776
|
+
// src/core/primitives/overlay-position.ts
|
|
777
|
+
function resolveSheetAnchoredStyle(mode, position, inset) {
|
|
778
|
+
const sizeOffset = `calc(var(--bs-size, 0px) + ${inset})`;
|
|
779
|
+
switch (mode) {
|
|
780
|
+
case "bottom":
|
|
781
|
+
if (position === "sheet-top-left") return { bottom: sizeOffset, left: inset };
|
|
782
|
+
if (position === "sheet-top-right") return { bottom: sizeOffset, right: inset };
|
|
783
|
+
return { bottom: sizeOffset, left: "50%", transform: "translateX(-50%)" };
|
|
784
|
+
case "top":
|
|
785
|
+
if (position === "sheet-top-left") return { top: sizeOffset, left: inset };
|
|
786
|
+
if (position === "sheet-top-right") return { top: sizeOffset, right: inset };
|
|
787
|
+
return { top: sizeOffset, left: "50%", transform: "translateX(-50%)" };
|
|
788
|
+
case "left":
|
|
789
|
+
if (position === "sheet-top-left") return { left: sizeOffset, top: inset };
|
|
790
|
+
if (position === "sheet-top-right") return { left: sizeOffset, bottom: inset };
|
|
791
|
+
return { left: sizeOffset, top: "50%", transform: "translateY(-50%)" };
|
|
792
|
+
case "right":
|
|
793
|
+
if (position === "sheet-top-left") return { right: sizeOffset, top: inset };
|
|
794
|
+
if (position === "sheet-top-right") return { right: sizeOffset, bottom: inset };
|
|
795
|
+
return { right: sizeOffset, top: "50%", transform: "translateY(-50%)" };
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
function applyOverlayPosition(ws, mode, position, inset) {
|
|
799
|
+
switch (position) {
|
|
800
|
+
case "top-left":
|
|
801
|
+
ws.top = inset;
|
|
802
|
+
ws.left = inset;
|
|
803
|
+
break;
|
|
804
|
+
case "top-center":
|
|
805
|
+
ws.top = inset;
|
|
806
|
+
ws.left = "50%";
|
|
807
|
+
ws.transform = "translateX(-50%)";
|
|
808
|
+
break;
|
|
809
|
+
case "top-right":
|
|
810
|
+
ws.top = inset;
|
|
811
|
+
ws.right = inset;
|
|
812
|
+
break;
|
|
813
|
+
case "center-left":
|
|
814
|
+
ws.top = "50%";
|
|
815
|
+
ws.left = inset;
|
|
816
|
+
ws.transform = "translateY(-50%)";
|
|
817
|
+
break;
|
|
818
|
+
case "center":
|
|
819
|
+
ws.top = "50%";
|
|
820
|
+
ws.left = "50%";
|
|
821
|
+
ws.transform = "translate(-50%, -50%)";
|
|
822
|
+
break;
|
|
823
|
+
case "center-right":
|
|
824
|
+
ws.top = "50%";
|
|
825
|
+
ws.right = inset;
|
|
826
|
+
ws.transform = "translateY(-50%)";
|
|
827
|
+
break;
|
|
828
|
+
case "bottom-left":
|
|
829
|
+
ws.bottom = inset;
|
|
830
|
+
ws.left = inset;
|
|
831
|
+
break;
|
|
832
|
+
case "bottom-center":
|
|
833
|
+
ws.bottom = inset;
|
|
834
|
+
ws.left = "50%";
|
|
835
|
+
ws.transform = "translateX(-50%)";
|
|
836
|
+
break;
|
|
837
|
+
case "bottom-right":
|
|
838
|
+
ws.bottom = inset;
|
|
839
|
+
ws.right = inset;
|
|
840
|
+
break;
|
|
841
|
+
case "sheet-top-left":
|
|
842
|
+
case "sheet-top-center":
|
|
843
|
+
case "sheet-top-right": {
|
|
844
|
+
const style = resolveSheetAnchoredStyle(mode, position, inset);
|
|
845
|
+
if (style.top !== void 0) ws.top = style.top;
|
|
846
|
+
if (style.bottom !== void 0) ws.bottom = style.bottom;
|
|
847
|
+
if (style.left !== void 0) ws.left = style.left;
|
|
848
|
+
if (style.right !== void 0) ws.right = style.right;
|
|
849
|
+
if (style.transform !== void 0) ws.transform = style.transform;
|
|
850
|
+
break;
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
|
|
694
855
|
// src/core/controllers/scrim-controller.ts
|
|
695
856
|
var VALID_CSS_LENGTH = /^-?\d+(?:\.\d+)?(?:px|em|rem|%)$/;
|
|
857
|
+
var DEFAULT_SCRIM_DIM = "rgba(0, 0, 0, 0.4)";
|
|
696
858
|
var ScrimController = class {
|
|
697
859
|
constructor(deps, opts) {
|
|
698
860
|
__publicField(this, "screenComponent");
|
|
@@ -703,6 +865,8 @@ var ScrimController = class {
|
|
|
703
865
|
__publicField(this, "getAllowedIds");
|
|
704
866
|
__publicField(this, "getResolvedSnaps");
|
|
705
867
|
__publicField(this, "snapToFn");
|
|
868
|
+
__publicField(this, "closeFn");
|
|
869
|
+
__publicField(this, "scrimInteractive", false);
|
|
706
870
|
__publicField(this, "scrimMode");
|
|
707
871
|
__publicField(this, "backdropRange");
|
|
708
872
|
__publicField(this, "screenRange");
|
|
@@ -723,14 +887,17 @@ var ScrimController = class {
|
|
|
723
887
|
this.getAllowedIds = deps.getAllowedIds;
|
|
724
888
|
this.getResolvedSnaps = deps.getResolvedSnaps;
|
|
725
889
|
this.snapToFn = deps.snapTo;
|
|
890
|
+
this.closeFn = deps.close;
|
|
726
891
|
this.scrimMode = opts.scrimMode ?? "full";
|
|
727
892
|
const preset = opts.scrimPreset ? SCRIM_PRESETS[opts.scrimPreset] : null;
|
|
728
893
|
this.backdropRange = opts.backdropRange ?? preset?.range ?? [0, 1];
|
|
729
894
|
this.screenRange = opts.screenRange ?? preset?.range ?? [0, 1];
|
|
730
895
|
this.scrimTapToCloseEnabled = opts.scrimTapToClose ?? false;
|
|
896
|
+
const explicitColor = opts.scrimColor ?? preset?.color;
|
|
897
|
+
const effectiveColor = explicitColor ?? (this.scrimMode !== "off" && !this.backdrop ? DEFAULT_SCRIM_DIM : void 0);
|
|
731
898
|
if (this.screenComponent) {
|
|
732
899
|
this.applyScrimStyles({
|
|
733
|
-
color:
|
|
900
|
+
color: effectiveColor,
|
|
734
901
|
blur: opts.scrimBlur ?? preset?.blur,
|
|
735
902
|
interactive: opts.scrimInteractive ?? preset?.interactive ?? false
|
|
736
903
|
});
|
|
@@ -864,11 +1031,15 @@ var ScrimController = class {
|
|
|
864
1031
|
}
|
|
865
1032
|
const onClick = () => {
|
|
866
1033
|
if (this.isDestroyed()) return;
|
|
1034
|
+
if (this.closeFn) {
|
|
1035
|
+
this.closeFn();
|
|
1036
|
+
return;
|
|
1037
|
+
}
|
|
867
1038
|
const allowed = this.getAllowedIds();
|
|
868
1039
|
const snaps = this.getResolvedSnaps();
|
|
869
1040
|
const fallback = allowed.find((id) => {
|
|
870
1041
|
const snap = findById(id, snaps);
|
|
871
|
-
return snap !== null && snap.size
|
|
1042
|
+
return snap !== null && snap.size === 0;
|
|
872
1043
|
});
|
|
873
1044
|
if (fallback) this.snapToFn(fallback);
|
|
874
1045
|
};
|
|
@@ -885,6 +1056,7 @@ var ScrimController = class {
|
|
|
885
1056
|
if (this.isDestroyed()) return;
|
|
886
1057
|
if (enabled === this.scrimEnabled) return;
|
|
887
1058
|
this.scrimEnabled = enabled;
|
|
1059
|
+
this.invalidateOpacityCache();
|
|
888
1060
|
if (!enabled) {
|
|
889
1061
|
this.savedScrimRanges = {
|
|
890
1062
|
screen: this.screenRange,
|
|
@@ -908,7 +1080,12 @@ var ScrimController = class {
|
|
|
908
1080
|
blur: cfg.blur ?? null,
|
|
909
1081
|
interactive: cfg.interactive
|
|
910
1082
|
});
|
|
911
|
-
this.
|
|
1083
|
+
if (!this.scrimEnabled && this.savedScrimRanges) {
|
|
1084
|
+
this.savedScrimRanges = { screen: cfg.range, backdrop: cfg.range };
|
|
1085
|
+
} else {
|
|
1086
|
+
this.screenRange = cfg.range;
|
|
1087
|
+
this.backdropRange = cfg.range;
|
|
1088
|
+
}
|
|
912
1089
|
}
|
|
913
1090
|
const noop = () => {
|
|
914
1091
|
};
|
|
@@ -958,59 +1135,7 @@ var ScrimController = class {
|
|
|
958
1135
|
wrapper.className = "bs-scrim-overlay";
|
|
959
1136
|
const ws = wrapper.style;
|
|
960
1137
|
ws.position = "absolute";
|
|
961
|
-
|
|
962
|
-
case "top-left":
|
|
963
|
-
ws.top = inset;
|
|
964
|
-
ws.left = inset;
|
|
965
|
-
break;
|
|
966
|
-
case "top-center":
|
|
967
|
-
ws.top = inset;
|
|
968
|
-
ws.left = "50%";
|
|
969
|
-
ws.transform = "translateX(-50%)";
|
|
970
|
-
break;
|
|
971
|
-
case "top-right":
|
|
972
|
-
ws.top = inset;
|
|
973
|
-
ws.right = inset;
|
|
974
|
-
break;
|
|
975
|
-
case "center-left":
|
|
976
|
-
ws.top = "50%";
|
|
977
|
-
ws.left = inset;
|
|
978
|
-
ws.transform = "translateY(-50%)";
|
|
979
|
-
break;
|
|
980
|
-
case "center":
|
|
981
|
-
ws.top = "50%";
|
|
982
|
-
ws.left = "50%";
|
|
983
|
-
ws.transform = "translate(-50%, -50%)";
|
|
984
|
-
break;
|
|
985
|
-
case "center-right":
|
|
986
|
-
ws.top = "50%";
|
|
987
|
-
ws.right = inset;
|
|
988
|
-
ws.transform = "translateY(-50%)";
|
|
989
|
-
break;
|
|
990
|
-
case "bottom-left":
|
|
991
|
-
ws.bottom = inset;
|
|
992
|
-
ws.left = inset;
|
|
993
|
-
break;
|
|
994
|
-
case "bottom-center":
|
|
995
|
-
ws.bottom = inset;
|
|
996
|
-
ws.left = "50%";
|
|
997
|
-
ws.transform = "translateX(-50%)";
|
|
998
|
-
break;
|
|
999
|
-
case "bottom-right":
|
|
1000
|
-
ws.bottom = inset;
|
|
1001
|
-
ws.right = inset;
|
|
1002
|
-
break;
|
|
1003
|
-
case "sheet-top-left":
|
|
1004
|
-
case "sheet-top-center":
|
|
1005
|
-
case "sheet-top-right":
|
|
1006
|
-
applySheetAnchoredPosition(
|
|
1007
|
-
ws,
|
|
1008
|
-
this.mode,
|
|
1009
|
-
position,
|
|
1010
|
-
inset
|
|
1011
|
-
);
|
|
1012
|
-
break;
|
|
1013
|
-
}
|
|
1138
|
+
applyOverlayPosition(ws, this.mode, position, inset);
|
|
1014
1139
|
if (interactive) {
|
|
1015
1140
|
ws.pointerEvents = "auto";
|
|
1016
1141
|
}
|
|
@@ -1069,6 +1194,7 @@ var ScrimController = class {
|
|
|
1069
1194
|
}
|
|
1070
1195
|
}
|
|
1071
1196
|
if (opts.interactive !== void 0) {
|
|
1197
|
+
this.scrimInteractive = opts.interactive;
|
|
1072
1198
|
s.pointerEvents = opts.interactive ? "auto" : "none";
|
|
1073
1199
|
}
|
|
1074
1200
|
}
|
|
@@ -1083,38 +1209,9 @@ var ScrimController = class {
|
|
|
1083
1209
|
const s = this.screenComponent.style;
|
|
1084
1210
|
s.position = "fixed";
|
|
1085
1211
|
s.inset = insetByMode[this.mode];
|
|
1086
|
-
s.pointerEvents = "none";
|
|
1212
|
+
s.pointerEvents = this.scrimInteractive || this.scrimTapToCloseEnabled ? "auto" : "none";
|
|
1087
1213
|
}
|
|
1088
1214
|
};
|
|
1089
|
-
function resolveSheetAnchoredStyle(mode, position, inset) {
|
|
1090
|
-
const sizeOffset = `calc(var(--bs-size, 0px) + ${inset})`;
|
|
1091
|
-
switch (mode) {
|
|
1092
|
-
case "bottom":
|
|
1093
|
-
if (position === "sheet-top-left") return { bottom: sizeOffset, left: inset };
|
|
1094
|
-
if (position === "sheet-top-right") return { bottom: sizeOffset, right: inset };
|
|
1095
|
-
return { bottom: sizeOffset, left: "50%", transform: "translateX(-50%)" };
|
|
1096
|
-
case "top":
|
|
1097
|
-
if (position === "sheet-top-left") return { top: sizeOffset, left: inset };
|
|
1098
|
-
if (position === "sheet-top-right") return { top: sizeOffset, right: inset };
|
|
1099
|
-
return { top: sizeOffset, left: "50%", transform: "translateX(-50%)" };
|
|
1100
|
-
case "left":
|
|
1101
|
-
if (position === "sheet-top-left") return { left: sizeOffset, top: inset };
|
|
1102
|
-
if (position === "sheet-top-right") return { left: sizeOffset, bottom: inset };
|
|
1103
|
-
return { left: sizeOffset, top: "50%", transform: "translateY(-50%)" };
|
|
1104
|
-
case "right":
|
|
1105
|
-
if (position === "sheet-top-left") return { right: sizeOffset, top: inset };
|
|
1106
|
-
if (position === "sheet-top-right") return { right: sizeOffset, bottom: inset };
|
|
1107
|
-
return { right: sizeOffset, top: "50%", transform: "translateY(-50%)" };
|
|
1108
|
-
}
|
|
1109
|
-
}
|
|
1110
|
-
function applySheetAnchoredPosition(ws, mode, position, inset) {
|
|
1111
|
-
const style = resolveSheetAnchoredStyle(mode, position, inset);
|
|
1112
|
-
if (style.top !== void 0) ws.top = style.top;
|
|
1113
|
-
if (style.bottom !== void 0) ws.bottom = style.bottom;
|
|
1114
|
-
if (style.left !== void 0) ws.left = style.left;
|
|
1115
|
-
if (style.right !== void 0) ws.right = style.right;
|
|
1116
|
-
if (style.transform !== void 0) ws.transform = style.transform;
|
|
1117
|
-
}
|
|
1118
1215
|
|
|
1119
1216
|
// src/core/animation/animation.ts
|
|
1120
1217
|
var easeOutBack = (t) => {
|
|
@@ -1166,6 +1263,10 @@ var tween = ({
|
|
|
1166
1263
|
promise
|
|
1167
1264
|
};
|
|
1168
1265
|
};
|
|
1266
|
+
var prefersReducedMotion = () => {
|
|
1267
|
+
if (typeof window === "undefined" || !window.matchMedia) return false;
|
|
1268
|
+
return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
1269
|
+
};
|
|
1169
1270
|
|
|
1170
1271
|
// src/core/animation/spring.ts
|
|
1171
1272
|
var DEFAULT_SPRING = {
|
|
@@ -1196,14 +1297,20 @@ var runSpring = ({
|
|
|
1196
1297
|
if (cancelled) return;
|
|
1197
1298
|
const dt = Math.min((now - lastTime) / 1e3, MAX_DT);
|
|
1198
1299
|
lastTime = now;
|
|
1199
|
-
const
|
|
1200
|
-
|
|
1300
|
+
const steps = Math.max(1, Math.ceil(dt * 240));
|
|
1301
|
+
const subDt = dt / steps;
|
|
1302
|
+
let stepsLeft = steps;
|
|
1201
1303
|
while (stepsLeft-- > 0) {
|
|
1202
1304
|
const force = -cfg.stiffness * (x - to) - cfg.damping * v;
|
|
1203
1305
|
const accel = force / cfg.mass;
|
|
1204
1306
|
v += accel * subDt;
|
|
1205
1307
|
x += v * subDt;
|
|
1206
1308
|
}
|
|
1309
|
+
if (!Number.isFinite(x) || !Number.isFinite(v)) {
|
|
1310
|
+
onUpdate(to, 0);
|
|
1311
|
+
resolve();
|
|
1312
|
+
return;
|
|
1313
|
+
}
|
|
1207
1314
|
onUpdate(x, v);
|
|
1208
1315
|
const isAtRest = Math.abs(to - x) < (cfg.restDelta ?? 0.5) && Math.abs(v) < (cfg.restSpeed ?? 0.5);
|
|
1209
1316
|
if (isAtRest) {
|
|
@@ -1378,9 +1485,13 @@ var isVisible = (el) => {
|
|
|
1378
1485
|
var focusables = (root2) => Array.from(root2.querySelectorAll(FOCUSABLE)).filter(
|
|
1379
1486
|
(el) => !el.hasAttribute("inert") && isVisible(el) && !el.matches("[aria-hidden='true']")
|
|
1380
1487
|
);
|
|
1488
|
+
var trapStack = [];
|
|
1381
1489
|
var installFocusTrap = (container, options = {}) => {
|
|
1382
1490
|
if (typeof document === "undefined") return () => {
|
|
1383
1491
|
};
|
|
1492
|
+
const token = {};
|
|
1493
|
+
trapStack.push(token);
|
|
1494
|
+
const isActive = () => trapStack[trapStack.length - 1] === token;
|
|
1384
1495
|
const previouslyFocused = document.activeElement;
|
|
1385
1496
|
const focusInitial = () => {
|
|
1386
1497
|
const initial = typeof options.initialFocus === "string" ? container.querySelector(options.initialFocus) : options.initialFocus ?? focusables(container)[0] ?? container;
|
|
@@ -1388,6 +1499,7 @@ var installFocusTrap = (container, options = {}) => {
|
|
|
1388
1499
|
};
|
|
1389
1500
|
focusInitial();
|
|
1390
1501
|
const handleKey = (e) => {
|
|
1502
|
+
if (!isActive()) return;
|
|
1391
1503
|
if (e.key === "Escape" && options.onEscape) {
|
|
1392
1504
|
options.onEscape();
|
|
1393
1505
|
return;
|
|
@@ -1410,6 +1522,7 @@ var installFocusTrap = (container, options = {}) => {
|
|
|
1410
1522
|
}
|
|
1411
1523
|
};
|
|
1412
1524
|
const handleFocusIn = (e) => {
|
|
1525
|
+
if (!isActive()) return;
|
|
1413
1526
|
const target = e.target;
|
|
1414
1527
|
if (target && !container.contains(target)) {
|
|
1415
1528
|
const list = focusables(container);
|
|
@@ -1422,6 +1535,8 @@ var installFocusTrap = (container, options = {}) => {
|
|
|
1422
1535
|
return () => {
|
|
1423
1536
|
if (released) return;
|
|
1424
1537
|
released = true;
|
|
1538
|
+
const idx = trapStack.indexOf(token);
|
|
1539
|
+
if (idx !== -1) trapStack.splice(idx, 1);
|
|
1425
1540
|
document.removeEventListener("keydown", handleKey, true);
|
|
1426
1541
|
document.removeEventListener("focusin", handleFocusIn, true);
|
|
1427
1542
|
if (previouslyFocused && document.contains(previouslyFocused)) {
|
|
@@ -1477,11 +1592,17 @@ function createInertSiblings(rootProvider) {
|
|
|
1477
1592
|
return {
|
|
1478
1593
|
apply() {
|
|
1479
1594
|
if (typeof document === "undefined") return;
|
|
1480
|
-
|
|
1481
|
-
|
|
1595
|
+
let top = rootProvider();
|
|
1596
|
+
while (top.parentElement && top.parentElement !== document.body) {
|
|
1597
|
+
top = top.parentElement;
|
|
1598
|
+
}
|
|
1599
|
+
const parent = top.parentElement ?? document.body;
|
|
1482
1600
|
for (const child2 of Array.from(parent.children)) {
|
|
1483
|
-
if (child2 ===
|
|
1601
|
+
if (child2 === top) continue;
|
|
1484
1602
|
if (child2.hasAttribute("inert")) continue;
|
|
1603
|
+
if (child2.classList.contains("bs-backdrop") || child2.classList.contains("bs-screen") || child2.classList.contains("bs-root")) {
|
|
1604
|
+
continue;
|
|
1605
|
+
}
|
|
1485
1606
|
child2.setAttribute("inert", "");
|
|
1486
1607
|
tracked.push(child2);
|
|
1487
1608
|
}
|
|
@@ -1497,7 +1618,6 @@ function createInertSiblings(rootProvider) {
|
|
|
1497
1618
|
var LifecycleController = class {
|
|
1498
1619
|
constructor(deps, opts) {
|
|
1499
1620
|
__publicField(this, "element");
|
|
1500
|
-
__publicField(this, "closeFn");
|
|
1501
1621
|
__publicField(this, "focusTrapEnabled");
|
|
1502
1622
|
__publicField(this, "initialFocus");
|
|
1503
1623
|
__publicField(this, "closeOnEscape");
|
|
@@ -1511,7 +1631,6 @@ var LifecycleController = class {
|
|
|
1511
1631
|
__publicField(this, "installed", false);
|
|
1512
1632
|
__publicField(this, "destroyed", false);
|
|
1513
1633
|
this.element = deps.element;
|
|
1514
|
-
this.closeFn = deps.close;
|
|
1515
1634
|
this.focusTrapEnabled = opts.focusTrap ?? false;
|
|
1516
1635
|
this.initialFocus = opts.initialFocus;
|
|
1517
1636
|
this.closeOnEscape = opts.closeOnEscape ?? true;
|
|
@@ -1521,6 +1640,9 @@ var LifecycleController = class {
|
|
|
1521
1640
|
this.returnFocus = opts.returnFocus;
|
|
1522
1641
|
this.inertSiblings = createInertSiblings(() => this.element);
|
|
1523
1642
|
}
|
|
1643
|
+
get isInstalled() {
|
|
1644
|
+
return this.installed;
|
|
1645
|
+
}
|
|
1524
1646
|
install() {
|
|
1525
1647
|
if (this.destroyed) return;
|
|
1526
1648
|
this.installed = true;
|
|
@@ -1529,8 +1651,7 @@ var LifecycleController = class {
|
|
|
1529
1651
|
}
|
|
1530
1652
|
if (this.focusTrapEnabled && !this.releaseFocusTrap) {
|
|
1531
1653
|
this.releaseFocusTrap = installFocusTrap(this.element, {
|
|
1532
|
-
initialFocus: this.initialFocus
|
|
1533
|
-
onEscape: this.closeOnEscape ? () => void this.closeFn() : void 0
|
|
1654
|
+
initialFocus: this.initialFocus
|
|
1534
1655
|
});
|
|
1535
1656
|
}
|
|
1536
1657
|
if (this.inertSiblingsEnabled && this.shouldApplyInertSiblings()) {
|
|
@@ -1550,7 +1671,7 @@ var LifecycleController = class {
|
|
|
1550
1671
|
this.releaseScrollLock = null;
|
|
1551
1672
|
this.inertSiblings.remove();
|
|
1552
1673
|
if (this.returnFocus) {
|
|
1553
|
-
const target = typeof this.returnFocus === "function" ? this.returnFocus() : this.returnFocus;
|
|
1674
|
+
const target = typeof this.returnFocus === "function" ? this.returnFocus() : typeof this.returnFocus === "string" ? typeof document !== "undefined" ? document.querySelector(this.returnFocus) : null : this.returnFocus;
|
|
1554
1675
|
target?.focus?.();
|
|
1555
1676
|
}
|
|
1556
1677
|
}
|
|
@@ -1684,10 +1805,11 @@ var installGestures = (handle, mode, callbacks) => {
|
|
|
1684
1805
|
};
|
|
1685
1806
|
|
|
1686
1807
|
// src/core/primitives/rubber-band.ts
|
|
1687
|
-
var RUBBER_BAND_FACTOR = 0.55;
|
|
1688
1808
|
function rubberBand(overshoot, maxAxisSize) {
|
|
1689
1809
|
const cap = Math.min(maxAxisSize * 0.15, 80);
|
|
1690
|
-
|
|
1810
|
+
if (cap <= 0) return 0;
|
|
1811
|
+
const abs = Math.abs(overshoot);
|
|
1812
|
+
return Math.sign(overshoot) * (cap * abs / (abs + cap));
|
|
1691
1813
|
}
|
|
1692
1814
|
|
|
1693
1815
|
// src/core/features/soft-keyboard.ts
|
|
@@ -1716,6 +1838,7 @@ var GestureController = class {
|
|
|
1716
1838
|
__publicField(this, "dragStartSize", 0);
|
|
1717
1839
|
__publicField(this, "currentPointerKind", "touch");
|
|
1718
1840
|
__publicField(this, "keyboardDismissed", false);
|
|
1841
|
+
__publicField(this, "dragSuppressed", false);
|
|
1719
1842
|
__publicField(this, "dragPayload", { size: 0, delta: 0 });
|
|
1720
1843
|
this.deps = deps;
|
|
1721
1844
|
}
|
|
@@ -1726,6 +1849,11 @@ var GestureController = class {
|
|
|
1726
1849
|
if (this.detach) return this.detach;
|
|
1727
1850
|
this.detach = installGestures(this.deps.handle, this.deps.mode, {
|
|
1728
1851
|
onStart: (_coord, kind) => {
|
|
1852
|
+
if (this.deps.getDisableDrag?.()) {
|
|
1853
|
+
this.dragSuppressed = true;
|
|
1854
|
+
return;
|
|
1855
|
+
}
|
|
1856
|
+
this.dragSuppressed = false;
|
|
1729
1857
|
this.deps.cancelAnimation();
|
|
1730
1858
|
this.isDragging_ = true;
|
|
1731
1859
|
this.dragStartSize = this.deps.getDragContext().size;
|
|
@@ -1736,6 +1864,7 @@ var GestureController = class {
|
|
|
1736
1864
|
this.deps.emit("dragstart", { size: this.dragStartSize });
|
|
1737
1865
|
},
|
|
1738
1866
|
onMove: (delta) => {
|
|
1867
|
+
if (this.dragSuppressed) return;
|
|
1739
1868
|
const ctx = this.deps.getDragContext();
|
|
1740
1869
|
const { min, max } = ctx.range;
|
|
1741
1870
|
const maxAxis = ctx.maxAxisSize;
|
|
@@ -1759,6 +1888,10 @@ var GestureController = class {
|
|
|
1759
1888
|
}
|
|
1760
1889
|
},
|
|
1761
1890
|
onEnd: (delta, velocity, kind) => {
|
|
1891
|
+
if (this.dragSuppressed) {
|
|
1892
|
+
this.dragSuppressed = false;
|
|
1893
|
+
return;
|
|
1894
|
+
}
|
|
1762
1895
|
this.isDragging_ = false;
|
|
1763
1896
|
this.keyboardDismissed = false;
|
|
1764
1897
|
this.deps.getRoot()?.removeAttribute("data-dragging");
|
|
@@ -1769,9 +1902,17 @@ var GestureController = class {
|
|
|
1769
1902
|
this.deps.settleAfterDrag(delta, velocity, kind);
|
|
1770
1903
|
},
|
|
1771
1904
|
onCancel: () => {
|
|
1905
|
+
if (this.dragSuppressed) {
|
|
1906
|
+
this.dragSuppressed = false;
|
|
1907
|
+
return;
|
|
1908
|
+
}
|
|
1772
1909
|
this.isDragging_ = false;
|
|
1773
1910
|
this.keyboardDismissed = false;
|
|
1774
1911
|
this.deps.getRoot()?.removeAttribute("data-dragging");
|
|
1912
|
+
this.deps.emit("dragend", {
|
|
1913
|
+
size: this.deps.getDragContext().size,
|
|
1914
|
+
velocity: 0
|
|
1915
|
+
});
|
|
1775
1916
|
const restoreTo = this.dragStartSize;
|
|
1776
1917
|
void this.deps.animateTo(restoreTo, 0);
|
|
1777
1918
|
}
|
|
@@ -1845,6 +1986,287 @@ function createScrollCache(deps) {
|
|
|
1845
1986
|
};
|
|
1846
1987
|
}
|
|
1847
1988
|
|
|
1989
|
+
// src/core/primitives/anchor-animations.ts
|
|
1990
|
+
var DEFAULT_DURATION3 = 200;
|
|
1991
|
+
var DEFAULT_EASING = "cubic-bezier(0.22, 1, 0.36, 1)";
|
|
1992
|
+
var PRESET_FRAMES = {
|
|
1993
|
+
fade: {
|
|
1994
|
+
enter: [{ opacity: 0 }, { opacity: 1 }],
|
|
1995
|
+
exit: [{ opacity: 1 }, { opacity: 0 }]
|
|
1996
|
+
},
|
|
1997
|
+
scale: {
|
|
1998
|
+
enter: [
|
|
1999
|
+
{ opacity: 0, transform: "scale(0.85)" },
|
|
2000
|
+
{ opacity: 1, transform: "scale(1)" }
|
|
2001
|
+
],
|
|
2002
|
+
exit: [
|
|
2003
|
+
{ opacity: 1, transform: "scale(1)" },
|
|
2004
|
+
{ opacity: 0, transform: "scale(0.85)" }
|
|
2005
|
+
]
|
|
2006
|
+
},
|
|
2007
|
+
slide: {
|
|
2008
|
+
enter: [
|
|
2009
|
+
{ opacity: 0, transform: "translateY(10px)" },
|
|
2010
|
+
{ opacity: 1, transform: "translateY(0)" }
|
|
2011
|
+
],
|
|
2012
|
+
exit: [
|
|
2013
|
+
{ opacity: 1, transform: "translateY(0)" },
|
|
2014
|
+
{ opacity: 0, transform: "translateY(10px)" }
|
|
2015
|
+
]
|
|
2016
|
+
},
|
|
2017
|
+
pop: {
|
|
2018
|
+
enter: [
|
|
2019
|
+
{ opacity: 0, transform: "scale(0.6)", offset: 0 },
|
|
2020
|
+
{ opacity: 1, transform: "scale(1.06)", offset: 0.7 },
|
|
2021
|
+
{ opacity: 1, transform: "scale(1)", offset: 1 }
|
|
2022
|
+
],
|
|
2023
|
+
exit: [
|
|
2024
|
+
{ opacity: 1, transform: "scale(1)" },
|
|
2025
|
+
{ opacity: 0, transform: "scale(0.6)" }
|
|
2026
|
+
]
|
|
2027
|
+
}
|
|
2028
|
+
};
|
|
2029
|
+
var INSTANT = {
|
|
2030
|
+
finished: Promise.resolve(),
|
|
2031
|
+
cancel: () => {
|
|
2032
|
+
}
|
|
2033
|
+
};
|
|
2034
|
+
function resolveTransitionFrames(spec, phase) {
|
|
2035
|
+
const fallback = { frames: null, duration: 0, easing: DEFAULT_EASING };
|
|
2036
|
+
if (spec === "none") return fallback;
|
|
2037
|
+
if (spec === void 0 || typeof spec === "string") {
|
|
2038
|
+
const preset2 = PRESET_FRAMES[spec ?? "fade"];
|
|
2039
|
+
return {
|
|
2040
|
+
frames: preset2[phase],
|
|
2041
|
+
duration: DEFAULT_DURATION3,
|
|
2042
|
+
easing: DEFAULT_EASING
|
|
2043
|
+
};
|
|
2044
|
+
}
|
|
2045
|
+
const custom = phase === "enter" ? spec.enter : spec.exit;
|
|
2046
|
+
if (custom) {
|
|
2047
|
+
return {
|
|
2048
|
+
frames: custom,
|
|
2049
|
+
duration: spec.duration ?? DEFAULT_DURATION3,
|
|
2050
|
+
easing: spec.easing ?? DEFAULT_EASING
|
|
2051
|
+
};
|
|
2052
|
+
}
|
|
2053
|
+
if (spec.preset === "none") return fallback;
|
|
2054
|
+
const preset = PRESET_FRAMES[spec.preset ?? "fade"];
|
|
2055
|
+
return {
|
|
2056
|
+
frames: preset[phase],
|
|
2057
|
+
duration: spec.duration ?? DEFAULT_DURATION3,
|
|
2058
|
+
easing: spec.easing ?? DEFAULT_EASING
|
|
2059
|
+
};
|
|
2060
|
+
}
|
|
2061
|
+
function runAnchorTransition(el, spec, phase) {
|
|
2062
|
+
const respectReduced = typeof spec === "object" ? spec.respectReducedMotion !== false : true;
|
|
2063
|
+
if (respectReduced && prefersReducedMotion()) return INSTANT;
|
|
2064
|
+
const { frames, duration, easing } = resolveTransitionFrames(spec, phase);
|
|
2065
|
+
if (!frames || duration <= 0) return INSTANT;
|
|
2066
|
+
if (typeof el.animate !== "function") return INSTANT;
|
|
2067
|
+
const animation = el.animate(frames, {
|
|
2068
|
+
duration,
|
|
2069
|
+
easing,
|
|
2070
|
+
fill: "both"
|
|
2071
|
+
});
|
|
2072
|
+
const finished = animation.finished.then(() => void 0).catch(() => void 0);
|
|
2073
|
+
return {
|
|
2074
|
+
finished,
|
|
2075
|
+
cancel: () => {
|
|
2076
|
+
try {
|
|
2077
|
+
animation.cancel();
|
|
2078
|
+
} catch {
|
|
2079
|
+
return;
|
|
2080
|
+
}
|
|
2081
|
+
}
|
|
2082
|
+
};
|
|
2083
|
+
}
|
|
2084
|
+
|
|
2085
|
+
// src/core/features/sheet-anchors.ts
|
|
2086
|
+
function attachAnchor(deps, opts) {
|
|
2087
|
+
const doc = deps.host.ownerDocument;
|
|
2088
|
+
const wrapper = doc.createElement("div");
|
|
2089
|
+
wrapper.className = "bs-anchor";
|
|
2090
|
+
const interactive = opts.interactive ?? true;
|
|
2091
|
+
const position = opts.position ?? "sheet-top-right";
|
|
2092
|
+
const isDock = position === "dock-bottom" || position === "dock-top";
|
|
2093
|
+
const ws = wrapper.style;
|
|
2094
|
+
ws.position = "fixed";
|
|
2095
|
+
if (isDock) {
|
|
2096
|
+
ws.left = "0";
|
|
2097
|
+
ws.right = "0";
|
|
2098
|
+
if (position === "dock-bottom") {
|
|
2099
|
+
ws.bottom = "0";
|
|
2100
|
+
} else {
|
|
2101
|
+
ws.top = "0";
|
|
2102
|
+
}
|
|
2103
|
+
} else {
|
|
2104
|
+
applyOverlayPosition(ws, deps.mode, position, opts.inset ?? "16px");
|
|
2105
|
+
}
|
|
2106
|
+
if (opts.fadeRange) {
|
|
2107
|
+
const [r0, r1] = opts.fadeRange;
|
|
2108
|
+
const span = Math.max(r1 - r0, 1e-4);
|
|
2109
|
+
ws.opacity = `clamp(0, calc((var(--bs-progress, 0) - ${r0}) / ${span}), 1)`;
|
|
2110
|
+
}
|
|
2111
|
+
wrapper.appendChild(opts.element);
|
|
2112
|
+
deps.host.appendChild(wrapper);
|
|
2113
|
+
let visible = null;
|
|
2114
|
+
let inFlight = null;
|
|
2115
|
+
const shouldShow = (state2) => {
|
|
2116
|
+
if (typeof opts.showOn === "function") return opts.showOn(state2);
|
|
2117
|
+
if (Array.isArray(opts.showOn)) return opts.showOn.includes(state2.activeId);
|
|
2118
|
+
return isDock || state2.size > 0;
|
|
2119
|
+
};
|
|
2120
|
+
const applyVisibility = (next, animate) => {
|
|
2121
|
+
if (next === visible) return;
|
|
2122
|
+
visible = next;
|
|
2123
|
+
inFlight?.cancel();
|
|
2124
|
+
inFlight = null;
|
|
2125
|
+
wrapper.style.pointerEvents = next && interactive ? "auto" : "none";
|
|
2126
|
+
if (next) {
|
|
2127
|
+
wrapper.style.visibility = "";
|
|
2128
|
+
if (animate) {
|
|
2129
|
+
inFlight = runAnchorTransition(opts.element, opts.animation, "enter");
|
|
2130
|
+
}
|
|
2131
|
+
return;
|
|
2132
|
+
}
|
|
2133
|
+
if (!animate) {
|
|
2134
|
+
wrapper.style.visibility = "hidden";
|
|
2135
|
+
return;
|
|
2136
|
+
}
|
|
2137
|
+
const handle = runAnchorTransition(opts.element, opts.animation, "exit");
|
|
2138
|
+
inFlight = handle;
|
|
2139
|
+
void handle.finished.then(() => {
|
|
2140
|
+
if (inFlight === handle && visible === false) {
|
|
2141
|
+
wrapper.style.visibility = "hidden";
|
|
2142
|
+
}
|
|
2143
|
+
});
|
|
2144
|
+
};
|
|
2145
|
+
const evaluate = (animate) => {
|
|
2146
|
+
if (deps.isDestroyed()) return;
|
|
2147
|
+
applyVisibility(shouldShow(deps.getState()), animate);
|
|
2148
|
+
};
|
|
2149
|
+
const offs = [
|
|
2150
|
+
deps.on("snap", () => evaluate(true)),
|
|
2151
|
+
deps.on("open", () => evaluate(true)),
|
|
2152
|
+
deps.on("close", () => evaluate(true))
|
|
2153
|
+
];
|
|
2154
|
+
evaluate(false);
|
|
2155
|
+
return {
|
|
2156
|
+
wrapper,
|
|
2157
|
+
detach: () => {
|
|
2158
|
+
offs.forEach((off) => off());
|
|
2159
|
+
inFlight?.cancel();
|
|
2160
|
+
inFlight = null;
|
|
2161
|
+
if (wrapper.parentNode) wrapper.parentNode.removeChild(wrapper);
|
|
2162
|
+
},
|
|
2163
|
+
syncZ: (z) => {
|
|
2164
|
+
wrapper.style.zIndex = String(z);
|
|
2165
|
+
}
|
|
2166
|
+
};
|
|
2167
|
+
}
|
|
2168
|
+
|
|
2169
|
+
// src/core/features/scrim-stages.ts
|
|
2170
|
+
var matchesId = (def, activeId) => {
|
|
2171
|
+
if (def.for === void 0) return false;
|
|
2172
|
+
return Array.isArray(def.for) ? def.for.includes(activeId) : def.for === activeId;
|
|
2173
|
+
};
|
|
2174
|
+
var matchesRange = (def, progress) => {
|
|
2175
|
+
if (!def.forRange) return false;
|
|
2176
|
+
const [from, to] = def.forRange;
|
|
2177
|
+
return progress >= from && progress <= to;
|
|
2178
|
+
};
|
|
2179
|
+
function installScrimStages(deps, opts) {
|
|
2180
|
+
const doc = deps.host.ownerDocument;
|
|
2181
|
+
const entries = opts.stages.map((def) => {
|
|
2182
|
+
const wrapper = doc.createElement("div");
|
|
2183
|
+
wrapper.className = "bs-scrim-stage";
|
|
2184
|
+
const ws = wrapper.style;
|
|
2185
|
+
ws.position = "absolute";
|
|
2186
|
+
applyOverlayPosition(
|
|
2187
|
+
ws,
|
|
2188
|
+
deps.mode,
|
|
2189
|
+
def.position ?? opts.position ?? "center",
|
|
2190
|
+
def.inset ?? opts.inset ?? "16px"
|
|
2191
|
+
);
|
|
2192
|
+
ws.visibility = "hidden";
|
|
2193
|
+
ws.pointerEvents = "none";
|
|
2194
|
+
wrapper.appendChild(def.element);
|
|
2195
|
+
deps.host.appendChild(wrapper);
|
|
2196
|
+
return { def, wrapper, inFlight: null };
|
|
2197
|
+
});
|
|
2198
|
+
let active = null;
|
|
2199
|
+
const resolveActive = () => {
|
|
2200
|
+
const state2 = deps.getState();
|
|
2201
|
+
if (state2.size === 0) {
|
|
2202
|
+
return entries.find((e) => matchesId(e.def, state2.activeId)) ?? null;
|
|
2203
|
+
}
|
|
2204
|
+
return entries.find((e) => matchesId(e.def, state2.activeId)) ?? entries.find((e) => matchesRange(e.def, state2.progress)) ?? null;
|
|
2205
|
+
};
|
|
2206
|
+
const hide = (entry, animate) => {
|
|
2207
|
+
entry.inFlight?.cancel();
|
|
2208
|
+
entry.wrapper.style.pointerEvents = "none";
|
|
2209
|
+
if (!animate) {
|
|
2210
|
+
entry.inFlight = null;
|
|
2211
|
+
entry.wrapper.style.visibility = "hidden";
|
|
2212
|
+
return;
|
|
2213
|
+
}
|
|
2214
|
+
const handle = runAnchorTransition(
|
|
2215
|
+
entry.def.element,
|
|
2216
|
+
entry.def.animation ?? opts.animation,
|
|
2217
|
+
"exit"
|
|
2218
|
+
);
|
|
2219
|
+
entry.inFlight = handle;
|
|
2220
|
+
void handle.finished.then(() => {
|
|
2221
|
+
if (entry.inFlight === handle && active !== entry) {
|
|
2222
|
+
entry.wrapper.style.visibility = "hidden";
|
|
2223
|
+
}
|
|
2224
|
+
});
|
|
2225
|
+
};
|
|
2226
|
+
const show = (entry, animate) => {
|
|
2227
|
+
entry.inFlight?.cancel();
|
|
2228
|
+
entry.inFlight = null;
|
|
2229
|
+
entry.wrapper.style.visibility = "";
|
|
2230
|
+
entry.wrapper.style.pointerEvents = entry.def.interactive ?? opts.interactive ?? false ? "auto" : "none";
|
|
2231
|
+
if (animate) {
|
|
2232
|
+
entry.inFlight = runAnchorTransition(
|
|
2233
|
+
entry.def.element,
|
|
2234
|
+
entry.def.animation ?? opts.animation,
|
|
2235
|
+
"enter"
|
|
2236
|
+
);
|
|
2237
|
+
}
|
|
2238
|
+
};
|
|
2239
|
+
const update = (animate) => {
|
|
2240
|
+
if (deps.isDestroyed()) return;
|
|
2241
|
+
const next = resolveActive();
|
|
2242
|
+
if (next === active) return;
|
|
2243
|
+
const prev = active;
|
|
2244
|
+
active = next;
|
|
2245
|
+
if (prev) hide(prev, animate);
|
|
2246
|
+
if (next) show(next, animate);
|
|
2247
|
+
};
|
|
2248
|
+
const offs = [
|
|
2249
|
+
deps.on("snap", () => update(true)),
|
|
2250
|
+
deps.on("open", () => update(true)),
|
|
2251
|
+
deps.on("close", () => update(true))
|
|
2252
|
+
];
|
|
2253
|
+
if (entries.some((e) => e.def.forRange)) {
|
|
2254
|
+
offs.push(deps.on("progress", () => update(true)));
|
|
2255
|
+
}
|
|
2256
|
+
update(false);
|
|
2257
|
+
return () => {
|
|
2258
|
+
offs.forEach((off) => off());
|
|
2259
|
+
for (const entry of entries) {
|
|
2260
|
+
entry.inFlight?.cancel();
|
|
2261
|
+
entry.inFlight = null;
|
|
2262
|
+
if (entry.wrapper.parentNode) {
|
|
2263
|
+
entry.wrapper.parentNode.removeChild(entry.wrapper);
|
|
2264
|
+
}
|
|
2265
|
+
}
|
|
2266
|
+
active = null;
|
|
2267
|
+
};
|
|
2268
|
+
}
|
|
2269
|
+
|
|
1848
2270
|
// src/core/primitives/engine-options.ts
|
|
1849
2271
|
var DEFAULT_FLICK_VELOCITY = 0.65;
|
|
1850
2272
|
var DEFAULT_DRAG_THRESHOLD = 18;
|
|
@@ -1863,6 +2285,12 @@ function resolveEngineOptions(opts, extras) {
|
|
|
1863
2285
|
dragThreshold: opts.dragThreshold ?? DEFAULT_DRAG_THRESHOLD,
|
|
1864
2286
|
rubberBandEnabled: opts.rubberBand ?? true,
|
|
1865
2287
|
closeOnBack: opts.closeOnBack ?? false,
|
|
2288
|
+
persistent: opts.persistent ?? false,
|
|
2289
|
+
disableClose: opts.disableClose ?? false,
|
|
2290
|
+
disableDrag: opts.disableDrag ?? false,
|
|
2291
|
+
closeOnRouteChange: opts.closeOnRouteChange ?? false,
|
|
2292
|
+
radius: opts.radius,
|
|
2293
|
+
maxHeight: opts.maxHeight,
|
|
1866
2294
|
initialAllowed,
|
|
1867
2295
|
initialId,
|
|
1868
2296
|
scrim: {
|
|
@@ -1889,7 +2317,8 @@ function resolveEngineOptions(opts, extras) {
|
|
|
1889
2317
|
closeOnEscape: opts.closeOnEscape,
|
|
1890
2318
|
lockBodyScroll: opts.lockBodyScroll,
|
|
1891
2319
|
inertSiblings: opts.inertSiblings,
|
|
1892
|
-
shouldApplyInertSiblings: extras?.shouldApplyInertSiblings
|
|
2320
|
+
shouldApplyInertSiblings: extras?.shouldApplyInertSiblings,
|
|
2321
|
+
returnFocus: opts.returnFocusTo
|
|
1893
2322
|
}
|
|
1894
2323
|
};
|
|
1895
2324
|
}
|
|
@@ -1934,6 +2363,11 @@ var BottomSheetEngine = class {
|
|
|
1934
2363
|
__publicField(this, "lifecycle");
|
|
1935
2364
|
__publicField(this, "closeOnBack");
|
|
1936
2365
|
__publicField(this, "routedTo");
|
|
2366
|
+
__publicField(this, "persistent");
|
|
2367
|
+
__publicField(this, "disableCloseFlag");
|
|
2368
|
+
__publicField(this, "disableDragFlag");
|
|
2369
|
+
__publicField(this, "closeOnRouteChange");
|
|
2370
|
+
__publicField(this, "maxHeightCap");
|
|
1937
2371
|
__publicField(this, "snapPointsRaw");
|
|
1938
2372
|
__publicField(this, "snaps");
|
|
1939
2373
|
__publicField(this, "activeId");
|
|
@@ -1946,6 +2380,7 @@ var BottomSheetEngine = class {
|
|
|
1946
2380
|
__publicField(this, "sizeWriteSentinel", new WriteSentinel());
|
|
1947
2381
|
__publicField(this, "progressWriteSentinel", new WriteSentinel());
|
|
1948
2382
|
__publicField(this, "isTopSheet", true);
|
|
2383
|
+
__publicField(this, "opening", false);
|
|
1949
2384
|
__publicField(this, "progressPayload", {
|
|
1950
2385
|
value: 0,
|
|
1951
2386
|
size: 0
|
|
@@ -1961,6 +2396,12 @@ var BottomSheetEngine = class {
|
|
|
1961
2396
|
__publicField(this, "linkedSheets", []);
|
|
1962
2397
|
__publicField(this, "scrollCache");
|
|
1963
2398
|
__publicField(this, "teardowns", new TeardownStack());
|
|
2399
|
+
__publicField(this, "anchors", []);
|
|
2400
|
+
__publicField(this, "anchorHost", null);
|
|
2401
|
+
__publicField(this, "stackZ", 100);
|
|
2402
|
+
__publicField(this, "detachScrimStages", null);
|
|
2403
|
+
__publicField(this, "stackEffectEnabled", false);
|
|
2404
|
+
__publicField(this, "stackEffectPrimed", false);
|
|
1964
2405
|
__publicField(this, "transformTemplate");
|
|
1965
2406
|
const resolved = resolveEngineOptions(opts, {
|
|
1966
2407
|
shouldApplyInertSiblings: () => {
|
|
@@ -1994,6 +2435,10 @@ var BottomSheetEngine = class {
|
|
|
1994
2435
|
getResolvedSnaps: () => this.snaps.getResolvedSnaps().slice(),
|
|
1995
2436
|
snapTo: (id) => {
|
|
1996
2437
|
void this.snapTo(id);
|
|
2438
|
+
},
|
|
2439
|
+
close: () => {
|
|
2440
|
+
if (!this.canDismiss()) return;
|
|
2441
|
+
void this.close("backdrop");
|
|
1997
2442
|
}
|
|
1998
2443
|
},
|
|
1999
2444
|
resolved.scrim
|
|
@@ -2017,6 +2462,11 @@ var BottomSheetEngine = class {
|
|
|
2017
2462
|
);
|
|
2018
2463
|
this.closeOnBack = resolved.closeOnBack;
|
|
2019
2464
|
this.routedTo = opts.routedTo;
|
|
2465
|
+
this.persistent = resolved.persistent;
|
|
2466
|
+
this.disableCloseFlag = resolved.disableClose;
|
|
2467
|
+
this.disableDragFlag = resolved.disableDrag;
|
|
2468
|
+
this.closeOnRouteChange = resolved.closeOnRouteChange;
|
|
2469
|
+
this.stackEffectEnabled = opts.stackEffect ?? false;
|
|
2020
2470
|
this.snapPointsRaw = opts.snapPoints;
|
|
2021
2471
|
this.persistKey = opts.persistKey;
|
|
2022
2472
|
if (opts.linkedSheets) {
|
|
@@ -2029,7 +2479,7 @@ var BottomSheetEngine = class {
|
|
|
2029
2479
|
this.snapPointsRaw,
|
|
2030
2480
|
resolved.initialAllowed,
|
|
2031
2481
|
this.mode,
|
|
2032
|
-
() => this.
|
|
2482
|
+
() => this.measureFitSize(),
|
|
2033
2483
|
(maxAxisSize) => {
|
|
2034
2484
|
this.element.style[layoutAxis(this.mode)] = `${maxAxisSize}px`;
|
|
2035
2485
|
}
|
|
@@ -2063,6 +2513,19 @@ var BottomSheetEngine = class {
|
|
|
2063
2513
|
io.observe(this.element);
|
|
2064
2514
|
this.teardowns.add(() => io.disconnect());
|
|
2065
2515
|
}
|
|
2516
|
+
this.installFitObserver();
|
|
2517
|
+
if (resolved.radius !== void 0) this.setRadius(resolved.radius);
|
|
2518
|
+
if (resolved.maxHeight !== void 0) this.setMaxHeight(resolved.maxHeight);
|
|
2519
|
+
this.applyAutoAriaLabelledBy();
|
|
2520
|
+
if (this.closeOnRouteChange) {
|
|
2521
|
+
this.teardowns.add(
|
|
2522
|
+
installRouteChange({
|
|
2523
|
+
isDestroyed: () => this.destroyed,
|
|
2524
|
+
getSize: () => this.size,
|
|
2525
|
+
close: () => this.close()
|
|
2526
|
+
})
|
|
2527
|
+
);
|
|
2528
|
+
}
|
|
2066
2529
|
if (this.persistKey) {
|
|
2067
2530
|
this.teardowns.add(installPersist(this, this.persistKey));
|
|
2068
2531
|
}
|
|
@@ -2087,7 +2550,7 @@ var BottomSheetEngine = class {
|
|
|
2087
2550
|
isTopSheet: () => this.isTopSheet,
|
|
2088
2551
|
getSize: () => this.size,
|
|
2089
2552
|
isDestroyed: () => this.destroyed,
|
|
2090
|
-
close: () => this.close(),
|
|
2553
|
+
close: () => this.close("back"),
|
|
2091
2554
|
on: (event, fn) => this.on(event, fn),
|
|
2092
2555
|
sheetId: this.id
|
|
2093
2556
|
})
|
|
@@ -2181,6 +2644,10 @@ var BottomSheetEngine = class {
|
|
|
2181
2644
|
const previousSize = this.size;
|
|
2182
2645
|
this.scrollCache.cache(previousId, previousSize, target.size);
|
|
2183
2646
|
this.activeId = id;
|
|
2647
|
+
if (wasClosed && target.size > 0) {
|
|
2648
|
+
this.opening = true;
|
|
2649
|
+
sheetStack.promote(this.id);
|
|
2650
|
+
}
|
|
2184
2651
|
if (this.animation.viewTransitionsAvailable) {
|
|
2185
2652
|
this.currentViewTransition?.skipTransition?.();
|
|
2186
2653
|
const vt = document.startViewTransition(() => {
|
|
@@ -2195,19 +2662,26 @@ var BottomSheetEngine = class {
|
|
|
2195
2662
|
} else {
|
|
2196
2663
|
await this.animation.animateTo(target.size, velocityPxPerMs);
|
|
2197
2664
|
}
|
|
2665
|
+
this.opening = false;
|
|
2198
2666
|
externalSignal?.removeEventListener("abort", onExternalAbort);
|
|
2199
2667
|
if (signal.aborted) return;
|
|
2200
2668
|
this.scrollCache.restore(id, previousSize, target.size);
|
|
2201
2669
|
this.updateAriaSlider();
|
|
2202
|
-
this.emit("snap", {
|
|
2670
|
+
this.emit("snap", {
|
|
2671
|
+
id,
|
|
2672
|
+
size: target.size,
|
|
2673
|
+
progress: this.computeProgress(target.size)
|
|
2674
|
+
});
|
|
2203
2675
|
if (wasClosed && target.size > 0) {
|
|
2204
2676
|
this.emit("open", { id });
|
|
2205
2677
|
this.handleOpen();
|
|
2206
2678
|
notifyLinkedSheets(this.linkedSheets, this);
|
|
2679
|
+
this.emit("opened", { id });
|
|
2207
2680
|
}
|
|
2208
2681
|
if (target.size === 0) {
|
|
2209
2682
|
this.emit("close", void 0);
|
|
2210
2683
|
this.handleClose();
|
|
2684
|
+
this.emit("closed", void 0);
|
|
2211
2685
|
}
|
|
2212
2686
|
}
|
|
2213
2687
|
async dragTo(targetSize, velocityOrOpts = 0) {
|
|
@@ -2232,18 +2706,76 @@ var BottomSheetEngine = class {
|
|
|
2232
2706
|
const target = id ?? this.snaps.getAllowedIds().find((a) => a !== "closed") ?? this.activeId;
|
|
2233
2707
|
return this.snapTo(target);
|
|
2234
2708
|
}
|
|
2235
|
-
close() {
|
|
2709
|
+
close(reason = "programmatic") {
|
|
2236
2710
|
if (this.destroyed) return Promise.resolve();
|
|
2711
|
+
if (this.disableCloseFlag) return Promise.resolve();
|
|
2712
|
+
if (this.size > 0 && this.emitBeforeClose(reason)) return Promise.resolve();
|
|
2237
2713
|
const closedId = this.snapPointsRaw.find((p) => p.id === "closed")?.id ?? this.snaps.getAllowedIds()[0];
|
|
2238
2714
|
return this.snapTo(closedId ?? this.activeId);
|
|
2239
2715
|
}
|
|
2240
|
-
|
|
2716
|
+
canDismiss() {
|
|
2717
|
+
return !this.persistent && !this.disableCloseFlag && !this.destroyed;
|
|
2718
|
+
}
|
|
2719
|
+
isTop() {
|
|
2720
|
+
return this.isTopSheet;
|
|
2721
|
+
}
|
|
2722
|
+
depth() {
|
|
2723
|
+
return sheetStack.depthOf(this.id);
|
|
2724
|
+
}
|
|
2725
|
+
expand() {
|
|
2726
|
+
if (this.destroyed) return Promise.resolve();
|
|
2727
|
+
const ids = this.allowedIdsBySize();
|
|
2728
|
+
const target = ids[ids.length - 1];
|
|
2729
|
+
if (!target) return Promise.resolve();
|
|
2730
|
+
return this.snapTo(target);
|
|
2731
|
+
}
|
|
2732
|
+
collapse() {
|
|
2733
|
+
if (this.destroyed) return Promise.resolve();
|
|
2734
|
+
const ids = this.allowedIdsBySize();
|
|
2735
|
+
const nonZero = ids.find((id) => (this.snaps.findById(id)?.size ?? 0) > 0);
|
|
2736
|
+
const target = nonZero ?? ids[0];
|
|
2737
|
+
if (!target) return Promise.resolve();
|
|
2738
|
+
return this.snapTo(target);
|
|
2739
|
+
}
|
|
2740
|
+
setRadius(r) {
|
|
2241
2741
|
if (this.destroyed) return;
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2742
|
+
this.element.style.setProperty(
|
|
2743
|
+
"--bs-radius",
|
|
2744
|
+
typeof r === "number" ? `${r}px` : r
|
|
2745
|
+
);
|
|
2746
|
+
}
|
|
2747
|
+
setMaxHeight(h) {
|
|
2748
|
+
if (this.destroyed) return;
|
|
2749
|
+
const value = typeof h === "number" ? `${h}px` : h;
|
|
2750
|
+
const axis = layoutAxis(this.mode);
|
|
2751
|
+
this.element.style.setProperty(
|
|
2752
|
+
axis === "height" ? "maxHeight" : "maxWidth",
|
|
2753
|
+
value
|
|
2754
|
+
);
|
|
2755
|
+
if (typeof h === "number") {
|
|
2756
|
+
this.maxHeightCap = h;
|
|
2757
|
+
this.clampToMaxHeight();
|
|
2758
|
+
} else if (typeof window !== "undefined") {
|
|
2759
|
+
const probe2 = document.createElement("div");
|
|
2760
|
+
probe2.style.cssText = `position:absolute;visibility:hidden;pointer-events:none;${axis === "height" ? "height" : "width"}:${value};`;
|
|
2761
|
+
document.body.appendChild(probe2);
|
|
2762
|
+
const measured = axis === "height" ? probe2.offsetHeight : probe2.offsetWidth;
|
|
2763
|
+
probe2.remove();
|
|
2764
|
+
this.maxHeightCap = measured > 0 ? measured : void 0;
|
|
2765
|
+
this.clampToMaxHeight();
|
|
2246
2766
|
}
|
|
2767
|
+
}
|
|
2768
|
+
clampToMaxHeight() {
|
|
2769
|
+
if (this.maxHeightCap === void 0) return;
|
|
2770
|
+
if (this.snaps.getMaxAxisSize() > this.maxHeightCap) {
|
|
2771
|
+
this.snaps.setMaxAxisSize(this.maxHeightCap);
|
|
2772
|
+
}
|
|
2773
|
+
if (this.size > this.maxHeightCap && !this.gesture?.isDragging) {
|
|
2774
|
+
this.applySize(this.maxHeightCap);
|
|
2775
|
+
}
|
|
2776
|
+
}
|
|
2777
|
+
setAllowed(ids, snap) {
|
|
2778
|
+
if (this.destroyed) return;
|
|
2247
2779
|
this.snaps.setAllowedIds(ids);
|
|
2248
2780
|
this.updateAriaSlider();
|
|
2249
2781
|
if (snap && ids.includes(snap)) {
|
|
@@ -2283,6 +2815,79 @@ var BottomSheetEngine = class {
|
|
|
2283
2815
|
setScrimOverlay(opts) {
|
|
2284
2816
|
return this.scrim.setScrimOverlay(opts);
|
|
2285
2817
|
}
|
|
2818
|
+
addAnchor(opts) {
|
|
2819
|
+
if (this.destroyed || typeof document === "undefined") return () => {
|
|
2820
|
+
};
|
|
2821
|
+
if (!this.anchorHost) {
|
|
2822
|
+
this.anchorHost = this.rootEl ?? this.element.parentElement ?? document.body;
|
|
2823
|
+
this.anchorHost.style.setProperty("--bs-size", `${this.size}px`);
|
|
2824
|
+
this.anchorHost.style.setProperty(
|
|
2825
|
+
"--bs-progress",
|
|
2826
|
+
String(this.computeProgress(this.size))
|
|
2827
|
+
);
|
|
2828
|
+
}
|
|
2829
|
+
const handle = attachAnchor(
|
|
2830
|
+
{
|
|
2831
|
+
mode: this.mode,
|
|
2832
|
+
host: this.anchorHost,
|
|
2833
|
+
getState: () => ({
|
|
2834
|
+
activeId: this.activeId,
|
|
2835
|
+
size: this.size,
|
|
2836
|
+
progress: this.computeProgress(this.size)
|
|
2837
|
+
}),
|
|
2838
|
+
on: (event, fn) => this.on(event, fn),
|
|
2839
|
+
isDestroyed: () => this.destroyed
|
|
2840
|
+
},
|
|
2841
|
+
opts
|
|
2842
|
+
);
|
|
2843
|
+
handle.syncZ(this.stackZ + 1);
|
|
2844
|
+
this.anchors.push(handle);
|
|
2845
|
+
const detach = () => {
|
|
2846
|
+
const idx = this.anchors.indexOf(handle);
|
|
2847
|
+
if (idx === -1) return;
|
|
2848
|
+
this.anchors.splice(idx, 1);
|
|
2849
|
+
handle.detach();
|
|
2850
|
+
};
|
|
2851
|
+
this.teardowns.add(detach);
|
|
2852
|
+
return detach;
|
|
2853
|
+
}
|
|
2854
|
+
setScrimStages(opts) {
|
|
2855
|
+
if (this.destroyed || typeof document === "undefined") return () => {
|
|
2856
|
+
};
|
|
2857
|
+
this.detachScrimStages?.();
|
|
2858
|
+
this.detachScrimStages = null;
|
|
2859
|
+
if (!opts) return () => {
|
|
2860
|
+
};
|
|
2861
|
+
const host = this.screenComponent?.parentElement;
|
|
2862
|
+
if (!host) {
|
|
2863
|
+
console.warn(
|
|
2864
|
+
"[BottomSheet] setScrimStages: no scrim element mounted \u2014 pass `scrim` to the engine first."
|
|
2865
|
+
);
|
|
2866
|
+
return () => {
|
|
2867
|
+
};
|
|
2868
|
+
}
|
|
2869
|
+
const detachInstalled = installScrimStages(
|
|
2870
|
+
{
|
|
2871
|
+
mode: this.mode,
|
|
2872
|
+
host,
|
|
2873
|
+
getState: () => ({
|
|
2874
|
+
activeId: this.activeId,
|
|
2875
|
+
size: this.size,
|
|
2876
|
+
progress: this.computeProgress(this.size)
|
|
2877
|
+
}),
|
|
2878
|
+
on: (event, fn) => this.on(event, fn),
|
|
2879
|
+
isDestroyed: () => this.destroyed
|
|
2880
|
+
},
|
|
2881
|
+
opts
|
|
2882
|
+
);
|
|
2883
|
+
const detach = () => {
|
|
2884
|
+
if (this.detachScrimStages === detach) this.detachScrimStages = null;
|
|
2885
|
+
detachInstalled();
|
|
2886
|
+
};
|
|
2887
|
+
this.detachScrimStages = detach;
|
|
2888
|
+
this.teardowns.add(() => this.detachScrimStages?.());
|
|
2889
|
+
return detach;
|
|
2890
|
+
}
|
|
2286
2891
|
getScrimState() {
|
|
2287
2892
|
return { mode: this.scrim.scrimMode, enabled: this.scrim.scrimEnabled };
|
|
2288
2893
|
}
|
|
@@ -2302,8 +2907,53 @@ var BottomSheetEngine = class {
|
|
|
2302
2907
|
}
|
|
2303
2908
|
this.updateAriaSlider();
|
|
2304
2909
|
}
|
|
2910
|
+
recompute() {
|
|
2911
|
+
if (this.destroyed) return;
|
|
2912
|
+
this.snaps.recompute();
|
|
2913
|
+
this.scrim.invalidateOpacityCache();
|
|
2914
|
+
if (this.gesture?.isDragging) return;
|
|
2915
|
+
const current = this.snaps.findById(this.activeId);
|
|
2916
|
+
if (current) {
|
|
2917
|
+
this.size = current.size;
|
|
2918
|
+
this.applySize(this.size);
|
|
2919
|
+
this.updateAriaSlider();
|
|
2920
|
+
}
|
|
2921
|
+
}
|
|
2922
|
+
measureFitSize() {
|
|
2923
|
+
const vertical = layoutAxis(this.mode) === "height";
|
|
2924
|
+
const handleSize = vertical ? this.handle.offsetHeight : this.handle.offsetWidth;
|
|
2925
|
+
const content = this.scrollContainer;
|
|
2926
|
+
const natural = content ? handleSize + (vertical ? content.scrollHeight : content.scrollWidth) : handleSize;
|
|
2927
|
+
if (typeof window === "undefined") return natural;
|
|
2928
|
+
const viewport = vertical ? window.innerHeight : window.innerWidth;
|
|
2929
|
+
return viewport > 0 ? Math.min(natural, viewport) : natural;
|
|
2930
|
+
}
|
|
2931
|
+
installFitObserver() {
|
|
2932
|
+
if (typeof ResizeObserver === "undefined") return;
|
|
2933
|
+
if (!this.snapPointsRaw.some((p) => p.size === "fit" || p.size === "content"))
|
|
2934
|
+
return;
|
|
2935
|
+
const targets = [this.handle];
|
|
2936
|
+
if (this.scrollContainer && this.scrollContainer !== this.handle) {
|
|
2937
|
+
targets.push(this.scrollContainer);
|
|
2938
|
+
}
|
|
2939
|
+
let raf = 0;
|
|
2940
|
+
const ro = new ResizeObserver(() => {
|
|
2941
|
+
if (raf) return;
|
|
2942
|
+
raf = requestAnimationFrame(() => {
|
|
2943
|
+
raf = 0;
|
|
2944
|
+
if (this.destroyed || this.gesture?.isDragging) return;
|
|
2945
|
+
this.recompute();
|
|
2946
|
+
});
|
|
2947
|
+
});
|
|
2948
|
+
for (const t of targets) ro.observe(t);
|
|
2949
|
+
this.teardowns.add(() => {
|
|
2950
|
+
ro.disconnect();
|
|
2951
|
+
if (raf) cancelAnimationFrame(raf);
|
|
2952
|
+
});
|
|
2953
|
+
}
|
|
2305
2954
|
destroy() {
|
|
2306
2955
|
this.destroyed = true;
|
|
2956
|
+
this.opening = false;
|
|
2307
2957
|
this.currentAbort.abort();
|
|
2308
2958
|
this.currentViewTransition?.skipTransition?.();
|
|
2309
2959
|
this.currentViewTransition = null;
|
|
@@ -2353,6 +3003,36 @@ var BottomSheetEngine = class {
|
|
|
2353
3003
|
frozen = true;
|
|
2354
3004
|
return cancelled;
|
|
2355
3005
|
}
|
|
3006
|
+
emitBeforeClose(reason) {
|
|
3007
|
+
let cancelled = false;
|
|
3008
|
+
let frozen = false;
|
|
3009
|
+
this.emit("before-close", {
|
|
3010
|
+
reason,
|
|
3011
|
+
cancel: () => {
|
|
3012
|
+
if (frozen) {
|
|
3013
|
+
console.warn(
|
|
3014
|
+
"[BottomSheet] before-close.cancel() called asynchronously \u2014 ignored. cancel() must be invoked synchronously inside the listener."
|
|
3015
|
+
);
|
|
3016
|
+
return;
|
|
3017
|
+
}
|
|
3018
|
+
cancelled = true;
|
|
3019
|
+
}
|
|
3020
|
+
});
|
|
3021
|
+
frozen = true;
|
|
3022
|
+
return cancelled;
|
|
3023
|
+
}
|
|
3024
|
+
applyAutoAriaLabelledBy() {
|
|
3025
|
+
if (typeof document === "undefined") return;
|
|
3026
|
+
if (!this.lifecycle.focusTrapEnabled) return;
|
|
3027
|
+
if (this.element.getAttribute("aria-labelledby")) return;
|
|
3028
|
+
const scope = this.handle ?? this.element;
|
|
3029
|
+
const titled = scope.querySelector("[data-bs-title]") ?? scope.querySelector("h1,h2,h3,h4,h5,h6");
|
|
3030
|
+
if (!titled) return;
|
|
3031
|
+
if (!titled.id) {
|
|
3032
|
+
titled.id = nextInstanceId("bs-title");
|
|
3033
|
+
}
|
|
3034
|
+
this.element.setAttribute("aria-labelledby", titled.id);
|
|
3035
|
+
}
|
|
2356
3036
|
recomputeSnaps() {
|
|
2357
3037
|
const seen = /* @__PURE__ */ new Set();
|
|
2358
3038
|
for (const p of this.snapPointsRaw) {
|
|
@@ -2369,24 +3049,42 @@ var BottomSheetEngine = class {
|
|
|
2369
3049
|
getAllowedRange() {
|
|
2370
3050
|
return this.snaps.getAllowedRange();
|
|
2371
3051
|
}
|
|
3052
|
+
allowedIdsBySize() {
|
|
3053
|
+
return this.snaps.getAllowedIds().slice().sort(
|
|
3054
|
+
(a, b) => (this.snaps.findById(a)?.size ?? 0) - (this.snaps.findById(b)?.size ?? 0)
|
|
3055
|
+
);
|
|
3056
|
+
}
|
|
2372
3057
|
updateAriaSlider() {
|
|
2373
|
-
this.aria.setValue(this.
|
|
3058
|
+
this.aria.setValue(this.allowedIdsBySize(), this.activeId);
|
|
2374
3059
|
}
|
|
2375
3060
|
registerInStack() {
|
|
2376
3061
|
this.teardowns.add(sheetStack.push({
|
|
2377
3062
|
id: this.id,
|
|
2378
3063
|
setZIndex: (z) => {
|
|
3064
|
+
this.stackZ = z;
|
|
2379
3065
|
this.element.style.zIndex = String(z);
|
|
2380
3066
|
if (this.backdrop) this.backdrop.style.zIndex = String(z - 1);
|
|
3067
|
+
for (const anchor of this.anchors) anchor.syncZ(z + 1);
|
|
2381
3068
|
},
|
|
2382
3069
|
setIsTop: (isTop) => {
|
|
2383
3070
|
this.isTopSheet = isTop;
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
}
|
|
3071
|
+
},
|
|
3072
|
+
isOpen: () => this.size > 0 || this.opening,
|
|
3073
|
+
setDepth: (depth) => this.applyStackDepth(depth)
|
|
2388
3074
|
}));
|
|
2389
3075
|
}
|
|
3076
|
+
applyStackDepth(depth) {
|
|
3077
|
+
if (!this.stackEffectEnabled) return;
|
|
3078
|
+
this.element.setAttribute("data-stack-depth", String(depth));
|
|
3079
|
+
if (!this.stackEffectPrimed) {
|
|
3080
|
+
this.stackEffectPrimed = true;
|
|
3081
|
+
const isVertical = this.mode === "bottom" || this.mode === "top";
|
|
3082
|
+
this.element.style.transformOrigin = isVertical ? "50% 100%" : "0% 50%";
|
|
3083
|
+
this.element.style.transition = "scale 320ms cubic-bezier(0.29, 1.04, 0.84, 0.99)";
|
|
3084
|
+
}
|
|
3085
|
+
const scale = Math.max(1 - depth * 0.04, 0.86);
|
|
3086
|
+
this.element.style.scale = scale === 1 ? "" : String(scale);
|
|
3087
|
+
}
|
|
2390
3088
|
attach() {
|
|
2391
3089
|
this.gesture = new GestureController({
|
|
2392
3090
|
handle: this.handle,
|
|
@@ -2403,6 +3101,7 @@ var BottomSheetEngine = class {
|
|
|
2403
3101
|
buf.rubberBandEnabled = this.rubberBandEnabled;
|
|
2404
3102
|
return buf;
|
|
2405
3103
|
},
|
|
3104
|
+
getDisableDrag: () => this.disableDragFlag,
|
|
2406
3105
|
cancelAnimation: () => this.animation.cancel(),
|
|
2407
3106
|
applySize: (size) => this.applySize(size),
|
|
2408
3107
|
animateTo: (size, velocity) => this.animation.animateTo(size, velocity),
|
|
@@ -2446,7 +3145,7 @@ var BottomSheetEngine = class {
|
|
|
2446
3145
|
container: this.scrollContainer,
|
|
2447
3146
|
isDragging: () => this.gesture?.isDragging ?? false,
|
|
2448
3147
|
isAnimating: () => this.animation.isAnimating,
|
|
2449
|
-
getAllowedIds: () => this.
|
|
3148
|
+
getAllowedIds: () => this.allowedIdsBySize(),
|
|
2450
3149
|
getActiveId: () => this.activeId,
|
|
2451
3150
|
snapTo: (id) => {
|
|
2452
3151
|
void this.snapTo(id);
|
|
@@ -2475,13 +3174,16 @@ var BottomSheetEngine = class {
|
|
|
2475
3174
|
},
|
|
2476
3175
|
newCycle: () => {
|
|
2477
3176
|
this.newCycle();
|
|
2478
|
-
}
|
|
3177
|
+
},
|
|
3178
|
+
isAnimating: () => this.animation.isAnimating,
|
|
3179
|
+
resyncAfterCancel: () => this.resyncAfterResize()
|
|
2479
3180
|
}));
|
|
2480
3181
|
if (this.lifecycle.closeOnEscape) {
|
|
2481
3182
|
const onKey = (e) => {
|
|
2482
|
-
if (this.destroyed) return;
|
|
3183
|
+
if (this.destroyed || e.defaultPrevented) return;
|
|
3184
|
+
if (!this.canDismiss()) return;
|
|
2483
3185
|
if (e.key === "Escape" && this.isTopSheet && this.size > 0) {
|
|
2484
|
-
void this.close();
|
|
3186
|
+
void this.close("escape");
|
|
2485
3187
|
}
|
|
2486
3188
|
};
|
|
2487
3189
|
document.addEventListener("keydown", onKey);
|
|
@@ -2511,7 +3213,7 @@ var BottomSheetEngine = class {
|
|
|
2511
3213
|
handle: this.handle,
|
|
2512
3214
|
mode: this.mode,
|
|
2513
3215
|
isDestroyed: () => this.destroyed,
|
|
2514
|
-
getAllowedIds: () => this.
|
|
3216
|
+
getAllowedIds: () => this.allowedIdsBySize(),
|
|
2515
3217
|
getActiveId: () => this.activeId,
|
|
2516
3218
|
snapTo: (id) => {
|
|
2517
3219
|
void this.snapTo(id);
|
|
@@ -2532,6 +3234,7 @@ var BottomSheetEngine = class {
|
|
|
2532
3234
|
});
|
|
2533
3235
|
if (!target) return;
|
|
2534
3236
|
const previousId = this.activeId;
|
|
3237
|
+
if (target.id === previousId && target.size === this.size) return;
|
|
2535
3238
|
if (this.emitBeforeSnap(target, previousId)) {
|
|
2536
3239
|
const restore = this.snaps.findById(previousId);
|
|
2537
3240
|
if (restore) {
|
|
@@ -2540,21 +3243,34 @@ var BottomSheetEngine = class {
|
|
|
2540
3243
|
return;
|
|
2541
3244
|
}
|
|
2542
3245
|
const previousSize = this.size;
|
|
3246
|
+
const previousSnapSize = this.snaps.findById(previousId)?.size;
|
|
2543
3247
|
this.scrollCache.cache(previousId, previousSize, target.size);
|
|
2544
3248
|
this.activeId = target.id;
|
|
3249
|
+
if (previousSnapSize === 0 && target.size > 0) {
|
|
3250
|
+
this.opening = true;
|
|
3251
|
+
sheetStack.promote(this.id);
|
|
3252
|
+
}
|
|
2545
3253
|
void this.animation.animateTo(target.size, velocity).then(() => {
|
|
3254
|
+
this.opening = false;
|
|
2546
3255
|
if (signal.aborted) return;
|
|
2547
3256
|
this.scrollCache.restore(target.id, previousSize, target.size);
|
|
2548
3257
|
this.updateAriaSlider();
|
|
2549
|
-
this.emit("snap", {
|
|
3258
|
+
this.emit("snap", {
|
|
3259
|
+
id: target.id,
|
|
3260
|
+
size: target.size,
|
|
3261
|
+
progress: this.computeProgress(target.size)
|
|
3262
|
+
});
|
|
2550
3263
|
this.haptic();
|
|
2551
|
-
if (
|
|
3264
|
+
if (previousSnapSize === 0 && target.size > 0) {
|
|
2552
3265
|
this.emit("open", { id: target.id });
|
|
2553
3266
|
this.handleOpen();
|
|
3267
|
+
notifyLinkedSheets(this.linkedSheets, this);
|
|
3268
|
+
this.emit("opened", { id: target.id });
|
|
2554
3269
|
}
|
|
2555
3270
|
if (target.size === 0) {
|
|
2556
3271
|
this.emit("close", void 0);
|
|
2557
3272
|
this.handleClose();
|
|
3273
|
+
this.emit("closed", void 0);
|
|
2558
3274
|
}
|
|
2559
3275
|
});
|
|
2560
3276
|
}
|
|
@@ -2576,6 +3292,9 @@ var BottomSheetEngine = class {
|
|
|
2576
3292
|
if (this.scrimParent) {
|
|
2577
3293
|
this.scrimParent.style.setProperty("--bs-size", `${size}px`);
|
|
2578
3294
|
}
|
|
3295
|
+
if (this.anchorHost && this.anchorHost !== this.scrimParent) {
|
|
3296
|
+
this.anchorHost.style.setProperty("--bs-size", `${size}px`);
|
|
3297
|
+
}
|
|
2579
3298
|
}
|
|
2580
3299
|
const progress = this.computeProgress(size);
|
|
2581
3300
|
const progressChanged = this.progressWriteSentinel.shouldWrite(
|
|
@@ -2584,6 +3303,9 @@ var BottomSheetEngine = class {
|
|
|
2584
3303
|
);
|
|
2585
3304
|
if (progressChanged) {
|
|
2586
3305
|
style.setProperty("--bs-progress", String(progress));
|
|
3306
|
+
if (this.anchorHost) {
|
|
3307
|
+
this.anchorHost.style.setProperty("--bs-progress", String(progress));
|
|
3308
|
+
}
|
|
2587
3309
|
}
|
|
2588
3310
|
this.scrim.applyOpacity(progress, progressChanged);
|
|
2589
3311
|
if (progressChanged && this.bus.listenerCount("progress") > 0) {
|
|
@@ -2598,6 +3320,7 @@ var BottomSheetEngine = class {
|
|
|
2598
3320
|
return Math.min(Math.max((size - min) / (max - min), 0), 1);
|
|
2599
3321
|
}
|
|
2600
3322
|
handleOpen() {
|
|
3323
|
+
sheetStack.promote(this.id);
|
|
2601
3324
|
try {
|
|
2602
3325
|
this.lifecycle.install();
|
|
2603
3326
|
} catch (err) {
|
|
@@ -2611,8 +3334,31 @@ var BottomSheetEngine = class {
|
|
|
2611
3334
|
});
|
|
2612
3335
|
}
|
|
2613
3336
|
}
|
|
3337
|
+
resyncAfterResize() {
|
|
3338
|
+
if (this.destroyed) return;
|
|
3339
|
+
const target = this.snaps.findById(this.activeId);
|
|
3340
|
+
if (!target) return;
|
|
3341
|
+
this.updateAriaSlider();
|
|
3342
|
+
this.emit("snap", {
|
|
3343
|
+
id: target.id,
|
|
3344
|
+
size: target.size,
|
|
3345
|
+
progress: this.computeProgress(target.size)
|
|
3346
|
+
});
|
|
3347
|
+
if (target.size > 0 && !this.lifecycle.isInstalled) {
|
|
3348
|
+
this.emit("open", { id: target.id });
|
|
3349
|
+
this.handleOpen();
|
|
3350
|
+
notifyLinkedSheets(this.linkedSheets, this);
|
|
3351
|
+
this.emit("opened", { id: target.id });
|
|
3352
|
+
} else if (target.size === 0 && this.lifecycle.isInstalled) {
|
|
3353
|
+
this.emit("close", void 0);
|
|
3354
|
+
this.handleClose();
|
|
3355
|
+
this.emit("closed", void 0);
|
|
3356
|
+
}
|
|
3357
|
+
}
|
|
2614
3358
|
handleClose() {
|
|
3359
|
+
this.opening = false;
|
|
2615
3360
|
this.lifecycle.release();
|
|
3361
|
+
sheetStack.update();
|
|
2616
3362
|
}
|
|
2617
3363
|
};
|
|
2618
3364
|
|
|
@@ -2630,17 +3376,18 @@ function createBottomSheet(opts) {
|
|
|
2630
3376
|
const attach = (refs) => {
|
|
2631
3377
|
if (engine) engine.destroy();
|
|
2632
3378
|
const { onSnap, ...engineOpts } = opts;
|
|
2633
|
-
|
|
3379
|
+
const created = new BottomSheetEngine({ ...engineOpts, ...refs });
|
|
3380
|
+
engine = created;
|
|
2634
3381
|
if (onSnap) {
|
|
2635
|
-
|
|
3382
|
+
created.on("snap", (payload) => onSnap(payload.id));
|
|
2636
3383
|
}
|
|
2637
3384
|
for (const entry of pending) {
|
|
2638
|
-
entry.engineUnsub =
|
|
3385
|
+
entry.engineUnsub = created.on(entry.event, entry.fn);
|
|
2639
3386
|
}
|
|
2640
3387
|
pending.length = 0;
|
|
2641
3388
|
return () => {
|
|
2642
|
-
|
|
2643
|
-
engine = null;
|
|
3389
|
+
created.destroy();
|
|
3390
|
+
if (engine === created) engine = null;
|
|
2644
3391
|
};
|
|
2645
3392
|
};
|
|
2646
3393
|
return {
|
|
@@ -2663,7 +3410,20 @@ function createBottomSheet(opts) {
|
|
|
2663
3410
|
snapTo: (id) => engine?.snapTo(id) ?? Promise.resolve(),
|
|
2664
3411
|
open: (id) => engine?.open(id) ?? Promise.resolve(),
|
|
2665
3412
|
close: () => engine?.close() ?? Promise.resolve(),
|
|
3413
|
+
expand: () => engine?.expand() ?? Promise.resolve(),
|
|
3414
|
+
collapse: () => engine?.collapse() ?? Promise.resolve(),
|
|
3415
|
+
isTop: () => engine?.isTop() ?? false,
|
|
3416
|
+
depth: () => engine?.depth() ?? 0,
|
|
2666
3417
|
setAllowed: (ids, snap) => engine?.setAllowed(ids, snap),
|
|
3418
|
+
setSnapPoints: (points, allowed) => engine?.setSnapPoints(points, allowed),
|
|
3419
|
+
setScrim: (scrimOpts) => engine?.setScrim(scrimOpts),
|
|
3420
|
+
setScrimOverlay: (overlayOpts) => engine?.setScrimOverlay(overlayOpts) ?? (() => {
|
|
3421
|
+
}),
|
|
3422
|
+
addAnchor: (anchorOpts) => engine?.addAnchor(anchorOpts) ?? (() => {
|
|
3423
|
+
}),
|
|
3424
|
+
setScrimStages: (stagesOpts) => engine?.setScrimStages(stagesOpts) ?? (() => {
|
|
3425
|
+
}),
|
|
3426
|
+
recompute: () => engine?.recompute(),
|
|
2667
3427
|
destroy: () => {
|
|
2668
3428
|
engine?.destroy();
|
|
2669
3429
|
engine = null;
|
|
@@ -2677,7 +3437,7 @@ var root_4 = $2__namespace.from_html(`<div class="bs-button-slot" data-side="rig
|
|
|
2677
3437
|
var root = $2__namespace.from_html(`<div class="bs-root"><!> <div class="bs-screen"><!></div> <section class="bs-sheet" role="dialog"><!> <!> <div class="bs-handle" role="slider" tabindex="0" aria-label="Resize sheet"><!></div> <div class="bs-content" tabindex="0" role="region" aria-label="Sheet content"><!></div> <span class="bs-sr-only" role="status" aria-live="polite"> </span></section></div>`);
|
|
2678
3438
|
function BottomSheet($$anchor, $$props) {
|
|
2679
3439
|
$2__namespace.push($$props, true);
|
|
2680
|
-
let mode = $2__namespace.prop($$props, "mode", 3, "bottom"), animation = $2__namespace.prop($$props, "animation", 3, "spring"), focusTrap = $2__namespace.prop($$props, "focusTrap", 3, false), closeOnEscape = $2__namespace.prop($$props, "closeOnEscape", 3, true), closeOnBack = $2__namespace.prop($$props, "closeOnBack", 3, false), lockBodyScroll2 = $2__namespace.prop($$props, "lockBodyScroll", 3, true), rubberBand2 = $2__namespace.prop($$props, "rubberBand", 3, true), backdrop = $2__namespace.prop($$props, "backdrop", 3, true), closeOnBackdrop = $2__namespace.prop($$props, "closeOnBackdrop", 3, true), ariaLabel = $2__namespace.prop($$props, "ariaLabel", 3, "Bottom sheet");
|
|
3440
|
+
let mode = $2__namespace.prop($$props, "mode", 3, "bottom"), animation = $2__namespace.prop($$props, "animation", 3, "spring"), focusTrap = $2__namespace.prop($$props, "focusTrap", 3, false), closeOnEscape = $2__namespace.prop($$props, "closeOnEscape", 3, true), closeOnBack = $2__namespace.prop($$props, "closeOnBack", 3, false), lockBodyScroll2 = $2__namespace.prop($$props, "lockBodyScroll", 3, true), rubberBand2 = $2__namespace.prop($$props, "rubberBand", 3, true), backdrop = $2__namespace.prop($$props, "backdrop", 3, true), closeOnBackdrop = $2__namespace.prop($$props, "closeOnBackdrop", 3, true), persistent = $2__namespace.prop($$props, "persistent", 3, false), disableClose = $2__namespace.prop($$props, "disableClose", 3, false), disableDrag = $2__namespace.prop($$props, "disableDrag", 3, false), closeOnRouteChange = $2__namespace.prop($$props, "closeOnRouteChange", 3, false), openProp = $2__namespace.prop($$props, "open", 15), snap = $2__namespace.prop($$props, "snap", 15), ariaLabel = $2__namespace.prop($$props, "ariaLabel", 3, "Bottom sheet");
|
|
2681
3441
|
let sheetEl = $2__namespace.state(void 0);
|
|
2682
3442
|
let handleEl = $2__namespace.state(void 0);
|
|
2683
3443
|
let contentEl = $2__namespace.state(void 0);
|
|
@@ -2685,7 +3445,7 @@ function BottomSheet($$anchor, $$props) {
|
|
|
2685
3445
|
let screenEl = $2__namespace.state(void 0);
|
|
2686
3446
|
let viewState = $2__namespace.state($2__namespace.proxy({
|
|
2687
3447
|
size: 0,
|
|
2688
|
-
activeId: $$props.initial ?? $$props.snapPoints[0]?.id ?? "default",
|
|
3448
|
+
activeId: svelte.untrack(() => $$props.initial ?? $$props.snapPoints[0]?.id ?? "default"),
|
|
2689
3449
|
isDragging: false,
|
|
2690
3450
|
isAnimating: false,
|
|
2691
3451
|
progress: 0
|
|
@@ -2710,7 +3470,14 @@ function BottomSheet($$anchor, $$props) {
|
|
|
2710
3470
|
closeOnBack: closeOnBack(),
|
|
2711
3471
|
lockBodyScroll: lockBodyScroll2(),
|
|
2712
3472
|
rubberBand: rubberBand2(),
|
|
2713
|
-
backdropRange: $$props.backdropRange
|
|
3473
|
+
backdropRange: $$props.backdropRange,
|
|
3474
|
+
persistent: persistent(),
|
|
3475
|
+
disableClose: disableClose(),
|
|
3476
|
+
disableDrag: disableDrag(),
|
|
3477
|
+
closeOnRouteChange: closeOnRouteChange(),
|
|
3478
|
+
radius: $$props.radius,
|
|
3479
|
+
maxHeight: $$props.maxHeight,
|
|
3480
|
+
returnFocusTo: $$props.returnFocusTo
|
|
2714
3481
|
});
|
|
2715
3482
|
const sync = () => {
|
|
2716
3483
|
if (!engine) return;
|
|
@@ -2718,14 +3485,32 @@ function BottomSheet($$anchor, $$props) {
|
|
|
2718
3485
|
$$props.onchange?.($2__namespace.get(viewState));
|
|
2719
3486
|
};
|
|
2720
3487
|
sync();
|
|
3488
|
+
if ($$props.backdropColor !== void 0) engine.setScrimColor($$props.backdropColor);
|
|
3489
|
+
if ($$props.backdropOpacity !== void 0) engine.setBackdropRange([0, $$props.backdropOpacity]);
|
|
2721
3490
|
engine.on("snap", (payload) => {
|
|
2722
3491
|
sync();
|
|
3492
|
+
snap(payload.id);
|
|
2723
3493
|
$$props.onsnap?.(payload.id);
|
|
2724
3494
|
});
|
|
2725
|
-
engine.on("open", (payload) =>
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
3495
|
+
engine.on("open", (payload) => {
|
|
3496
|
+
openProp(true);
|
|
3497
|
+
$$props.onopen?.(payload.id);
|
|
3498
|
+
});
|
|
3499
|
+
engine.on("close", () => {
|
|
3500
|
+
openProp(false);
|
|
3501
|
+
$$props.onclose?.();
|
|
3502
|
+
});
|
|
3503
|
+
engine.on("before-close", (payload) => $$props.onbeforeclose?.(payload));
|
|
3504
|
+
engine.on("opened", (payload) => $$props.onopened?.(payload.id));
|
|
3505
|
+
engine.on("closed", () => $$props.onclosed?.());
|
|
3506
|
+
engine.on("dragstart", () => {
|
|
3507
|
+
sync();
|
|
3508
|
+
$$props.ondragstart?.();
|
|
3509
|
+
});
|
|
3510
|
+
engine.on("dragend", () => {
|
|
3511
|
+
sync();
|
|
3512
|
+
$$props.ondragend?.();
|
|
3513
|
+
});
|
|
2729
3514
|
});
|
|
2730
3515
|
svelte.onDestroy(() => {
|
|
2731
3516
|
engine?.destroy();
|
|
@@ -2734,13 +3519,46 @@ function BottomSheet($$anchor, $$props) {
|
|
|
2734
3519
|
const snapTo = (id) => engine?.snapTo(id) ?? Promise.resolve();
|
|
2735
3520
|
const open = (id) => engine?.open(id) ?? Promise.resolve();
|
|
2736
3521
|
const close = () => engine?.close() ?? Promise.resolve();
|
|
2737
|
-
const
|
|
3522
|
+
const expand = () => engine?.expand() ?? Promise.resolve();
|
|
3523
|
+
const collapse = () => engine?.collapse() ?? Promise.resolve();
|
|
3524
|
+
const isTop = () => engine?.isTop() ?? false;
|
|
3525
|
+
const depth = () => engine?.depth() ?? 0;
|
|
3526
|
+
const setAllowed = (ids, snap2) => engine?.setAllowed(ids, snap2);
|
|
2738
3527
|
const setSnapPoints = (points, nextAllowed) => engine?.setSnapPoints(points, nextAllowed);
|
|
2739
3528
|
const setScrim = (opts) => engine?.setScrim(opts);
|
|
2740
3529
|
const setScrimOverlay = (opts) => engine?.setScrimOverlay(opts) ?? (() => {
|
|
2741
3530
|
});
|
|
3531
|
+
const setRadius = (r) => engine?.setRadius(r);
|
|
3532
|
+
const setMaxHeight = (h) => engine?.setMaxHeight(h);
|
|
3533
|
+
const canDismiss = () => engine?.canDismiss() ?? false;
|
|
2742
3534
|
const getState = () => engine?.state ?? $2__namespace.get(viewState);
|
|
2743
3535
|
const getEngine = () => engine;
|
|
3536
|
+
$2__namespace.user_effect(() => {
|
|
3537
|
+
if ($$props.radius !== void 0) engine?.setRadius($$props.radius);
|
|
3538
|
+
});
|
|
3539
|
+
$2__namespace.user_effect(() => {
|
|
3540
|
+
if ($$props.maxHeight !== void 0) engine?.setMaxHeight($$props.maxHeight);
|
|
3541
|
+
});
|
|
3542
|
+
$2__namespace.user_effect(() => {
|
|
3543
|
+
if ($$props.backdropColor !== void 0) engine?.setScrimColor($$props.backdropColor);
|
|
3544
|
+
});
|
|
3545
|
+
$2__namespace.user_effect(() => {
|
|
3546
|
+
if ($$props.backdropOpacity !== void 0) engine?.setBackdropRange([0, $$props.backdropOpacity]);
|
|
3547
|
+
});
|
|
3548
|
+
$2__namespace.user_effect(() => {
|
|
3549
|
+
if (snap() === void 0) return;
|
|
3550
|
+
const next = snap();
|
|
3551
|
+
if (!engine || svelte.untrack(() => $2__namespace.get(viewState).activeId) === next) return;
|
|
3552
|
+
void engine.snapTo(next);
|
|
3553
|
+
});
|
|
3554
|
+
$2__namespace.user_effect(() => {
|
|
3555
|
+
if (openProp() === void 0) return;
|
|
3556
|
+
const next = openProp();
|
|
3557
|
+
if (!engine) return;
|
|
3558
|
+
const isOpen = svelte.untrack(() => $2__namespace.get(viewState).size) > 0;
|
|
3559
|
+
if (next && !isOpen) void engine.open();
|
|
3560
|
+
else if (!next && isOpen) void engine.close();
|
|
3561
|
+
});
|
|
2744
3562
|
let allowedIds = $2__namespace.derived(() => $$props.allowed && $$props.allowed.length > 0 ? $$props.allowed : $$props.snapPoints.map((s) => s.id));
|
|
2745
3563
|
let activeIdx = $2__namespace.derived(() => $2__namespace.get(allowedIds).indexOf($2__namespace.get(viewState).activeId));
|
|
2746
3564
|
let isVerticalAxis = $2__namespace.derived(() => mode() === "bottom" || mode() === "top");
|
|
@@ -2748,10 +3566,17 @@ function BottomSheet($$anchor, $$props) {
|
|
|
2748
3566
|
snapTo,
|
|
2749
3567
|
open,
|
|
2750
3568
|
close,
|
|
3569
|
+
expand,
|
|
3570
|
+
collapse,
|
|
3571
|
+
isTop,
|
|
3572
|
+
depth,
|
|
2751
3573
|
setAllowed,
|
|
2752
3574
|
setSnapPoints,
|
|
2753
3575
|
setScrim,
|
|
2754
3576
|
setScrimOverlay,
|
|
3577
|
+
setRadius,
|
|
3578
|
+
setMaxHeight,
|
|
3579
|
+
canDismiss,
|
|
2755
3580
|
getState,
|
|
2756
3581
|
getEngine
|
|
2757
3582
|
};
|
|
@@ -2762,7 +3587,9 @@ function BottomSheet($$anchor, $$props) {
|
|
|
2762
3587
|
var div_1 = root_1();
|
|
2763
3588
|
$2__namespace.bind_this(div_1, ($$value) => $2__namespace.set(backdropEl, $$value), () => $2__namespace.get(backdropEl));
|
|
2764
3589
|
$2__namespace.delegated("click", div_1, function(...$$args) {
|
|
2765
|
-
(closeOnBackdrop() ? () =>
|
|
3590
|
+
(closeOnBackdrop() ? () => {
|
|
3591
|
+
if (engine?.canDismiss()) void engine.close("backdrop");
|
|
3592
|
+
} : void 0)?.apply(this, $$args);
|
|
2766
3593
|
});
|
|
2767
3594
|
$2__namespace.append($$anchor2, div_1);
|
|
2768
3595
|
};
|