@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/index.cjs
CHANGED
|
@@ -22,16 +22,52 @@ var SheetStack = class {
|
|
|
22
22
|
this.entries.splice(idx, 1);
|
|
23
23
|
this.recompute();
|
|
24
24
|
}
|
|
25
|
+
promote(id) {
|
|
26
|
+
const idx = this.entries.findIndex((e) => e.id === id);
|
|
27
|
+
if (idx === -1) return;
|
|
28
|
+
if (idx !== this.entries.length - 1) {
|
|
29
|
+
const [entry] = this.entries.splice(idx, 1);
|
|
30
|
+
this.entries.push(entry);
|
|
31
|
+
}
|
|
32
|
+
this.recompute();
|
|
33
|
+
}
|
|
34
|
+
update() {
|
|
35
|
+
this.recompute();
|
|
36
|
+
}
|
|
25
37
|
size() {
|
|
26
38
|
return this.entries.length;
|
|
27
39
|
}
|
|
40
|
+
depthOf(id) {
|
|
41
|
+
const open = [];
|
|
42
|
+
for (const entry of this.entries) {
|
|
43
|
+
if (!entry.isOpen || entry.isOpen()) open.push(entry);
|
|
44
|
+
}
|
|
45
|
+
const idx = open.findIndex((e) => e.id === id);
|
|
46
|
+
if (idx === -1) return 0;
|
|
47
|
+
return open.length - 1 - idx;
|
|
48
|
+
}
|
|
28
49
|
clear() {
|
|
29
50
|
this.entries = [];
|
|
30
51
|
}
|
|
31
52
|
recompute() {
|
|
53
|
+
let top = null;
|
|
54
|
+
const open = [];
|
|
55
|
+
for (const entry of this.entries) {
|
|
56
|
+
if (!entry.isOpen || entry.isOpen()) {
|
|
57
|
+
top = entry;
|
|
58
|
+
open.push(entry);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (!top && this.entries.length > 0) {
|
|
62
|
+
top = this.entries[this.entries.length - 1];
|
|
63
|
+
}
|
|
32
64
|
this.entries.forEach((entry, i) => {
|
|
33
65
|
entry.setZIndex(BASE_Z + i * STEP);
|
|
34
|
-
entry.setIsTop(
|
|
66
|
+
entry.setIsTop(entry === top);
|
|
67
|
+
if (entry.setDepth) {
|
|
68
|
+
const openIdx = open.indexOf(entry);
|
|
69
|
+
entry.setDepth(openIdx === -1 ? 0 : open.length - 1 - openIdx);
|
|
70
|
+
}
|
|
35
71
|
});
|
|
36
72
|
}
|
|
37
73
|
};
|
|
@@ -134,7 +170,9 @@ var PERCENT = /^(-?\d+(?:\.\d+)?)%$/;
|
|
|
134
170
|
var resolveSnap = (point, mode, measureFit) => {
|
|
135
171
|
if (typeof point === "number") return Math.max(0, point);
|
|
136
172
|
if (point === "full") return viewportSize(mode);
|
|
137
|
-
if (point === "fit"
|
|
173
|
+
if (point === "fit" || point === "content") {
|
|
174
|
+
return Math.max(0, measureFit?.() ?? 0);
|
|
175
|
+
}
|
|
138
176
|
const pctMatch = point.match(PERCENT);
|
|
139
177
|
if (pctMatch) {
|
|
140
178
|
const pct = parseFloat(pctMatch[1]) / 100;
|
|
@@ -322,14 +360,17 @@ function installAutoCollapse(deps) {
|
|
|
322
360
|
const fire = () => {
|
|
323
361
|
if (deps.isDestroyed()) return;
|
|
324
362
|
if (deps.isDragging()) return;
|
|
325
|
-
const
|
|
326
|
-
|
|
363
|
+
const active = deps.resolveSnap(deps.getActiveId());
|
|
364
|
+
if (!active || active.size === 0) return;
|
|
365
|
+
let target = null;
|
|
366
|
+
for (const id of deps.getAllowedIds()) {
|
|
327
367
|
const snap = deps.resolveSnap(id);
|
|
328
|
-
|
|
329
|
-
|
|
368
|
+
if (!snap || snap.size <= 0) continue;
|
|
369
|
+
if (!target || snap.size < target.size) target = snap;
|
|
370
|
+
}
|
|
330
371
|
if (!target) return;
|
|
331
|
-
if (target ===
|
|
332
|
-
deps.snapTo(target);
|
|
372
|
+
if (target.id === active.id || target.size >= active.size) return;
|
|
373
|
+
deps.snapTo(target.id);
|
|
333
374
|
};
|
|
334
375
|
const reset = () => {
|
|
335
376
|
clearTimer();
|
|
@@ -340,6 +381,7 @@ function installAutoCollapse(deps) {
|
|
|
340
381
|
}, ms);
|
|
341
382
|
};
|
|
342
383
|
const unsubscribe = deps.on("snap", () => reset());
|
|
384
|
+
if ((deps.resolveSnap(deps.getActiveId())?.size ?? 0) > 0) reset();
|
|
343
385
|
return () => {
|
|
344
386
|
clearTimer();
|
|
345
387
|
unsubscribe();
|
|
@@ -352,6 +394,7 @@ function notifyLinkedSheets(sheets, self) {
|
|
|
352
394
|
for (const linked of sheets) {
|
|
353
395
|
if (linked === self) continue;
|
|
354
396
|
try {
|
|
397
|
+
if (linked.state.size === 0) continue;
|
|
355
398
|
const ids = linked.getAllowedIds();
|
|
356
399
|
const target = ids.find((id) => id !== "closed");
|
|
357
400
|
if (target && target !== linked.state.activeId) {
|
|
@@ -366,6 +409,42 @@ function notifyLinkedSheets(sheets, self) {
|
|
|
366
409
|
}
|
|
367
410
|
|
|
368
411
|
// src/core/features/route.ts
|
|
412
|
+
var closers = [];
|
|
413
|
+
var handlerInstalled = false;
|
|
414
|
+
var suppress = 0;
|
|
415
|
+
var ensureHandler = () => {
|
|
416
|
+
if (handlerInstalled || typeof window === "undefined") return;
|
|
417
|
+
handlerInstalled = true;
|
|
418
|
+
window.addEventListener("popstate", () => {
|
|
419
|
+
if (suppress > 0) {
|
|
420
|
+
suppress -= 1;
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
let target = null;
|
|
424
|
+
for (let i = closers.length - 1; i >= 0; i -= 1) {
|
|
425
|
+
const c = closers[i];
|
|
426
|
+
if (!c.isOpen()) continue;
|
|
427
|
+
if (!target) target = c;
|
|
428
|
+
if (c.isTop()) {
|
|
429
|
+
target = c;
|
|
430
|
+
break;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
if (!target) return;
|
|
434
|
+
target.consumed = true;
|
|
435
|
+
const idx = closers.indexOf(target);
|
|
436
|
+
if (idx !== -1) closers.splice(idx, 1);
|
|
437
|
+
target.close();
|
|
438
|
+
});
|
|
439
|
+
};
|
|
440
|
+
var programmaticBack = () => {
|
|
441
|
+
suppress += 1;
|
|
442
|
+
try {
|
|
443
|
+
history.back();
|
|
444
|
+
} catch {
|
|
445
|
+
suppress = Math.max(0, suppress - 1);
|
|
446
|
+
}
|
|
447
|
+
};
|
|
369
448
|
function installRoute(deps) {
|
|
370
449
|
if (typeof window === "undefined") {
|
|
371
450
|
return () => {
|
|
@@ -375,82 +454,81 @@ function installRoute(deps) {
|
|
|
375
454
|
return () => {
|
|
376
455
|
};
|
|
377
456
|
}
|
|
378
|
-
let
|
|
379
|
-
let
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
457
|
+
let pushed = false;
|
|
458
|
+
let closer = null;
|
|
459
|
+
const teardownEntry = () => {
|
|
460
|
+
if (closer) {
|
|
461
|
+
const idx = closers.indexOf(closer);
|
|
462
|
+
if (idx !== -1) closers.splice(idx, 1);
|
|
463
|
+
}
|
|
464
|
+
const wasConsumed = closer?.consumed ?? false;
|
|
465
|
+
closer = null;
|
|
466
|
+
if (pushed && !wasConsumed) {
|
|
467
|
+
pushed = false;
|
|
468
|
+
programmaticBack();
|
|
469
|
+
} else {
|
|
470
|
+
pushed = false;
|
|
388
471
|
}
|
|
389
472
|
};
|
|
390
473
|
const onOpen = () => {
|
|
391
|
-
if (
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
}
|
|
405
|
-
};
|
|
406
|
-
window.addEventListener("popstate", onPop);
|
|
407
|
-
detachPopstate = () => window.removeEventListener("popstate", onPop);
|
|
408
|
-
} else if (deps.closeOnBack && !detachPopstate) {
|
|
409
|
-
try {
|
|
474
|
+
if (closer) return;
|
|
475
|
+
closer = {
|
|
476
|
+
isOpen: () => !deps.isDestroyed() && deps.getSize() > 0,
|
|
477
|
+
isTop: () => deps.isTopSheet(),
|
|
478
|
+
close: () => void deps.close(),
|
|
479
|
+
consumed: false
|
|
480
|
+
};
|
|
481
|
+
ensureHandler();
|
|
482
|
+
closers.push(closer);
|
|
483
|
+
try {
|
|
484
|
+
if (deps.routedTo !== void 0) {
|
|
485
|
+
history.pushState({ __bsRouted: deps.sheetId }, "", deps.routedTo);
|
|
486
|
+
} else {
|
|
410
487
|
history.pushState({ __bsSheet: deps.sheetId }, "");
|
|
411
|
-
closeOnBackPushed = true;
|
|
412
|
-
} catch {
|
|
413
488
|
}
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
const state = history.state;
|
|
418
|
-
if (state?.__bsSheet !== deps.sheetId) closeOnBackPushed = false;
|
|
419
|
-
void deps.close();
|
|
420
|
-
}
|
|
421
|
-
};
|
|
422
|
-
window.addEventListener("popstate", onPop);
|
|
423
|
-
detachPopstate = () => window.removeEventListener("popstate", onPop);
|
|
424
|
-
}
|
|
425
|
-
};
|
|
426
|
-
const onClose = () => {
|
|
427
|
-
detachPopstate?.();
|
|
428
|
-
detachPopstate = null;
|
|
429
|
-
if (routePushed) {
|
|
430
|
-
routePushed = false;
|
|
431
|
-
if (deps.routedTo !== void 0) popOurMarker("__bsRouted", deps.routedTo);
|
|
432
|
-
}
|
|
433
|
-
if (closeOnBackPushed) {
|
|
434
|
-
closeOnBackPushed = false;
|
|
435
|
-
popOurMarker("__bsSheet", deps.sheetId);
|
|
489
|
+
pushed = true;
|
|
490
|
+
} catch {
|
|
491
|
+
pushed = false;
|
|
436
492
|
}
|
|
437
493
|
};
|
|
438
494
|
const unsubscribeOpen = deps.on("open", onOpen);
|
|
439
|
-
const unsubscribeClose = deps.on("close",
|
|
495
|
+
const unsubscribeClose = deps.on("close", teardownEntry);
|
|
440
496
|
if (deps.getSize() > 0) onOpen();
|
|
441
497
|
return () => {
|
|
442
498
|
unsubscribeOpen();
|
|
443
499
|
unsubscribeClose();
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
500
|
+
teardownEntry();
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
function installRouteChange(deps) {
|
|
504
|
+
if (typeof window === "undefined" || typeof history === "undefined") {
|
|
505
|
+
return () => {
|
|
506
|
+
};
|
|
507
|
+
}
|
|
508
|
+
const onChange = () => {
|
|
509
|
+
if (deps.isDestroyed() || deps.getSize() <= 0) return;
|
|
510
|
+
void deps.close();
|
|
511
|
+
};
|
|
512
|
+
const wrap = (key) => {
|
|
513
|
+
const original = history[key];
|
|
514
|
+
const patched = function(...args) {
|
|
515
|
+
original.apply(this, args);
|
|
516
|
+
onChange();
|
|
517
|
+
};
|
|
518
|
+
history[key] = patched;
|
|
519
|
+
return () => {
|
|
520
|
+
if (history[key] === patched) {
|
|
521
|
+
history[key] = original;
|
|
522
|
+
}
|
|
523
|
+
};
|
|
524
|
+
};
|
|
525
|
+
window.addEventListener("popstate", onChange);
|
|
526
|
+
const restorePush = wrap("pushState");
|
|
527
|
+
const restoreReplace = wrap("replaceState");
|
|
528
|
+
return () => {
|
|
529
|
+
window.removeEventListener("popstate", onChange);
|
|
530
|
+
restorePush();
|
|
531
|
+
restoreReplace();
|
|
454
532
|
};
|
|
455
533
|
}
|
|
456
534
|
|
|
@@ -552,13 +630,17 @@ function installResizeObserver(deps) {
|
|
|
552
630
|
if (viewportSize2 > 0 && viewportSize2 < max) {
|
|
553
631
|
deps.setMaxAxisSize(viewportSize2);
|
|
554
632
|
}
|
|
633
|
+
const wasAnimating = deps.isAnimating?.() ?? false;
|
|
555
634
|
deps.cancelInFlight();
|
|
556
635
|
deps.newCycle();
|
|
557
636
|
const current = deps.resolveActiveSnap();
|
|
558
637
|
const newMax = deps.getMaxAxisSize();
|
|
559
638
|
const targetSize = current ? Math.min(current.size, newMax) : Math.min(deps.getSize(), newMax);
|
|
560
639
|
deps.setSize(targetSize);
|
|
561
|
-
if (current && !deps.isDragging())
|
|
640
|
+
if (current && !deps.isDragging()) {
|
|
641
|
+
deps.applySize(targetSize);
|
|
642
|
+
if (wasAnimating) deps.resyncAfterCancel?.();
|
|
643
|
+
}
|
|
562
644
|
};
|
|
563
645
|
let resizeObserver = null;
|
|
564
646
|
if (typeof ResizeObserver !== "undefined") {
|
|
@@ -673,8 +755,88 @@ function devWarn(...args) {
|
|
|
673
755
|
}
|
|
674
756
|
}
|
|
675
757
|
|
|
758
|
+
// src/core/primitives/overlay-position.ts
|
|
759
|
+
function resolveSheetAnchoredStyle(mode, position, inset) {
|
|
760
|
+
const sizeOffset = `calc(var(--bs-size, 0px) + ${inset})`;
|
|
761
|
+
switch (mode) {
|
|
762
|
+
case "bottom":
|
|
763
|
+
if (position === "sheet-top-left") return { bottom: sizeOffset, left: inset };
|
|
764
|
+
if (position === "sheet-top-right") return { bottom: sizeOffset, right: inset };
|
|
765
|
+
return { bottom: sizeOffset, left: "50%", transform: "translateX(-50%)" };
|
|
766
|
+
case "top":
|
|
767
|
+
if (position === "sheet-top-left") return { top: sizeOffset, left: inset };
|
|
768
|
+
if (position === "sheet-top-right") return { top: sizeOffset, right: inset };
|
|
769
|
+
return { top: sizeOffset, left: "50%", transform: "translateX(-50%)" };
|
|
770
|
+
case "left":
|
|
771
|
+
if (position === "sheet-top-left") return { left: sizeOffset, top: inset };
|
|
772
|
+
if (position === "sheet-top-right") return { left: sizeOffset, bottom: inset };
|
|
773
|
+
return { left: sizeOffset, top: "50%", transform: "translateY(-50%)" };
|
|
774
|
+
case "right":
|
|
775
|
+
if (position === "sheet-top-left") return { right: sizeOffset, top: inset };
|
|
776
|
+
if (position === "sheet-top-right") return { right: sizeOffset, bottom: inset };
|
|
777
|
+
return { right: sizeOffset, top: "50%", transform: "translateY(-50%)" };
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
function applyOverlayPosition(ws, mode, position, inset) {
|
|
781
|
+
switch (position) {
|
|
782
|
+
case "top-left":
|
|
783
|
+
ws.top = inset;
|
|
784
|
+
ws.left = inset;
|
|
785
|
+
break;
|
|
786
|
+
case "top-center":
|
|
787
|
+
ws.top = inset;
|
|
788
|
+
ws.left = "50%";
|
|
789
|
+
ws.transform = "translateX(-50%)";
|
|
790
|
+
break;
|
|
791
|
+
case "top-right":
|
|
792
|
+
ws.top = inset;
|
|
793
|
+
ws.right = inset;
|
|
794
|
+
break;
|
|
795
|
+
case "center-left":
|
|
796
|
+
ws.top = "50%";
|
|
797
|
+
ws.left = inset;
|
|
798
|
+
ws.transform = "translateY(-50%)";
|
|
799
|
+
break;
|
|
800
|
+
case "center":
|
|
801
|
+
ws.top = "50%";
|
|
802
|
+
ws.left = "50%";
|
|
803
|
+
ws.transform = "translate(-50%, -50%)";
|
|
804
|
+
break;
|
|
805
|
+
case "center-right":
|
|
806
|
+
ws.top = "50%";
|
|
807
|
+
ws.right = inset;
|
|
808
|
+
ws.transform = "translateY(-50%)";
|
|
809
|
+
break;
|
|
810
|
+
case "bottom-left":
|
|
811
|
+
ws.bottom = inset;
|
|
812
|
+
ws.left = inset;
|
|
813
|
+
break;
|
|
814
|
+
case "bottom-center":
|
|
815
|
+
ws.bottom = inset;
|
|
816
|
+
ws.left = "50%";
|
|
817
|
+
ws.transform = "translateX(-50%)";
|
|
818
|
+
break;
|
|
819
|
+
case "bottom-right":
|
|
820
|
+
ws.bottom = inset;
|
|
821
|
+
ws.right = inset;
|
|
822
|
+
break;
|
|
823
|
+
case "sheet-top-left":
|
|
824
|
+
case "sheet-top-center":
|
|
825
|
+
case "sheet-top-right": {
|
|
826
|
+
const style = resolveSheetAnchoredStyle(mode, position, inset);
|
|
827
|
+
if (style.top !== void 0) ws.top = style.top;
|
|
828
|
+
if (style.bottom !== void 0) ws.bottom = style.bottom;
|
|
829
|
+
if (style.left !== void 0) ws.left = style.left;
|
|
830
|
+
if (style.right !== void 0) ws.right = style.right;
|
|
831
|
+
if (style.transform !== void 0) ws.transform = style.transform;
|
|
832
|
+
break;
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
|
|
676
837
|
// src/core/controllers/scrim-controller.ts
|
|
677
838
|
var VALID_CSS_LENGTH = /^-?\d+(?:\.\d+)?(?:px|em|rem|%)$/;
|
|
839
|
+
var DEFAULT_SCRIM_DIM = "rgba(0, 0, 0, 0.4)";
|
|
678
840
|
var ScrimController = class {
|
|
679
841
|
constructor(deps, opts) {
|
|
680
842
|
__publicField(this, "screenComponent");
|
|
@@ -685,6 +847,8 @@ var ScrimController = class {
|
|
|
685
847
|
__publicField(this, "getAllowedIds");
|
|
686
848
|
__publicField(this, "getResolvedSnaps");
|
|
687
849
|
__publicField(this, "snapToFn");
|
|
850
|
+
__publicField(this, "closeFn");
|
|
851
|
+
__publicField(this, "scrimInteractive", false);
|
|
688
852
|
__publicField(this, "scrimMode");
|
|
689
853
|
__publicField(this, "backdropRange");
|
|
690
854
|
__publicField(this, "screenRange");
|
|
@@ -705,14 +869,17 @@ var ScrimController = class {
|
|
|
705
869
|
this.getAllowedIds = deps.getAllowedIds;
|
|
706
870
|
this.getResolvedSnaps = deps.getResolvedSnaps;
|
|
707
871
|
this.snapToFn = deps.snapTo;
|
|
872
|
+
this.closeFn = deps.close;
|
|
708
873
|
this.scrimMode = opts.scrimMode ?? "full";
|
|
709
874
|
const preset = opts.scrimPreset ? SCRIM_PRESETS[opts.scrimPreset] : null;
|
|
710
875
|
this.backdropRange = opts.backdropRange ?? preset?.range ?? [0, 1];
|
|
711
876
|
this.screenRange = opts.screenRange ?? preset?.range ?? [0, 1];
|
|
712
877
|
this.scrimTapToCloseEnabled = opts.scrimTapToClose ?? false;
|
|
878
|
+
const explicitColor = opts.scrimColor ?? preset?.color;
|
|
879
|
+
const effectiveColor = explicitColor ?? (this.scrimMode !== "off" && !this.backdrop ? DEFAULT_SCRIM_DIM : void 0);
|
|
713
880
|
if (this.screenComponent) {
|
|
714
881
|
this.applyScrimStyles({
|
|
715
|
-
color:
|
|
882
|
+
color: effectiveColor,
|
|
716
883
|
blur: opts.scrimBlur ?? preset?.blur,
|
|
717
884
|
interactive: opts.scrimInteractive ?? preset?.interactive ?? false
|
|
718
885
|
});
|
|
@@ -846,11 +1013,15 @@ var ScrimController = class {
|
|
|
846
1013
|
}
|
|
847
1014
|
const onClick = () => {
|
|
848
1015
|
if (this.isDestroyed()) return;
|
|
1016
|
+
if (this.closeFn) {
|
|
1017
|
+
this.closeFn();
|
|
1018
|
+
return;
|
|
1019
|
+
}
|
|
849
1020
|
const allowed = this.getAllowedIds();
|
|
850
1021
|
const snaps = this.getResolvedSnaps();
|
|
851
1022
|
const fallback = allowed.find((id) => {
|
|
852
1023
|
const snap = findById(id, snaps);
|
|
853
|
-
return snap !== null && snap.size
|
|
1024
|
+
return snap !== null && snap.size === 0;
|
|
854
1025
|
});
|
|
855
1026
|
if (fallback) this.snapToFn(fallback);
|
|
856
1027
|
};
|
|
@@ -867,6 +1038,7 @@ var ScrimController = class {
|
|
|
867
1038
|
if (this.isDestroyed()) return;
|
|
868
1039
|
if (enabled === this.scrimEnabled) return;
|
|
869
1040
|
this.scrimEnabled = enabled;
|
|
1041
|
+
this.invalidateOpacityCache();
|
|
870
1042
|
if (!enabled) {
|
|
871
1043
|
this.savedScrimRanges = {
|
|
872
1044
|
screen: this.screenRange,
|
|
@@ -890,7 +1062,12 @@ var ScrimController = class {
|
|
|
890
1062
|
blur: cfg.blur ?? null,
|
|
891
1063
|
interactive: cfg.interactive
|
|
892
1064
|
});
|
|
893
|
-
this.
|
|
1065
|
+
if (!this.scrimEnabled && this.savedScrimRanges) {
|
|
1066
|
+
this.savedScrimRanges = { screen: cfg.range, backdrop: cfg.range };
|
|
1067
|
+
} else {
|
|
1068
|
+
this.screenRange = cfg.range;
|
|
1069
|
+
this.backdropRange = cfg.range;
|
|
1070
|
+
}
|
|
894
1071
|
}
|
|
895
1072
|
const noop = () => {
|
|
896
1073
|
};
|
|
@@ -940,59 +1117,7 @@ var ScrimController = class {
|
|
|
940
1117
|
wrapper.className = "bs-scrim-overlay";
|
|
941
1118
|
const ws = wrapper.style;
|
|
942
1119
|
ws.position = "absolute";
|
|
943
|
-
|
|
944
|
-
case "top-left":
|
|
945
|
-
ws.top = inset;
|
|
946
|
-
ws.left = inset;
|
|
947
|
-
break;
|
|
948
|
-
case "top-center":
|
|
949
|
-
ws.top = inset;
|
|
950
|
-
ws.left = "50%";
|
|
951
|
-
ws.transform = "translateX(-50%)";
|
|
952
|
-
break;
|
|
953
|
-
case "top-right":
|
|
954
|
-
ws.top = inset;
|
|
955
|
-
ws.right = inset;
|
|
956
|
-
break;
|
|
957
|
-
case "center-left":
|
|
958
|
-
ws.top = "50%";
|
|
959
|
-
ws.left = inset;
|
|
960
|
-
ws.transform = "translateY(-50%)";
|
|
961
|
-
break;
|
|
962
|
-
case "center":
|
|
963
|
-
ws.top = "50%";
|
|
964
|
-
ws.left = "50%";
|
|
965
|
-
ws.transform = "translate(-50%, -50%)";
|
|
966
|
-
break;
|
|
967
|
-
case "center-right":
|
|
968
|
-
ws.top = "50%";
|
|
969
|
-
ws.right = inset;
|
|
970
|
-
ws.transform = "translateY(-50%)";
|
|
971
|
-
break;
|
|
972
|
-
case "bottom-left":
|
|
973
|
-
ws.bottom = inset;
|
|
974
|
-
ws.left = inset;
|
|
975
|
-
break;
|
|
976
|
-
case "bottom-center":
|
|
977
|
-
ws.bottom = inset;
|
|
978
|
-
ws.left = "50%";
|
|
979
|
-
ws.transform = "translateX(-50%)";
|
|
980
|
-
break;
|
|
981
|
-
case "bottom-right":
|
|
982
|
-
ws.bottom = inset;
|
|
983
|
-
ws.right = inset;
|
|
984
|
-
break;
|
|
985
|
-
case "sheet-top-left":
|
|
986
|
-
case "sheet-top-center":
|
|
987
|
-
case "sheet-top-right":
|
|
988
|
-
applySheetAnchoredPosition(
|
|
989
|
-
ws,
|
|
990
|
-
this.mode,
|
|
991
|
-
position,
|
|
992
|
-
inset
|
|
993
|
-
);
|
|
994
|
-
break;
|
|
995
|
-
}
|
|
1120
|
+
applyOverlayPosition(ws, this.mode, position, inset);
|
|
996
1121
|
if (interactive) {
|
|
997
1122
|
ws.pointerEvents = "auto";
|
|
998
1123
|
}
|
|
@@ -1051,6 +1176,7 @@ var ScrimController = class {
|
|
|
1051
1176
|
}
|
|
1052
1177
|
}
|
|
1053
1178
|
if (opts.interactive !== void 0) {
|
|
1179
|
+
this.scrimInteractive = opts.interactive;
|
|
1054
1180
|
s.pointerEvents = opts.interactive ? "auto" : "none";
|
|
1055
1181
|
}
|
|
1056
1182
|
}
|
|
@@ -1065,38 +1191,9 @@ var ScrimController = class {
|
|
|
1065
1191
|
const s = this.screenComponent.style;
|
|
1066
1192
|
s.position = "fixed";
|
|
1067
1193
|
s.inset = insetByMode[this.mode];
|
|
1068
|
-
s.pointerEvents = "none";
|
|
1194
|
+
s.pointerEvents = this.scrimInteractive || this.scrimTapToCloseEnabled ? "auto" : "none";
|
|
1069
1195
|
}
|
|
1070
1196
|
};
|
|
1071
|
-
function resolveSheetAnchoredStyle(mode, position, inset) {
|
|
1072
|
-
const sizeOffset = `calc(var(--bs-size, 0px) + ${inset})`;
|
|
1073
|
-
switch (mode) {
|
|
1074
|
-
case "bottom":
|
|
1075
|
-
if (position === "sheet-top-left") return { bottom: sizeOffset, left: inset };
|
|
1076
|
-
if (position === "sheet-top-right") return { bottom: sizeOffset, right: inset };
|
|
1077
|
-
return { bottom: sizeOffset, left: "50%", transform: "translateX(-50%)" };
|
|
1078
|
-
case "top":
|
|
1079
|
-
if (position === "sheet-top-left") return { top: sizeOffset, left: inset };
|
|
1080
|
-
if (position === "sheet-top-right") return { top: sizeOffset, right: inset };
|
|
1081
|
-
return { top: sizeOffset, left: "50%", transform: "translateX(-50%)" };
|
|
1082
|
-
case "left":
|
|
1083
|
-
if (position === "sheet-top-left") return { left: sizeOffset, top: inset };
|
|
1084
|
-
if (position === "sheet-top-right") return { left: sizeOffset, bottom: inset };
|
|
1085
|
-
return { left: sizeOffset, top: "50%", transform: "translateY(-50%)" };
|
|
1086
|
-
case "right":
|
|
1087
|
-
if (position === "sheet-top-left") return { right: sizeOffset, top: inset };
|
|
1088
|
-
if (position === "sheet-top-right") return { right: sizeOffset, bottom: inset };
|
|
1089
|
-
return { right: sizeOffset, top: "50%", transform: "translateY(-50%)" };
|
|
1090
|
-
}
|
|
1091
|
-
}
|
|
1092
|
-
function applySheetAnchoredPosition(ws, mode, position, inset) {
|
|
1093
|
-
const style = resolveSheetAnchoredStyle(mode, position, inset);
|
|
1094
|
-
if (style.top !== void 0) ws.top = style.top;
|
|
1095
|
-
if (style.bottom !== void 0) ws.bottom = style.bottom;
|
|
1096
|
-
if (style.left !== void 0) ws.left = style.left;
|
|
1097
|
-
if (style.right !== void 0) ws.right = style.right;
|
|
1098
|
-
if (style.transform !== void 0) ws.transform = style.transform;
|
|
1099
|
-
}
|
|
1100
1197
|
|
|
1101
1198
|
// src/core/animation/animation.ts
|
|
1102
1199
|
var easeOutBack = (t) => {
|
|
@@ -1182,14 +1279,20 @@ var runSpring = ({
|
|
|
1182
1279
|
if (cancelled) return;
|
|
1183
1280
|
const dt = Math.min((now - lastTime) / 1e3, MAX_DT);
|
|
1184
1281
|
lastTime = now;
|
|
1185
|
-
const
|
|
1186
|
-
|
|
1282
|
+
const steps = Math.max(1, Math.ceil(dt * 240));
|
|
1283
|
+
const subDt = dt / steps;
|
|
1284
|
+
let stepsLeft = steps;
|
|
1187
1285
|
while (stepsLeft-- > 0) {
|
|
1188
1286
|
const force = -cfg.stiffness * (x - to) - cfg.damping * v;
|
|
1189
1287
|
const accel = force / cfg.mass;
|
|
1190
1288
|
v += accel * subDt;
|
|
1191
1289
|
x += v * subDt;
|
|
1192
1290
|
}
|
|
1291
|
+
if (!Number.isFinite(x) || !Number.isFinite(v)) {
|
|
1292
|
+
onUpdate(to, 0);
|
|
1293
|
+
resolve();
|
|
1294
|
+
return;
|
|
1295
|
+
}
|
|
1193
1296
|
onUpdate(x, v);
|
|
1194
1297
|
const isAtRest = Math.abs(to - x) < (cfg.restDelta ?? 0.5) && Math.abs(v) < (cfg.restSpeed ?? 0.5);
|
|
1195
1298
|
if (isAtRest) {
|
|
@@ -1364,9 +1467,13 @@ var isVisible = (el) => {
|
|
|
1364
1467
|
var focusables = (root) => Array.from(root.querySelectorAll(FOCUSABLE)).filter(
|
|
1365
1468
|
(el) => !el.hasAttribute("inert") && isVisible(el) && !el.matches("[aria-hidden='true']")
|
|
1366
1469
|
);
|
|
1470
|
+
var trapStack = [];
|
|
1367
1471
|
var installFocusTrap = (container, options = {}) => {
|
|
1368
1472
|
if (typeof document === "undefined") return () => {
|
|
1369
1473
|
};
|
|
1474
|
+
const token = {};
|
|
1475
|
+
trapStack.push(token);
|
|
1476
|
+
const isActive = () => trapStack[trapStack.length - 1] === token;
|
|
1370
1477
|
const previouslyFocused = document.activeElement;
|
|
1371
1478
|
const focusInitial = () => {
|
|
1372
1479
|
const initial = typeof options.initialFocus === "string" ? container.querySelector(options.initialFocus) : options.initialFocus ?? focusables(container)[0] ?? container;
|
|
@@ -1374,6 +1481,7 @@ var installFocusTrap = (container, options = {}) => {
|
|
|
1374
1481
|
};
|
|
1375
1482
|
focusInitial();
|
|
1376
1483
|
const handleKey = (e) => {
|
|
1484
|
+
if (!isActive()) return;
|
|
1377
1485
|
if (e.key === "Escape" && options.onEscape) {
|
|
1378
1486
|
options.onEscape();
|
|
1379
1487
|
return;
|
|
@@ -1396,6 +1504,7 @@ var installFocusTrap = (container, options = {}) => {
|
|
|
1396
1504
|
}
|
|
1397
1505
|
};
|
|
1398
1506
|
const handleFocusIn = (e) => {
|
|
1507
|
+
if (!isActive()) return;
|
|
1399
1508
|
const target = e.target;
|
|
1400
1509
|
if (target && !container.contains(target)) {
|
|
1401
1510
|
const list = focusables(container);
|
|
@@ -1408,6 +1517,8 @@ var installFocusTrap = (container, options = {}) => {
|
|
|
1408
1517
|
return () => {
|
|
1409
1518
|
if (released) return;
|
|
1410
1519
|
released = true;
|
|
1520
|
+
const idx = trapStack.indexOf(token);
|
|
1521
|
+
if (idx !== -1) trapStack.splice(idx, 1);
|
|
1411
1522
|
document.removeEventListener("keydown", handleKey, true);
|
|
1412
1523
|
document.removeEventListener("focusin", handleFocusIn, true);
|
|
1413
1524
|
if (previouslyFocused && document.contains(previouslyFocused)) {
|
|
@@ -1463,11 +1574,17 @@ function createInertSiblings(rootProvider) {
|
|
|
1463
1574
|
return {
|
|
1464
1575
|
apply() {
|
|
1465
1576
|
if (typeof document === "undefined") return;
|
|
1466
|
-
|
|
1467
|
-
|
|
1577
|
+
let top = rootProvider();
|
|
1578
|
+
while (top.parentElement && top.parentElement !== document.body) {
|
|
1579
|
+
top = top.parentElement;
|
|
1580
|
+
}
|
|
1581
|
+
const parent = top.parentElement ?? document.body;
|
|
1468
1582
|
for (const child of Array.from(parent.children)) {
|
|
1469
|
-
if (child ===
|
|
1583
|
+
if (child === top) continue;
|
|
1470
1584
|
if (child.hasAttribute("inert")) continue;
|
|
1585
|
+
if (child.classList.contains("bs-backdrop") || child.classList.contains("bs-screen") || child.classList.contains("bs-root")) {
|
|
1586
|
+
continue;
|
|
1587
|
+
}
|
|
1471
1588
|
child.setAttribute("inert", "");
|
|
1472
1589
|
tracked.push(child);
|
|
1473
1590
|
}
|
|
@@ -1483,7 +1600,6 @@ function createInertSiblings(rootProvider) {
|
|
|
1483
1600
|
var LifecycleController = class {
|
|
1484
1601
|
constructor(deps, opts) {
|
|
1485
1602
|
__publicField(this, "element");
|
|
1486
|
-
__publicField(this, "closeFn");
|
|
1487
1603
|
__publicField(this, "focusTrapEnabled");
|
|
1488
1604
|
__publicField(this, "initialFocus");
|
|
1489
1605
|
__publicField(this, "closeOnEscape");
|
|
@@ -1497,7 +1613,6 @@ var LifecycleController = class {
|
|
|
1497
1613
|
__publicField(this, "installed", false);
|
|
1498
1614
|
__publicField(this, "destroyed", false);
|
|
1499
1615
|
this.element = deps.element;
|
|
1500
|
-
this.closeFn = deps.close;
|
|
1501
1616
|
this.focusTrapEnabled = opts.focusTrap ?? false;
|
|
1502
1617
|
this.initialFocus = opts.initialFocus;
|
|
1503
1618
|
this.closeOnEscape = opts.closeOnEscape ?? true;
|
|
@@ -1507,6 +1622,9 @@ var LifecycleController = class {
|
|
|
1507
1622
|
this.returnFocus = opts.returnFocus;
|
|
1508
1623
|
this.inertSiblings = createInertSiblings(() => this.element);
|
|
1509
1624
|
}
|
|
1625
|
+
get isInstalled() {
|
|
1626
|
+
return this.installed;
|
|
1627
|
+
}
|
|
1510
1628
|
install() {
|
|
1511
1629
|
if (this.destroyed) return;
|
|
1512
1630
|
this.installed = true;
|
|
@@ -1515,8 +1633,7 @@ var LifecycleController = class {
|
|
|
1515
1633
|
}
|
|
1516
1634
|
if (this.focusTrapEnabled && !this.releaseFocusTrap) {
|
|
1517
1635
|
this.releaseFocusTrap = installFocusTrap(this.element, {
|
|
1518
|
-
initialFocus: this.initialFocus
|
|
1519
|
-
onEscape: this.closeOnEscape ? () => void this.closeFn() : void 0
|
|
1636
|
+
initialFocus: this.initialFocus
|
|
1520
1637
|
});
|
|
1521
1638
|
}
|
|
1522
1639
|
if (this.inertSiblingsEnabled && this.shouldApplyInertSiblings()) {
|
|
@@ -1536,7 +1653,7 @@ var LifecycleController = class {
|
|
|
1536
1653
|
this.releaseScrollLock = null;
|
|
1537
1654
|
this.inertSiblings.remove();
|
|
1538
1655
|
if (this.returnFocus) {
|
|
1539
|
-
const target = typeof this.returnFocus === "function" ? this.returnFocus() : this.returnFocus;
|
|
1656
|
+
const target = typeof this.returnFocus === "function" ? this.returnFocus() : typeof this.returnFocus === "string" ? typeof document !== "undefined" ? document.querySelector(this.returnFocus) : null : this.returnFocus;
|
|
1540
1657
|
target?.focus?.();
|
|
1541
1658
|
}
|
|
1542
1659
|
}
|
|
@@ -1671,10 +1788,11 @@ var installGestures = (handle, mode, callbacks) => {
|
|
|
1671
1788
|
var attachGestures = installGestures;
|
|
1672
1789
|
|
|
1673
1790
|
// src/core/primitives/rubber-band.ts
|
|
1674
|
-
var RUBBER_BAND_FACTOR = 0.55;
|
|
1675
1791
|
function rubberBand(overshoot, maxAxisSize) {
|
|
1676
1792
|
const cap = Math.min(maxAxisSize * 0.15, 80);
|
|
1677
|
-
|
|
1793
|
+
if (cap <= 0) return 0;
|
|
1794
|
+
const abs = Math.abs(overshoot);
|
|
1795
|
+
return Math.sign(overshoot) * (cap * abs / (abs + cap));
|
|
1678
1796
|
}
|
|
1679
1797
|
|
|
1680
1798
|
// src/core/features/soft-keyboard.ts
|
|
@@ -1703,6 +1821,7 @@ var GestureController = class {
|
|
|
1703
1821
|
__publicField(this, "dragStartSize", 0);
|
|
1704
1822
|
__publicField(this, "currentPointerKind", "touch");
|
|
1705
1823
|
__publicField(this, "keyboardDismissed", false);
|
|
1824
|
+
__publicField(this, "dragSuppressed", false);
|
|
1706
1825
|
__publicField(this, "dragPayload", { size: 0, delta: 0 });
|
|
1707
1826
|
this.deps = deps;
|
|
1708
1827
|
}
|
|
@@ -1713,6 +1832,11 @@ var GestureController = class {
|
|
|
1713
1832
|
if (this.detach) return this.detach;
|
|
1714
1833
|
this.detach = installGestures(this.deps.handle, this.deps.mode, {
|
|
1715
1834
|
onStart: (_coord, kind) => {
|
|
1835
|
+
if (this.deps.getDisableDrag?.()) {
|
|
1836
|
+
this.dragSuppressed = true;
|
|
1837
|
+
return;
|
|
1838
|
+
}
|
|
1839
|
+
this.dragSuppressed = false;
|
|
1716
1840
|
this.deps.cancelAnimation();
|
|
1717
1841
|
this.isDragging_ = true;
|
|
1718
1842
|
this.dragStartSize = this.deps.getDragContext().size;
|
|
@@ -1723,6 +1847,7 @@ var GestureController = class {
|
|
|
1723
1847
|
this.deps.emit("dragstart", { size: this.dragStartSize });
|
|
1724
1848
|
},
|
|
1725
1849
|
onMove: (delta) => {
|
|
1850
|
+
if (this.dragSuppressed) return;
|
|
1726
1851
|
const ctx = this.deps.getDragContext();
|
|
1727
1852
|
const { min, max } = ctx.range;
|
|
1728
1853
|
const maxAxis = ctx.maxAxisSize;
|
|
@@ -1746,6 +1871,10 @@ var GestureController = class {
|
|
|
1746
1871
|
}
|
|
1747
1872
|
},
|
|
1748
1873
|
onEnd: (delta, velocity, kind) => {
|
|
1874
|
+
if (this.dragSuppressed) {
|
|
1875
|
+
this.dragSuppressed = false;
|
|
1876
|
+
return;
|
|
1877
|
+
}
|
|
1749
1878
|
this.isDragging_ = false;
|
|
1750
1879
|
this.keyboardDismissed = false;
|
|
1751
1880
|
this.deps.getRoot()?.removeAttribute("data-dragging");
|
|
@@ -1756,9 +1885,17 @@ var GestureController = class {
|
|
|
1756
1885
|
this.deps.settleAfterDrag(delta, velocity, kind);
|
|
1757
1886
|
},
|
|
1758
1887
|
onCancel: () => {
|
|
1888
|
+
if (this.dragSuppressed) {
|
|
1889
|
+
this.dragSuppressed = false;
|
|
1890
|
+
return;
|
|
1891
|
+
}
|
|
1759
1892
|
this.isDragging_ = false;
|
|
1760
1893
|
this.keyboardDismissed = false;
|
|
1761
1894
|
this.deps.getRoot()?.removeAttribute("data-dragging");
|
|
1895
|
+
this.deps.emit("dragend", {
|
|
1896
|
+
size: this.deps.getDragContext().size,
|
|
1897
|
+
velocity: 0
|
|
1898
|
+
});
|
|
1762
1899
|
const restoreTo = this.dragStartSize;
|
|
1763
1900
|
void this.deps.animateTo(restoreTo, 0);
|
|
1764
1901
|
}
|
|
@@ -1832,6 +1969,287 @@ function createScrollCache(deps) {
|
|
|
1832
1969
|
};
|
|
1833
1970
|
}
|
|
1834
1971
|
|
|
1972
|
+
// src/core/primitives/anchor-animations.ts
|
|
1973
|
+
var DEFAULT_DURATION3 = 200;
|
|
1974
|
+
var DEFAULT_EASING = "cubic-bezier(0.22, 1, 0.36, 1)";
|
|
1975
|
+
var PRESET_FRAMES = {
|
|
1976
|
+
fade: {
|
|
1977
|
+
enter: [{ opacity: 0 }, { opacity: 1 }],
|
|
1978
|
+
exit: [{ opacity: 1 }, { opacity: 0 }]
|
|
1979
|
+
},
|
|
1980
|
+
scale: {
|
|
1981
|
+
enter: [
|
|
1982
|
+
{ opacity: 0, transform: "scale(0.85)" },
|
|
1983
|
+
{ opacity: 1, transform: "scale(1)" }
|
|
1984
|
+
],
|
|
1985
|
+
exit: [
|
|
1986
|
+
{ opacity: 1, transform: "scale(1)" },
|
|
1987
|
+
{ opacity: 0, transform: "scale(0.85)" }
|
|
1988
|
+
]
|
|
1989
|
+
},
|
|
1990
|
+
slide: {
|
|
1991
|
+
enter: [
|
|
1992
|
+
{ opacity: 0, transform: "translateY(10px)" },
|
|
1993
|
+
{ opacity: 1, transform: "translateY(0)" }
|
|
1994
|
+
],
|
|
1995
|
+
exit: [
|
|
1996
|
+
{ opacity: 1, transform: "translateY(0)" },
|
|
1997
|
+
{ opacity: 0, transform: "translateY(10px)" }
|
|
1998
|
+
]
|
|
1999
|
+
},
|
|
2000
|
+
pop: {
|
|
2001
|
+
enter: [
|
|
2002
|
+
{ opacity: 0, transform: "scale(0.6)", offset: 0 },
|
|
2003
|
+
{ opacity: 1, transform: "scale(1.06)", offset: 0.7 },
|
|
2004
|
+
{ opacity: 1, transform: "scale(1)", offset: 1 }
|
|
2005
|
+
],
|
|
2006
|
+
exit: [
|
|
2007
|
+
{ opacity: 1, transform: "scale(1)" },
|
|
2008
|
+
{ opacity: 0, transform: "scale(0.6)" }
|
|
2009
|
+
]
|
|
2010
|
+
}
|
|
2011
|
+
};
|
|
2012
|
+
var INSTANT = {
|
|
2013
|
+
finished: Promise.resolve(),
|
|
2014
|
+
cancel: () => {
|
|
2015
|
+
}
|
|
2016
|
+
};
|
|
2017
|
+
function resolveTransitionFrames(spec, phase) {
|
|
2018
|
+
const fallback = { frames: null, duration: 0, easing: DEFAULT_EASING };
|
|
2019
|
+
if (spec === "none") return fallback;
|
|
2020
|
+
if (spec === void 0 || typeof spec === "string") {
|
|
2021
|
+
const preset2 = PRESET_FRAMES[spec ?? "fade"];
|
|
2022
|
+
return {
|
|
2023
|
+
frames: preset2[phase],
|
|
2024
|
+
duration: DEFAULT_DURATION3,
|
|
2025
|
+
easing: DEFAULT_EASING
|
|
2026
|
+
};
|
|
2027
|
+
}
|
|
2028
|
+
const custom = phase === "enter" ? spec.enter : spec.exit;
|
|
2029
|
+
if (custom) {
|
|
2030
|
+
return {
|
|
2031
|
+
frames: custom,
|
|
2032
|
+
duration: spec.duration ?? DEFAULT_DURATION3,
|
|
2033
|
+
easing: spec.easing ?? DEFAULT_EASING
|
|
2034
|
+
};
|
|
2035
|
+
}
|
|
2036
|
+
if (spec.preset === "none") return fallback;
|
|
2037
|
+
const preset = PRESET_FRAMES[spec.preset ?? "fade"];
|
|
2038
|
+
return {
|
|
2039
|
+
frames: preset[phase],
|
|
2040
|
+
duration: spec.duration ?? DEFAULT_DURATION3,
|
|
2041
|
+
easing: spec.easing ?? DEFAULT_EASING
|
|
2042
|
+
};
|
|
2043
|
+
}
|
|
2044
|
+
function runAnchorTransition(el, spec, phase) {
|
|
2045
|
+
const respectReduced = typeof spec === "object" ? spec.respectReducedMotion !== false : true;
|
|
2046
|
+
if (respectReduced && prefersReducedMotion()) return INSTANT;
|
|
2047
|
+
const { frames, duration, easing } = resolveTransitionFrames(spec, phase);
|
|
2048
|
+
if (!frames || duration <= 0) return INSTANT;
|
|
2049
|
+
if (typeof el.animate !== "function") return INSTANT;
|
|
2050
|
+
const animation = el.animate(frames, {
|
|
2051
|
+
duration,
|
|
2052
|
+
easing,
|
|
2053
|
+
fill: "both"
|
|
2054
|
+
});
|
|
2055
|
+
const finished = animation.finished.then(() => void 0).catch(() => void 0);
|
|
2056
|
+
return {
|
|
2057
|
+
finished,
|
|
2058
|
+
cancel: () => {
|
|
2059
|
+
try {
|
|
2060
|
+
animation.cancel();
|
|
2061
|
+
} catch {
|
|
2062
|
+
return;
|
|
2063
|
+
}
|
|
2064
|
+
}
|
|
2065
|
+
};
|
|
2066
|
+
}
|
|
2067
|
+
|
|
2068
|
+
// src/core/features/sheet-anchors.ts
|
|
2069
|
+
function attachAnchor(deps, opts) {
|
|
2070
|
+
const doc = deps.host.ownerDocument;
|
|
2071
|
+
const wrapper = doc.createElement("div");
|
|
2072
|
+
wrapper.className = "bs-anchor";
|
|
2073
|
+
const interactive = opts.interactive ?? true;
|
|
2074
|
+
const position = opts.position ?? "sheet-top-right";
|
|
2075
|
+
const isDock = position === "dock-bottom" || position === "dock-top";
|
|
2076
|
+
const ws = wrapper.style;
|
|
2077
|
+
ws.position = "fixed";
|
|
2078
|
+
if (isDock) {
|
|
2079
|
+
ws.left = "0";
|
|
2080
|
+
ws.right = "0";
|
|
2081
|
+
if (position === "dock-bottom") {
|
|
2082
|
+
ws.bottom = "0";
|
|
2083
|
+
} else {
|
|
2084
|
+
ws.top = "0";
|
|
2085
|
+
}
|
|
2086
|
+
} else {
|
|
2087
|
+
applyOverlayPosition(ws, deps.mode, position, opts.inset ?? "16px");
|
|
2088
|
+
}
|
|
2089
|
+
if (opts.fadeRange) {
|
|
2090
|
+
const [r0, r1] = opts.fadeRange;
|
|
2091
|
+
const span = Math.max(r1 - r0, 1e-4);
|
|
2092
|
+
ws.opacity = `clamp(0, calc((var(--bs-progress, 0) - ${r0}) / ${span}), 1)`;
|
|
2093
|
+
}
|
|
2094
|
+
wrapper.appendChild(opts.element);
|
|
2095
|
+
deps.host.appendChild(wrapper);
|
|
2096
|
+
let visible = null;
|
|
2097
|
+
let inFlight = null;
|
|
2098
|
+
const shouldShow = (state) => {
|
|
2099
|
+
if (typeof opts.showOn === "function") return opts.showOn(state);
|
|
2100
|
+
if (Array.isArray(opts.showOn)) return opts.showOn.includes(state.activeId);
|
|
2101
|
+
return isDock || state.size > 0;
|
|
2102
|
+
};
|
|
2103
|
+
const applyVisibility = (next, animate) => {
|
|
2104
|
+
if (next === visible) return;
|
|
2105
|
+
visible = next;
|
|
2106
|
+
inFlight?.cancel();
|
|
2107
|
+
inFlight = null;
|
|
2108
|
+
wrapper.style.pointerEvents = next && interactive ? "auto" : "none";
|
|
2109
|
+
if (next) {
|
|
2110
|
+
wrapper.style.visibility = "";
|
|
2111
|
+
if (animate) {
|
|
2112
|
+
inFlight = runAnchorTransition(opts.element, opts.animation, "enter");
|
|
2113
|
+
}
|
|
2114
|
+
return;
|
|
2115
|
+
}
|
|
2116
|
+
if (!animate) {
|
|
2117
|
+
wrapper.style.visibility = "hidden";
|
|
2118
|
+
return;
|
|
2119
|
+
}
|
|
2120
|
+
const handle = runAnchorTransition(opts.element, opts.animation, "exit");
|
|
2121
|
+
inFlight = handle;
|
|
2122
|
+
void handle.finished.then(() => {
|
|
2123
|
+
if (inFlight === handle && visible === false) {
|
|
2124
|
+
wrapper.style.visibility = "hidden";
|
|
2125
|
+
}
|
|
2126
|
+
});
|
|
2127
|
+
};
|
|
2128
|
+
const evaluate = (animate) => {
|
|
2129
|
+
if (deps.isDestroyed()) return;
|
|
2130
|
+
applyVisibility(shouldShow(deps.getState()), animate);
|
|
2131
|
+
};
|
|
2132
|
+
const offs = [
|
|
2133
|
+
deps.on("snap", () => evaluate(true)),
|
|
2134
|
+
deps.on("open", () => evaluate(true)),
|
|
2135
|
+
deps.on("close", () => evaluate(true))
|
|
2136
|
+
];
|
|
2137
|
+
evaluate(false);
|
|
2138
|
+
return {
|
|
2139
|
+
wrapper,
|
|
2140
|
+
detach: () => {
|
|
2141
|
+
offs.forEach((off) => off());
|
|
2142
|
+
inFlight?.cancel();
|
|
2143
|
+
inFlight = null;
|
|
2144
|
+
if (wrapper.parentNode) wrapper.parentNode.removeChild(wrapper);
|
|
2145
|
+
},
|
|
2146
|
+
syncZ: (z) => {
|
|
2147
|
+
wrapper.style.zIndex = String(z);
|
|
2148
|
+
}
|
|
2149
|
+
};
|
|
2150
|
+
}
|
|
2151
|
+
|
|
2152
|
+
// src/core/features/scrim-stages.ts
|
|
2153
|
+
var matchesId = (def, activeId) => {
|
|
2154
|
+
if (def.for === void 0) return false;
|
|
2155
|
+
return Array.isArray(def.for) ? def.for.includes(activeId) : def.for === activeId;
|
|
2156
|
+
};
|
|
2157
|
+
var matchesRange = (def, progress) => {
|
|
2158
|
+
if (!def.forRange) return false;
|
|
2159
|
+
const [from, to] = def.forRange;
|
|
2160
|
+
return progress >= from && progress <= to;
|
|
2161
|
+
};
|
|
2162
|
+
function installScrimStages(deps, opts) {
|
|
2163
|
+
const doc = deps.host.ownerDocument;
|
|
2164
|
+
const entries = opts.stages.map((def) => {
|
|
2165
|
+
const wrapper = doc.createElement("div");
|
|
2166
|
+
wrapper.className = "bs-scrim-stage";
|
|
2167
|
+
const ws = wrapper.style;
|
|
2168
|
+
ws.position = "absolute";
|
|
2169
|
+
applyOverlayPosition(
|
|
2170
|
+
ws,
|
|
2171
|
+
deps.mode,
|
|
2172
|
+
def.position ?? opts.position ?? "center",
|
|
2173
|
+
def.inset ?? opts.inset ?? "16px"
|
|
2174
|
+
);
|
|
2175
|
+
ws.visibility = "hidden";
|
|
2176
|
+
ws.pointerEvents = "none";
|
|
2177
|
+
wrapper.appendChild(def.element);
|
|
2178
|
+
deps.host.appendChild(wrapper);
|
|
2179
|
+
return { def, wrapper, inFlight: null };
|
|
2180
|
+
});
|
|
2181
|
+
let active = null;
|
|
2182
|
+
const resolveActive = () => {
|
|
2183
|
+
const state = deps.getState();
|
|
2184
|
+
if (state.size === 0) {
|
|
2185
|
+
return entries.find((e) => matchesId(e.def, state.activeId)) ?? null;
|
|
2186
|
+
}
|
|
2187
|
+
return entries.find((e) => matchesId(e.def, state.activeId)) ?? entries.find((e) => matchesRange(e.def, state.progress)) ?? null;
|
|
2188
|
+
};
|
|
2189
|
+
const hide = (entry, animate) => {
|
|
2190
|
+
entry.inFlight?.cancel();
|
|
2191
|
+
entry.wrapper.style.pointerEvents = "none";
|
|
2192
|
+
if (!animate) {
|
|
2193
|
+
entry.inFlight = null;
|
|
2194
|
+
entry.wrapper.style.visibility = "hidden";
|
|
2195
|
+
return;
|
|
2196
|
+
}
|
|
2197
|
+
const handle = runAnchorTransition(
|
|
2198
|
+
entry.def.element,
|
|
2199
|
+
entry.def.animation ?? opts.animation,
|
|
2200
|
+
"exit"
|
|
2201
|
+
);
|
|
2202
|
+
entry.inFlight = handle;
|
|
2203
|
+
void handle.finished.then(() => {
|
|
2204
|
+
if (entry.inFlight === handle && active !== entry) {
|
|
2205
|
+
entry.wrapper.style.visibility = "hidden";
|
|
2206
|
+
}
|
|
2207
|
+
});
|
|
2208
|
+
};
|
|
2209
|
+
const show = (entry, animate) => {
|
|
2210
|
+
entry.inFlight?.cancel();
|
|
2211
|
+
entry.inFlight = null;
|
|
2212
|
+
entry.wrapper.style.visibility = "";
|
|
2213
|
+
entry.wrapper.style.pointerEvents = entry.def.interactive ?? opts.interactive ?? false ? "auto" : "none";
|
|
2214
|
+
if (animate) {
|
|
2215
|
+
entry.inFlight = runAnchorTransition(
|
|
2216
|
+
entry.def.element,
|
|
2217
|
+
entry.def.animation ?? opts.animation,
|
|
2218
|
+
"enter"
|
|
2219
|
+
);
|
|
2220
|
+
}
|
|
2221
|
+
};
|
|
2222
|
+
const update = (animate) => {
|
|
2223
|
+
if (deps.isDestroyed()) return;
|
|
2224
|
+
const next = resolveActive();
|
|
2225
|
+
if (next === active) return;
|
|
2226
|
+
const prev = active;
|
|
2227
|
+
active = next;
|
|
2228
|
+
if (prev) hide(prev, animate);
|
|
2229
|
+
if (next) show(next, animate);
|
|
2230
|
+
};
|
|
2231
|
+
const offs = [
|
|
2232
|
+
deps.on("snap", () => update(true)),
|
|
2233
|
+
deps.on("open", () => update(true)),
|
|
2234
|
+
deps.on("close", () => update(true))
|
|
2235
|
+
];
|
|
2236
|
+
if (entries.some((e) => e.def.forRange)) {
|
|
2237
|
+
offs.push(deps.on("progress", () => update(true)));
|
|
2238
|
+
}
|
|
2239
|
+
update(false);
|
|
2240
|
+
return () => {
|
|
2241
|
+
offs.forEach((off) => off());
|
|
2242
|
+
for (const entry of entries) {
|
|
2243
|
+
entry.inFlight?.cancel();
|
|
2244
|
+
entry.inFlight = null;
|
|
2245
|
+
if (entry.wrapper.parentNode) {
|
|
2246
|
+
entry.wrapper.parentNode.removeChild(entry.wrapper);
|
|
2247
|
+
}
|
|
2248
|
+
}
|
|
2249
|
+
active = null;
|
|
2250
|
+
};
|
|
2251
|
+
}
|
|
2252
|
+
|
|
1835
2253
|
// src/core/primitives/engine-options.ts
|
|
1836
2254
|
var DEFAULT_FLICK_VELOCITY = 0.65;
|
|
1837
2255
|
var DEFAULT_DRAG_THRESHOLD = 18;
|
|
@@ -1850,6 +2268,12 @@ function resolveEngineOptions(opts, extras) {
|
|
|
1850
2268
|
dragThreshold: opts.dragThreshold ?? DEFAULT_DRAG_THRESHOLD,
|
|
1851
2269
|
rubberBandEnabled: opts.rubberBand ?? true,
|
|
1852
2270
|
closeOnBack: opts.closeOnBack ?? false,
|
|
2271
|
+
persistent: opts.persistent ?? false,
|
|
2272
|
+
disableClose: opts.disableClose ?? false,
|
|
2273
|
+
disableDrag: opts.disableDrag ?? false,
|
|
2274
|
+
closeOnRouteChange: opts.closeOnRouteChange ?? false,
|
|
2275
|
+
radius: opts.radius,
|
|
2276
|
+
maxHeight: opts.maxHeight,
|
|
1853
2277
|
initialAllowed,
|
|
1854
2278
|
initialId,
|
|
1855
2279
|
scrim: {
|
|
@@ -1876,7 +2300,8 @@ function resolveEngineOptions(opts, extras) {
|
|
|
1876
2300
|
closeOnEscape: opts.closeOnEscape,
|
|
1877
2301
|
lockBodyScroll: opts.lockBodyScroll,
|
|
1878
2302
|
inertSiblings: opts.inertSiblings,
|
|
1879
|
-
shouldApplyInertSiblings: extras?.shouldApplyInertSiblings
|
|
2303
|
+
shouldApplyInertSiblings: extras?.shouldApplyInertSiblings,
|
|
2304
|
+
returnFocus: opts.returnFocusTo
|
|
1880
2305
|
}
|
|
1881
2306
|
};
|
|
1882
2307
|
}
|
|
@@ -1921,6 +2346,11 @@ var BottomSheetEngine = class {
|
|
|
1921
2346
|
__publicField(this, "lifecycle");
|
|
1922
2347
|
__publicField(this, "closeOnBack");
|
|
1923
2348
|
__publicField(this, "routedTo");
|
|
2349
|
+
__publicField(this, "persistent");
|
|
2350
|
+
__publicField(this, "disableCloseFlag");
|
|
2351
|
+
__publicField(this, "disableDragFlag");
|
|
2352
|
+
__publicField(this, "closeOnRouteChange");
|
|
2353
|
+
__publicField(this, "maxHeightCap");
|
|
1924
2354
|
__publicField(this, "snapPointsRaw");
|
|
1925
2355
|
__publicField(this, "snaps");
|
|
1926
2356
|
__publicField(this, "activeId");
|
|
@@ -1933,6 +2363,7 @@ var BottomSheetEngine = class {
|
|
|
1933
2363
|
__publicField(this, "sizeWriteSentinel", new WriteSentinel());
|
|
1934
2364
|
__publicField(this, "progressWriteSentinel", new WriteSentinel());
|
|
1935
2365
|
__publicField(this, "isTopSheet", true);
|
|
2366
|
+
__publicField(this, "opening", false);
|
|
1936
2367
|
__publicField(this, "progressPayload", {
|
|
1937
2368
|
value: 0,
|
|
1938
2369
|
size: 0
|
|
@@ -1948,6 +2379,12 @@ var BottomSheetEngine = class {
|
|
|
1948
2379
|
__publicField(this, "linkedSheets", []);
|
|
1949
2380
|
__publicField(this, "scrollCache");
|
|
1950
2381
|
__publicField(this, "teardowns", new TeardownStack());
|
|
2382
|
+
__publicField(this, "anchors", []);
|
|
2383
|
+
__publicField(this, "anchorHost", null);
|
|
2384
|
+
__publicField(this, "stackZ", 100);
|
|
2385
|
+
__publicField(this, "detachScrimStages", null);
|
|
2386
|
+
__publicField(this, "stackEffectEnabled", false);
|
|
2387
|
+
__publicField(this, "stackEffectPrimed", false);
|
|
1951
2388
|
__publicField(this, "transformTemplate");
|
|
1952
2389
|
const resolved = resolveEngineOptions(opts, {
|
|
1953
2390
|
shouldApplyInertSiblings: () => {
|
|
@@ -1981,6 +2418,10 @@ var BottomSheetEngine = class {
|
|
|
1981
2418
|
getResolvedSnaps: () => this.snaps.getResolvedSnaps().slice(),
|
|
1982
2419
|
snapTo: (id) => {
|
|
1983
2420
|
void this.snapTo(id);
|
|
2421
|
+
},
|
|
2422
|
+
close: () => {
|
|
2423
|
+
if (!this.canDismiss()) return;
|
|
2424
|
+
void this.close("backdrop");
|
|
1984
2425
|
}
|
|
1985
2426
|
},
|
|
1986
2427
|
resolved.scrim
|
|
@@ -2004,6 +2445,11 @@ var BottomSheetEngine = class {
|
|
|
2004
2445
|
);
|
|
2005
2446
|
this.closeOnBack = resolved.closeOnBack;
|
|
2006
2447
|
this.routedTo = opts.routedTo;
|
|
2448
|
+
this.persistent = resolved.persistent;
|
|
2449
|
+
this.disableCloseFlag = resolved.disableClose;
|
|
2450
|
+
this.disableDragFlag = resolved.disableDrag;
|
|
2451
|
+
this.closeOnRouteChange = resolved.closeOnRouteChange;
|
|
2452
|
+
this.stackEffectEnabled = opts.stackEffect ?? false;
|
|
2007
2453
|
this.snapPointsRaw = opts.snapPoints;
|
|
2008
2454
|
this.persistKey = opts.persistKey;
|
|
2009
2455
|
if (opts.linkedSheets) {
|
|
@@ -2016,7 +2462,7 @@ var BottomSheetEngine = class {
|
|
|
2016
2462
|
this.snapPointsRaw,
|
|
2017
2463
|
resolved.initialAllowed,
|
|
2018
2464
|
this.mode,
|
|
2019
|
-
() => this.
|
|
2465
|
+
() => this.measureFitSize(),
|
|
2020
2466
|
(maxAxisSize) => {
|
|
2021
2467
|
this.element.style[layoutAxis(this.mode)] = `${maxAxisSize}px`;
|
|
2022
2468
|
}
|
|
@@ -2050,6 +2496,19 @@ var BottomSheetEngine = class {
|
|
|
2050
2496
|
io.observe(this.element);
|
|
2051
2497
|
this.teardowns.add(() => io.disconnect());
|
|
2052
2498
|
}
|
|
2499
|
+
this.installFitObserver();
|
|
2500
|
+
if (resolved.radius !== void 0) this.setRadius(resolved.radius);
|
|
2501
|
+
if (resolved.maxHeight !== void 0) this.setMaxHeight(resolved.maxHeight);
|
|
2502
|
+
this.applyAutoAriaLabelledBy();
|
|
2503
|
+
if (this.closeOnRouteChange) {
|
|
2504
|
+
this.teardowns.add(
|
|
2505
|
+
installRouteChange({
|
|
2506
|
+
isDestroyed: () => this.destroyed,
|
|
2507
|
+
getSize: () => this.size,
|
|
2508
|
+
close: () => this.close()
|
|
2509
|
+
})
|
|
2510
|
+
);
|
|
2511
|
+
}
|
|
2053
2512
|
if (this.persistKey) {
|
|
2054
2513
|
this.teardowns.add(installPersist(this, this.persistKey));
|
|
2055
2514
|
}
|
|
@@ -2074,7 +2533,7 @@ var BottomSheetEngine = class {
|
|
|
2074
2533
|
isTopSheet: () => this.isTopSheet,
|
|
2075
2534
|
getSize: () => this.size,
|
|
2076
2535
|
isDestroyed: () => this.destroyed,
|
|
2077
|
-
close: () => this.close(),
|
|
2536
|
+
close: () => this.close("back"),
|
|
2078
2537
|
on: (event, fn) => this.on(event, fn),
|
|
2079
2538
|
sheetId: this.id
|
|
2080
2539
|
})
|
|
@@ -2168,6 +2627,10 @@ var BottomSheetEngine = class {
|
|
|
2168
2627
|
const previousSize = this.size;
|
|
2169
2628
|
this.scrollCache.cache(previousId, previousSize, target.size);
|
|
2170
2629
|
this.activeId = id;
|
|
2630
|
+
if (wasClosed && target.size > 0) {
|
|
2631
|
+
this.opening = true;
|
|
2632
|
+
sheetStack.promote(this.id);
|
|
2633
|
+
}
|
|
2171
2634
|
if (this.animation.viewTransitionsAvailable) {
|
|
2172
2635
|
this.currentViewTransition?.skipTransition?.();
|
|
2173
2636
|
const vt = document.startViewTransition(() => {
|
|
@@ -2182,19 +2645,26 @@ var BottomSheetEngine = class {
|
|
|
2182
2645
|
} else {
|
|
2183
2646
|
await this.animation.animateTo(target.size, velocityPxPerMs);
|
|
2184
2647
|
}
|
|
2648
|
+
this.opening = false;
|
|
2185
2649
|
externalSignal?.removeEventListener("abort", onExternalAbort);
|
|
2186
2650
|
if (signal.aborted) return;
|
|
2187
2651
|
this.scrollCache.restore(id, previousSize, target.size);
|
|
2188
2652
|
this.updateAriaSlider();
|
|
2189
|
-
this.emit("snap", {
|
|
2653
|
+
this.emit("snap", {
|
|
2654
|
+
id,
|
|
2655
|
+
size: target.size,
|
|
2656
|
+
progress: this.computeProgress(target.size)
|
|
2657
|
+
});
|
|
2190
2658
|
if (wasClosed && target.size > 0) {
|
|
2191
2659
|
this.emit("open", { id });
|
|
2192
2660
|
this.handleOpen();
|
|
2193
2661
|
notifyLinkedSheets(this.linkedSheets, this);
|
|
2662
|
+
this.emit("opened", { id });
|
|
2194
2663
|
}
|
|
2195
2664
|
if (target.size === 0) {
|
|
2196
2665
|
this.emit("close", void 0);
|
|
2197
2666
|
this.handleClose();
|
|
2667
|
+
this.emit("closed", void 0);
|
|
2198
2668
|
}
|
|
2199
2669
|
}
|
|
2200
2670
|
async dragTo(targetSize, velocityOrOpts = 0) {
|
|
@@ -2219,18 +2689,76 @@ var BottomSheetEngine = class {
|
|
|
2219
2689
|
const target = id ?? this.snaps.getAllowedIds().find((a) => a !== "closed") ?? this.activeId;
|
|
2220
2690
|
return this.snapTo(target);
|
|
2221
2691
|
}
|
|
2222
|
-
close() {
|
|
2692
|
+
close(reason = "programmatic") {
|
|
2223
2693
|
if (this.destroyed) return Promise.resolve();
|
|
2694
|
+
if (this.disableCloseFlag) return Promise.resolve();
|
|
2695
|
+
if (this.size > 0 && this.emitBeforeClose(reason)) return Promise.resolve();
|
|
2224
2696
|
const closedId = this.snapPointsRaw.find((p) => p.id === "closed")?.id ?? this.snaps.getAllowedIds()[0];
|
|
2225
2697
|
return this.snapTo(closedId ?? this.activeId);
|
|
2226
2698
|
}
|
|
2227
|
-
|
|
2699
|
+
canDismiss() {
|
|
2700
|
+
return !this.persistent && !this.disableCloseFlag && !this.destroyed;
|
|
2701
|
+
}
|
|
2702
|
+
isTop() {
|
|
2703
|
+
return this.isTopSheet;
|
|
2704
|
+
}
|
|
2705
|
+
depth() {
|
|
2706
|
+
return sheetStack.depthOf(this.id);
|
|
2707
|
+
}
|
|
2708
|
+
expand() {
|
|
2709
|
+
if (this.destroyed) return Promise.resolve();
|
|
2710
|
+
const ids = this.allowedIdsBySize();
|
|
2711
|
+
const target = ids[ids.length - 1];
|
|
2712
|
+
if (!target) return Promise.resolve();
|
|
2713
|
+
return this.snapTo(target);
|
|
2714
|
+
}
|
|
2715
|
+
collapse() {
|
|
2716
|
+
if (this.destroyed) return Promise.resolve();
|
|
2717
|
+
const ids = this.allowedIdsBySize();
|
|
2718
|
+
const nonZero = ids.find((id) => (this.snaps.findById(id)?.size ?? 0) > 0);
|
|
2719
|
+
const target = nonZero ?? ids[0];
|
|
2720
|
+
if (!target) return Promise.resolve();
|
|
2721
|
+
return this.snapTo(target);
|
|
2722
|
+
}
|
|
2723
|
+
setRadius(r) {
|
|
2228
2724
|
if (this.destroyed) return;
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2725
|
+
this.element.style.setProperty(
|
|
2726
|
+
"--bs-radius",
|
|
2727
|
+
typeof r === "number" ? `${r}px` : r
|
|
2728
|
+
);
|
|
2729
|
+
}
|
|
2730
|
+
setMaxHeight(h) {
|
|
2731
|
+
if (this.destroyed) return;
|
|
2732
|
+
const value = typeof h === "number" ? `${h}px` : h;
|
|
2733
|
+
const axis = layoutAxis(this.mode);
|
|
2734
|
+
this.element.style.setProperty(
|
|
2735
|
+
axis === "height" ? "maxHeight" : "maxWidth",
|
|
2736
|
+
value
|
|
2737
|
+
);
|
|
2738
|
+
if (typeof h === "number") {
|
|
2739
|
+
this.maxHeightCap = h;
|
|
2740
|
+
this.clampToMaxHeight();
|
|
2741
|
+
} else if (typeof window !== "undefined") {
|
|
2742
|
+
const probe2 = document.createElement("div");
|
|
2743
|
+
probe2.style.cssText = `position:absolute;visibility:hidden;pointer-events:none;${axis === "height" ? "height" : "width"}:${value};`;
|
|
2744
|
+
document.body.appendChild(probe2);
|
|
2745
|
+
const measured = axis === "height" ? probe2.offsetHeight : probe2.offsetWidth;
|
|
2746
|
+
probe2.remove();
|
|
2747
|
+
this.maxHeightCap = measured > 0 ? measured : void 0;
|
|
2748
|
+
this.clampToMaxHeight();
|
|
2749
|
+
}
|
|
2750
|
+
}
|
|
2751
|
+
clampToMaxHeight() {
|
|
2752
|
+
if (this.maxHeightCap === void 0) return;
|
|
2753
|
+
if (this.snaps.getMaxAxisSize() > this.maxHeightCap) {
|
|
2754
|
+
this.snaps.setMaxAxisSize(this.maxHeightCap);
|
|
2755
|
+
}
|
|
2756
|
+
if (this.size > this.maxHeightCap && !this.gesture?.isDragging) {
|
|
2757
|
+
this.applySize(this.maxHeightCap);
|
|
2233
2758
|
}
|
|
2759
|
+
}
|
|
2760
|
+
setAllowed(ids, snap) {
|
|
2761
|
+
if (this.destroyed) return;
|
|
2234
2762
|
this.snaps.setAllowedIds(ids);
|
|
2235
2763
|
this.updateAriaSlider();
|
|
2236
2764
|
if (snap && ids.includes(snap)) {
|
|
@@ -2270,6 +2798,79 @@ var BottomSheetEngine = class {
|
|
|
2270
2798
|
setScrimOverlay(opts) {
|
|
2271
2799
|
return this.scrim.setScrimOverlay(opts);
|
|
2272
2800
|
}
|
|
2801
|
+
addAnchor(opts) {
|
|
2802
|
+
if (this.destroyed || typeof document === "undefined") return () => {
|
|
2803
|
+
};
|
|
2804
|
+
if (!this.anchorHost) {
|
|
2805
|
+
this.anchorHost = this.rootEl ?? this.element.parentElement ?? document.body;
|
|
2806
|
+
this.anchorHost.style.setProperty("--bs-size", `${this.size}px`);
|
|
2807
|
+
this.anchorHost.style.setProperty(
|
|
2808
|
+
"--bs-progress",
|
|
2809
|
+
String(this.computeProgress(this.size))
|
|
2810
|
+
);
|
|
2811
|
+
}
|
|
2812
|
+
const handle = attachAnchor(
|
|
2813
|
+
{
|
|
2814
|
+
mode: this.mode,
|
|
2815
|
+
host: this.anchorHost,
|
|
2816
|
+
getState: () => ({
|
|
2817
|
+
activeId: this.activeId,
|
|
2818
|
+
size: this.size,
|
|
2819
|
+
progress: this.computeProgress(this.size)
|
|
2820
|
+
}),
|
|
2821
|
+
on: (event, fn) => this.on(event, fn),
|
|
2822
|
+
isDestroyed: () => this.destroyed
|
|
2823
|
+
},
|
|
2824
|
+
opts
|
|
2825
|
+
);
|
|
2826
|
+
handle.syncZ(this.stackZ + 1);
|
|
2827
|
+
this.anchors.push(handle);
|
|
2828
|
+
const detach = () => {
|
|
2829
|
+
const idx = this.anchors.indexOf(handle);
|
|
2830
|
+
if (idx === -1) return;
|
|
2831
|
+
this.anchors.splice(idx, 1);
|
|
2832
|
+
handle.detach();
|
|
2833
|
+
};
|
|
2834
|
+
this.teardowns.add(detach);
|
|
2835
|
+
return detach;
|
|
2836
|
+
}
|
|
2837
|
+
setScrimStages(opts) {
|
|
2838
|
+
if (this.destroyed || typeof document === "undefined") return () => {
|
|
2839
|
+
};
|
|
2840
|
+
this.detachScrimStages?.();
|
|
2841
|
+
this.detachScrimStages = null;
|
|
2842
|
+
if (!opts) return () => {
|
|
2843
|
+
};
|
|
2844
|
+
const host = this.screenComponent?.parentElement;
|
|
2845
|
+
if (!host) {
|
|
2846
|
+
console.warn(
|
|
2847
|
+
"[BottomSheet] setScrimStages: no scrim element mounted \u2014 pass `scrim` to the engine first."
|
|
2848
|
+
);
|
|
2849
|
+
return () => {
|
|
2850
|
+
};
|
|
2851
|
+
}
|
|
2852
|
+
const detachInstalled = installScrimStages(
|
|
2853
|
+
{
|
|
2854
|
+
mode: this.mode,
|
|
2855
|
+
host,
|
|
2856
|
+
getState: () => ({
|
|
2857
|
+
activeId: this.activeId,
|
|
2858
|
+
size: this.size,
|
|
2859
|
+
progress: this.computeProgress(this.size)
|
|
2860
|
+
}),
|
|
2861
|
+
on: (event, fn) => this.on(event, fn),
|
|
2862
|
+
isDestroyed: () => this.destroyed
|
|
2863
|
+
},
|
|
2864
|
+
opts
|
|
2865
|
+
);
|
|
2866
|
+
const detach = () => {
|
|
2867
|
+
if (this.detachScrimStages === detach) this.detachScrimStages = null;
|
|
2868
|
+
detachInstalled();
|
|
2869
|
+
};
|
|
2870
|
+
this.detachScrimStages = detach;
|
|
2871
|
+
this.teardowns.add(() => this.detachScrimStages?.());
|
|
2872
|
+
return detach;
|
|
2873
|
+
}
|
|
2273
2874
|
getScrimState() {
|
|
2274
2875
|
return { mode: this.scrim.scrimMode, enabled: this.scrim.scrimEnabled };
|
|
2275
2876
|
}
|
|
@@ -2289,8 +2890,53 @@ var BottomSheetEngine = class {
|
|
|
2289
2890
|
}
|
|
2290
2891
|
this.updateAriaSlider();
|
|
2291
2892
|
}
|
|
2893
|
+
recompute() {
|
|
2894
|
+
if (this.destroyed) return;
|
|
2895
|
+
this.snaps.recompute();
|
|
2896
|
+
this.scrim.invalidateOpacityCache();
|
|
2897
|
+
if (this.gesture?.isDragging) return;
|
|
2898
|
+
const current = this.snaps.findById(this.activeId);
|
|
2899
|
+
if (current) {
|
|
2900
|
+
this.size = current.size;
|
|
2901
|
+
this.applySize(this.size);
|
|
2902
|
+
this.updateAriaSlider();
|
|
2903
|
+
}
|
|
2904
|
+
}
|
|
2905
|
+
measureFitSize() {
|
|
2906
|
+
const vertical = layoutAxis(this.mode) === "height";
|
|
2907
|
+
const handleSize = vertical ? this.handle.offsetHeight : this.handle.offsetWidth;
|
|
2908
|
+
const content = this.scrollContainer;
|
|
2909
|
+
const natural = content ? handleSize + (vertical ? content.scrollHeight : content.scrollWidth) : handleSize;
|
|
2910
|
+
if (typeof window === "undefined") return natural;
|
|
2911
|
+
const viewport = vertical ? window.innerHeight : window.innerWidth;
|
|
2912
|
+
return viewport > 0 ? Math.min(natural, viewport) : natural;
|
|
2913
|
+
}
|
|
2914
|
+
installFitObserver() {
|
|
2915
|
+
if (typeof ResizeObserver === "undefined") return;
|
|
2916
|
+
if (!this.snapPointsRaw.some((p) => p.size === "fit" || p.size === "content"))
|
|
2917
|
+
return;
|
|
2918
|
+
const targets = [this.handle];
|
|
2919
|
+
if (this.scrollContainer && this.scrollContainer !== this.handle) {
|
|
2920
|
+
targets.push(this.scrollContainer);
|
|
2921
|
+
}
|
|
2922
|
+
let raf = 0;
|
|
2923
|
+
const ro = new ResizeObserver(() => {
|
|
2924
|
+
if (raf) return;
|
|
2925
|
+
raf = requestAnimationFrame(() => {
|
|
2926
|
+
raf = 0;
|
|
2927
|
+
if (this.destroyed || this.gesture?.isDragging) return;
|
|
2928
|
+
this.recompute();
|
|
2929
|
+
});
|
|
2930
|
+
});
|
|
2931
|
+
for (const t of targets) ro.observe(t);
|
|
2932
|
+
this.teardowns.add(() => {
|
|
2933
|
+
ro.disconnect();
|
|
2934
|
+
if (raf) cancelAnimationFrame(raf);
|
|
2935
|
+
});
|
|
2936
|
+
}
|
|
2292
2937
|
destroy() {
|
|
2293
2938
|
this.destroyed = true;
|
|
2939
|
+
this.opening = false;
|
|
2294
2940
|
this.currentAbort.abort();
|
|
2295
2941
|
this.currentViewTransition?.skipTransition?.();
|
|
2296
2942
|
this.currentViewTransition = null;
|
|
@@ -2340,6 +2986,36 @@ var BottomSheetEngine = class {
|
|
|
2340
2986
|
frozen = true;
|
|
2341
2987
|
return cancelled;
|
|
2342
2988
|
}
|
|
2989
|
+
emitBeforeClose(reason) {
|
|
2990
|
+
let cancelled = false;
|
|
2991
|
+
let frozen = false;
|
|
2992
|
+
this.emit("before-close", {
|
|
2993
|
+
reason,
|
|
2994
|
+
cancel: () => {
|
|
2995
|
+
if (frozen) {
|
|
2996
|
+
console.warn(
|
|
2997
|
+
"[BottomSheet] before-close.cancel() called asynchronously \u2014 ignored. cancel() must be invoked synchronously inside the listener."
|
|
2998
|
+
);
|
|
2999
|
+
return;
|
|
3000
|
+
}
|
|
3001
|
+
cancelled = true;
|
|
3002
|
+
}
|
|
3003
|
+
});
|
|
3004
|
+
frozen = true;
|
|
3005
|
+
return cancelled;
|
|
3006
|
+
}
|
|
3007
|
+
applyAutoAriaLabelledBy() {
|
|
3008
|
+
if (typeof document === "undefined") return;
|
|
3009
|
+
if (!this.lifecycle.focusTrapEnabled) return;
|
|
3010
|
+
if (this.element.getAttribute("aria-labelledby")) return;
|
|
3011
|
+
const scope = this.handle ?? this.element;
|
|
3012
|
+
const titled = scope.querySelector("[data-bs-title]") ?? scope.querySelector("h1,h2,h3,h4,h5,h6");
|
|
3013
|
+
if (!titled) return;
|
|
3014
|
+
if (!titled.id) {
|
|
3015
|
+
titled.id = nextInstanceId("bs-title");
|
|
3016
|
+
}
|
|
3017
|
+
this.element.setAttribute("aria-labelledby", titled.id);
|
|
3018
|
+
}
|
|
2343
3019
|
recomputeSnaps() {
|
|
2344
3020
|
const seen = /* @__PURE__ */ new Set();
|
|
2345
3021
|
for (const p of this.snapPointsRaw) {
|
|
@@ -2356,24 +3032,42 @@ var BottomSheetEngine = class {
|
|
|
2356
3032
|
getAllowedRange() {
|
|
2357
3033
|
return this.snaps.getAllowedRange();
|
|
2358
3034
|
}
|
|
3035
|
+
allowedIdsBySize() {
|
|
3036
|
+
return this.snaps.getAllowedIds().slice().sort(
|
|
3037
|
+
(a, b) => (this.snaps.findById(a)?.size ?? 0) - (this.snaps.findById(b)?.size ?? 0)
|
|
3038
|
+
);
|
|
3039
|
+
}
|
|
2359
3040
|
updateAriaSlider() {
|
|
2360
|
-
this.aria.setValue(this.
|
|
3041
|
+
this.aria.setValue(this.allowedIdsBySize(), this.activeId);
|
|
2361
3042
|
}
|
|
2362
3043
|
registerInStack() {
|
|
2363
3044
|
this.teardowns.add(sheetStack.push({
|
|
2364
3045
|
id: this.id,
|
|
2365
3046
|
setZIndex: (z) => {
|
|
3047
|
+
this.stackZ = z;
|
|
2366
3048
|
this.element.style.zIndex = String(z);
|
|
2367
3049
|
if (this.backdrop) this.backdrop.style.zIndex = String(z - 1);
|
|
3050
|
+
for (const anchor of this.anchors) anchor.syncZ(z + 1);
|
|
2368
3051
|
},
|
|
2369
3052
|
setIsTop: (isTop) => {
|
|
2370
3053
|
this.isTopSheet = isTop;
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
}
|
|
3054
|
+
},
|
|
3055
|
+
isOpen: () => this.size > 0 || this.opening,
|
|
3056
|
+
setDepth: (depth) => this.applyStackDepth(depth)
|
|
2375
3057
|
}));
|
|
2376
3058
|
}
|
|
3059
|
+
applyStackDepth(depth) {
|
|
3060
|
+
if (!this.stackEffectEnabled) return;
|
|
3061
|
+
this.element.setAttribute("data-stack-depth", String(depth));
|
|
3062
|
+
if (!this.stackEffectPrimed) {
|
|
3063
|
+
this.stackEffectPrimed = true;
|
|
3064
|
+
const isVertical = this.mode === "bottom" || this.mode === "top";
|
|
3065
|
+
this.element.style.transformOrigin = isVertical ? "50% 100%" : "0% 50%";
|
|
3066
|
+
this.element.style.transition = "scale 320ms cubic-bezier(0.29, 1.04, 0.84, 0.99)";
|
|
3067
|
+
}
|
|
3068
|
+
const scale = Math.max(1 - depth * 0.04, 0.86);
|
|
3069
|
+
this.element.style.scale = scale === 1 ? "" : String(scale);
|
|
3070
|
+
}
|
|
2377
3071
|
attach() {
|
|
2378
3072
|
this.gesture = new GestureController({
|
|
2379
3073
|
handle: this.handle,
|
|
@@ -2390,6 +3084,7 @@ var BottomSheetEngine = class {
|
|
|
2390
3084
|
buf.rubberBandEnabled = this.rubberBandEnabled;
|
|
2391
3085
|
return buf;
|
|
2392
3086
|
},
|
|
3087
|
+
getDisableDrag: () => this.disableDragFlag,
|
|
2393
3088
|
cancelAnimation: () => this.animation.cancel(),
|
|
2394
3089
|
applySize: (size) => this.applySize(size),
|
|
2395
3090
|
animateTo: (size, velocity) => this.animation.animateTo(size, velocity),
|
|
@@ -2433,7 +3128,7 @@ var BottomSheetEngine = class {
|
|
|
2433
3128
|
container: this.scrollContainer,
|
|
2434
3129
|
isDragging: () => this.gesture?.isDragging ?? false,
|
|
2435
3130
|
isAnimating: () => this.animation.isAnimating,
|
|
2436
|
-
getAllowedIds: () => this.
|
|
3131
|
+
getAllowedIds: () => this.allowedIdsBySize(),
|
|
2437
3132
|
getActiveId: () => this.activeId,
|
|
2438
3133
|
snapTo: (id) => {
|
|
2439
3134
|
void this.snapTo(id);
|
|
@@ -2462,13 +3157,16 @@ var BottomSheetEngine = class {
|
|
|
2462
3157
|
},
|
|
2463
3158
|
newCycle: () => {
|
|
2464
3159
|
this.newCycle();
|
|
2465
|
-
}
|
|
3160
|
+
},
|
|
3161
|
+
isAnimating: () => this.animation.isAnimating,
|
|
3162
|
+
resyncAfterCancel: () => this.resyncAfterResize()
|
|
2466
3163
|
}));
|
|
2467
3164
|
if (this.lifecycle.closeOnEscape) {
|
|
2468
3165
|
const onKey = (e) => {
|
|
2469
|
-
if (this.destroyed) return;
|
|
3166
|
+
if (this.destroyed || e.defaultPrevented) return;
|
|
3167
|
+
if (!this.canDismiss()) return;
|
|
2470
3168
|
if (e.key === "Escape" && this.isTopSheet && this.size > 0) {
|
|
2471
|
-
void this.close();
|
|
3169
|
+
void this.close("escape");
|
|
2472
3170
|
}
|
|
2473
3171
|
};
|
|
2474
3172
|
document.addEventListener("keydown", onKey);
|
|
@@ -2498,7 +3196,7 @@ var BottomSheetEngine = class {
|
|
|
2498
3196
|
handle: this.handle,
|
|
2499
3197
|
mode: this.mode,
|
|
2500
3198
|
isDestroyed: () => this.destroyed,
|
|
2501
|
-
getAllowedIds: () => this.
|
|
3199
|
+
getAllowedIds: () => this.allowedIdsBySize(),
|
|
2502
3200
|
getActiveId: () => this.activeId,
|
|
2503
3201
|
snapTo: (id) => {
|
|
2504
3202
|
void this.snapTo(id);
|
|
@@ -2519,6 +3217,7 @@ var BottomSheetEngine = class {
|
|
|
2519
3217
|
});
|
|
2520
3218
|
if (!target) return;
|
|
2521
3219
|
const previousId = this.activeId;
|
|
3220
|
+
if (target.id === previousId && target.size === this.size) return;
|
|
2522
3221
|
if (this.emitBeforeSnap(target, previousId)) {
|
|
2523
3222
|
const restore = this.snaps.findById(previousId);
|
|
2524
3223
|
if (restore) {
|
|
@@ -2527,21 +3226,34 @@ var BottomSheetEngine = class {
|
|
|
2527
3226
|
return;
|
|
2528
3227
|
}
|
|
2529
3228
|
const previousSize = this.size;
|
|
3229
|
+
const previousSnapSize = this.snaps.findById(previousId)?.size;
|
|
2530
3230
|
this.scrollCache.cache(previousId, previousSize, target.size);
|
|
2531
3231
|
this.activeId = target.id;
|
|
3232
|
+
if (previousSnapSize === 0 && target.size > 0) {
|
|
3233
|
+
this.opening = true;
|
|
3234
|
+
sheetStack.promote(this.id);
|
|
3235
|
+
}
|
|
2532
3236
|
void this.animation.animateTo(target.size, velocity).then(() => {
|
|
3237
|
+
this.opening = false;
|
|
2533
3238
|
if (signal.aborted) return;
|
|
2534
3239
|
this.scrollCache.restore(target.id, previousSize, target.size);
|
|
2535
3240
|
this.updateAriaSlider();
|
|
2536
|
-
this.emit("snap", {
|
|
3241
|
+
this.emit("snap", {
|
|
3242
|
+
id: target.id,
|
|
3243
|
+
size: target.size,
|
|
3244
|
+
progress: this.computeProgress(target.size)
|
|
3245
|
+
});
|
|
2537
3246
|
this.haptic();
|
|
2538
|
-
if (
|
|
3247
|
+
if (previousSnapSize === 0 && target.size > 0) {
|
|
2539
3248
|
this.emit("open", { id: target.id });
|
|
2540
3249
|
this.handleOpen();
|
|
3250
|
+
notifyLinkedSheets(this.linkedSheets, this);
|
|
3251
|
+
this.emit("opened", { id: target.id });
|
|
2541
3252
|
}
|
|
2542
3253
|
if (target.size === 0) {
|
|
2543
3254
|
this.emit("close", void 0);
|
|
2544
3255
|
this.handleClose();
|
|
3256
|
+
this.emit("closed", void 0);
|
|
2545
3257
|
}
|
|
2546
3258
|
});
|
|
2547
3259
|
}
|
|
@@ -2563,6 +3275,9 @@ var BottomSheetEngine = class {
|
|
|
2563
3275
|
if (this.scrimParent) {
|
|
2564
3276
|
this.scrimParent.style.setProperty("--bs-size", `${size}px`);
|
|
2565
3277
|
}
|
|
3278
|
+
if (this.anchorHost && this.anchorHost !== this.scrimParent) {
|
|
3279
|
+
this.anchorHost.style.setProperty("--bs-size", `${size}px`);
|
|
3280
|
+
}
|
|
2566
3281
|
}
|
|
2567
3282
|
const progress = this.computeProgress(size);
|
|
2568
3283
|
const progressChanged = this.progressWriteSentinel.shouldWrite(
|
|
@@ -2571,6 +3286,9 @@ var BottomSheetEngine = class {
|
|
|
2571
3286
|
);
|
|
2572
3287
|
if (progressChanged) {
|
|
2573
3288
|
style.setProperty("--bs-progress", String(progress));
|
|
3289
|
+
if (this.anchorHost) {
|
|
3290
|
+
this.anchorHost.style.setProperty("--bs-progress", String(progress));
|
|
3291
|
+
}
|
|
2574
3292
|
}
|
|
2575
3293
|
this.scrim.applyOpacity(progress, progressChanged);
|
|
2576
3294
|
if (progressChanged && this.bus.listenerCount("progress") > 0) {
|
|
@@ -2585,6 +3303,7 @@ var BottomSheetEngine = class {
|
|
|
2585
3303
|
return Math.min(Math.max((size - min) / (max - min), 0), 1);
|
|
2586
3304
|
}
|
|
2587
3305
|
handleOpen() {
|
|
3306
|
+
sheetStack.promote(this.id);
|
|
2588
3307
|
try {
|
|
2589
3308
|
this.lifecycle.install();
|
|
2590
3309
|
} catch (err) {
|
|
@@ -2598,8 +3317,31 @@ var BottomSheetEngine = class {
|
|
|
2598
3317
|
});
|
|
2599
3318
|
}
|
|
2600
3319
|
}
|
|
3320
|
+
resyncAfterResize() {
|
|
3321
|
+
if (this.destroyed) return;
|
|
3322
|
+
const target = this.snaps.findById(this.activeId);
|
|
3323
|
+
if (!target) return;
|
|
3324
|
+
this.updateAriaSlider();
|
|
3325
|
+
this.emit("snap", {
|
|
3326
|
+
id: target.id,
|
|
3327
|
+
size: target.size,
|
|
3328
|
+
progress: this.computeProgress(target.size)
|
|
3329
|
+
});
|
|
3330
|
+
if (target.size > 0 && !this.lifecycle.isInstalled) {
|
|
3331
|
+
this.emit("open", { id: target.id });
|
|
3332
|
+
this.handleOpen();
|
|
3333
|
+
notifyLinkedSheets(this.linkedSheets, this);
|
|
3334
|
+
this.emit("opened", { id: target.id });
|
|
3335
|
+
} else if (target.size === 0 && this.lifecycle.isInstalled) {
|
|
3336
|
+
this.emit("close", void 0);
|
|
3337
|
+
this.handleClose();
|
|
3338
|
+
this.emit("closed", void 0);
|
|
3339
|
+
}
|
|
3340
|
+
}
|
|
2601
3341
|
handleClose() {
|
|
3342
|
+
this.opening = false;
|
|
2602
3343
|
this.lifecycle.release();
|
|
3344
|
+
sheetStack.update();
|
|
2603
3345
|
}
|
|
2604
3346
|
};
|
|
2605
3347
|
|
|
@@ -2708,6 +3450,10 @@ var OverlayEngine = class {
|
|
|
2708
3450
|
__publicField(this, "closeOnOutsidePointerEnabled");
|
|
2709
3451
|
__publicField(this, "detachOutsidePointer", null);
|
|
2710
3452
|
__publicField(this, "detachSwipe", null);
|
|
3453
|
+
__publicField(this, "respectReducedMotionEnabled");
|
|
3454
|
+
__publicField(this, "isTop", true);
|
|
3455
|
+
__publicField(this, "backPushed", false);
|
|
3456
|
+
__publicField(this, "movedToTarget", false);
|
|
2711
3457
|
__publicField(this, "onOpenCb");
|
|
2712
3458
|
__publicField(this, "onCloseCb");
|
|
2713
3459
|
__publicField(this, "isOpen_", false);
|
|
@@ -2744,6 +3490,7 @@ var OverlayEngine = class {
|
|
|
2744
3490
|
this.mountTarget = opts.mountTo;
|
|
2745
3491
|
this.peekRaw = opts.peek;
|
|
2746
3492
|
this.closeOnOutsidePointerEnabled = opts.closeOnOutsidePointer ?? false;
|
|
3493
|
+
this.respectReducedMotionEnabled = opts.respectReducedMotion ?? true;
|
|
2747
3494
|
this.onOpenCb = opts.onOpen;
|
|
2748
3495
|
this.onCloseCb = opts.onClose;
|
|
2749
3496
|
if (this.peekRaw !== void 0 && this.edge !== "bottom") {
|
|
@@ -2791,15 +3538,17 @@ var OverlayEngine = class {
|
|
|
2791
3538
|
this.emit("before-open", void 0);
|
|
2792
3539
|
this.isOpen_ = true;
|
|
2793
3540
|
this.isAnimating_ = true;
|
|
3541
|
+
sheetStack.promote(this.id);
|
|
2794
3542
|
this.element.removeAttribute("hidden");
|
|
2795
3543
|
this.element.setAttribute("data-state", "entering");
|
|
2796
3544
|
if (this.focusTrapEnabled) {
|
|
2797
3545
|
this.element.setAttribute("aria-modal", "true");
|
|
2798
3546
|
}
|
|
2799
|
-
const
|
|
3547
|
+
const dur = this.effectiveDuration();
|
|
3548
|
+
const transitionStr = `transform ${dur}ms ${this.enterEasing}, opacity ${dur}ms ease-out`;
|
|
2800
3549
|
this.element.style.transition = transitionStr;
|
|
2801
3550
|
if (this.backdrop) {
|
|
2802
|
-
this.backdrop.style.transition = `opacity ${
|
|
3551
|
+
this.backdrop.style.transition = `opacity ${dur}ms ease-out`;
|
|
2803
3552
|
}
|
|
2804
3553
|
const cycle = ++this.cycleNonce;
|
|
2805
3554
|
return new Promise((resolve) => {
|
|
@@ -2811,7 +3560,7 @@ var OverlayEngine = class {
|
|
|
2811
3560
|
this.element.style.opacity = "1";
|
|
2812
3561
|
if (this.backdrop) {
|
|
2813
3562
|
this.backdrop.style.opacity = String(this.backdropOpacity);
|
|
2814
|
-
this.backdrop.style.pointerEvents = "auto";
|
|
3563
|
+
this.backdrop.style.pointerEvents = this.backdropOpacity > 0 ? "auto" : "none";
|
|
2815
3564
|
if (this.backdropFilter) {
|
|
2816
3565
|
this.backdrop.style.backdropFilter = this.backdropFilter;
|
|
2817
3566
|
this.backdrop.style.webkitBackdropFilter = this.backdropFilter;
|
|
@@ -2847,7 +3596,10 @@ var OverlayEngine = class {
|
|
|
2847
3596
|
});
|
|
2848
3597
|
return resolve();
|
|
2849
3598
|
}
|
|
2850
|
-
this.awaitTransition(
|
|
3599
|
+
this.awaitTransition(
|
|
3600
|
+
cycle,
|
|
3601
|
+
this.enterAnimation === "fade" ? "opacity" : "transform"
|
|
3602
|
+
).then(() => {
|
|
2851
3603
|
if (this.destroyed || cycle !== this.cycleNonce) return resolve();
|
|
2852
3604
|
this.isAnimating_ = false;
|
|
2853
3605
|
this.element.setAttribute("data-state", "open");
|
|
@@ -2864,11 +3616,14 @@ var OverlayEngine = class {
|
|
|
2864
3616
|
this.emit("before-close", void 0);
|
|
2865
3617
|
this.isOpen_ = false;
|
|
2866
3618
|
this.isAnimating_ = true;
|
|
3619
|
+
sheetStack.update();
|
|
3620
|
+
this.popBackMarker(reason);
|
|
2867
3621
|
this.element.setAttribute("data-state", "exiting");
|
|
2868
|
-
const
|
|
3622
|
+
const dur = this.effectiveDuration();
|
|
3623
|
+
const transitionStr = `transform ${dur}ms ${this.exitEasing}, opacity ${dur}ms ease-in`;
|
|
2869
3624
|
this.element.style.transition = transitionStr;
|
|
2870
3625
|
if (this.backdrop) {
|
|
2871
|
-
this.backdrop.style.transition = `opacity ${
|
|
3626
|
+
this.backdrop.style.transition = `opacity ${dur}ms ease-in`;
|
|
2872
3627
|
}
|
|
2873
3628
|
const cycle = ++this.cycleNonce;
|
|
2874
3629
|
return new Promise((resolve) => {
|
|
@@ -2879,7 +3634,7 @@ var OverlayEngine = class {
|
|
|
2879
3634
|
this.exitAnimation,
|
|
2880
3635
|
this.peekPx
|
|
2881
3636
|
);
|
|
2882
|
-
this.element.style.opacity = "0";
|
|
3637
|
+
this.element.style.opacity = this.peekPx !== void 0 ? "1" : "0";
|
|
2883
3638
|
if (this.backdrop) {
|
|
2884
3639
|
this.backdrop.style.opacity = "0";
|
|
2885
3640
|
this.backdrop.style.pointerEvents = "none";
|
|
@@ -2889,7 +3644,10 @@ var OverlayEngine = class {
|
|
|
2889
3644
|
}
|
|
2890
3645
|
}
|
|
2891
3646
|
this.releaseInteractiveListeners();
|
|
2892
|
-
this.awaitTransition(
|
|
3647
|
+
this.awaitTransition(
|
|
3648
|
+
cycle,
|
|
3649
|
+
this.exitAnimation === "fade" ? "opacity" : "transform"
|
|
3650
|
+
).then(() => {
|
|
2893
3651
|
if (this.destroyed || cycle !== this.cycleNonce) return resolve();
|
|
2894
3652
|
this.isAnimating_ = false;
|
|
2895
3653
|
if (this.peekPx === void 0) {
|
|
@@ -2917,7 +3675,11 @@ var OverlayEngine = class {
|
|
|
2917
3675
|
this.releaseInteractiveListeners();
|
|
2918
3676
|
this.releaseStackEntry?.();
|
|
2919
3677
|
this.releaseStackEntry = null;
|
|
3678
|
+
const hadOriginalParent = this.originalParent !== null;
|
|
2920
3679
|
this.restoreMount();
|
|
3680
|
+
if (this.movedToTarget && !hadOriginalParent && this.element.parentNode) {
|
|
3681
|
+
this.element.parentNode.removeChild(this.element);
|
|
3682
|
+
}
|
|
2921
3683
|
}
|
|
2922
3684
|
setBackdropOpacity(opacity) {
|
|
2923
3685
|
if (this.destroyed) return;
|
|
@@ -3018,6 +3780,36 @@ var OverlayEngine = class {
|
|
|
3018
3780
|
}
|
|
3019
3781
|
}
|
|
3020
3782
|
}
|
|
3783
|
+
if (opts.duration !== void 0) this.duration = opts.duration;
|
|
3784
|
+
if (opts.enterEasing !== void 0) this.enterEasing = opts.enterEasing;
|
|
3785
|
+
if (opts.exitEasing !== void 0) this.exitEasing = opts.exitEasing;
|
|
3786
|
+
if (opts.closeOnEscape !== void 0) {
|
|
3787
|
+
this.closeOnEscape = opts.closeOnEscape;
|
|
3788
|
+
if (!opts.closeOnEscape) {
|
|
3789
|
+
this.detachEscape?.();
|
|
3790
|
+
this.detachEscape = null;
|
|
3791
|
+
} else if (this.isOpen_) {
|
|
3792
|
+
this.installInteractiveListeners();
|
|
3793
|
+
}
|
|
3794
|
+
}
|
|
3795
|
+
if (opts.closeOnBackdrop !== void 0) {
|
|
3796
|
+
this.closeOnBackdropEnabled = opts.closeOnBackdrop;
|
|
3797
|
+
if (!opts.closeOnBackdrop) {
|
|
3798
|
+
this.detachBackdrop?.();
|
|
3799
|
+
this.detachBackdrop = null;
|
|
3800
|
+
} else if (this.isOpen_) {
|
|
3801
|
+
this.installInteractiveListeners();
|
|
3802
|
+
}
|
|
3803
|
+
}
|
|
3804
|
+
if (opts.closeOnOutsidePointer !== void 0) {
|
|
3805
|
+
this.closeOnOutsidePointerEnabled = opts.closeOnOutsidePointer;
|
|
3806
|
+
if (!opts.closeOnOutsidePointer) {
|
|
3807
|
+
this.detachOutsidePointer?.();
|
|
3808
|
+
this.detachOutsidePointer = null;
|
|
3809
|
+
} else if (this.isOpen_) {
|
|
3810
|
+
this.installInteractiveListeners();
|
|
3811
|
+
}
|
|
3812
|
+
}
|
|
3021
3813
|
if (opts.children !== void 0) {
|
|
3022
3814
|
if (opts.children === null) {
|
|
3023
3815
|
this.clearOverlayChildren();
|
|
@@ -3051,6 +3843,22 @@ var OverlayEngine = class {
|
|
|
3051
3843
|
emit(event, payload) {
|
|
3052
3844
|
this.bus.emit(event, payload);
|
|
3053
3845
|
}
|
|
3846
|
+
effectiveDuration() {
|
|
3847
|
+
return this.respectReducedMotionEnabled && prefersReducedMotion() ? 0 : this.duration;
|
|
3848
|
+
}
|
|
3849
|
+
popBackMarker(reason) {
|
|
3850
|
+
if (!this.backPushed) return;
|
|
3851
|
+
this.backPushed = false;
|
|
3852
|
+
if (reason === "back") return;
|
|
3853
|
+
const state = history.state;
|
|
3854
|
+
if (state && state.__bsOverlay === this.id) {
|
|
3855
|
+
try {
|
|
3856
|
+
history.back();
|
|
3857
|
+
} catch {
|
|
3858
|
+
return;
|
|
3859
|
+
}
|
|
3860
|
+
}
|
|
3861
|
+
}
|
|
3054
3862
|
resolvePeekPx(raw) {
|
|
3055
3863
|
if (typeof raw === "number") return Math.max(0, raw);
|
|
3056
3864
|
try {
|
|
@@ -3072,6 +3880,7 @@ var OverlayEngine = class {
|
|
|
3072
3880
|
this.originalParent = this.element.parentNode;
|
|
3073
3881
|
this.originalNextSibling = this.element.nextSibling;
|
|
3074
3882
|
target.appendChild(this.element);
|
|
3883
|
+
this.movedToTarget = true;
|
|
3075
3884
|
this.mounted = true;
|
|
3076
3885
|
}
|
|
3077
3886
|
restoreMount() {
|
|
@@ -3105,7 +3914,7 @@ var OverlayEngine = class {
|
|
|
3105
3914
|
this.backdrop.style.willChange = "opacity";
|
|
3106
3915
|
}
|
|
3107
3916
|
}
|
|
3108
|
-
awaitTransition(cycle) {
|
|
3917
|
+
awaitTransition(cycle, property = "transform") {
|
|
3109
3918
|
return new Promise((resolve) => {
|
|
3110
3919
|
let done = false;
|
|
3111
3920
|
const finish = () => {
|
|
@@ -3120,10 +3929,10 @@ var OverlayEngine = class {
|
|
|
3120
3929
|
finish();
|
|
3121
3930
|
return;
|
|
3122
3931
|
}
|
|
3123
|
-
if (e.propertyName ===
|
|
3932
|
+
if (e.target === this.element && e.propertyName === property) finish();
|
|
3124
3933
|
};
|
|
3125
3934
|
this.element.addEventListener("transitionend", onEnd);
|
|
3126
|
-
const timer = window.setTimeout(finish, this.
|
|
3935
|
+
const timer = window.setTimeout(finish, this.effectiveDuration() + 50);
|
|
3127
3936
|
});
|
|
3128
3937
|
}
|
|
3129
3938
|
installInteractiveListeners() {
|
|
@@ -3133,7 +3942,10 @@ var OverlayEngine = class {
|
|
|
3133
3942
|
}
|
|
3134
3943
|
if (this.closeOnEscape && !this.detachEscape) {
|
|
3135
3944
|
const handler = (e) => {
|
|
3136
|
-
if (e.
|
|
3945
|
+
if (e.defaultPrevented) return;
|
|
3946
|
+
if (e.key === "Escape" && this.isOpen_ && this.isTop) {
|
|
3947
|
+
void this.close("escape");
|
|
3948
|
+
}
|
|
3137
3949
|
};
|
|
3138
3950
|
document.addEventListener("keydown", handler);
|
|
3139
3951
|
this.detachEscape = () => document.removeEventListener("keydown", handler);
|
|
@@ -3146,10 +3958,14 @@ var OverlayEngine = class {
|
|
|
3146
3958
|
if (this.closeOnBackEnabled && typeof window !== "undefined" && !this.detachHardwareBack) {
|
|
3147
3959
|
try {
|
|
3148
3960
|
history.pushState({ __bsOverlay: this.id }, "");
|
|
3961
|
+
this.backPushed = true;
|
|
3149
3962
|
} catch {
|
|
3150
3963
|
}
|
|
3151
3964
|
const onPop = () => {
|
|
3152
|
-
if (this.isOpen_
|
|
3965
|
+
if (this.isOpen_ && this.isTop) {
|
|
3966
|
+
this.backPushed = false;
|
|
3967
|
+
void this.close("back");
|
|
3968
|
+
}
|
|
3153
3969
|
};
|
|
3154
3970
|
window.addEventListener("popstate", onPop);
|
|
3155
3971
|
this.detachHardwareBack = () => window.removeEventListener("popstate", onPop);
|
|
@@ -3185,43 +4001,52 @@ var OverlayEngine = class {
|
|
|
3185
4001
|
const edge = this.edge;
|
|
3186
4002
|
const isVertical = edge === "bottom" || edge === "top";
|
|
3187
4003
|
const sign = edge === "bottom" || edge === "right" ? 1 : -1;
|
|
3188
|
-
const
|
|
3189
|
-
const velocityThreshold = this.swipeVelocityThreshold;
|
|
4004
|
+
const SLOP = 8;
|
|
3190
4005
|
let startX = 0;
|
|
3191
4006
|
let startY = 0;
|
|
3192
4007
|
let startT = 0;
|
|
4008
|
+
let tracking = false;
|
|
3193
4009
|
let dragging = false;
|
|
3194
4010
|
let pointerId = null;
|
|
4011
|
+
const previousTouchAction = el.style.touchAction;
|
|
4012
|
+
el.style.touchAction = isVertical ? "pan-x" : "pan-y";
|
|
3195
4013
|
const onDown = (e) => {
|
|
3196
4014
|
if (e.button !== void 0 && e.button !== 0) return;
|
|
3197
4015
|
pointerId = e.pointerId;
|
|
3198
4016
|
startX = e.clientX;
|
|
3199
4017
|
startY = e.clientY;
|
|
3200
4018
|
startT = performance.now();
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
try {
|
|
3204
|
-
el.setPointerCapture(e.pointerId);
|
|
3205
|
-
} catch {
|
|
3206
|
-
}
|
|
4019
|
+
tracking = true;
|
|
4020
|
+
dragging = false;
|
|
3207
4021
|
};
|
|
3208
4022
|
const onMove = (e) => {
|
|
3209
|
-
if (!
|
|
4023
|
+
if (!tracking || e.pointerId !== pointerId) return;
|
|
3210
4024
|
const delta = isVertical ? e.clientY - startY : e.clientX - startX;
|
|
4025
|
+
if (!dragging) {
|
|
4026
|
+
if (Math.abs(delta) < SLOP) return;
|
|
4027
|
+
dragging = true;
|
|
4028
|
+
el.style.transition = "none";
|
|
4029
|
+
try {
|
|
4030
|
+
el.setPointerCapture(e.pointerId);
|
|
4031
|
+
} catch {
|
|
4032
|
+
}
|
|
4033
|
+
}
|
|
3211
4034
|
const offset = Math.max(0, sign * delta);
|
|
3212
4035
|
el.style.transform = isVertical ? `translate3d(0, ${sign * offset}px, 0)` : `translate3d(${sign * offset}px, 0, 0)`;
|
|
3213
4036
|
};
|
|
3214
4037
|
const finish = (e) => {
|
|
3215
|
-
if (!
|
|
3216
|
-
|
|
4038
|
+
if (!tracking || e.pointerId !== pointerId) return;
|
|
4039
|
+
tracking = false;
|
|
3217
4040
|
pointerId = null;
|
|
4041
|
+
if (!dragging) return;
|
|
4042
|
+
dragging = false;
|
|
3218
4043
|
const dt = performance.now() - startT || 1;
|
|
3219
4044
|
const delta = isVertical ? e.clientY - startY : e.clientX - startX;
|
|
3220
4045
|
const offset = Math.max(0, sign * delta);
|
|
3221
4046
|
const velocity = sign * delta / dt;
|
|
3222
4047
|
const size = isVertical ? el.offsetHeight : el.offsetWidth;
|
|
3223
|
-
const past = offset > size *
|
|
3224
|
-
el.style.transition = `transform ${this.
|
|
4048
|
+
const past = offset > size * this.swipeThreshold || velocity > this.swipeVelocityThreshold;
|
|
4049
|
+
el.style.transition = `transform ${this.effectiveDuration()}ms ${this.exitEasing}`;
|
|
3225
4050
|
if (past) {
|
|
3226
4051
|
void this.close("swipe");
|
|
3227
4052
|
} else {
|
|
@@ -3233,6 +4058,7 @@ var OverlayEngine = class {
|
|
|
3233
4058
|
el.addEventListener("pointerup", finish);
|
|
3234
4059
|
el.addEventListener("pointercancel", finish);
|
|
3235
4060
|
return () => {
|
|
4061
|
+
el.style.touchAction = previousTouchAction;
|
|
3236
4062
|
el.removeEventListener("pointerdown", onDown);
|
|
3237
4063
|
el.removeEventListener("pointermove", onMove);
|
|
3238
4064
|
el.removeEventListener("pointerup", finish);
|
|
@@ -3247,10 +4073,12 @@ var OverlayEngine = class {
|
|
|
3247
4073
|
if (this.backdrop) this.backdrop.style.zIndex = String(z - 1);
|
|
3248
4074
|
},
|
|
3249
4075
|
setIsTop: (isTop) => {
|
|
4076
|
+
this.isTop = isTop;
|
|
3250
4077
|
if (this.backdrop) {
|
|
3251
4078
|
this.backdrop.style.display = isTop ? "" : "none";
|
|
3252
4079
|
}
|
|
3253
|
-
}
|
|
4080
|
+
},
|
|
4081
|
+
isOpen: () => this.isOpen_
|
|
3254
4082
|
});
|
|
3255
4083
|
}
|
|
3256
4084
|
};
|
|
@@ -3263,6 +4091,7 @@ exports.Overlay = OverlayEngine;
|
|
|
3263
4091
|
exports.OverlayEngine = OverlayEngine;
|
|
3264
4092
|
exports.SCRIM_PRESETS = SCRIM_PRESETS;
|
|
3265
4093
|
exports.allowedRange = allowedRange;
|
|
4094
|
+
exports.applyOverlayPosition = applyOverlayPosition;
|
|
3266
4095
|
exports.attachGestures = attachGestures;
|
|
3267
4096
|
exports.createOverlay = createOverlay;
|
|
3268
4097
|
exports.createSheetManager = createSheetManager;
|
|
@@ -3274,8 +4103,10 @@ exports.installFocusTrap = installFocusTrap;
|
|
|
3274
4103
|
exports.installGestures = installGestures;
|
|
3275
4104
|
exports.lockBodyScroll = lockBodyScroll;
|
|
3276
4105
|
exports.prefersReducedMotion = prefersReducedMotion;
|
|
4106
|
+
exports.resolveSheetAnchoredStyle = resolveSheetAnchoredStyle;
|
|
3277
4107
|
exports.resolveSnap = resolveSnap;
|
|
3278
4108
|
exports.resolveSnapList = resolveSnapList;
|
|
4109
|
+
exports.runAnchorTransition = runAnchorTransition;
|
|
3279
4110
|
exports.runSpring = runSpring;
|
|
3280
4111
|
exports.sheetStack = sheetStack;
|
|
3281
4112
|
exports.tween = tween;
|