@surdeddd/bottom-sheet 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +51 -21
- package/dist/{BottomSheetEngine-CIT9Htti.d.cts → BottomSheetEngine-BJrH7qY3.d.cts} +105 -3
- package/dist/{BottomSheetEngine-Df9MwBbm.d.ts → BottomSheetEngine-L05jGZvU.d.ts} +105 -3
- package/dist/element.cjs +1170 -196
- package/dist/element.d.cts +29 -5
- package/dist/element.d.ts +29 -5
- package/dist/element.iife.global.js +2 -2
- package/dist/element.js +1170 -196
- package/dist/index.cjs +1051 -220
- package/dist/index.d.cts +18 -3
- package/dist/index.d.ts +18 -3
- package/dist/index.js +1049 -221
- package/dist/integrations/formik.d.cts +1 -1
- package/dist/integrations/formik.d.ts +1 -1
- package/dist/integrations/react-hook-form.d.cts +1 -1
- package/dist/integrations/react-hook-form.d.ts +1 -1
- package/dist/overlay.cjs +181 -37
- package/dist/overlay.d.cts +13 -0
- package/dist/overlay.d.ts +13 -0
- package/dist/overlay.js +181 -37
- package/dist/preact.d.cts +1 -1
- package/dist/preact.d.ts +1 -1
- package/dist/qwik.cjs +966 -195
- package/dist/qwik.d.cts +4 -2
- package/dist/qwik.d.ts +4 -2
- package/dist/qwik.js +967 -196
- package/dist/react.cjs +1242 -272
- package/dist/react.d.cts +47 -5
- package/dist/react.d.ts +47 -5
- package/dist/react.js +1242 -272
- package/dist/solid.cjs +992 -236
- package/dist/solid.d.cts +299 -4
- package/dist/solid.d.ts +299 -4
- package/dist/solid.js +993 -237
- package/dist/solid.source.jsx +3476 -0
- package/dist/styles.css +67 -66
- package/dist/svelte-core.cjs +3415 -0
- package/dist/svelte-core.js +3413 -0
- package/dist/svelte-src/BottomSheet.svelte +308 -0
- package/dist/svelte-src/index.js +2 -0
- package/dist/svelte.cjs +1034 -207
- package/dist/svelte.d.cts +121 -0
- package/dist/svelte.d.ts +28 -3
- package/dist/svelte.js +1035 -208
- package/dist/vue.cjs +1191 -205
- package/dist/vue.d.cts +127 -0
- package/dist/vue.d.ts +57 -4
- package/dist/vue.js +1192 -206
- package/package.json +105 -45
package/dist/svelte.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as $2 from 'svelte/internal/client';
|
|
2
2
|
import 'svelte/internal/disclose-version';
|
|
3
|
-
import { onMount, onDestroy } from 'svelte';
|
|
3
|
+
import { untrack, onMount, onDestroy } from 'svelte';
|
|
4
4
|
|
|
5
5
|
var __defProp = Object.defineProperty;
|
|
6
6
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
@@ -24,16 +24,52 @@ var SheetStack = class {
|
|
|
24
24
|
this.entries.splice(idx, 1);
|
|
25
25
|
this.recompute();
|
|
26
26
|
}
|
|
27
|
+
promote(id) {
|
|
28
|
+
const idx = this.entries.findIndex((e) => e.id === id);
|
|
29
|
+
if (idx === -1) return;
|
|
30
|
+
if (idx !== this.entries.length - 1) {
|
|
31
|
+
const [entry] = this.entries.splice(idx, 1);
|
|
32
|
+
this.entries.push(entry);
|
|
33
|
+
}
|
|
34
|
+
this.recompute();
|
|
35
|
+
}
|
|
36
|
+
update() {
|
|
37
|
+
this.recompute();
|
|
38
|
+
}
|
|
27
39
|
size() {
|
|
28
40
|
return this.entries.length;
|
|
29
41
|
}
|
|
42
|
+
depthOf(id) {
|
|
43
|
+
const open = [];
|
|
44
|
+
for (const entry of this.entries) {
|
|
45
|
+
if (!entry.isOpen || entry.isOpen()) open.push(entry);
|
|
46
|
+
}
|
|
47
|
+
const idx = open.findIndex((e) => e.id === id);
|
|
48
|
+
if (idx === -1) return 0;
|
|
49
|
+
return open.length - 1 - idx;
|
|
50
|
+
}
|
|
30
51
|
clear() {
|
|
31
52
|
this.entries = [];
|
|
32
53
|
}
|
|
33
54
|
recompute() {
|
|
55
|
+
let top = null;
|
|
56
|
+
const open = [];
|
|
57
|
+
for (const entry of this.entries) {
|
|
58
|
+
if (!entry.isOpen || entry.isOpen()) {
|
|
59
|
+
top = entry;
|
|
60
|
+
open.push(entry);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (!top && this.entries.length > 0) {
|
|
64
|
+
top = this.entries[this.entries.length - 1];
|
|
65
|
+
}
|
|
34
66
|
this.entries.forEach((entry, i) => {
|
|
35
67
|
entry.setZIndex(BASE_Z + i * STEP);
|
|
36
|
-
entry.setIsTop(
|
|
68
|
+
entry.setIsTop(entry === top);
|
|
69
|
+
if (entry.setDepth) {
|
|
70
|
+
const openIdx = open.indexOf(entry);
|
|
71
|
+
entry.setDepth(openIdx === -1 ? 0 : open.length - 1 - openIdx);
|
|
72
|
+
}
|
|
37
73
|
});
|
|
38
74
|
}
|
|
39
75
|
};
|
|
@@ -130,7 +166,9 @@ var PERCENT = /^(-?\d+(?:\.\d+)?)%$/;
|
|
|
130
166
|
var resolveSnap = (point, mode, measureFit) => {
|
|
131
167
|
if (typeof point === "number") return Math.max(0, point);
|
|
132
168
|
if (point === "full") return viewportSize(mode);
|
|
133
|
-
if (point === "fit"
|
|
169
|
+
if (point === "fit" || point === "content") {
|
|
170
|
+
return Math.max(0, measureFit?.() ?? 0);
|
|
171
|
+
}
|
|
134
172
|
const pctMatch = point.match(PERCENT);
|
|
135
173
|
if (pctMatch) {
|
|
136
174
|
const pct = parseFloat(pctMatch[1]) / 100;
|
|
@@ -318,14 +356,17 @@ function installAutoCollapse(deps) {
|
|
|
318
356
|
const fire = () => {
|
|
319
357
|
if (deps.isDestroyed()) return;
|
|
320
358
|
if (deps.isDragging()) return;
|
|
321
|
-
const
|
|
322
|
-
|
|
359
|
+
const active = deps.resolveSnap(deps.getActiveId());
|
|
360
|
+
if (!active || active.size === 0) return;
|
|
361
|
+
let target = null;
|
|
362
|
+
for (const id of deps.getAllowedIds()) {
|
|
323
363
|
const snap = deps.resolveSnap(id);
|
|
324
|
-
|
|
325
|
-
|
|
364
|
+
if (!snap || snap.size <= 0) continue;
|
|
365
|
+
if (!target || snap.size < target.size) target = snap;
|
|
366
|
+
}
|
|
326
367
|
if (!target) return;
|
|
327
|
-
if (target ===
|
|
328
|
-
deps.snapTo(target);
|
|
368
|
+
if (target.id === active.id || target.size >= active.size) return;
|
|
369
|
+
deps.snapTo(target.id);
|
|
329
370
|
};
|
|
330
371
|
const reset2 = () => {
|
|
331
372
|
clearTimer();
|
|
@@ -336,6 +377,7 @@ function installAutoCollapse(deps) {
|
|
|
336
377
|
}, ms);
|
|
337
378
|
};
|
|
338
379
|
const unsubscribe = deps.on("snap", () => reset2());
|
|
380
|
+
if ((deps.resolveSnap(deps.getActiveId())?.size ?? 0) > 0) reset2();
|
|
339
381
|
return () => {
|
|
340
382
|
clearTimer();
|
|
341
383
|
unsubscribe();
|
|
@@ -348,6 +390,7 @@ function notifyLinkedSheets(sheets, self) {
|
|
|
348
390
|
for (const linked of sheets) {
|
|
349
391
|
if (linked === self) continue;
|
|
350
392
|
try {
|
|
393
|
+
if (linked.state.size === 0) continue;
|
|
351
394
|
const ids = linked.getAllowedIds();
|
|
352
395
|
const target = ids.find((id) => id !== "closed");
|
|
353
396
|
if (target && target !== linked.state.activeId) {
|
|
@@ -362,6 +405,42 @@ function notifyLinkedSheets(sheets, self) {
|
|
|
362
405
|
}
|
|
363
406
|
|
|
364
407
|
// src/core/features/route.ts
|
|
408
|
+
var closers = [];
|
|
409
|
+
var handlerInstalled = false;
|
|
410
|
+
var suppress = 0;
|
|
411
|
+
var ensureHandler = () => {
|
|
412
|
+
if (handlerInstalled || typeof window === "undefined") return;
|
|
413
|
+
handlerInstalled = true;
|
|
414
|
+
window.addEventListener("popstate", () => {
|
|
415
|
+
if (suppress > 0) {
|
|
416
|
+
suppress -= 1;
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
let target = null;
|
|
420
|
+
for (let i = closers.length - 1; i >= 0; i -= 1) {
|
|
421
|
+
const c = closers[i];
|
|
422
|
+
if (!c.isOpen()) continue;
|
|
423
|
+
if (!target) target = c;
|
|
424
|
+
if (c.isTop()) {
|
|
425
|
+
target = c;
|
|
426
|
+
break;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
if (!target) return;
|
|
430
|
+
target.consumed = true;
|
|
431
|
+
const idx = closers.indexOf(target);
|
|
432
|
+
if (idx !== -1) closers.splice(idx, 1);
|
|
433
|
+
target.close();
|
|
434
|
+
});
|
|
435
|
+
};
|
|
436
|
+
var programmaticBack = () => {
|
|
437
|
+
suppress += 1;
|
|
438
|
+
try {
|
|
439
|
+
history.back();
|
|
440
|
+
} catch {
|
|
441
|
+
suppress = Math.max(0, suppress - 1);
|
|
442
|
+
}
|
|
443
|
+
};
|
|
365
444
|
function installRoute(deps) {
|
|
366
445
|
if (typeof window === "undefined") {
|
|
367
446
|
return () => {
|
|
@@ -371,82 +450,81 @@ function installRoute(deps) {
|
|
|
371
450
|
return () => {
|
|
372
451
|
};
|
|
373
452
|
}
|
|
374
|
-
let
|
|
375
|
-
let
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
453
|
+
let pushed = false;
|
|
454
|
+
let closer = null;
|
|
455
|
+
const teardownEntry = () => {
|
|
456
|
+
if (closer) {
|
|
457
|
+
const idx = closers.indexOf(closer);
|
|
458
|
+
if (idx !== -1) closers.splice(idx, 1);
|
|
459
|
+
}
|
|
460
|
+
const wasConsumed = closer?.consumed ?? false;
|
|
461
|
+
closer = null;
|
|
462
|
+
if (pushed && !wasConsumed) {
|
|
463
|
+
pushed = false;
|
|
464
|
+
programmaticBack();
|
|
465
|
+
} else {
|
|
466
|
+
pushed = false;
|
|
384
467
|
}
|
|
385
468
|
};
|
|
386
469
|
const onOpen = () => {
|
|
387
|
-
if (
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
}
|
|
401
|
-
};
|
|
402
|
-
window.addEventListener("popstate", onPop);
|
|
403
|
-
detachPopstate = () => window.removeEventListener("popstate", onPop);
|
|
404
|
-
} else if (deps.closeOnBack && !detachPopstate) {
|
|
405
|
-
try {
|
|
470
|
+
if (closer) return;
|
|
471
|
+
closer = {
|
|
472
|
+
isOpen: () => !deps.isDestroyed() && deps.getSize() > 0,
|
|
473
|
+
isTop: () => deps.isTopSheet(),
|
|
474
|
+
close: () => void deps.close(),
|
|
475
|
+
consumed: false
|
|
476
|
+
};
|
|
477
|
+
ensureHandler();
|
|
478
|
+
closers.push(closer);
|
|
479
|
+
try {
|
|
480
|
+
if (deps.routedTo !== void 0) {
|
|
481
|
+
history.pushState({ __bsRouted: deps.sheetId }, "", deps.routedTo);
|
|
482
|
+
} else {
|
|
406
483
|
history.pushState({ __bsSheet: deps.sheetId }, "");
|
|
407
|
-
closeOnBackPushed = true;
|
|
408
|
-
} catch {
|
|
409
484
|
}
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
const state2 = history.state;
|
|
414
|
-
if (state2?.__bsSheet !== deps.sheetId) closeOnBackPushed = false;
|
|
415
|
-
void deps.close();
|
|
416
|
-
}
|
|
417
|
-
};
|
|
418
|
-
window.addEventListener("popstate", onPop);
|
|
419
|
-
detachPopstate = () => window.removeEventListener("popstate", onPop);
|
|
420
|
-
}
|
|
421
|
-
};
|
|
422
|
-
const onClose = () => {
|
|
423
|
-
detachPopstate?.();
|
|
424
|
-
detachPopstate = null;
|
|
425
|
-
if (routePushed) {
|
|
426
|
-
routePushed = false;
|
|
427
|
-
if (deps.routedTo !== void 0) popOurMarker("__bsRouted", deps.routedTo);
|
|
428
|
-
}
|
|
429
|
-
if (closeOnBackPushed) {
|
|
430
|
-
closeOnBackPushed = false;
|
|
431
|
-
popOurMarker("__bsSheet", deps.sheetId);
|
|
485
|
+
pushed = true;
|
|
486
|
+
} catch {
|
|
487
|
+
pushed = false;
|
|
432
488
|
}
|
|
433
489
|
};
|
|
434
490
|
const unsubscribeOpen = deps.on("open", onOpen);
|
|
435
|
-
const unsubscribeClose = deps.on("close",
|
|
491
|
+
const unsubscribeClose = deps.on("close", teardownEntry);
|
|
436
492
|
if (deps.getSize() > 0) onOpen();
|
|
437
493
|
return () => {
|
|
438
494
|
unsubscribeOpen();
|
|
439
495
|
unsubscribeClose();
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
496
|
+
teardownEntry();
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
function installRouteChange(deps) {
|
|
500
|
+
if (typeof window === "undefined" || typeof history === "undefined") {
|
|
501
|
+
return () => {
|
|
502
|
+
};
|
|
503
|
+
}
|
|
504
|
+
const onChange = () => {
|
|
505
|
+
if (deps.isDestroyed() || deps.getSize() <= 0) return;
|
|
506
|
+
void deps.close();
|
|
507
|
+
};
|
|
508
|
+
const wrap = (key) => {
|
|
509
|
+
const original = history[key];
|
|
510
|
+
const patched = function(...args) {
|
|
511
|
+
original.apply(this, args);
|
|
512
|
+
onChange();
|
|
513
|
+
};
|
|
514
|
+
history[key] = patched;
|
|
515
|
+
return () => {
|
|
516
|
+
if (history[key] === patched) {
|
|
517
|
+
history[key] = original;
|
|
518
|
+
}
|
|
519
|
+
};
|
|
520
|
+
};
|
|
521
|
+
window.addEventListener("popstate", onChange);
|
|
522
|
+
const restorePush = wrap("pushState");
|
|
523
|
+
const restoreReplace = wrap("replaceState");
|
|
524
|
+
return () => {
|
|
525
|
+
window.removeEventListener("popstate", onChange);
|
|
526
|
+
restorePush();
|
|
527
|
+
restoreReplace();
|
|
450
528
|
};
|
|
451
529
|
}
|
|
452
530
|
|
|
@@ -548,13 +626,17 @@ function installResizeObserver(deps) {
|
|
|
548
626
|
if (viewportSize2 > 0 && viewportSize2 < max) {
|
|
549
627
|
deps.setMaxAxisSize(viewportSize2);
|
|
550
628
|
}
|
|
629
|
+
const wasAnimating = deps.isAnimating?.() ?? false;
|
|
551
630
|
deps.cancelInFlight();
|
|
552
631
|
deps.newCycle();
|
|
553
632
|
const current = deps.resolveActiveSnap();
|
|
554
633
|
const newMax = deps.getMaxAxisSize();
|
|
555
634
|
const targetSize = current ? Math.min(current.size, newMax) : Math.min(deps.getSize(), newMax);
|
|
556
635
|
deps.setSize(targetSize);
|
|
557
|
-
if (current && !deps.isDragging())
|
|
636
|
+
if (current && !deps.isDragging()) {
|
|
637
|
+
deps.applySize(targetSize);
|
|
638
|
+
if (wasAnimating) deps.resyncAfterCancel?.();
|
|
639
|
+
}
|
|
558
640
|
};
|
|
559
641
|
let resizeObserver = null;
|
|
560
642
|
if (typeof ResizeObserver !== "undefined") {
|
|
@@ -669,8 +751,88 @@ function devWarn(...args) {
|
|
|
669
751
|
}
|
|
670
752
|
}
|
|
671
753
|
|
|
754
|
+
// src/core/primitives/overlay-position.ts
|
|
755
|
+
function resolveSheetAnchoredStyle(mode, position, inset) {
|
|
756
|
+
const sizeOffset = `calc(var(--bs-size, 0px) + ${inset})`;
|
|
757
|
+
switch (mode) {
|
|
758
|
+
case "bottom":
|
|
759
|
+
if (position === "sheet-top-left") return { bottom: sizeOffset, left: inset };
|
|
760
|
+
if (position === "sheet-top-right") return { bottom: sizeOffset, right: inset };
|
|
761
|
+
return { bottom: sizeOffset, left: "50%", transform: "translateX(-50%)" };
|
|
762
|
+
case "top":
|
|
763
|
+
if (position === "sheet-top-left") return { top: sizeOffset, left: inset };
|
|
764
|
+
if (position === "sheet-top-right") return { top: sizeOffset, right: inset };
|
|
765
|
+
return { top: sizeOffset, left: "50%", transform: "translateX(-50%)" };
|
|
766
|
+
case "left":
|
|
767
|
+
if (position === "sheet-top-left") return { left: sizeOffset, top: inset };
|
|
768
|
+
if (position === "sheet-top-right") return { left: sizeOffset, bottom: inset };
|
|
769
|
+
return { left: sizeOffset, top: "50%", transform: "translateY(-50%)" };
|
|
770
|
+
case "right":
|
|
771
|
+
if (position === "sheet-top-left") return { right: sizeOffset, top: inset };
|
|
772
|
+
if (position === "sheet-top-right") return { right: sizeOffset, bottom: inset };
|
|
773
|
+
return { right: sizeOffset, top: "50%", transform: "translateY(-50%)" };
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
function applyOverlayPosition(ws, mode, position, inset) {
|
|
777
|
+
switch (position) {
|
|
778
|
+
case "top-left":
|
|
779
|
+
ws.top = inset;
|
|
780
|
+
ws.left = inset;
|
|
781
|
+
break;
|
|
782
|
+
case "top-center":
|
|
783
|
+
ws.top = inset;
|
|
784
|
+
ws.left = "50%";
|
|
785
|
+
ws.transform = "translateX(-50%)";
|
|
786
|
+
break;
|
|
787
|
+
case "top-right":
|
|
788
|
+
ws.top = inset;
|
|
789
|
+
ws.right = inset;
|
|
790
|
+
break;
|
|
791
|
+
case "center-left":
|
|
792
|
+
ws.top = "50%";
|
|
793
|
+
ws.left = inset;
|
|
794
|
+
ws.transform = "translateY(-50%)";
|
|
795
|
+
break;
|
|
796
|
+
case "center":
|
|
797
|
+
ws.top = "50%";
|
|
798
|
+
ws.left = "50%";
|
|
799
|
+
ws.transform = "translate(-50%, -50%)";
|
|
800
|
+
break;
|
|
801
|
+
case "center-right":
|
|
802
|
+
ws.top = "50%";
|
|
803
|
+
ws.right = inset;
|
|
804
|
+
ws.transform = "translateY(-50%)";
|
|
805
|
+
break;
|
|
806
|
+
case "bottom-left":
|
|
807
|
+
ws.bottom = inset;
|
|
808
|
+
ws.left = inset;
|
|
809
|
+
break;
|
|
810
|
+
case "bottom-center":
|
|
811
|
+
ws.bottom = inset;
|
|
812
|
+
ws.left = "50%";
|
|
813
|
+
ws.transform = "translateX(-50%)";
|
|
814
|
+
break;
|
|
815
|
+
case "bottom-right":
|
|
816
|
+
ws.bottom = inset;
|
|
817
|
+
ws.right = inset;
|
|
818
|
+
break;
|
|
819
|
+
case "sheet-top-left":
|
|
820
|
+
case "sheet-top-center":
|
|
821
|
+
case "sheet-top-right": {
|
|
822
|
+
const style = resolveSheetAnchoredStyle(mode, position, inset);
|
|
823
|
+
if (style.top !== void 0) ws.top = style.top;
|
|
824
|
+
if (style.bottom !== void 0) ws.bottom = style.bottom;
|
|
825
|
+
if (style.left !== void 0) ws.left = style.left;
|
|
826
|
+
if (style.right !== void 0) ws.right = style.right;
|
|
827
|
+
if (style.transform !== void 0) ws.transform = style.transform;
|
|
828
|
+
break;
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
|
|
672
833
|
// src/core/controllers/scrim-controller.ts
|
|
673
834
|
var VALID_CSS_LENGTH = /^-?\d+(?:\.\d+)?(?:px|em|rem|%)$/;
|
|
835
|
+
var DEFAULT_SCRIM_DIM = "rgba(0, 0, 0, 0.4)";
|
|
674
836
|
var ScrimController = class {
|
|
675
837
|
constructor(deps, opts) {
|
|
676
838
|
__publicField(this, "screenComponent");
|
|
@@ -681,6 +843,8 @@ var ScrimController = class {
|
|
|
681
843
|
__publicField(this, "getAllowedIds");
|
|
682
844
|
__publicField(this, "getResolvedSnaps");
|
|
683
845
|
__publicField(this, "snapToFn");
|
|
846
|
+
__publicField(this, "closeFn");
|
|
847
|
+
__publicField(this, "scrimInteractive", false);
|
|
684
848
|
__publicField(this, "scrimMode");
|
|
685
849
|
__publicField(this, "backdropRange");
|
|
686
850
|
__publicField(this, "screenRange");
|
|
@@ -701,14 +865,17 @@ var ScrimController = class {
|
|
|
701
865
|
this.getAllowedIds = deps.getAllowedIds;
|
|
702
866
|
this.getResolvedSnaps = deps.getResolvedSnaps;
|
|
703
867
|
this.snapToFn = deps.snapTo;
|
|
868
|
+
this.closeFn = deps.close;
|
|
704
869
|
this.scrimMode = opts.scrimMode ?? "full";
|
|
705
870
|
const preset = opts.scrimPreset ? SCRIM_PRESETS[opts.scrimPreset] : null;
|
|
706
871
|
this.backdropRange = opts.backdropRange ?? preset?.range ?? [0, 1];
|
|
707
872
|
this.screenRange = opts.screenRange ?? preset?.range ?? [0, 1];
|
|
708
873
|
this.scrimTapToCloseEnabled = opts.scrimTapToClose ?? false;
|
|
874
|
+
const explicitColor = opts.scrimColor ?? preset?.color;
|
|
875
|
+
const effectiveColor = explicitColor ?? (this.scrimMode !== "off" && !this.backdrop ? DEFAULT_SCRIM_DIM : void 0);
|
|
709
876
|
if (this.screenComponent) {
|
|
710
877
|
this.applyScrimStyles({
|
|
711
|
-
color:
|
|
878
|
+
color: effectiveColor,
|
|
712
879
|
blur: opts.scrimBlur ?? preset?.blur,
|
|
713
880
|
interactive: opts.scrimInteractive ?? preset?.interactive ?? false
|
|
714
881
|
});
|
|
@@ -842,11 +1009,15 @@ var ScrimController = class {
|
|
|
842
1009
|
}
|
|
843
1010
|
const onClick = () => {
|
|
844
1011
|
if (this.isDestroyed()) return;
|
|
1012
|
+
if (this.closeFn) {
|
|
1013
|
+
this.closeFn();
|
|
1014
|
+
return;
|
|
1015
|
+
}
|
|
845
1016
|
const allowed = this.getAllowedIds();
|
|
846
1017
|
const snaps = this.getResolvedSnaps();
|
|
847
1018
|
const fallback = allowed.find((id) => {
|
|
848
1019
|
const snap = findById(id, snaps);
|
|
849
|
-
return snap !== null && snap.size
|
|
1020
|
+
return snap !== null && snap.size === 0;
|
|
850
1021
|
});
|
|
851
1022
|
if (fallback) this.snapToFn(fallback);
|
|
852
1023
|
};
|
|
@@ -863,6 +1034,7 @@ var ScrimController = class {
|
|
|
863
1034
|
if (this.isDestroyed()) return;
|
|
864
1035
|
if (enabled === this.scrimEnabled) return;
|
|
865
1036
|
this.scrimEnabled = enabled;
|
|
1037
|
+
this.invalidateOpacityCache();
|
|
866
1038
|
if (!enabled) {
|
|
867
1039
|
this.savedScrimRanges = {
|
|
868
1040
|
screen: this.screenRange,
|
|
@@ -886,7 +1058,12 @@ var ScrimController = class {
|
|
|
886
1058
|
blur: cfg.blur ?? null,
|
|
887
1059
|
interactive: cfg.interactive
|
|
888
1060
|
});
|
|
889
|
-
this.
|
|
1061
|
+
if (!this.scrimEnabled && this.savedScrimRanges) {
|
|
1062
|
+
this.savedScrimRanges = { screen: cfg.range, backdrop: cfg.range };
|
|
1063
|
+
} else {
|
|
1064
|
+
this.screenRange = cfg.range;
|
|
1065
|
+
this.backdropRange = cfg.range;
|
|
1066
|
+
}
|
|
890
1067
|
}
|
|
891
1068
|
const noop = () => {
|
|
892
1069
|
};
|
|
@@ -936,59 +1113,7 @@ var ScrimController = class {
|
|
|
936
1113
|
wrapper.className = "bs-scrim-overlay";
|
|
937
1114
|
const ws = wrapper.style;
|
|
938
1115
|
ws.position = "absolute";
|
|
939
|
-
|
|
940
|
-
case "top-left":
|
|
941
|
-
ws.top = inset;
|
|
942
|
-
ws.left = inset;
|
|
943
|
-
break;
|
|
944
|
-
case "top-center":
|
|
945
|
-
ws.top = inset;
|
|
946
|
-
ws.left = "50%";
|
|
947
|
-
ws.transform = "translateX(-50%)";
|
|
948
|
-
break;
|
|
949
|
-
case "top-right":
|
|
950
|
-
ws.top = inset;
|
|
951
|
-
ws.right = inset;
|
|
952
|
-
break;
|
|
953
|
-
case "center-left":
|
|
954
|
-
ws.top = "50%";
|
|
955
|
-
ws.left = inset;
|
|
956
|
-
ws.transform = "translateY(-50%)";
|
|
957
|
-
break;
|
|
958
|
-
case "center":
|
|
959
|
-
ws.top = "50%";
|
|
960
|
-
ws.left = "50%";
|
|
961
|
-
ws.transform = "translate(-50%, -50%)";
|
|
962
|
-
break;
|
|
963
|
-
case "center-right":
|
|
964
|
-
ws.top = "50%";
|
|
965
|
-
ws.right = inset;
|
|
966
|
-
ws.transform = "translateY(-50%)";
|
|
967
|
-
break;
|
|
968
|
-
case "bottom-left":
|
|
969
|
-
ws.bottom = inset;
|
|
970
|
-
ws.left = inset;
|
|
971
|
-
break;
|
|
972
|
-
case "bottom-center":
|
|
973
|
-
ws.bottom = inset;
|
|
974
|
-
ws.left = "50%";
|
|
975
|
-
ws.transform = "translateX(-50%)";
|
|
976
|
-
break;
|
|
977
|
-
case "bottom-right":
|
|
978
|
-
ws.bottom = inset;
|
|
979
|
-
ws.right = inset;
|
|
980
|
-
break;
|
|
981
|
-
case "sheet-top-left":
|
|
982
|
-
case "sheet-top-center":
|
|
983
|
-
case "sheet-top-right":
|
|
984
|
-
applySheetAnchoredPosition(
|
|
985
|
-
ws,
|
|
986
|
-
this.mode,
|
|
987
|
-
position,
|
|
988
|
-
inset
|
|
989
|
-
);
|
|
990
|
-
break;
|
|
991
|
-
}
|
|
1116
|
+
applyOverlayPosition(ws, this.mode, position, inset);
|
|
992
1117
|
if (interactive) {
|
|
993
1118
|
ws.pointerEvents = "auto";
|
|
994
1119
|
}
|
|
@@ -1047,6 +1172,7 @@ var ScrimController = class {
|
|
|
1047
1172
|
}
|
|
1048
1173
|
}
|
|
1049
1174
|
if (opts.interactive !== void 0) {
|
|
1175
|
+
this.scrimInteractive = opts.interactive;
|
|
1050
1176
|
s.pointerEvents = opts.interactive ? "auto" : "none";
|
|
1051
1177
|
}
|
|
1052
1178
|
}
|
|
@@ -1061,38 +1187,9 @@ var ScrimController = class {
|
|
|
1061
1187
|
const s = this.screenComponent.style;
|
|
1062
1188
|
s.position = "fixed";
|
|
1063
1189
|
s.inset = insetByMode[this.mode];
|
|
1064
|
-
s.pointerEvents = "none";
|
|
1190
|
+
s.pointerEvents = this.scrimInteractive || this.scrimTapToCloseEnabled ? "auto" : "none";
|
|
1065
1191
|
}
|
|
1066
1192
|
};
|
|
1067
|
-
function resolveSheetAnchoredStyle(mode, position, inset) {
|
|
1068
|
-
const sizeOffset = `calc(var(--bs-size, 0px) + ${inset})`;
|
|
1069
|
-
switch (mode) {
|
|
1070
|
-
case "bottom":
|
|
1071
|
-
if (position === "sheet-top-left") return { bottom: sizeOffset, left: inset };
|
|
1072
|
-
if (position === "sheet-top-right") return { bottom: sizeOffset, right: inset };
|
|
1073
|
-
return { bottom: sizeOffset, left: "50%", transform: "translateX(-50%)" };
|
|
1074
|
-
case "top":
|
|
1075
|
-
if (position === "sheet-top-left") return { top: sizeOffset, left: inset };
|
|
1076
|
-
if (position === "sheet-top-right") return { top: sizeOffset, right: inset };
|
|
1077
|
-
return { top: sizeOffset, left: "50%", transform: "translateX(-50%)" };
|
|
1078
|
-
case "left":
|
|
1079
|
-
if (position === "sheet-top-left") return { left: sizeOffset, top: inset };
|
|
1080
|
-
if (position === "sheet-top-right") return { left: sizeOffset, bottom: inset };
|
|
1081
|
-
return { left: sizeOffset, top: "50%", transform: "translateY(-50%)" };
|
|
1082
|
-
case "right":
|
|
1083
|
-
if (position === "sheet-top-left") return { right: sizeOffset, top: inset };
|
|
1084
|
-
if (position === "sheet-top-right") return { right: sizeOffset, bottom: inset };
|
|
1085
|
-
return { right: sizeOffset, top: "50%", transform: "translateY(-50%)" };
|
|
1086
|
-
}
|
|
1087
|
-
}
|
|
1088
|
-
function applySheetAnchoredPosition(ws, mode, position, inset) {
|
|
1089
|
-
const style = resolveSheetAnchoredStyle(mode, position, inset);
|
|
1090
|
-
if (style.top !== void 0) ws.top = style.top;
|
|
1091
|
-
if (style.bottom !== void 0) ws.bottom = style.bottom;
|
|
1092
|
-
if (style.left !== void 0) ws.left = style.left;
|
|
1093
|
-
if (style.right !== void 0) ws.right = style.right;
|
|
1094
|
-
if (style.transform !== void 0) ws.transform = style.transform;
|
|
1095
|
-
}
|
|
1096
1193
|
|
|
1097
1194
|
// src/core/animation/animation.ts
|
|
1098
1195
|
var easeOutBack = (t) => {
|
|
@@ -1144,6 +1241,10 @@ var tween = ({
|
|
|
1144
1241
|
promise
|
|
1145
1242
|
};
|
|
1146
1243
|
};
|
|
1244
|
+
var prefersReducedMotion = () => {
|
|
1245
|
+
if (typeof window === "undefined" || !window.matchMedia) return false;
|
|
1246
|
+
return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
1247
|
+
};
|
|
1147
1248
|
|
|
1148
1249
|
// src/core/animation/spring.ts
|
|
1149
1250
|
var DEFAULT_SPRING = {
|
|
@@ -1174,14 +1275,20 @@ var runSpring = ({
|
|
|
1174
1275
|
if (cancelled) return;
|
|
1175
1276
|
const dt = Math.min((now - lastTime) / 1e3, MAX_DT);
|
|
1176
1277
|
lastTime = now;
|
|
1177
|
-
const
|
|
1178
|
-
|
|
1278
|
+
const steps = Math.max(1, Math.ceil(dt * 240));
|
|
1279
|
+
const subDt = dt / steps;
|
|
1280
|
+
let stepsLeft = steps;
|
|
1179
1281
|
while (stepsLeft-- > 0) {
|
|
1180
1282
|
const force = -cfg.stiffness * (x - to) - cfg.damping * v;
|
|
1181
1283
|
const accel = force / cfg.mass;
|
|
1182
1284
|
v += accel * subDt;
|
|
1183
1285
|
x += v * subDt;
|
|
1184
1286
|
}
|
|
1287
|
+
if (!Number.isFinite(x) || !Number.isFinite(v)) {
|
|
1288
|
+
onUpdate(to, 0);
|
|
1289
|
+
resolve();
|
|
1290
|
+
return;
|
|
1291
|
+
}
|
|
1185
1292
|
onUpdate(x, v);
|
|
1186
1293
|
const isAtRest = Math.abs(to - x) < (cfg.restDelta ?? 0.5) && Math.abs(v) < (cfg.restSpeed ?? 0.5);
|
|
1187
1294
|
if (isAtRest) {
|
|
@@ -1356,9 +1463,13 @@ var isVisible = (el) => {
|
|
|
1356
1463
|
var focusables = (root2) => Array.from(root2.querySelectorAll(FOCUSABLE)).filter(
|
|
1357
1464
|
(el) => !el.hasAttribute("inert") && isVisible(el) && !el.matches("[aria-hidden='true']")
|
|
1358
1465
|
);
|
|
1466
|
+
var trapStack = [];
|
|
1359
1467
|
var installFocusTrap = (container, options = {}) => {
|
|
1360
1468
|
if (typeof document === "undefined") return () => {
|
|
1361
1469
|
};
|
|
1470
|
+
const token = {};
|
|
1471
|
+
trapStack.push(token);
|
|
1472
|
+
const isActive = () => trapStack[trapStack.length - 1] === token;
|
|
1362
1473
|
const previouslyFocused = document.activeElement;
|
|
1363
1474
|
const focusInitial = () => {
|
|
1364
1475
|
const initial = typeof options.initialFocus === "string" ? container.querySelector(options.initialFocus) : options.initialFocus ?? focusables(container)[0] ?? container;
|
|
@@ -1366,6 +1477,7 @@ var installFocusTrap = (container, options = {}) => {
|
|
|
1366
1477
|
};
|
|
1367
1478
|
focusInitial();
|
|
1368
1479
|
const handleKey = (e) => {
|
|
1480
|
+
if (!isActive()) return;
|
|
1369
1481
|
if (e.key === "Escape" && options.onEscape) {
|
|
1370
1482
|
options.onEscape();
|
|
1371
1483
|
return;
|
|
@@ -1388,6 +1500,7 @@ var installFocusTrap = (container, options = {}) => {
|
|
|
1388
1500
|
}
|
|
1389
1501
|
};
|
|
1390
1502
|
const handleFocusIn = (e) => {
|
|
1503
|
+
if (!isActive()) return;
|
|
1391
1504
|
const target = e.target;
|
|
1392
1505
|
if (target && !container.contains(target)) {
|
|
1393
1506
|
const list = focusables(container);
|
|
@@ -1400,6 +1513,8 @@ var installFocusTrap = (container, options = {}) => {
|
|
|
1400
1513
|
return () => {
|
|
1401
1514
|
if (released) return;
|
|
1402
1515
|
released = true;
|
|
1516
|
+
const idx = trapStack.indexOf(token);
|
|
1517
|
+
if (idx !== -1) trapStack.splice(idx, 1);
|
|
1403
1518
|
document.removeEventListener("keydown", handleKey, true);
|
|
1404
1519
|
document.removeEventListener("focusin", handleFocusIn, true);
|
|
1405
1520
|
if (previouslyFocused && document.contains(previouslyFocused)) {
|
|
@@ -1455,11 +1570,17 @@ function createInertSiblings(rootProvider) {
|
|
|
1455
1570
|
return {
|
|
1456
1571
|
apply() {
|
|
1457
1572
|
if (typeof document === "undefined") return;
|
|
1458
|
-
|
|
1459
|
-
|
|
1573
|
+
let top = rootProvider();
|
|
1574
|
+
while (top.parentElement && top.parentElement !== document.body) {
|
|
1575
|
+
top = top.parentElement;
|
|
1576
|
+
}
|
|
1577
|
+
const parent = top.parentElement ?? document.body;
|
|
1460
1578
|
for (const child2 of Array.from(parent.children)) {
|
|
1461
|
-
if (child2 ===
|
|
1579
|
+
if (child2 === top) continue;
|
|
1462
1580
|
if (child2.hasAttribute("inert")) continue;
|
|
1581
|
+
if (child2.classList.contains("bs-backdrop") || child2.classList.contains("bs-screen") || child2.classList.contains("bs-root")) {
|
|
1582
|
+
continue;
|
|
1583
|
+
}
|
|
1463
1584
|
child2.setAttribute("inert", "");
|
|
1464
1585
|
tracked.push(child2);
|
|
1465
1586
|
}
|
|
@@ -1475,7 +1596,6 @@ function createInertSiblings(rootProvider) {
|
|
|
1475
1596
|
var LifecycleController = class {
|
|
1476
1597
|
constructor(deps, opts) {
|
|
1477
1598
|
__publicField(this, "element");
|
|
1478
|
-
__publicField(this, "closeFn");
|
|
1479
1599
|
__publicField(this, "focusTrapEnabled");
|
|
1480
1600
|
__publicField(this, "initialFocus");
|
|
1481
1601
|
__publicField(this, "closeOnEscape");
|
|
@@ -1489,7 +1609,6 @@ var LifecycleController = class {
|
|
|
1489
1609
|
__publicField(this, "installed", false);
|
|
1490
1610
|
__publicField(this, "destroyed", false);
|
|
1491
1611
|
this.element = deps.element;
|
|
1492
|
-
this.closeFn = deps.close;
|
|
1493
1612
|
this.focusTrapEnabled = opts.focusTrap ?? false;
|
|
1494
1613
|
this.initialFocus = opts.initialFocus;
|
|
1495
1614
|
this.closeOnEscape = opts.closeOnEscape ?? true;
|
|
@@ -1499,6 +1618,9 @@ var LifecycleController = class {
|
|
|
1499
1618
|
this.returnFocus = opts.returnFocus;
|
|
1500
1619
|
this.inertSiblings = createInertSiblings(() => this.element);
|
|
1501
1620
|
}
|
|
1621
|
+
get isInstalled() {
|
|
1622
|
+
return this.installed;
|
|
1623
|
+
}
|
|
1502
1624
|
install() {
|
|
1503
1625
|
if (this.destroyed) return;
|
|
1504
1626
|
this.installed = true;
|
|
@@ -1507,8 +1629,7 @@ var LifecycleController = class {
|
|
|
1507
1629
|
}
|
|
1508
1630
|
if (this.focusTrapEnabled && !this.releaseFocusTrap) {
|
|
1509
1631
|
this.releaseFocusTrap = installFocusTrap(this.element, {
|
|
1510
|
-
initialFocus: this.initialFocus
|
|
1511
|
-
onEscape: this.closeOnEscape ? () => void this.closeFn() : void 0
|
|
1632
|
+
initialFocus: this.initialFocus
|
|
1512
1633
|
});
|
|
1513
1634
|
}
|
|
1514
1635
|
if (this.inertSiblingsEnabled && this.shouldApplyInertSiblings()) {
|
|
@@ -1528,7 +1649,7 @@ var LifecycleController = class {
|
|
|
1528
1649
|
this.releaseScrollLock = null;
|
|
1529
1650
|
this.inertSiblings.remove();
|
|
1530
1651
|
if (this.returnFocus) {
|
|
1531
|
-
const target = typeof this.returnFocus === "function" ? this.returnFocus() : this.returnFocus;
|
|
1652
|
+
const target = typeof this.returnFocus === "function" ? this.returnFocus() : typeof this.returnFocus === "string" ? typeof document !== "undefined" ? document.querySelector(this.returnFocus) : null : this.returnFocus;
|
|
1532
1653
|
target?.focus?.();
|
|
1533
1654
|
}
|
|
1534
1655
|
}
|
|
@@ -1662,10 +1783,11 @@ var installGestures = (handle, mode, callbacks) => {
|
|
|
1662
1783
|
};
|
|
1663
1784
|
|
|
1664
1785
|
// src/core/primitives/rubber-band.ts
|
|
1665
|
-
var RUBBER_BAND_FACTOR = 0.55;
|
|
1666
1786
|
function rubberBand(overshoot, maxAxisSize) {
|
|
1667
1787
|
const cap = Math.min(maxAxisSize * 0.15, 80);
|
|
1668
|
-
|
|
1788
|
+
if (cap <= 0) return 0;
|
|
1789
|
+
const abs = Math.abs(overshoot);
|
|
1790
|
+
return Math.sign(overshoot) * (cap * abs / (abs + cap));
|
|
1669
1791
|
}
|
|
1670
1792
|
|
|
1671
1793
|
// src/core/features/soft-keyboard.ts
|
|
@@ -1694,6 +1816,7 @@ var GestureController = class {
|
|
|
1694
1816
|
__publicField(this, "dragStartSize", 0);
|
|
1695
1817
|
__publicField(this, "currentPointerKind", "touch");
|
|
1696
1818
|
__publicField(this, "keyboardDismissed", false);
|
|
1819
|
+
__publicField(this, "dragSuppressed", false);
|
|
1697
1820
|
__publicField(this, "dragPayload", { size: 0, delta: 0 });
|
|
1698
1821
|
this.deps = deps;
|
|
1699
1822
|
}
|
|
@@ -1704,6 +1827,11 @@ var GestureController = class {
|
|
|
1704
1827
|
if (this.detach) return this.detach;
|
|
1705
1828
|
this.detach = installGestures(this.deps.handle, this.deps.mode, {
|
|
1706
1829
|
onStart: (_coord, kind) => {
|
|
1830
|
+
if (this.deps.getDisableDrag?.()) {
|
|
1831
|
+
this.dragSuppressed = true;
|
|
1832
|
+
return;
|
|
1833
|
+
}
|
|
1834
|
+
this.dragSuppressed = false;
|
|
1707
1835
|
this.deps.cancelAnimation();
|
|
1708
1836
|
this.isDragging_ = true;
|
|
1709
1837
|
this.dragStartSize = this.deps.getDragContext().size;
|
|
@@ -1714,6 +1842,7 @@ var GestureController = class {
|
|
|
1714
1842
|
this.deps.emit("dragstart", { size: this.dragStartSize });
|
|
1715
1843
|
},
|
|
1716
1844
|
onMove: (delta) => {
|
|
1845
|
+
if (this.dragSuppressed) return;
|
|
1717
1846
|
const ctx = this.deps.getDragContext();
|
|
1718
1847
|
const { min, max } = ctx.range;
|
|
1719
1848
|
const maxAxis = ctx.maxAxisSize;
|
|
@@ -1737,6 +1866,10 @@ var GestureController = class {
|
|
|
1737
1866
|
}
|
|
1738
1867
|
},
|
|
1739
1868
|
onEnd: (delta, velocity, kind) => {
|
|
1869
|
+
if (this.dragSuppressed) {
|
|
1870
|
+
this.dragSuppressed = false;
|
|
1871
|
+
return;
|
|
1872
|
+
}
|
|
1740
1873
|
this.isDragging_ = false;
|
|
1741
1874
|
this.keyboardDismissed = false;
|
|
1742
1875
|
this.deps.getRoot()?.removeAttribute("data-dragging");
|
|
@@ -1747,9 +1880,17 @@ var GestureController = class {
|
|
|
1747
1880
|
this.deps.settleAfterDrag(delta, velocity, kind);
|
|
1748
1881
|
},
|
|
1749
1882
|
onCancel: () => {
|
|
1883
|
+
if (this.dragSuppressed) {
|
|
1884
|
+
this.dragSuppressed = false;
|
|
1885
|
+
return;
|
|
1886
|
+
}
|
|
1750
1887
|
this.isDragging_ = false;
|
|
1751
1888
|
this.keyboardDismissed = false;
|
|
1752
1889
|
this.deps.getRoot()?.removeAttribute("data-dragging");
|
|
1890
|
+
this.deps.emit("dragend", {
|
|
1891
|
+
size: this.deps.getDragContext().size,
|
|
1892
|
+
velocity: 0
|
|
1893
|
+
});
|
|
1753
1894
|
const restoreTo = this.dragStartSize;
|
|
1754
1895
|
void this.deps.animateTo(restoreTo, 0);
|
|
1755
1896
|
}
|
|
@@ -1823,6 +1964,287 @@ function createScrollCache(deps) {
|
|
|
1823
1964
|
};
|
|
1824
1965
|
}
|
|
1825
1966
|
|
|
1967
|
+
// src/core/primitives/anchor-animations.ts
|
|
1968
|
+
var DEFAULT_DURATION3 = 200;
|
|
1969
|
+
var DEFAULT_EASING = "cubic-bezier(0.22, 1, 0.36, 1)";
|
|
1970
|
+
var PRESET_FRAMES = {
|
|
1971
|
+
fade: {
|
|
1972
|
+
enter: [{ opacity: 0 }, { opacity: 1 }],
|
|
1973
|
+
exit: [{ opacity: 1 }, { opacity: 0 }]
|
|
1974
|
+
},
|
|
1975
|
+
scale: {
|
|
1976
|
+
enter: [
|
|
1977
|
+
{ opacity: 0, transform: "scale(0.85)" },
|
|
1978
|
+
{ opacity: 1, transform: "scale(1)" }
|
|
1979
|
+
],
|
|
1980
|
+
exit: [
|
|
1981
|
+
{ opacity: 1, transform: "scale(1)" },
|
|
1982
|
+
{ opacity: 0, transform: "scale(0.85)" }
|
|
1983
|
+
]
|
|
1984
|
+
},
|
|
1985
|
+
slide: {
|
|
1986
|
+
enter: [
|
|
1987
|
+
{ opacity: 0, transform: "translateY(10px)" },
|
|
1988
|
+
{ opacity: 1, transform: "translateY(0)" }
|
|
1989
|
+
],
|
|
1990
|
+
exit: [
|
|
1991
|
+
{ opacity: 1, transform: "translateY(0)" },
|
|
1992
|
+
{ opacity: 0, transform: "translateY(10px)" }
|
|
1993
|
+
]
|
|
1994
|
+
},
|
|
1995
|
+
pop: {
|
|
1996
|
+
enter: [
|
|
1997
|
+
{ opacity: 0, transform: "scale(0.6)", offset: 0 },
|
|
1998
|
+
{ opacity: 1, transform: "scale(1.06)", offset: 0.7 },
|
|
1999
|
+
{ opacity: 1, transform: "scale(1)", offset: 1 }
|
|
2000
|
+
],
|
|
2001
|
+
exit: [
|
|
2002
|
+
{ opacity: 1, transform: "scale(1)" },
|
|
2003
|
+
{ opacity: 0, transform: "scale(0.6)" }
|
|
2004
|
+
]
|
|
2005
|
+
}
|
|
2006
|
+
};
|
|
2007
|
+
var INSTANT = {
|
|
2008
|
+
finished: Promise.resolve(),
|
|
2009
|
+
cancel: () => {
|
|
2010
|
+
}
|
|
2011
|
+
};
|
|
2012
|
+
function resolveTransitionFrames(spec, phase) {
|
|
2013
|
+
const fallback = { frames: null, duration: 0, easing: DEFAULT_EASING };
|
|
2014
|
+
if (spec === "none") return fallback;
|
|
2015
|
+
if (spec === void 0 || typeof spec === "string") {
|
|
2016
|
+
const preset2 = PRESET_FRAMES[spec ?? "fade"];
|
|
2017
|
+
return {
|
|
2018
|
+
frames: preset2[phase],
|
|
2019
|
+
duration: DEFAULT_DURATION3,
|
|
2020
|
+
easing: DEFAULT_EASING
|
|
2021
|
+
};
|
|
2022
|
+
}
|
|
2023
|
+
const custom = phase === "enter" ? spec.enter : spec.exit;
|
|
2024
|
+
if (custom) {
|
|
2025
|
+
return {
|
|
2026
|
+
frames: custom,
|
|
2027
|
+
duration: spec.duration ?? DEFAULT_DURATION3,
|
|
2028
|
+
easing: spec.easing ?? DEFAULT_EASING
|
|
2029
|
+
};
|
|
2030
|
+
}
|
|
2031
|
+
if (spec.preset === "none") return fallback;
|
|
2032
|
+
const preset = PRESET_FRAMES[spec.preset ?? "fade"];
|
|
2033
|
+
return {
|
|
2034
|
+
frames: preset[phase],
|
|
2035
|
+
duration: spec.duration ?? DEFAULT_DURATION3,
|
|
2036
|
+
easing: spec.easing ?? DEFAULT_EASING
|
|
2037
|
+
};
|
|
2038
|
+
}
|
|
2039
|
+
function runAnchorTransition(el, spec, phase) {
|
|
2040
|
+
const respectReduced = typeof spec === "object" ? spec.respectReducedMotion !== false : true;
|
|
2041
|
+
if (respectReduced && prefersReducedMotion()) return INSTANT;
|
|
2042
|
+
const { frames, duration, easing } = resolveTransitionFrames(spec, phase);
|
|
2043
|
+
if (!frames || duration <= 0) return INSTANT;
|
|
2044
|
+
if (typeof el.animate !== "function") return INSTANT;
|
|
2045
|
+
const animation = el.animate(frames, {
|
|
2046
|
+
duration,
|
|
2047
|
+
easing,
|
|
2048
|
+
fill: "both"
|
|
2049
|
+
});
|
|
2050
|
+
const finished = animation.finished.then(() => void 0).catch(() => void 0);
|
|
2051
|
+
return {
|
|
2052
|
+
finished,
|
|
2053
|
+
cancel: () => {
|
|
2054
|
+
try {
|
|
2055
|
+
animation.cancel();
|
|
2056
|
+
} catch {
|
|
2057
|
+
return;
|
|
2058
|
+
}
|
|
2059
|
+
}
|
|
2060
|
+
};
|
|
2061
|
+
}
|
|
2062
|
+
|
|
2063
|
+
// src/core/features/sheet-anchors.ts
|
|
2064
|
+
function attachAnchor(deps, opts) {
|
|
2065
|
+
const doc = deps.host.ownerDocument;
|
|
2066
|
+
const wrapper = doc.createElement("div");
|
|
2067
|
+
wrapper.className = "bs-anchor";
|
|
2068
|
+
const interactive = opts.interactive ?? true;
|
|
2069
|
+
const position = opts.position ?? "sheet-top-right";
|
|
2070
|
+
const isDock = position === "dock-bottom" || position === "dock-top";
|
|
2071
|
+
const ws = wrapper.style;
|
|
2072
|
+
ws.position = "fixed";
|
|
2073
|
+
if (isDock) {
|
|
2074
|
+
ws.left = "0";
|
|
2075
|
+
ws.right = "0";
|
|
2076
|
+
if (position === "dock-bottom") {
|
|
2077
|
+
ws.bottom = "0";
|
|
2078
|
+
} else {
|
|
2079
|
+
ws.top = "0";
|
|
2080
|
+
}
|
|
2081
|
+
} else {
|
|
2082
|
+
applyOverlayPosition(ws, deps.mode, position, opts.inset ?? "16px");
|
|
2083
|
+
}
|
|
2084
|
+
if (opts.fadeRange) {
|
|
2085
|
+
const [r0, r1] = opts.fadeRange;
|
|
2086
|
+
const span = Math.max(r1 - r0, 1e-4);
|
|
2087
|
+
ws.opacity = `clamp(0, calc((var(--bs-progress, 0) - ${r0}) / ${span}), 1)`;
|
|
2088
|
+
}
|
|
2089
|
+
wrapper.appendChild(opts.element);
|
|
2090
|
+
deps.host.appendChild(wrapper);
|
|
2091
|
+
let visible = null;
|
|
2092
|
+
let inFlight = null;
|
|
2093
|
+
const shouldShow = (state2) => {
|
|
2094
|
+
if (typeof opts.showOn === "function") return opts.showOn(state2);
|
|
2095
|
+
if (Array.isArray(opts.showOn)) return opts.showOn.includes(state2.activeId);
|
|
2096
|
+
return isDock || state2.size > 0;
|
|
2097
|
+
};
|
|
2098
|
+
const applyVisibility = (next, animate) => {
|
|
2099
|
+
if (next === visible) return;
|
|
2100
|
+
visible = next;
|
|
2101
|
+
inFlight?.cancel();
|
|
2102
|
+
inFlight = null;
|
|
2103
|
+
wrapper.style.pointerEvents = next && interactive ? "auto" : "none";
|
|
2104
|
+
if (next) {
|
|
2105
|
+
wrapper.style.visibility = "";
|
|
2106
|
+
if (animate) {
|
|
2107
|
+
inFlight = runAnchorTransition(opts.element, opts.animation, "enter");
|
|
2108
|
+
}
|
|
2109
|
+
return;
|
|
2110
|
+
}
|
|
2111
|
+
if (!animate) {
|
|
2112
|
+
wrapper.style.visibility = "hidden";
|
|
2113
|
+
return;
|
|
2114
|
+
}
|
|
2115
|
+
const handle = runAnchorTransition(opts.element, opts.animation, "exit");
|
|
2116
|
+
inFlight = handle;
|
|
2117
|
+
void handle.finished.then(() => {
|
|
2118
|
+
if (inFlight === handle && visible === false) {
|
|
2119
|
+
wrapper.style.visibility = "hidden";
|
|
2120
|
+
}
|
|
2121
|
+
});
|
|
2122
|
+
};
|
|
2123
|
+
const evaluate = (animate) => {
|
|
2124
|
+
if (deps.isDestroyed()) return;
|
|
2125
|
+
applyVisibility(shouldShow(deps.getState()), animate);
|
|
2126
|
+
};
|
|
2127
|
+
const offs = [
|
|
2128
|
+
deps.on("snap", () => evaluate(true)),
|
|
2129
|
+
deps.on("open", () => evaluate(true)),
|
|
2130
|
+
deps.on("close", () => evaluate(true))
|
|
2131
|
+
];
|
|
2132
|
+
evaluate(false);
|
|
2133
|
+
return {
|
|
2134
|
+
wrapper,
|
|
2135
|
+
detach: () => {
|
|
2136
|
+
offs.forEach((off) => off());
|
|
2137
|
+
inFlight?.cancel();
|
|
2138
|
+
inFlight = null;
|
|
2139
|
+
if (wrapper.parentNode) wrapper.parentNode.removeChild(wrapper);
|
|
2140
|
+
},
|
|
2141
|
+
syncZ: (z) => {
|
|
2142
|
+
wrapper.style.zIndex = String(z);
|
|
2143
|
+
}
|
|
2144
|
+
};
|
|
2145
|
+
}
|
|
2146
|
+
|
|
2147
|
+
// src/core/features/scrim-stages.ts
|
|
2148
|
+
var matchesId = (def, activeId) => {
|
|
2149
|
+
if (def.for === void 0) return false;
|
|
2150
|
+
return Array.isArray(def.for) ? def.for.includes(activeId) : def.for === activeId;
|
|
2151
|
+
};
|
|
2152
|
+
var matchesRange = (def, progress) => {
|
|
2153
|
+
if (!def.forRange) return false;
|
|
2154
|
+
const [from, to] = def.forRange;
|
|
2155
|
+
return progress >= from && progress <= to;
|
|
2156
|
+
};
|
|
2157
|
+
function installScrimStages(deps, opts) {
|
|
2158
|
+
const doc = deps.host.ownerDocument;
|
|
2159
|
+
const entries = opts.stages.map((def) => {
|
|
2160
|
+
const wrapper = doc.createElement("div");
|
|
2161
|
+
wrapper.className = "bs-scrim-stage";
|
|
2162
|
+
const ws = wrapper.style;
|
|
2163
|
+
ws.position = "absolute";
|
|
2164
|
+
applyOverlayPosition(
|
|
2165
|
+
ws,
|
|
2166
|
+
deps.mode,
|
|
2167
|
+
def.position ?? opts.position ?? "center",
|
|
2168
|
+
def.inset ?? opts.inset ?? "16px"
|
|
2169
|
+
);
|
|
2170
|
+
ws.visibility = "hidden";
|
|
2171
|
+
ws.pointerEvents = "none";
|
|
2172
|
+
wrapper.appendChild(def.element);
|
|
2173
|
+
deps.host.appendChild(wrapper);
|
|
2174
|
+
return { def, wrapper, inFlight: null };
|
|
2175
|
+
});
|
|
2176
|
+
let active = null;
|
|
2177
|
+
const resolveActive = () => {
|
|
2178
|
+
const state2 = deps.getState();
|
|
2179
|
+
if (state2.size === 0) {
|
|
2180
|
+
return entries.find((e) => matchesId(e.def, state2.activeId)) ?? null;
|
|
2181
|
+
}
|
|
2182
|
+
return entries.find((e) => matchesId(e.def, state2.activeId)) ?? entries.find((e) => matchesRange(e.def, state2.progress)) ?? null;
|
|
2183
|
+
};
|
|
2184
|
+
const hide = (entry, animate) => {
|
|
2185
|
+
entry.inFlight?.cancel();
|
|
2186
|
+
entry.wrapper.style.pointerEvents = "none";
|
|
2187
|
+
if (!animate) {
|
|
2188
|
+
entry.inFlight = null;
|
|
2189
|
+
entry.wrapper.style.visibility = "hidden";
|
|
2190
|
+
return;
|
|
2191
|
+
}
|
|
2192
|
+
const handle = runAnchorTransition(
|
|
2193
|
+
entry.def.element,
|
|
2194
|
+
entry.def.animation ?? opts.animation,
|
|
2195
|
+
"exit"
|
|
2196
|
+
);
|
|
2197
|
+
entry.inFlight = handle;
|
|
2198
|
+
void handle.finished.then(() => {
|
|
2199
|
+
if (entry.inFlight === handle && active !== entry) {
|
|
2200
|
+
entry.wrapper.style.visibility = "hidden";
|
|
2201
|
+
}
|
|
2202
|
+
});
|
|
2203
|
+
};
|
|
2204
|
+
const show = (entry, animate) => {
|
|
2205
|
+
entry.inFlight?.cancel();
|
|
2206
|
+
entry.inFlight = null;
|
|
2207
|
+
entry.wrapper.style.visibility = "";
|
|
2208
|
+
entry.wrapper.style.pointerEvents = entry.def.interactive ?? opts.interactive ?? false ? "auto" : "none";
|
|
2209
|
+
if (animate) {
|
|
2210
|
+
entry.inFlight = runAnchorTransition(
|
|
2211
|
+
entry.def.element,
|
|
2212
|
+
entry.def.animation ?? opts.animation,
|
|
2213
|
+
"enter"
|
|
2214
|
+
);
|
|
2215
|
+
}
|
|
2216
|
+
};
|
|
2217
|
+
const update = (animate) => {
|
|
2218
|
+
if (deps.isDestroyed()) return;
|
|
2219
|
+
const next = resolveActive();
|
|
2220
|
+
if (next === active) return;
|
|
2221
|
+
const prev = active;
|
|
2222
|
+
active = next;
|
|
2223
|
+
if (prev) hide(prev, animate);
|
|
2224
|
+
if (next) show(next, animate);
|
|
2225
|
+
};
|
|
2226
|
+
const offs = [
|
|
2227
|
+
deps.on("snap", () => update(true)),
|
|
2228
|
+
deps.on("open", () => update(true)),
|
|
2229
|
+
deps.on("close", () => update(true))
|
|
2230
|
+
];
|
|
2231
|
+
if (entries.some((e) => e.def.forRange)) {
|
|
2232
|
+
offs.push(deps.on("progress", () => update(true)));
|
|
2233
|
+
}
|
|
2234
|
+
update(false);
|
|
2235
|
+
return () => {
|
|
2236
|
+
offs.forEach((off) => off());
|
|
2237
|
+
for (const entry of entries) {
|
|
2238
|
+
entry.inFlight?.cancel();
|
|
2239
|
+
entry.inFlight = null;
|
|
2240
|
+
if (entry.wrapper.parentNode) {
|
|
2241
|
+
entry.wrapper.parentNode.removeChild(entry.wrapper);
|
|
2242
|
+
}
|
|
2243
|
+
}
|
|
2244
|
+
active = null;
|
|
2245
|
+
};
|
|
2246
|
+
}
|
|
2247
|
+
|
|
1826
2248
|
// src/core/primitives/engine-options.ts
|
|
1827
2249
|
var DEFAULT_FLICK_VELOCITY = 0.65;
|
|
1828
2250
|
var DEFAULT_DRAG_THRESHOLD = 18;
|
|
@@ -1841,6 +2263,12 @@ function resolveEngineOptions(opts, extras) {
|
|
|
1841
2263
|
dragThreshold: opts.dragThreshold ?? DEFAULT_DRAG_THRESHOLD,
|
|
1842
2264
|
rubberBandEnabled: opts.rubberBand ?? true,
|
|
1843
2265
|
closeOnBack: opts.closeOnBack ?? false,
|
|
2266
|
+
persistent: opts.persistent ?? false,
|
|
2267
|
+
disableClose: opts.disableClose ?? false,
|
|
2268
|
+
disableDrag: opts.disableDrag ?? false,
|
|
2269
|
+
closeOnRouteChange: opts.closeOnRouteChange ?? false,
|
|
2270
|
+
radius: opts.radius,
|
|
2271
|
+
maxHeight: opts.maxHeight,
|
|
1844
2272
|
initialAllowed,
|
|
1845
2273
|
initialId,
|
|
1846
2274
|
scrim: {
|
|
@@ -1867,7 +2295,8 @@ function resolveEngineOptions(opts, extras) {
|
|
|
1867
2295
|
closeOnEscape: opts.closeOnEscape,
|
|
1868
2296
|
lockBodyScroll: opts.lockBodyScroll,
|
|
1869
2297
|
inertSiblings: opts.inertSiblings,
|
|
1870
|
-
shouldApplyInertSiblings: extras?.shouldApplyInertSiblings
|
|
2298
|
+
shouldApplyInertSiblings: extras?.shouldApplyInertSiblings,
|
|
2299
|
+
returnFocus: opts.returnFocusTo
|
|
1871
2300
|
}
|
|
1872
2301
|
};
|
|
1873
2302
|
}
|
|
@@ -1912,6 +2341,11 @@ var BottomSheetEngine = class {
|
|
|
1912
2341
|
__publicField(this, "lifecycle");
|
|
1913
2342
|
__publicField(this, "closeOnBack");
|
|
1914
2343
|
__publicField(this, "routedTo");
|
|
2344
|
+
__publicField(this, "persistent");
|
|
2345
|
+
__publicField(this, "disableCloseFlag");
|
|
2346
|
+
__publicField(this, "disableDragFlag");
|
|
2347
|
+
__publicField(this, "closeOnRouteChange");
|
|
2348
|
+
__publicField(this, "maxHeightCap");
|
|
1915
2349
|
__publicField(this, "snapPointsRaw");
|
|
1916
2350
|
__publicField(this, "snaps");
|
|
1917
2351
|
__publicField(this, "activeId");
|
|
@@ -1924,6 +2358,7 @@ var BottomSheetEngine = class {
|
|
|
1924
2358
|
__publicField(this, "sizeWriteSentinel", new WriteSentinel());
|
|
1925
2359
|
__publicField(this, "progressWriteSentinel", new WriteSentinel());
|
|
1926
2360
|
__publicField(this, "isTopSheet", true);
|
|
2361
|
+
__publicField(this, "opening", false);
|
|
1927
2362
|
__publicField(this, "progressPayload", {
|
|
1928
2363
|
value: 0,
|
|
1929
2364
|
size: 0
|
|
@@ -1939,6 +2374,12 @@ var BottomSheetEngine = class {
|
|
|
1939
2374
|
__publicField(this, "linkedSheets", []);
|
|
1940
2375
|
__publicField(this, "scrollCache");
|
|
1941
2376
|
__publicField(this, "teardowns", new TeardownStack());
|
|
2377
|
+
__publicField(this, "anchors", []);
|
|
2378
|
+
__publicField(this, "anchorHost", null);
|
|
2379
|
+
__publicField(this, "stackZ", 100);
|
|
2380
|
+
__publicField(this, "detachScrimStages", null);
|
|
2381
|
+
__publicField(this, "stackEffectEnabled", false);
|
|
2382
|
+
__publicField(this, "stackEffectPrimed", false);
|
|
1942
2383
|
__publicField(this, "transformTemplate");
|
|
1943
2384
|
const resolved = resolveEngineOptions(opts, {
|
|
1944
2385
|
shouldApplyInertSiblings: () => {
|
|
@@ -1972,6 +2413,10 @@ var BottomSheetEngine = class {
|
|
|
1972
2413
|
getResolvedSnaps: () => this.snaps.getResolvedSnaps().slice(),
|
|
1973
2414
|
snapTo: (id) => {
|
|
1974
2415
|
void this.snapTo(id);
|
|
2416
|
+
},
|
|
2417
|
+
close: () => {
|
|
2418
|
+
if (!this.canDismiss()) return;
|
|
2419
|
+
void this.close("backdrop");
|
|
1975
2420
|
}
|
|
1976
2421
|
},
|
|
1977
2422
|
resolved.scrim
|
|
@@ -1995,6 +2440,11 @@ var BottomSheetEngine = class {
|
|
|
1995
2440
|
);
|
|
1996
2441
|
this.closeOnBack = resolved.closeOnBack;
|
|
1997
2442
|
this.routedTo = opts.routedTo;
|
|
2443
|
+
this.persistent = resolved.persistent;
|
|
2444
|
+
this.disableCloseFlag = resolved.disableClose;
|
|
2445
|
+
this.disableDragFlag = resolved.disableDrag;
|
|
2446
|
+
this.closeOnRouteChange = resolved.closeOnRouteChange;
|
|
2447
|
+
this.stackEffectEnabled = opts.stackEffect ?? false;
|
|
1998
2448
|
this.snapPointsRaw = opts.snapPoints;
|
|
1999
2449
|
this.persistKey = opts.persistKey;
|
|
2000
2450
|
if (opts.linkedSheets) {
|
|
@@ -2007,7 +2457,7 @@ var BottomSheetEngine = class {
|
|
|
2007
2457
|
this.snapPointsRaw,
|
|
2008
2458
|
resolved.initialAllowed,
|
|
2009
2459
|
this.mode,
|
|
2010
|
-
() => this.
|
|
2460
|
+
() => this.measureFitSize(),
|
|
2011
2461
|
(maxAxisSize) => {
|
|
2012
2462
|
this.element.style[layoutAxis(this.mode)] = `${maxAxisSize}px`;
|
|
2013
2463
|
}
|
|
@@ -2041,6 +2491,19 @@ var BottomSheetEngine = class {
|
|
|
2041
2491
|
io.observe(this.element);
|
|
2042
2492
|
this.teardowns.add(() => io.disconnect());
|
|
2043
2493
|
}
|
|
2494
|
+
this.installFitObserver();
|
|
2495
|
+
if (resolved.radius !== void 0) this.setRadius(resolved.radius);
|
|
2496
|
+
if (resolved.maxHeight !== void 0) this.setMaxHeight(resolved.maxHeight);
|
|
2497
|
+
this.applyAutoAriaLabelledBy();
|
|
2498
|
+
if (this.closeOnRouteChange) {
|
|
2499
|
+
this.teardowns.add(
|
|
2500
|
+
installRouteChange({
|
|
2501
|
+
isDestroyed: () => this.destroyed,
|
|
2502
|
+
getSize: () => this.size,
|
|
2503
|
+
close: () => this.close()
|
|
2504
|
+
})
|
|
2505
|
+
);
|
|
2506
|
+
}
|
|
2044
2507
|
if (this.persistKey) {
|
|
2045
2508
|
this.teardowns.add(installPersist(this, this.persistKey));
|
|
2046
2509
|
}
|
|
@@ -2065,7 +2528,7 @@ var BottomSheetEngine = class {
|
|
|
2065
2528
|
isTopSheet: () => this.isTopSheet,
|
|
2066
2529
|
getSize: () => this.size,
|
|
2067
2530
|
isDestroyed: () => this.destroyed,
|
|
2068
|
-
close: () => this.close(),
|
|
2531
|
+
close: () => this.close("back"),
|
|
2069
2532
|
on: (event, fn) => this.on(event, fn),
|
|
2070
2533
|
sheetId: this.id
|
|
2071
2534
|
})
|
|
@@ -2159,6 +2622,10 @@ var BottomSheetEngine = class {
|
|
|
2159
2622
|
const previousSize = this.size;
|
|
2160
2623
|
this.scrollCache.cache(previousId, previousSize, target.size);
|
|
2161
2624
|
this.activeId = id;
|
|
2625
|
+
if (wasClosed && target.size > 0) {
|
|
2626
|
+
this.opening = true;
|
|
2627
|
+
sheetStack.promote(this.id);
|
|
2628
|
+
}
|
|
2162
2629
|
if (this.animation.viewTransitionsAvailable) {
|
|
2163
2630
|
this.currentViewTransition?.skipTransition?.();
|
|
2164
2631
|
const vt = document.startViewTransition(() => {
|
|
@@ -2173,19 +2640,26 @@ var BottomSheetEngine = class {
|
|
|
2173
2640
|
} else {
|
|
2174
2641
|
await this.animation.animateTo(target.size, velocityPxPerMs);
|
|
2175
2642
|
}
|
|
2643
|
+
this.opening = false;
|
|
2176
2644
|
externalSignal?.removeEventListener("abort", onExternalAbort);
|
|
2177
2645
|
if (signal.aborted) return;
|
|
2178
2646
|
this.scrollCache.restore(id, previousSize, target.size);
|
|
2179
2647
|
this.updateAriaSlider();
|
|
2180
|
-
this.emit("snap", {
|
|
2648
|
+
this.emit("snap", {
|
|
2649
|
+
id,
|
|
2650
|
+
size: target.size,
|
|
2651
|
+
progress: this.computeProgress(target.size)
|
|
2652
|
+
});
|
|
2181
2653
|
if (wasClosed && target.size > 0) {
|
|
2182
2654
|
this.emit("open", { id });
|
|
2183
2655
|
this.handleOpen();
|
|
2184
2656
|
notifyLinkedSheets(this.linkedSheets, this);
|
|
2657
|
+
this.emit("opened", { id });
|
|
2185
2658
|
}
|
|
2186
2659
|
if (target.size === 0) {
|
|
2187
2660
|
this.emit("close", void 0);
|
|
2188
2661
|
this.handleClose();
|
|
2662
|
+
this.emit("closed", void 0);
|
|
2189
2663
|
}
|
|
2190
2664
|
}
|
|
2191
2665
|
async dragTo(targetSize, velocityOrOpts = 0) {
|
|
@@ -2210,18 +2684,76 @@ var BottomSheetEngine = class {
|
|
|
2210
2684
|
const target = id ?? this.snaps.getAllowedIds().find((a) => a !== "closed") ?? this.activeId;
|
|
2211
2685
|
return this.snapTo(target);
|
|
2212
2686
|
}
|
|
2213
|
-
close() {
|
|
2687
|
+
close(reason = "programmatic") {
|
|
2214
2688
|
if (this.destroyed) return Promise.resolve();
|
|
2689
|
+
if (this.disableCloseFlag) return Promise.resolve();
|
|
2690
|
+
if (this.size > 0 && this.emitBeforeClose(reason)) return Promise.resolve();
|
|
2215
2691
|
const closedId = this.snapPointsRaw.find((p) => p.id === "closed")?.id ?? this.snaps.getAllowedIds()[0];
|
|
2216
2692
|
return this.snapTo(closedId ?? this.activeId);
|
|
2217
2693
|
}
|
|
2218
|
-
|
|
2694
|
+
canDismiss() {
|
|
2695
|
+
return !this.persistent && !this.disableCloseFlag && !this.destroyed;
|
|
2696
|
+
}
|
|
2697
|
+
isTop() {
|
|
2698
|
+
return this.isTopSheet;
|
|
2699
|
+
}
|
|
2700
|
+
depth() {
|
|
2701
|
+
return sheetStack.depthOf(this.id);
|
|
2702
|
+
}
|
|
2703
|
+
expand() {
|
|
2704
|
+
if (this.destroyed) return Promise.resolve();
|
|
2705
|
+
const ids = this.allowedIdsBySize();
|
|
2706
|
+
const target = ids[ids.length - 1];
|
|
2707
|
+
if (!target) return Promise.resolve();
|
|
2708
|
+
return this.snapTo(target);
|
|
2709
|
+
}
|
|
2710
|
+
collapse() {
|
|
2711
|
+
if (this.destroyed) return Promise.resolve();
|
|
2712
|
+
const ids = this.allowedIdsBySize();
|
|
2713
|
+
const nonZero = ids.find((id) => (this.snaps.findById(id)?.size ?? 0) > 0);
|
|
2714
|
+
const target = nonZero ?? ids[0];
|
|
2715
|
+
if (!target) return Promise.resolve();
|
|
2716
|
+
return this.snapTo(target);
|
|
2717
|
+
}
|
|
2718
|
+
setRadius(r) {
|
|
2219
2719
|
if (this.destroyed) return;
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2720
|
+
this.element.style.setProperty(
|
|
2721
|
+
"--bs-radius",
|
|
2722
|
+
typeof r === "number" ? `${r}px` : r
|
|
2723
|
+
);
|
|
2724
|
+
}
|
|
2725
|
+
setMaxHeight(h) {
|
|
2726
|
+
if (this.destroyed) return;
|
|
2727
|
+
const value = typeof h === "number" ? `${h}px` : h;
|
|
2728
|
+
const axis = layoutAxis(this.mode);
|
|
2729
|
+
this.element.style.setProperty(
|
|
2730
|
+
axis === "height" ? "maxHeight" : "maxWidth",
|
|
2731
|
+
value
|
|
2732
|
+
);
|
|
2733
|
+
if (typeof h === "number") {
|
|
2734
|
+
this.maxHeightCap = h;
|
|
2735
|
+
this.clampToMaxHeight();
|
|
2736
|
+
} else if (typeof window !== "undefined") {
|
|
2737
|
+
const probe2 = document.createElement("div");
|
|
2738
|
+
probe2.style.cssText = `position:absolute;visibility:hidden;pointer-events:none;${axis === "height" ? "height" : "width"}:${value};`;
|
|
2739
|
+
document.body.appendChild(probe2);
|
|
2740
|
+
const measured = axis === "height" ? probe2.offsetHeight : probe2.offsetWidth;
|
|
2741
|
+
probe2.remove();
|
|
2742
|
+
this.maxHeightCap = measured > 0 ? measured : void 0;
|
|
2743
|
+
this.clampToMaxHeight();
|
|
2224
2744
|
}
|
|
2745
|
+
}
|
|
2746
|
+
clampToMaxHeight() {
|
|
2747
|
+
if (this.maxHeightCap === void 0) return;
|
|
2748
|
+
if (this.snaps.getMaxAxisSize() > this.maxHeightCap) {
|
|
2749
|
+
this.snaps.setMaxAxisSize(this.maxHeightCap);
|
|
2750
|
+
}
|
|
2751
|
+
if (this.size > this.maxHeightCap && !this.gesture?.isDragging) {
|
|
2752
|
+
this.applySize(this.maxHeightCap);
|
|
2753
|
+
}
|
|
2754
|
+
}
|
|
2755
|
+
setAllowed(ids, snap) {
|
|
2756
|
+
if (this.destroyed) return;
|
|
2225
2757
|
this.snaps.setAllowedIds(ids);
|
|
2226
2758
|
this.updateAriaSlider();
|
|
2227
2759
|
if (snap && ids.includes(snap)) {
|
|
@@ -2261,6 +2793,79 @@ var BottomSheetEngine = class {
|
|
|
2261
2793
|
setScrimOverlay(opts) {
|
|
2262
2794
|
return this.scrim.setScrimOverlay(opts);
|
|
2263
2795
|
}
|
|
2796
|
+
addAnchor(opts) {
|
|
2797
|
+
if (this.destroyed || typeof document === "undefined") return () => {
|
|
2798
|
+
};
|
|
2799
|
+
if (!this.anchorHost) {
|
|
2800
|
+
this.anchorHost = this.rootEl ?? this.element.parentElement ?? document.body;
|
|
2801
|
+
this.anchorHost.style.setProperty("--bs-size", `${this.size}px`);
|
|
2802
|
+
this.anchorHost.style.setProperty(
|
|
2803
|
+
"--bs-progress",
|
|
2804
|
+
String(this.computeProgress(this.size))
|
|
2805
|
+
);
|
|
2806
|
+
}
|
|
2807
|
+
const handle = attachAnchor(
|
|
2808
|
+
{
|
|
2809
|
+
mode: this.mode,
|
|
2810
|
+
host: this.anchorHost,
|
|
2811
|
+
getState: () => ({
|
|
2812
|
+
activeId: this.activeId,
|
|
2813
|
+
size: this.size,
|
|
2814
|
+
progress: this.computeProgress(this.size)
|
|
2815
|
+
}),
|
|
2816
|
+
on: (event, fn) => this.on(event, fn),
|
|
2817
|
+
isDestroyed: () => this.destroyed
|
|
2818
|
+
},
|
|
2819
|
+
opts
|
|
2820
|
+
);
|
|
2821
|
+
handle.syncZ(this.stackZ + 1);
|
|
2822
|
+
this.anchors.push(handle);
|
|
2823
|
+
const detach = () => {
|
|
2824
|
+
const idx = this.anchors.indexOf(handle);
|
|
2825
|
+
if (idx === -1) return;
|
|
2826
|
+
this.anchors.splice(idx, 1);
|
|
2827
|
+
handle.detach();
|
|
2828
|
+
};
|
|
2829
|
+
this.teardowns.add(detach);
|
|
2830
|
+
return detach;
|
|
2831
|
+
}
|
|
2832
|
+
setScrimStages(opts) {
|
|
2833
|
+
if (this.destroyed || typeof document === "undefined") return () => {
|
|
2834
|
+
};
|
|
2835
|
+
this.detachScrimStages?.();
|
|
2836
|
+
this.detachScrimStages = null;
|
|
2837
|
+
if (!opts) return () => {
|
|
2838
|
+
};
|
|
2839
|
+
const host = this.screenComponent?.parentElement;
|
|
2840
|
+
if (!host) {
|
|
2841
|
+
console.warn(
|
|
2842
|
+
"[BottomSheet] setScrimStages: no scrim element mounted \u2014 pass `scrim` to the engine first."
|
|
2843
|
+
);
|
|
2844
|
+
return () => {
|
|
2845
|
+
};
|
|
2846
|
+
}
|
|
2847
|
+
const detachInstalled = installScrimStages(
|
|
2848
|
+
{
|
|
2849
|
+
mode: this.mode,
|
|
2850
|
+
host,
|
|
2851
|
+
getState: () => ({
|
|
2852
|
+
activeId: this.activeId,
|
|
2853
|
+
size: this.size,
|
|
2854
|
+
progress: this.computeProgress(this.size)
|
|
2855
|
+
}),
|
|
2856
|
+
on: (event, fn) => this.on(event, fn),
|
|
2857
|
+
isDestroyed: () => this.destroyed
|
|
2858
|
+
},
|
|
2859
|
+
opts
|
|
2860
|
+
);
|
|
2861
|
+
const detach = () => {
|
|
2862
|
+
if (this.detachScrimStages === detach) this.detachScrimStages = null;
|
|
2863
|
+
detachInstalled();
|
|
2864
|
+
};
|
|
2865
|
+
this.detachScrimStages = detach;
|
|
2866
|
+
this.teardowns.add(() => this.detachScrimStages?.());
|
|
2867
|
+
return detach;
|
|
2868
|
+
}
|
|
2264
2869
|
getScrimState() {
|
|
2265
2870
|
return { mode: this.scrim.scrimMode, enabled: this.scrim.scrimEnabled };
|
|
2266
2871
|
}
|
|
@@ -2280,8 +2885,53 @@ var BottomSheetEngine = class {
|
|
|
2280
2885
|
}
|
|
2281
2886
|
this.updateAriaSlider();
|
|
2282
2887
|
}
|
|
2888
|
+
recompute() {
|
|
2889
|
+
if (this.destroyed) return;
|
|
2890
|
+
this.snaps.recompute();
|
|
2891
|
+
this.scrim.invalidateOpacityCache();
|
|
2892
|
+
if (this.gesture?.isDragging) return;
|
|
2893
|
+
const current = this.snaps.findById(this.activeId);
|
|
2894
|
+
if (current) {
|
|
2895
|
+
this.size = current.size;
|
|
2896
|
+
this.applySize(this.size);
|
|
2897
|
+
this.updateAriaSlider();
|
|
2898
|
+
}
|
|
2899
|
+
}
|
|
2900
|
+
measureFitSize() {
|
|
2901
|
+
const vertical = layoutAxis(this.mode) === "height";
|
|
2902
|
+
const handleSize = vertical ? this.handle.offsetHeight : this.handle.offsetWidth;
|
|
2903
|
+
const content = this.scrollContainer;
|
|
2904
|
+
const natural = content ? handleSize + (vertical ? content.scrollHeight : content.scrollWidth) : handleSize;
|
|
2905
|
+
if (typeof window === "undefined") return natural;
|
|
2906
|
+
const viewport = vertical ? window.innerHeight : window.innerWidth;
|
|
2907
|
+
return viewport > 0 ? Math.min(natural, viewport) : natural;
|
|
2908
|
+
}
|
|
2909
|
+
installFitObserver() {
|
|
2910
|
+
if (typeof ResizeObserver === "undefined") return;
|
|
2911
|
+
if (!this.snapPointsRaw.some((p) => p.size === "fit" || p.size === "content"))
|
|
2912
|
+
return;
|
|
2913
|
+
const targets = [this.handle];
|
|
2914
|
+
if (this.scrollContainer && this.scrollContainer !== this.handle) {
|
|
2915
|
+
targets.push(this.scrollContainer);
|
|
2916
|
+
}
|
|
2917
|
+
let raf = 0;
|
|
2918
|
+
const ro = new ResizeObserver(() => {
|
|
2919
|
+
if (raf) return;
|
|
2920
|
+
raf = requestAnimationFrame(() => {
|
|
2921
|
+
raf = 0;
|
|
2922
|
+
if (this.destroyed || this.gesture?.isDragging) return;
|
|
2923
|
+
this.recompute();
|
|
2924
|
+
});
|
|
2925
|
+
});
|
|
2926
|
+
for (const t of targets) ro.observe(t);
|
|
2927
|
+
this.teardowns.add(() => {
|
|
2928
|
+
ro.disconnect();
|
|
2929
|
+
if (raf) cancelAnimationFrame(raf);
|
|
2930
|
+
});
|
|
2931
|
+
}
|
|
2283
2932
|
destroy() {
|
|
2284
2933
|
this.destroyed = true;
|
|
2934
|
+
this.opening = false;
|
|
2285
2935
|
this.currentAbort.abort();
|
|
2286
2936
|
this.currentViewTransition?.skipTransition?.();
|
|
2287
2937
|
this.currentViewTransition = null;
|
|
@@ -2331,6 +2981,36 @@ var BottomSheetEngine = class {
|
|
|
2331
2981
|
frozen = true;
|
|
2332
2982
|
return cancelled;
|
|
2333
2983
|
}
|
|
2984
|
+
emitBeforeClose(reason) {
|
|
2985
|
+
let cancelled = false;
|
|
2986
|
+
let frozen = false;
|
|
2987
|
+
this.emit("before-close", {
|
|
2988
|
+
reason,
|
|
2989
|
+
cancel: () => {
|
|
2990
|
+
if (frozen) {
|
|
2991
|
+
console.warn(
|
|
2992
|
+
"[BottomSheet] before-close.cancel() called asynchronously \u2014 ignored. cancel() must be invoked synchronously inside the listener."
|
|
2993
|
+
);
|
|
2994
|
+
return;
|
|
2995
|
+
}
|
|
2996
|
+
cancelled = true;
|
|
2997
|
+
}
|
|
2998
|
+
});
|
|
2999
|
+
frozen = true;
|
|
3000
|
+
return cancelled;
|
|
3001
|
+
}
|
|
3002
|
+
applyAutoAriaLabelledBy() {
|
|
3003
|
+
if (typeof document === "undefined") return;
|
|
3004
|
+
if (!this.lifecycle.focusTrapEnabled) return;
|
|
3005
|
+
if (this.element.getAttribute("aria-labelledby")) return;
|
|
3006
|
+
const scope = this.handle ?? this.element;
|
|
3007
|
+
const titled = scope.querySelector("[data-bs-title]") ?? scope.querySelector("h1,h2,h3,h4,h5,h6");
|
|
3008
|
+
if (!titled) return;
|
|
3009
|
+
if (!titled.id) {
|
|
3010
|
+
titled.id = nextInstanceId("bs-title");
|
|
3011
|
+
}
|
|
3012
|
+
this.element.setAttribute("aria-labelledby", titled.id);
|
|
3013
|
+
}
|
|
2334
3014
|
recomputeSnaps() {
|
|
2335
3015
|
const seen = /* @__PURE__ */ new Set();
|
|
2336
3016
|
for (const p of this.snapPointsRaw) {
|
|
@@ -2347,24 +3027,42 @@ var BottomSheetEngine = class {
|
|
|
2347
3027
|
getAllowedRange() {
|
|
2348
3028
|
return this.snaps.getAllowedRange();
|
|
2349
3029
|
}
|
|
3030
|
+
allowedIdsBySize() {
|
|
3031
|
+
return this.snaps.getAllowedIds().slice().sort(
|
|
3032
|
+
(a, b) => (this.snaps.findById(a)?.size ?? 0) - (this.snaps.findById(b)?.size ?? 0)
|
|
3033
|
+
);
|
|
3034
|
+
}
|
|
2350
3035
|
updateAriaSlider() {
|
|
2351
|
-
this.aria.setValue(this.
|
|
3036
|
+
this.aria.setValue(this.allowedIdsBySize(), this.activeId);
|
|
2352
3037
|
}
|
|
2353
3038
|
registerInStack() {
|
|
2354
3039
|
this.teardowns.add(sheetStack.push({
|
|
2355
3040
|
id: this.id,
|
|
2356
3041
|
setZIndex: (z) => {
|
|
3042
|
+
this.stackZ = z;
|
|
2357
3043
|
this.element.style.zIndex = String(z);
|
|
2358
3044
|
if (this.backdrop) this.backdrop.style.zIndex = String(z - 1);
|
|
3045
|
+
for (const anchor of this.anchors) anchor.syncZ(z + 1);
|
|
2359
3046
|
},
|
|
2360
3047
|
setIsTop: (isTop) => {
|
|
2361
3048
|
this.isTopSheet = isTop;
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
}
|
|
3049
|
+
},
|
|
3050
|
+
isOpen: () => this.size > 0 || this.opening,
|
|
3051
|
+
setDepth: (depth) => this.applyStackDepth(depth)
|
|
2366
3052
|
}));
|
|
2367
3053
|
}
|
|
3054
|
+
applyStackDepth(depth) {
|
|
3055
|
+
if (!this.stackEffectEnabled) return;
|
|
3056
|
+
this.element.setAttribute("data-stack-depth", String(depth));
|
|
3057
|
+
if (!this.stackEffectPrimed) {
|
|
3058
|
+
this.stackEffectPrimed = true;
|
|
3059
|
+
const isVertical = this.mode === "bottom" || this.mode === "top";
|
|
3060
|
+
this.element.style.transformOrigin = isVertical ? "50% 100%" : "0% 50%";
|
|
3061
|
+
this.element.style.transition = "scale 320ms cubic-bezier(0.29, 1.04, 0.84, 0.99)";
|
|
3062
|
+
}
|
|
3063
|
+
const scale = Math.max(1 - depth * 0.04, 0.86);
|
|
3064
|
+
this.element.style.scale = scale === 1 ? "" : String(scale);
|
|
3065
|
+
}
|
|
2368
3066
|
attach() {
|
|
2369
3067
|
this.gesture = new GestureController({
|
|
2370
3068
|
handle: this.handle,
|
|
@@ -2381,6 +3079,7 @@ var BottomSheetEngine = class {
|
|
|
2381
3079
|
buf.rubberBandEnabled = this.rubberBandEnabled;
|
|
2382
3080
|
return buf;
|
|
2383
3081
|
},
|
|
3082
|
+
getDisableDrag: () => this.disableDragFlag,
|
|
2384
3083
|
cancelAnimation: () => this.animation.cancel(),
|
|
2385
3084
|
applySize: (size) => this.applySize(size),
|
|
2386
3085
|
animateTo: (size, velocity) => this.animation.animateTo(size, velocity),
|
|
@@ -2424,7 +3123,7 @@ var BottomSheetEngine = class {
|
|
|
2424
3123
|
container: this.scrollContainer,
|
|
2425
3124
|
isDragging: () => this.gesture?.isDragging ?? false,
|
|
2426
3125
|
isAnimating: () => this.animation.isAnimating,
|
|
2427
|
-
getAllowedIds: () => this.
|
|
3126
|
+
getAllowedIds: () => this.allowedIdsBySize(),
|
|
2428
3127
|
getActiveId: () => this.activeId,
|
|
2429
3128
|
snapTo: (id) => {
|
|
2430
3129
|
void this.snapTo(id);
|
|
@@ -2453,13 +3152,16 @@ var BottomSheetEngine = class {
|
|
|
2453
3152
|
},
|
|
2454
3153
|
newCycle: () => {
|
|
2455
3154
|
this.newCycle();
|
|
2456
|
-
}
|
|
3155
|
+
},
|
|
3156
|
+
isAnimating: () => this.animation.isAnimating,
|
|
3157
|
+
resyncAfterCancel: () => this.resyncAfterResize()
|
|
2457
3158
|
}));
|
|
2458
3159
|
if (this.lifecycle.closeOnEscape) {
|
|
2459
3160
|
const onKey = (e) => {
|
|
2460
|
-
if (this.destroyed) return;
|
|
3161
|
+
if (this.destroyed || e.defaultPrevented) return;
|
|
3162
|
+
if (!this.canDismiss()) return;
|
|
2461
3163
|
if (e.key === "Escape" && this.isTopSheet && this.size > 0) {
|
|
2462
|
-
void this.close();
|
|
3164
|
+
void this.close("escape");
|
|
2463
3165
|
}
|
|
2464
3166
|
};
|
|
2465
3167
|
document.addEventListener("keydown", onKey);
|
|
@@ -2489,7 +3191,7 @@ var BottomSheetEngine = class {
|
|
|
2489
3191
|
handle: this.handle,
|
|
2490
3192
|
mode: this.mode,
|
|
2491
3193
|
isDestroyed: () => this.destroyed,
|
|
2492
|
-
getAllowedIds: () => this.
|
|
3194
|
+
getAllowedIds: () => this.allowedIdsBySize(),
|
|
2493
3195
|
getActiveId: () => this.activeId,
|
|
2494
3196
|
snapTo: (id) => {
|
|
2495
3197
|
void this.snapTo(id);
|
|
@@ -2510,6 +3212,7 @@ var BottomSheetEngine = class {
|
|
|
2510
3212
|
});
|
|
2511
3213
|
if (!target) return;
|
|
2512
3214
|
const previousId = this.activeId;
|
|
3215
|
+
if (target.id === previousId && target.size === this.size) return;
|
|
2513
3216
|
if (this.emitBeforeSnap(target, previousId)) {
|
|
2514
3217
|
const restore = this.snaps.findById(previousId);
|
|
2515
3218
|
if (restore) {
|
|
@@ -2518,21 +3221,34 @@ var BottomSheetEngine = class {
|
|
|
2518
3221
|
return;
|
|
2519
3222
|
}
|
|
2520
3223
|
const previousSize = this.size;
|
|
3224
|
+
const previousSnapSize = this.snaps.findById(previousId)?.size;
|
|
2521
3225
|
this.scrollCache.cache(previousId, previousSize, target.size);
|
|
2522
3226
|
this.activeId = target.id;
|
|
3227
|
+
if (previousSnapSize === 0 && target.size > 0) {
|
|
3228
|
+
this.opening = true;
|
|
3229
|
+
sheetStack.promote(this.id);
|
|
3230
|
+
}
|
|
2523
3231
|
void this.animation.animateTo(target.size, velocity).then(() => {
|
|
3232
|
+
this.opening = false;
|
|
2524
3233
|
if (signal.aborted) return;
|
|
2525
3234
|
this.scrollCache.restore(target.id, previousSize, target.size);
|
|
2526
3235
|
this.updateAriaSlider();
|
|
2527
|
-
this.emit("snap", {
|
|
3236
|
+
this.emit("snap", {
|
|
3237
|
+
id: target.id,
|
|
3238
|
+
size: target.size,
|
|
3239
|
+
progress: this.computeProgress(target.size)
|
|
3240
|
+
});
|
|
2528
3241
|
this.haptic();
|
|
2529
|
-
if (
|
|
3242
|
+
if (previousSnapSize === 0 && target.size > 0) {
|
|
2530
3243
|
this.emit("open", { id: target.id });
|
|
2531
3244
|
this.handleOpen();
|
|
3245
|
+
notifyLinkedSheets(this.linkedSheets, this);
|
|
3246
|
+
this.emit("opened", { id: target.id });
|
|
2532
3247
|
}
|
|
2533
3248
|
if (target.size === 0) {
|
|
2534
3249
|
this.emit("close", void 0);
|
|
2535
3250
|
this.handleClose();
|
|
3251
|
+
this.emit("closed", void 0);
|
|
2536
3252
|
}
|
|
2537
3253
|
});
|
|
2538
3254
|
}
|
|
@@ -2554,6 +3270,9 @@ var BottomSheetEngine = class {
|
|
|
2554
3270
|
if (this.scrimParent) {
|
|
2555
3271
|
this.scrimParent.style.setProperty("--bs-size", `${size}px`);
|
|
2556
3272
|
}
|
|
3273
|
+
if (this.anchorHost && this.anchorHost !== this.scrimParent) {
|
|
3274
|
+
this.anchorHost.style.setProperty("--bs-size", `${size}px`);
|
|
3275
|
+
}
|
|
2557
3276
|
}
|
|
2558
3277
|
const progress = this.computeProgress(size);
|
|
2559
3278
|
const progressChanged = this.progressWriteSentinel.shouldWrite(
|
|
@@ -2562,6 +3281,9 @@ var BottomSheetEngine = class {
|
|
|
2562
3281
|
);
|
|
2563
3282
|
if (progressChanged) {
|
|
2564
3283
|
style.setProperty("--bs-progress", String(progress));
|
|
3284
|
+
if (this.anchorHost) {
|
|
3285
|
+
this.anchorHost.style.setProperty("--bs-progress", String(progress));
|
|
3286
|
+
}
|
|
2565
3287
|
}
|
|
2566
3288
|
this.scrim.applyOpacity(progress, progressChanged);
|
|
2567
3289
|
if (progressChanged && this.bus.listenerCount("progress") > 0) {
|
|
@@ -2576,6 +3298,7 @@ var BottomSheetEngine = class {
|
|
|
2576
3298
|
return Math.min(Math.max((size - min) / (max - min), 0), 1);
|
|
2577
3299
|
}
|
|
2578
3300
|
handleOpen() {
|
|
3301
|
+
sheetStack.promote(this.id);
|
|
2579
3302
|
try {
|
|
2580
3303
|
this.lifecycle.install();
|
|
2581
3304
|
} catch (err) {
|
|
@@ -2589,8 +3312,31 @@ var BottomSheetEngine = class {
|
|
|
2589
3312
|
});
|
|
2590
3313
|
}
|
|
2591
3314
|
}
|
|
3315
|
+
resyncAfterResize() {
|
|
3316
|
+
if (this.destroyed) return;
|
|
3317
|
+
const target = this.snaps.findById(this.activeId);
|
|
3318
|
+
if (!target) return;
|
|
3319
|
+
this.updateAriaSlider();
|
|
3320
|
+
this.emit("snap", {
|
|
3321
|
+
id: target.id,
|
|
3322
|
+
size: target.size,
|
|
3323
|
+
progress: this.computeProgress(target.size)
|
|
3324
|
+
});
|
|
3325
|
+
if (target.size > 0 && !this.lifecycle.isInstalled) {
|
|
3326
|
+
this.emit("open", { id: target.id });
|
|
3327
|
+
this.handleOpen();
|
|
3328
|
+
notifyLinkedSheets(this.linkedSheets, this);
|
|
3329
|
+
this.emit("opened", { id: target.id });
|
|
3330
|
+
} else if (target.size === 0 && this.lifecycle.isInstalled) {
|
|
3331
|
+
this.emit("close", void 0);
|
|
3332
|
+
this.handleClose();
|
|
3333
|
+
this.emit("closed", void 0);
|
|
3334
|
+
}
|
|
3335
|
+
}
|
|
2592
3336
|
handleClose() {
|
|
3337
|
+
this.opening = false;
|
|
2593
3338
|
this.lifecycle.release();
|
|
3339
|
+
sheetStack.update();
|
|
2594
3340
|
}
|
|
2595
3341
|
};
|
|
2596
3342
|
|
|
@@ -2608,17 +3354,18 @@ function createBottomSheet(opts) {
|
|
|
2608
3354
|
const attach = (refs) => {
|
|
2609
3355
|
if (engine) engine.destroy();
|
|
2610
3356
|
const { onSnap, ...engineOpts } = opts;
|
|
2611
|
-
|
|
3357
|
+
const created = new BottomSheetEngine({ ...engineOpts, ...refs });
|
|
3358
|
+
engine = created;
|
|
2612
3359
|
if (onSnap) {
|
|
2613
|
-
|
|
3360
|
+
created.on("snap", (payload) => onSnap(payload.id));
|
|
2614
3361
|
}
|
|
2615
3362
|
for (const entry of pending) {
|
|
2616
|
-
entry.engineUnsub =
|
|
3363
|
+
entry.engineUnsub = created.on(entry.event, entry.fn);
|
|
2617
3364
|
}
|
|
2618
3365
|
pending.length = 0;
|
|
2619
3366
|
return () => {
|
|
2620
|
-
|
|
2621
|
-
engine = null;
|
|
3367
|
+
created.destroy();
|
|
3368
|
+
if (engine === created) engine = null;
|
|
2622
3369
|
};
|
|
2623
3370
|
};
|
|
2624
3371
|
return {
|
|
@@ -2641,7 +3388,20 @@ function createBottomSheet(opts) {
|
|
|
2641
3388
|
snapTo: (id) => engine?.snapTo(id) ?? Promise.resolve(),
|
|
2642
3389
|
open: (id) => engine?.open(id) ?? Promise.resolve(),
|
|
2643
3390
|
close: () => engine?.close() ?? Promise.resolve(),
|
|
3391
|
+
expand: () => engine?.expand() ?? Promise.resolve(),
|
|
3392
|
+
collapse: () => engine?.collapse() ?? Promise.resolve(),
|
|
3393
|
+
isTop: () => engine?.isTop() ?? false,
|
|
3394
|
+
depth: () => engine?.depth() ?? 0,
|
|
2644
3395
|
setAllowed: (ids, snap) => engine?.setAllowed(ids, snap),
|
|
3396
|
+
setSnapPoints: (points, allowed) => engine?.setSnapPoints(points, allowed),
|
|
3397
|
+
setScrim: (scrimOpts) => engine?.setScrim(scrimOpts),
|
|
3398
|
+
setScrimOverlay: (overlayOpts) => engine?.setScrimOverlay(overlayOpts) ?? (() => {
|
|
3399
|
+
}),
|
|
3400
|
+
addAnchor: (anchorOpts) => engine?.addAnchor(anchorOpts) ?? (() => {
|
|
3401
|
+
}),
|
|
3402
|
+
setScrimStages: (stagesOpts) => engine?.setScrimStages(stagesOpts) ?? (() => {
|
|
3403
|
+
}),
|
|
3404
|
+
recompute: () => engine?.recompute(),
|
|
2645
3405
|
destroy: () => {
|
|
2646
3406
|
engine?.destroy();
|
|
2647
3407
|
engine = null;
|
|
@@ -2655,7 +3415,7 @@ var root_4 = $2.from_html(`<div class="bs-button-slot" data-side="right"><!></di
|
|
|
2655
3415
|
var root = $2.from_html(`<div class="bs-root"><!> <div class="bs-screen"><!></div> <section class="bs-sheet" role="dialog"><!> <!> <div class="bs-handle" role="slider" tabindex="0" aria-label="Resize sheet"><!></div> <div class="bs-content" tabindex="0" role="region" aria-label="Sheet content"><!></div> <span class="bs-sr-only" role="status" aria-live="polite"> </span></section></div>`);
|
|
2656
3416
|
function BottomSheet($$anchor, $$props) {
|
|
2657
3417
|
$2.push($$props, true);
|
|
2658
|
-
let mode = $2.prop($$props, "mode", 3, "bottom"), animation = $2.prop($$props, "animation", 3, "spring"), focusTrap = $2.prop($$props, "focusTrap", 3, false), closeOnEscape = $2.prop($$props, "closeOnEscape", 3, true), closeOnBack = $2.prop($$props, "closeOnBack", 3, false), lockBodyScroll2 = $2.prop($$props, "lockBodyScroll", 3, true), rubberBand2 = $2.prop($$props, "rubberBand", 3, true), backdrop = $2.prop($$props, "backdrop", 3, true), closeOnBackdrop = $2.prop($$props, "closeOnBackdrop", 3, true), ariaLabel = $2.prop($$props, "ariaLabel", 3, "Bottom sheet");
|
|
3418
|
+
let mode = $2.prop($$props, "mode", 3, "bottom"), animation = $2.prop($$props, "animation", 3, "spring"), focusTrap = $2.prop($$props, "focusTrap", 3, false), closeOnEscape = $2.prop($$props, "closeOnEscape", 3, true), closeOnBack = $2.prop($$props, "closeOnBack", 3, false), lockBodyScroll2 = $2.prop($$props, "lockBodyScroll", 3, true), rubberBand2 = $2.prop($$props, "rubberBand", 3, true), backdrop = $2.prop($$props, "backdrop", 3, true), closeOnBackdrop = $2.prop($$props, "closeOnBackdrop", 3, true), persistent = $2.prop($$props, "persistent", 3, false), disableClose = $2.prop($$props, "disableClose", 3, false), disableDrag = $2.prop($$props, "disableDrag", 3, false), closeOnRouteChange = $2.prop($$props, "closeOnRouteChange", 3, false), openProp = $2.prop($$props, "open", 15), snap = $2.prop($$props, "snap", 15), ariaLabel = $2.prop($$props, "ariaLabel", 3, "Bottom sheet");
|
|
2659
3419
|
let sheetEl = $2.state(void 0);
|
|
2660
3420
|
let handleEl = $2.state(void 0);
|
|
2661
3421
|
let contentEl = $2.state(void 0);
|
|
@@ -2663,7 +3423,7 @@ function BottomSheet($$anchor, $$props) {
|
|
|
2663
3423
|
let screenEl = $2.state(void 0);
|
|
2664
3424
|
let viewState = $2.state($2.proxy({
|
|
2665
3425
|
size: 0,
|
|
2666
|
-
activeId: $$props.initial ?? $$props.snapPoints[0]?.id ?? "default",
|
|
3426
|
+
activeId: untrack(() => $$props.initial ?? $$props.snapPoints[0]?.id ?? "default"),
|
|
2667
3427
|
isDragging: false,
|
|
2668
3428
|
isAnimating: false,
|
|
2669
3429
|
progress: 0
|
|
@@ -2688,7 +3448,14 @@ function BottomSheet($$anchor, $$props) {
|
|
|
2688
3448
|
closeOnBack: closeOnBack(),
|
|
2689
3449
|
lockBodyScroll: lockBodyScroll2(),
|
|
2690
3450
|
rubberBand: rubberBand2(),
|
|
2691
|
-
backdropRange: $$props.backdropRange
|
|
3451
|
+
backdropRange: $$props.backdropRange,
|
|
3452
|
+
persistent: persistent(),
|
|
3453
|
+
disableClose: disableClose(),
|
|
3454
|
+
disableDrag: disableDrag(),
|
|
3455
|
+
closeOnRouteChange: closeOnRouteChange(),
|
|
3456
|
+
radius: $$props.radius,
|
|
3457
|
+
maxHeight: $$props.maxHeight,
|
|
3458
|
+
returnFocusTo: $$props.returnFocusTo
|
|
2692
3459
|
});
|
|
2693
3460
|
const sync = () => {
|
|
2694
3461
|
if (!engine) return;
|
|
@@ -2696,14 +3463,32 @@ function BottomSheet($$anchor, $$props) {
|
|
|
2696
3463
|
$$props.onchange?.($2.get(viewState));
|
|
2697
3464
|
};
|
|
2698
3465
|
sync();
|
|
3466
|
+
if ($$props.backdropColor !== void 0) engine.setScrimColor($$props.backdropColor);
|
|
3467
|
+
if ($$props.backdropOpacity !== void 0) engine.setBackdropRange([0, $$props.backdropOpacity]);
|
|
2699
3468
|
engine.on("snap", (payload) => {
|
|
2700
3469
|
sync();
|
|
3470
|
+
snap(payload.id);
|
|
2701
3471
|
$$props.onsnap?.(payload.id);
|
|
2702
3472
|
});
|
|
2703
|
-
engine.on("open", (payload) =>
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
3473
|
+
engine.on("open", (payload) => {
|
|
3474
|
+
openProp(true);
|
|
3475
|
+
$$props.onopen?.(payload.id);
|
|
3476
|
+
});
|
|
3477
|
+
engine.on("close", () => {
|
|
3478
|
+
openProp(false);
|
|
3479
|
+
$$props.onclose?.();
|
|
3480
|
+
});
|
|
3481
|
+
engine.on("before-close", (payload) => $$props.onbeforeclose?.(payload));
|
|
3482
|
+
engine.on("opened", (payload) => $$props.onopened?.(payload.id));
|
|
3483
|
+
engine.on("closed", () => $$props.onclosed?.());
|
|
3484
|
+
engine.on("dragstart", () => {
|
|
3485
|
+
sync();
|
|
3486
|
+
$$props.ondragstart?.();
|
|
3487
|
+
});
|
|
3488
|
+
engine.on("dragend", () => {
|
|
3489
|
+
sync();
|
|
3490
|
+
$$props.ondragend?.();
|
|
3491
|
+
});
|
|
2707
3492
|
});
|
|
2708
3493
|
onDestroy(() => {
|
|
2709
3494
|
engine?.destroy();
|
|
@@ -2712,13 +3497,46 @@ function BottomSheet($$anchor, $$props) {
|
|
|
2712
3497
|
const snapTo = (id) => engine?.snapTo(id) ?? Promise.resolve();
|
|
2713
3498
|
const open = (id) => engine?.open(id) ?? Promise.resolve();
|
|
2714
3499
|
const close = () => engine?.close() ?? Promise.resolve();
|
|
2715
|
-
const
|
|
3500
|
+
const expand = () => engine?.expand() ?? Promise.resolve();
|
|
3501
|
+
const collapse = () => engine?.collapse() ?? Promise.resolve();
|
|
3502
|
+
const isTop = () => engine?.isTop() ?? false;
|
|
3503
|
+
const depth = () => engine?.depth() ?? 0;
|
|
3504
|
+
const setAllowed = (ids, snap2) => engine?.setAllowed(ids, snap2);
|
|
2716
3505
|
const setSnapPoints = (points, nextAllowed) => engine?.setSnapPoints(points, nextAllowed);
|
|
2717
3506
|
const setScrim = (opts) => engine?.setScrim(opts);
|
|
2718
3507
|
const setScrimOverlay = (opts) => engine?.setScrimOverlay(opts) ?? (() => {
|
|
2719
3508
|
});
|
|
3509
|
+
const setRadius = (r) => engine?.setRadius(r);
|
|
3510
|
+
const setMaxHeight = (h) => engine?.setMaxHeight(h);
|
|
3511
|
+
const canDismiss = () => engine?.canDismiss() ?? false;
|
|
2720
3512
|
const getState = () => engine?.state ?? $2.get(viewState);
|
|
2721
3513
|
const getEngine = () => engine;
|
|
3514
|
+
$2.user_effect(() => {
|
|
3515
|
+
if ($$props.radius !== void 0) engine?.setRadius($$props.radius);
|
|
3516
|
+
});
|
|
3517
|
+
$2.user_effect(() => {
|
|
3518
|
+
if ($$props.maxHeight !== void 0) engine?.setMaxHeight($$props.maxHeight);
|
|
3519
|
+
});
|
|
3520
|
+
$2.user_effect(() => {
|
|
3521
|
+
if ($$props.backdropColor !== void 0) engine?.setScrimColor($$props.backdropColor);
|
|
3522
|
+
});
|
|
3523
|
+
$2.user_effect(() => {
|
|
3524
|
+
if ($$props.backdropOpacity !== void 0) engine?.setBackdropRange([0, $$props.backdropOpacity]);
|
|
3525
|
+
});
|
|
3526
|
+
$2.user_effect(() => {
|
|
3527
|
+
if (snap() === void 0) return;
|
|
3528
|
+
const next = snap();
|
|
3529
|
+
if (!engine || untrack(() => $2.get(viewState).activeId) === next) return;
|
|
3530
|
+
void engine.snapTo(next);
|
|
3531
|
+
});
|
|
3532
|
+
$2.user_effect(() => {
|
|
3533
|
+
if (openProp() === void 0) return;
|
|
3534
|
+
const next = openProp();
|
|
3535
|
+
if (!engine) return;
|
|
3536
|
+
const isOpen = untrack(() => $2.get(viewState).size) > 0;
|
|
3537
|
+
if (next && !isOpen) void engine.open();
|
|
3538
|
+
else if (!next && isOpen) void engine.close();
|
|
3539
|
+
});
|
|
2722
3540
|
let allowedIds = $2.derived(() => $$props.allowed && $$props.allowed.length > 0 ? $$props.allowed : $$props.snapPoints.map((s) => s.id));
|
|
2723
3541
|
let activeIdx = $2.derived(() => $2.get(allowedIds).indexOf($2.get(viewState).activeId));
|
|
2724
3542
|
let isVerticalAxis = $2.derived(() => mode() === "bottom" || mode() === "top");
|
|
@@ -2726,10 +3544,17 @@ function BottomSheet($$anchor, $$props) {
|
|
|
2726
3544
|
snapTo,
|
|
2727
3545
|
open,
|
|
2728
3546
|
close,
|
|
3547
|
+
expand,
|
|
3548
|
+
collapse,
|
|
3549
|
+
isTop,
|
|
3550
|
+
depth,
|
|
2729
3551
|
setAllowed,
|
|
2730
3552
|
setSnapPoints,
|
|
2731
3553
|
setScrim,
|
|
2732
3554
|
setScrimOverlay,
|
|
3555
|
+
setRadius,
|
|
3556
|
+
setMaxHeight,
|
|
3557
|
+
canDismiss,
|
|
2733
3558
|
getState,
|
|
2734
3559
|
getEngine
|
|
2735
3560
|
};
|
|
@@ -2740,7 +3565,9 @@ function BottomSheet($$anchor, $$props) {
|
|
|
2740
3565
|
var div_1 = root_1();
|
|
2741
3566
|
$2.bind_this(div_1, ($$value) => $2.set(backdropEl, $$value), () => $2.get(backdropEl));
|
|
2742
3567
|
$2.delegated("click", div_1, function(...$$args) {
|
|
2743
|
-
(closeOnBackdrop() ? () =>
|
|
3568
|
+
(closeOnBackdrop() ? () => {
|
|
3569
|
+
if (engine?.canDismiss()) void engine.close("backdrop");
|
|
3570
|
+
} : void 0)?.apply(this, $$args);
|
|
2744
3571
|
});
|
|
2745
3572
|
$2.append($$anchor2, div_1);
|
|
2746
3573
|
};
|