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