@surdeddd/bottom-sheet 0.2.0 → 0.3.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-CAymrH-P.d.cts} +67 -1
- package/dist/{BottomSheetEngine-Df9MwBbm.d.ts → BottomSheetEngine-DcqcuudN.d.ts} +67 -1
- package/dist/element.cjs +699 -116
- package/dist/element.d.cts +7 -2
- package/dist/element.d.ts +7 -2
- package/dist/element.iife.global.js +2 -2
- package/dist/element.js +699 -116
- package/dist/index.cjs +715 -145
- package/dist/index.d.cts +17 -3
- package/dist/index.d.ts +17 -3
- package/dist/index.js +713 -146
- 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 +168 -35
- package/dist/overlay.d.cts +13 -0
- package/dist/overlay.d.ts +13 -0
- package/dist/overlay.js +168 -35
- package/dist/preact.d.cts +1 -1
- package/dist/preact.d.ts +1 -1
- package/dist/qwik.cjs +619 -119
- package/dist/qwik.d.cts +2 -2
- package/dist/qwik.d.ts +2 -2
- package/dist/qwik.js +620 -120
- package/dist/react.cjs +821 -191
- package/dist/react.d.cts +20 -3
- package/dist/react.d.ts +20 -3
- package/dist/react.js +821 -191
- package/dist/solid.cjs +656 -161
- package/dist/solid.d.cts +263 -4
- package/dist/solid.d.ts +263 -4
- package/dist/solid.js +657 -162
- package/dist/solid.source.jsx +3215 -0
- package/dist/styles.css +10 -10
- package/dist/svelte-core.cjs +3149 -0
- package/dist/svelte-core.js +3147 -0
- package/dist/svelte-src/BottomSheet.svelte +210 -0
- package/dist/svelte-src/index.js +2 -0
- package/dist/svelte.cjs +618 -124
- package/dist/svelte.d.cts +100 -0
- package/dist/svelte.d.ts +7 -3
- package/dist/svelte.js +619 -125
- package/dist/vue.cjs +612 -119
- package/dist/vue.d.cts +78 -0
- package/dist/vue.d.ts +6 -2
- package/dist/vue.js +612 -119
- package/package.json +103 -43
package/dist/solid.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { insert, memo, use, effect, setAttribute, template } from 'solid-js/web';
|
|
2
|
+
import { createSignal, onMount, onCleanup, createEffect, on, createMemo } from 'solid-js';
|
|
3
3
|
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
5
5
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
@@ -23,6 +23,18 @@ var SheetStack = class {
|
|
|
23
23
|
this.entries.splice(idx, 1);
|
|
24
24
|
this.recompute();
|
|
25
25
|
}
|
|
26
|
+
promote(id) {
|
|
27
|
+
const idx = this.entries.findIndex((e) => e.id === id);
|
|
28
|
+
if (idx === -1) return;
|
|
29
|
+
if (idx !== this.entries.length - 1) {
|
|
30
|
+
const [entry] = this.entries.splice(idx, 1);
|
|
31
|
+
this.entries.push(entry);
|
|
32
|
+
}
|
|
33
|
+
this.recompute();
|
|
34
|
+
}
|
|
35
|
+
update() {
|
|
36
|
+
this.recompute();
|
|
37
|
+
}
|
|
26
38
|
size() {
|
|
27
39
|
return this.entries.length;
|
|
28
40
|
}
|
|
@@ -30,9 +42,24 @@ var SheetStack = class {
|
|
|
30
42
|
this.entries = [];
|
|
31
43
|
}
|
|
32
44
|
recompute() {
|
|
45
|
+
let top = null;
|
|
46
|
+
const open = [];
|
|
47
|
+
for (const entry of this.entries) {
|
|
48
|
+
if (!entry.isOpen || entry.isOpen()) {
|
|
49
|
+
top = entry;
|
|
50
|
+
open.push(entry);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (!top && this.entries.length > 0) {
|
|
54
|
+
top = this.entries[this.entries.length - 1];
|
|
55
|
+
}
|
|
33
56
|
this.entries.forEach((entry, i) => {
|
|
34
57
|
entry.setZIndex(BASE_Z + i * STEP);
|
|
35
|
-
entry.setIsTop(
|
|
58
|
+
entry.setIsTop(entry === top);
|
|
59
|
+
if (entry.setDepth) {
|
|
60
|
+
const openIdx = open.indexOf(entry);
|
|
61
|
+
entry.setDepth(openIdx === -1 ? 0 : open.length - 1 - openIdx);
|
|
62
|
+
}
|
|
36
63
|
});
|
|
37
64
|
}
|
|
38
65
|
};
|
|
@@ -317,14 +344,17 @@ function installAutoCollapse(deps) {
|
|
|
317
344
|
const fire = () => {
|
|
318
345
|
if (deps.isDestroyed()) return;
|
|
319
346
|
if (deps.isDragging()) return;
|
|
320
|
-
const
|
|
321
|
-
|
|
347
|
+
const active = deps.resolveSnap(deps.getActiveId());
|
|
348
|
+
if (!active || active.size === 0) return;
|
|
349
|
+
let target = null;
|
|
350
|
+
for (const id of deps.getAllowedIds()) {
|
|
322
351
|
const snap = deps.resolveSnap(id);
|
|
323
|
-
|
|
324
|
-
|
|
352
|
+
if (!snap || snap.size <= 0) continue;
|
|
353
|
+
if (!target || snap.size < target.size) target = snap;
|
|
354
|
+
}
|
|
325
355
|
if (!target) return;
|
|
326
|
-
if (target ===
|
|
327
|
-
deps.snapTo(target);
|
|
356
|
+
if (target.id === active.id || target.size >= active.size) return;
|
|
357
|
+
deps.snapTo(target.id);
|
|
328
358
|
};
|
|
329
359
|
const reset = () => {
|
|
330
360
|
clearTimer();
|
|
@@ -335,6 +365,7 @@ function installAutoCollapse(deps) {
|
|
|
335
365
|
}, ms);
|
|
336
366
|
};
|
|
337
367
|
const unsubscribe = deps.on("snap", () => reset());
|
|
368
|
+
if ((deps.resolveSnap(deps.getActiveId())?.size ?? 0) > 0) reset();
|
|
338
369
|
return () => {
|
|
339
370
|
clearTimer();
|
|
340
371
|
unsubscribe();
|
|
@@ -347,6 +378,7 @@ function notifyLinkedSheets(sheets, self) {
|
|
|
347
378
|
for (const linked of sheets) {
|
|
348
379
|
if (linked === self) continue;
|
|
349
380
|
try {
|
|
381
|
+
if (linked.state.size === 0) continue;
|
|
350
382
|
const ids = linked.getAllowedIds();
|
|
351
383
|
const target = ids.find((id) => id !== "closed");
|
|
352
384
|
if (target && target !== linked.state.activeId) {
|
|
@@ -393,7 +425,7 @@ function installRoute(deps) {
|
|
|
393
425
|
const onPop = (event) => {
|
|
394
426
|
if (deps.isDestroyed()) return;
|
|
395
427
|
const state = event.state;
|
|
396
|
-
if (state
|
|
428
|
+
if ((!state || state.__bsRouted !== target) && deps.getSize() > 0) {
|
|
397
429
|
routePushed = false;
|
|
398
430
|
void deps.close();
|
|
399
431
|
}
|
|
@@ -547,13 +579,17 @@ function installResizeObserver(deps) {
|
|
|
547
579
|
if (viewportSize2 > 0 && viewportSize2 < max) {
|
|
548
580
|
deps.setMaxAxisSize(viewportSize2);
|
|
549
581
|
}
|
|
582
|
+
const wasAnimating = deps.isAnimating?.() ?? false;
|
|
550
583
|
deps.cancelInFlight();
|
|
551
584
|
deps.newCycle();
|
|
552
585
|
const current = deps.resolveActiveSnap();
|
|
553
586
|
const newMax = deps.getMaxAxisSize();
|
|
554
587
|
const targetSize = current ? Math.min(current.size, newMax) : Math.min(deps.getSize(), newMax);
|
|
555
588
|
deps.setSize(targetSize);
|
|
556
|
-
if (current && !deps.isDragging())
|
|
589
|
+
if (current && !deps.isDragging()) {
|
|
590
|
+
deps.applySize(targetSize);
|
|
591
|
+
if (wasAnimating) deps.resyncAfterCancel?.();
|
|
592
|
+
}
|
|
557
593
|
};
|
|
558
594
|
let resizeObserver = null;
|
|
559
595
|
if (typeof ResizeObserver !== "undefined") {
|
|
@@ -668,6 +704,85 @@ function devWarn(...args) {
|
|
|
668
704
|
}
|
|
669
705
|
}
|
|
670
706
|
|
|
707
|
+
// src/core/primitives/overlay-position.ts
|
|
708
|
+
function resolveSheetAnchoredStyle(mode, position, inset) {
|
|
709
|
+
const sizeOffset = `calc(var(--bs-size, 0px) + ${inset})`;
|
|
710
|
+
switch (mode) {
|
|
711
|
+
case "bottom":
|
|
712
|
+
if (position === "sheet-top-left") return { bottom: sizeOffset, left: inset };
|
|
713
|
+
if (position === "sheet-top-right") return { bottom: sizeOffset, right: inset };
|
|
714
|
+
return { bottom: sizeOffset, left: "50%", transform: "translateX(-50%)" };
|
|
715
|
+
case "top":
|
|
716
|
+
if (position === "sheet-top-left") return { top: sizeOffset, left: inset };
|
|
717
|
+
if (position === "sheet-top-right") return { top: sizeOffset, right: inset };
|
|
718
|
+
return { top: sizeOffset, left: "50%", transform: "translateX(-50%)" };
|
|
719
|
+
case "left":
|
|
720
|
+
if (position === "sheet-top-left") return { left: sizeOffset, top: inset };
|
|
721
|
+
if (position === "sheet-top-right") return { left: sizeOffset, bottom: inset };
|
|
722
|
+
return { left: sizeOffset, top: "50%", transform: "translateY(-50%)" };
|
|
723
|
+
case "right":
|
|
724
|
+
if (position === "sheet-top-left") return { right: sizeOffset, top: inset };
|
|
725
|
+
if (position === "sheet-top-right") return { right: sizeOffset, bottom: inset };
|
|
726
|
+
return { right: sizeOffset, top: "50%", transform: "translateY(-50%)" };
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
function applyOverlayPosition(ws, mode, position, inset) {
|
|
730
|
+
switch (position) {
|
|
731
|
+
case "top-left":
|
|
732
|
+
ws.top = inset;
|
|
733
|
+
ws.left = inset;
|
|
734
|
+
break;
|
|
735
|
+
case "top-center":
|
|
736
|
+
ws.top = inset;
|
|
737
|
+
ws.left = "50%";
|
|
738
|
+
ws.transform = "translateX(-50%)";
|
|
739
|
+
break;
|
|
740
|
+
case "top-right":
|
|
741
|
+
ws.top = inset;
|
|
742
|
+
ws.right = inset;
|
|
743
|
+
break;
|
|
744
|
+
case "center-left":
|
|
745
|
+
ws.top = "50%";
|
|
746
|
+
ws.left = inset;
|
|
747
|
+
ws.transform = "translateY(-50%)";
|
|
748
|
+
break;
|
|
749
|
+
case "center":
|
|
750
|
+
ws.top = "50%";
|
|
751
|
+
ws.left = "50%";
|
|
752
|
+
ws.transform = "translate(-50%, -50%)";
|
|
753
|
+
break;
|
|
754
|
+
case "center-right":
|
|
755
|
+
ws.top = "50%";
|
|
756
|
+
ws.right = inset;
|
|
757
|
+
ws.transform = "translateY(-50%)";
|
|
758
|
+
break;
|
|
759
|
+
case "bottom-left":
|
|
760
|
+
ws.bottom = inset;
|
|
761
|
+
ws.left = inset;
|
|
762
|
+
break;
|
|
763
|
+
case "bottom-center":
|
|
764
|
+
ws.bottom = inset;
|
|
765
|
+
ws.left = "50%";
|
|
766
|
+
ws.transform = "translateX(-50%)";
|
|
767
|
+
break;
|
|
768
|
+
case "bottom-right":
|
|
769
|
+
ws.bottom = inset;
|
|
770
|
+
ws.right = inset;
|
|
771
|
+
break;
|
|
772
|
+
case "sheet-top-left":
|
|
773
|
+
case "sheet-top-center":
|
|
774
|
+
case "sheet-top-right": {
|
|
775
|
+
const style = resolveSheetAnchoredStyle(mode, position, inset);
|
|
776
|
+
if (style.top !== void 0) ws.top = style.top;
|
|
777
|
+
if (style.bottom !== void 0) ws.bottom = style.bottom;
|
|
778
|
+
if (style.left !== void 0) ws.left = style.left;
|
|
779
|
+
if (style.right !== void 0) ws.right = style.right;
|
|
780
|
+
if (style.transform !== void 0) ws.transform = style.transform;
|
|
781
|
+
break;
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
|
|
671
786
|
// src/core/controllers/scrim-controller.ts
|
|
672
787
|
var VALID_CSS_LENGTH = /^-?\d+(?:\.\d+)?(?:px|em|rem|%)$/;
|
|
673
788
|
var ScrimController = class {
|
|
@@ -680,6 +795,8 @@ var ScrimController = class {
|
|
|
680
795
|
__publicField(this, "getAllowedIds");
|
|
681
796
|
__publicField(this, "getResolvedSnaps");
|
|
682
797
|
__publicField(this, "snapToFn");
|
|
798
|
+
__publicField(this, "closeFn");
|
|
799
|
+
__publicField(this, "scrimInteractive", false);
|
|
683
800
|
__publicField(this, "scrimMode");
|
|
684
801
|
__publicField(this, "backdropRange");
|
|
685
802
|
__publicField(this, "screenRange");
|
|
@@ -700,6 +817,7 @@ var ScrimController = class {
|
|
|
700
817
|
this.getAllowedIds = deps.getAllowedIds;
|
|
701
818
|
this.getResolvedSnaps = deps.getResolvedSnaps;
|
|
702
819
|
this.snapToFn = deps.snapTo;
|
|
820
|
+
this.closeFn = deps.close;
|
|
703
821
|
this.scrimMode = opts.scrimMode ?? "full";
|
|
704
822
|
const preset = opts.scrimPreset ? SCRIM_PRESETS[opts.scrimPreset] : null;
|
|
705
823
|
this.backdropRange = opts.backdropRange ?? preset?.range ?? [0, 1];
|
|
@@ -841,11 +959,15 @@ var ScrimController = class {
|
|
|
841
959
|
}
|
|
842
960
|
const onClick = () => {
|
|
843
961
|
if (this.isDestroyed()) return;
|
|
962
|
+
if (this.closeFn) {
|
|
963
|
+
this.closeFn();
|
|
964
|
+
return;
|
|
965
|
+
}
|
|
844
966
|
const allowed = this.getAllowedIds();
|
|
845
967
|
const snaps = this.getResolvedSnaps();
|
|
846
968
|
const fallback = allowed.find((id) => {
|
|
847
969
|
const snap = findById(id, snaps);
|
|
848
|
-
return snap !== null && snap.size
|
|
970
|
+
return snap !== null && snap.size === 0;
|
|
849
971
|
});
|
|
850
972
|
if (fallback) this.snapToFn(fallback);
|
|
851
973
|
};
|
|
@@ -862,6 +984,7 @@ var ScrimController = class {
|
|
|
862
984
|
if (this.isDestroyed()) return;
|
|
863
985
|
if (enabled === this.scrimEnabled) return;
|
|
864
986
|
this.scrimEnabled = enabled;
|
|
987
|
+
this.invalidateOpacityCache();
|
|
865
988
|
if (!enabled) {
|
|
866
989
|
this.savedScrimRanges = {
|
|
867
990
|
screen: this.screenRange,
|
|
@@ -885,7 +1008,12 @@ var ScrimController = class {
|
|
|
885
1008
|
blur: cfg.blur ?? null,
|
|
886
1009
|
interactive: cfg.interactive
|
|
887
1010
|
});
|
|
888
|
-
this.
|
|
1011
|
+
if (!this.scrimEnabled && this.savedScrimRanges) {
|
|
1012
|
+
this.savedScrimRanges = { screen: cfg.range, backdrop: cfg.range };
|
|
1013
|
+
} else {
|
|
1014
|
+
this.screenRange = cfg.range;
|
|
1015
|
+
this.backdropRange = cfg.range;
|
|
1016
|
+
}
|
|
889
1017
|
}
|
|
890
1018
|
const noop = () => {
|
|
891
1019
|
};
|
|
@@ -935,59 +1063,7 @@ var ScrimController = class {
|
|
|
935
1063
|
wrapper.className = "bs-scrim-overlay";
|
|
936
1064
|
const ws = wrapper.style;
|
|
937
1065
|
ws.position = "absolute";
|
|
938
|
-
|
|
939
|
-
case "top-left":
|
|
940
|
-
ws.top = inset;
|
|
941
|
-
ws.left = inset;
|
|
942
|
-
break;
|
|
943
|
-
case "top-center":
|
|
944
|
-
ws.top = inset;
|
|
945
|
-
ws.left = "50%";
|
|
946
|
-
ws.transform = "translateX(-50%)";
|
|
947
|
-
break;
|
|
948
|
-
case "top-right":
|
|
949
|
-
ws.top = inset;
|
|
950
|
-
ws.right = inset;
|
|
951
|
-
break;
|
|
952
|
-
case "center-left":
|
|
953
|
-
ws.top = "50%";
|
|
954
|
-
ws.left = inset;
|
|
955
|
-
ws.transform = "translateY(-50%)";
|
|
956
|
-
break;
|
|
957
|
-
case "center":
|
|
958
|
-
ws.top = "50%";
|
|
959
|
-
ws.left = "50%";
|
|
960
|
-
ws.transform = "translate(-50%, -50%)";
|
|
961
|
-
break;
|
|
962
|
-
case "center-right":
|
|
963
|
-
ws.top = "50%";
|
|
964
|
-
ws.right = inset;
|
|
965
|
-
ws.transform = "translateY(-50%)";
|
|
966
|
-
break;
|
|
967
|
-
case "bottom-left":
|
|
968
|
-
ws.bottom = inset;
|
|
969
|
-
ws.left = inset;
|
|
970
|
-
break;
|
|
971
|
-
case "bottom-center":
|
|
972
|
-
ws.bottom = inset;
|
|
973
|
-
ws.left = "50%";
|
|
974
|
-
ws.transform = "translateX(-50%)";
|
|
975
|
-
break;
|
|
976
|
-
case "bottom-right":
|
|
977
|
-
ws.bottom = inset;
|
|
978
|
-
ws.right = inset;
|
|
979
|
-
break;
|
|
980
|
-
case "sheet-top-left":
|
|
981
|
-
case "sheet-top-center":
|
|
982
|
-
case "sheet-top-right":
|
|
983
|
-
applySheetAnchoredPosition(
|
|
984
|
-
ws,
|
|
985
|
-
this.mode,
|
|
986
|
-
position,
|
|
987
|
-
inset
|
|
988
|
-
);
|
|
989
|
-
break;
|
|
990
|
-
}
|
|
1066
|
+
applyOverlayPosition(ws, this.mode, position, inset);
|
|
991
1067
|
if (interactive) {
|
|
992
1068
|
ws.pointerEvents = "auto";
|
|
993
1069
|
}
|
|
@@ -1046,6 +1122,7 @@ var ScrimController = class {
|
|
|
1046
1122
|
}
|
|
1047
1123
|
}
|
|
1048
1124
|
if (opts.interactive !== void 0) {
|
|
1125
|
+
this.scrimInteractive = opts.interactive;
|
|
1049
1126
|
s.pointerEvents = opts.interactive ? "auto" : "none";
|
|
1050
1127
|
}
|
|
1051
1128
|
}
|
|
@@ -1060,38 +1137,9 @@ var ScrimController = class {
|
|
|
1060
1137
|
const s = this.screenComponent.style;
|
|
1061
1138
|
s.position = "fixed";
|
|
1062
1139
|
s.inset = insetByMode[this.mode];
|
|
1063
|
-
s.pointerEvents = "none";
|
|
1140
|
+
s.pointerEvents = this.scrimInteractive || this.scrimTapToCloseEnabled ? "auto" : "none";
|
|
1064
1141
|
}
|
|
1065
1142
|
};
|
|
1066
|
-
function resolveSheetAnchoredStyle(mode, position, inset) {
|
|
1067
|
-
const sizeOffset = `calc(var(--bs-size, 0px) + ${inset})`;
|
|
1068
|
-
switch (mode) {
|
|
1069
|
-
case "bottom":
|
|
1070
|
-
if (position === "sheet-top-left") return { bottom: sizeOffset, left: inset };
|
|
1071
|
-
if (position === "sheet-top-right") return { bottom: sizeOffset, right: inset };
|
|
1072
|
-
return { bottom: sizeOffset, left: "50%", transform: "translateX(-50%)" };
|
|
1073
|
-
case "top":
|
|
1074
|
-
if (position === "sheet-top-left") return { top: sizeOffset, left: inset };
|
|
1075
|
-
if (position === "sheet-top-right") return { top: sizeOffset, right: inset };
|
|
1076
|
-
return { top: sizeOffset, left: "50%", transform: "translateX(-50%)" };
|
|
1077
|
-
case "left":
|
|
1078
|
-
if (position === "sheet-top-left") return { left: sizeOffset, top: inset };
|
|
1079
|
-
if (position === "sheet-top-right") return { left: sizeOffset, bottom: inset };
|
|
1080
|
-
return { left: sizeOffset, top: "50%", transform: "translateY(-50%)" };
|
|
1081
|
-
case "right":
|
|
1082
|
-
if (position === "sheet-top-left") return { right: sizeOffset, top: inset };
|
|
1083
|
-
if (position === "sheet-top-right") return { right: sizeOffset, bottom: inset };
|
|
1084
|
-
return { right: sizeOffset, top: "50%", transform: "translateY(-50%)" };
|
|
1085
|
-
}
|
|
1086
|
-
}
|
|
1087
|
-
function applySheetAnchoredPosition(ws, mode, position, inset) {
|
|
1088
|
-
const style = resolveSheetAnchoredStyle(mode, position, inset);
|
|
1089
|
-
if (style.top !== void 0) ws.top = style.top;
|
|
1090
|
-
if (style.bottom !== void 0) ws.bottom = style.bottom;
|
|
1091
|
-
if (style.left !== void 0) ws.left = style.left;
|
|
1092
|
-
if (style.right !== void 0) ws.right = style.right;
|
|
1093
|
-
if (style.transform !== void 0) ws.transform = style.transform;
|
|
1094
|
-
}
|
|
1095
1143
|
|
|
1096
1144
|
// src/core/animation/animation.ts
|
|
1097
1145
|
var easeOutBack = (t) => {
|
|
@@ -1143,6 +1191,10 @@ var tween = ({
|
|
|
1143
1191
|
promise
|
|
1144
1192
|
};
|
|
1145
1193
|
};
|
|
1194
|
+
var prefersReducedMotion = () => {
|
|
1195
|
+
if (typeof window === "undefined" || !window.matchMedia) return false;
|
|
1196
|
+
return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
1197
|
+
};
|
|
1146
1198
|
|
|
1147
1199
|
// src/core/animation/spring.ts
|
|
1148
1200
|
var DEFAULT_SPRING = {
|
|
@@ -1173,14 +1225,20 @@ var runSpring = ({
|
|
|
1173
1225
|
if (cancelled) return;
|
|
1174
1226
|
const dt = Math.min((now - lastTime) / 1e3, MAX_DT);
|
|
1175
1227
|
lastTime = now;
|
|
1176
|
-
const
|
|
1177
|
-
|
|
1228
|
+
const steps = Math.max(1, Math.ceil(dt * 240));
|
|
1229
|
+
const subDt = dt / steps;
|
|
1230
|
+
let stepsLeft = steps;
|
|
1178
1231
|
while (stepsLeft-- > 0) {
|
|
1179
1232
|
const force = -cfg.stiffness * (x - to) - cfg.damping * v;
|
|
1180
1233
|
const accel = force / cfg.mass;
|
|
1181
1234
|
v += accel * subDt;
|
|
1182
1235
|
x += v * subDt;
|
|
1183
1236
|
}
|
|
1237
|
+
if (!Number.isFinite(x) || !Number.isFinite(v)) {
|
|
1238
|
+
onUpdate(to, 0);
|
|
1239
|
+
resolve();
|
|
1240
|
+
return;
|
|
1241
|
+
}
|
|
1184
1242
|
onUpdate(x, v);
|
|
1185
1243
|
const isAtRest = Math.abs(to - x) < (cfg.restDelta ?? 0.5) && Math.abs(v) < (cfg.restSpeed ?? 0.5);
|
|
1186
1244
|
if (isAtRest) {
|
|
@@ -1355,9 +1413,13 @@ var isVisible = (el) => {
|
|
|
1355
1413
|
var focusables = (root) => Array.from(root.querySelectorAll(FOCUSABLE)).filter(
|
|
1356
1414
|
(el) => !el.hasAttribute("inert") && isVisible(el) && !el.matches("[aria-hidden='true']")
|
|
1357
1415
|
);
|
|
1416
|
+
var trapStack = [];
|
|
1358
1417
|
var installFocusTrap = (container, options = {}) => {
|
|
1359
1418
|
if (typeof document === "undefined") return () => {
|
|
1360
1419
|
};
|
|
1420
|
+
const token = {};
|
|
1421
|
+
trapStack.push(token);
|
|
1422
|
+
const isActive = () => trapStack[trapStack.length - 1] === token;
|
|
1361
1423
|
const previouslyFocused = document.activeElement;
|
|
1362
1424
|
const focusInitial = () => {
|
|
1363
1425
|
const initial = typeof options.initialFocus === "string" ? container.querySelector(options.initialFocus) : options.initialFocus ?? focusables(container)[0] ?? container;
|
|
@@ -1365,6 +1427,7 @@ var installFocusTrap = (container, options = {}) => {
|
|
|
1365
1427
|
};
|
|
1366
1428
|
focusInitial();
|
|
1367
1429
|
const handleKey = (e) => {
|
|
1430
|
+
if (!isActive()) return;
|
|
1368
1431
|
if (e.key === "Escape" && options.onEscape) {
|
|
1369
1432
|
options.onEscape();
|
|
1370
1433
|
return;
|
|
@@ -1387,6 +1450,7 @@ var installFocusTrap = (container, options = {}) => {
|
|
|
1387
1450
|
}
|
|
1388
1451
|
};
|
|
1389
1452
|
const handleFocusIn = (e) => {
|
|
1453
|
+
if (!isActive()) return;
|
|
1390
1454
|
const target = e.target;
|
|
1391
1455
|
if (target && !container.contains(target)) {
|
|
1392
1456
|
const list = focusables(container);
|
|
@@ -1399,6 +1463,8 @@ var installFocusTrap = (container, options = {}) => {
|
|
|
1399
1463
|
return () => {
|
|
1400
1464
|
if (released) return;
|
|
1401
1465
|
released = true;
|
|
1466
|
+
const idx = trapStack.indexOf(token);
|
|
1467
|
+
if (idx !== -1) trapStack.splice(idx, 1);
|
|
1402
1468
|
document.removeEventListener("keydown", handleKey, true);
|
|
1403
1469
|
document.removeEventListener("focusin", handleFocusIn, true);
|
|
1404
1470
|
if (previouslyFocused && document.contains(previouslyFocused)) {
|
|
@@ -1454,11 +1520,17 @@ function createInertSiblings(rootProvider) {
|
|
|
1454
1520
|
return {
|
|
1455
1521
|
apply() {
|
|
1456
1522
|
if (typeof document === "undefined") return;
|
|
1457
|
-
|
|
1458
|
-
|
|
1523
|
+
let top = rootProvider();
|
|
1524
|
+
while (top.parentElement && top.parentElement !== document.body) {
|
|
1525
|
+
top = top.parentElement;
|
|
1526
|
+
}
|
|
1527
|
+
const parent = top.parentElement ?? document.body;
|
|
1459
1528
|
for (const child of Array.from(parent.children)) {
|
|
1460
|
-
if (child ===
|
|
1529
|
+
if (child === top) continue;
|
|
1461
1530
|
if (child.hasAttribute("inert")) continue;
|
|
1531
|
+
if (child.classList.contains("bs-backdrop") || child.classList.contains("bs-screen") || child.classList.contains("bs-root")) {
|
|
1532
|
+
continue;
|
|
1533
|
+
}
|
|
1462
1534
|
child.setAttribute("inert", "");
|
|
1463
1535
|
tracked.push(child);
|
|
1464
1536
|
}
|
|
@@ -1474,7 +1546,6 @@ function createInertSiblings(rootProvider) {
|
|
|
1474
1546
|
var LifecycleController = class {
|
|
1475
1547
|
constructor(deps, opts) {
|
|
1476
1548
|
__publicField(this, "element");
|
|
1477
|
-
__publicField(this, "closeFn");
|
|
1478
1549
|
__publicField(this, "focusTrapEnabled");
|
|
1479
1550
|
__publicField(this, "initialFocus");
|
|
1480
1551
|
__publicField(this, "closeOnEscape");
|
|
@@ -1488,7 +1559,6 @@ var LifecycleController = class {
|
|
|
1488
1559
|
__publicField(this, "installed", false);
|
|
1489
1560
|
__publicField(this, "destroyed", false);
|
|
1490
1561
|
this.element = deps.element;
|
|
1491
|
-
this.closeFn = deps.close;
|
|
1492
1562
|
this.focusTrapEnabled = opts.focusTrap ?? false;
|
|
1493
1563
|
this.initialFocus = opts.initialFocus;
|
|
1494
1564
|
this.closeOnEscape = opts.closeOnEscape ?? true;
|
|
@@ -1498,6 +1568,9 @@ var LifecycleController = class {
|
|
|
1498
1568
|
this.returnFocus = opts.returnFocus;
|
|
1499
1569
|
this.inertSiblings = createInertSiblings(() => this.element);
|
|
1500
1570
|
}
|
|
1571
|
+
get isInstalled() {
|
|
1572
|
+
return this.installed;
|
|
1573
|
+
}
|
|
1501
1574
|
install() {
|
|
1502
1575
|
if (this.destroyed) return;
|
|
1503
1576
|
this.installed = true;
|
|
@@ -1506,8 +1579,7 @@ var LifecycleController = class {
|
|
|
1506
1579
|
}
|
|
1507
1580
|
if (this.focusTrapEnabled && !this.releaseFocusTrap) {
|
|
1508
1581
|
this.releaseFocusTrap = installFocusTrap(this.element, {
|
|
1509
|
-
initialFocus: this.initialFocus
|
|
1510
|
-
onEscape: this.closeOnEscape ? () => void this.closeFn() : void 0
|
|
1582
|
+
initialFocus: this.initialFocus
|
|
1511
1583
|
});
|
|
1512
1584
|
}
|
|
1513
1585
|
if (this.inertSiblingsEnabled && this.shouldApplyInertSiblings()) {
|
|
@@ -1661,10 +1733,11 @@ var installGestures = (handle, mode, callbacks) => {
|
|
|
1661
1733
|
};
|
|
1662
1734
|
|
|
1663
1735
|
// src/core/primitives/rubber-band.ts
|
|
1664
|
-
var RUBBER_BAND_FACTOR = 0.55;
|
|
1665
1736
|
function rubberBand(overshoot, maxAxisSize) {
|
|
1666
1737
|
const cap = Math.min(maxAxisSize * 0.15, 80);
|
|
1667
|
-
|
|
1738
|
+
if (cap <= 0) return 0;
|
|
1739
|
+
const abs = Math.abs(overshoot);
|
|
1740
|
+
return Math.sign(overshoot) * (cap * abs / (abs + cap));
|
|
1668
1741
|
}
|
|
1669
1742
|
|
|
1670
1743
|
// src/core/features/soft-keyboard.ts
|
|
@@ -1749,6 +1822,10 @@ var GestureController = class {
|
|
|
1749
1822
|
this.isDragging_ = false;
|
|
1750
1823
|
this.keyboardDismissed = false;
|
|
1751
1824
|
this.deps.getRoot()?.removeAttribute("data-dragging");
|
|
1825
|
+
this.deps.emit("dragend", {
|
|
1826
|
+
size: this.deps.getDragContext().size,
|
|
1827
|
+
velocity: 0
|
|
1828
|
+
});
|
|
1752
1829
|
const restoreTo = this.dragStartSize;
|
|
1753
1830
|
void this.deps.animateTo(restoreTo, 0);
|
|
1754
1831
|
}
|
|
@@ -1822,6 +1899,287 @@ function createScrollCache(deps) {
|
|
|
1822
1899
|
};
|
|
1823
1900
|
}
|
|
1824
1901
|
|
|
1902
|
+
// src/core/primitives/anchor-animations.ts
|
|
1903
|
+
var DEFAULT_DURATION3 = 200;
|
|
1904
|
+
var DEFAULT_EASING = "cubic-bezier(0.22, 1, 0.36, 1)";
|
|
1905
|
+
var PRESET_FRAMES = {
|
|
1906
|
+
fade: {
|
|
1907
|
+
enter: [{ opacity: 0 }, { opacity: 1 }],
|
|
1908
|
+
exit: [{ opacity: 1 }, { opacity: 0 }]
|
|
1909
|
+
},
|
|
1910
|
+
scale: {
|
|
1911
|
+
enter: [
|
|
1912
|
+
{ opacity: 0, transform: "scale(0.85)" },
|
|
1913
|
+
{ opacity: 1, transform: "scale(1)" }
|
|
1914
|
+
],
|
|
1915
|
+
exit: [
|
|
1916
|
+
{ opacity: 1, transform: "scale(1)" },
|
|
1917
|
+
{ opacity: 0, transform: "scale(0.85)" }
|
|
1918
|
+
]
|
|
1919
|
+
},
|
|
1920
|
+
slide: {
|
|
1921
|
+
enter: [
|
|
1922
|
+
{ opacity: 0, transform: "translateY(10px)" },
|
|
1923
|
+
{ opacity: 1, transform: "translateY(0)" }
|
|
1924
|
+
],
|
|
1925
|
+
exit: [
|
|
1926
|
+
{ opacity: 1, transform: "translateY(0)" },
|
|
1927
|
+
{ opacity: 0, transform: "translateY(10px)" }
|
|
1928
|
+
]
|
|
1929
|
+
},
|
|
1930
|
+
pop: {
|
|
1931
|
+
enter: [
|
|
1932
|
+
{ opacity: 0, transform: "scale(0.6)", offset: 0 },
|
|
1933
|
+
{ opacity: 1, transform: "scale(1.06)", offset: 0.7 },
|
|
1934
|
+
{ opacity: 1, transform: "scale(1)", offset: 1 }
|
|
1935
|
+
],
|
|
1936
|
+
exit: [
|
|
1937
|
+
{ opacity: 1, transform: "scale(1)" },
|
|
1938
|
+
{ opacity: 0, transform: "scale(0.6)" }
|
|
1939
|
+
]
|
|
1940
|
+
}
|
|
1941
|
+
};
|
|
1942
|
+
var INSTANT = {
|
|
1943
|
+
finished: Promise.resolve(),
|
|
1944
|
+
cancel: () => {
|
|
1945
|
+
}
|
|
1946
|
+
};
|
|
1947
|
+
function resolveTransitionFrames(spec, phase) {
|
|
1948
|
+
const fallback = { frames: null, duration: 0, easing: DEFAULT_EASING };
|
|
1949
|
+
if (spec === "none") return fallback;
|
|
1950
|
+
if (spec === void 0 || typeof spec === "string") {
|
|
1951
|
+
const preset2 = PRESET_FRAMES[spec ?? "fade"];
|
|
1952
|
+
return {
|
|
1953
|
+
frames: preset2[phase],
|
|
1954
|
+
duration: DEFAULT_DURATION3,
|
|
1955
|
+
easing: DEFAULT_EASING
|
|
1956
|
+
};
|
|
1957
|
+
}
|
|
1958
|
+
const custom = phase === "enter" ? spec.enter : spec.exit;
|
|
1959
|
+
if (custom) {
|
|
1960
|
+
return {
|
|
1961
|
+
frames: custom,
|
|
1962
|
+
duration: spec.duration ?? DEFAULT_DURATION3,
|
|
1963
|
+
easing: spec.easing ?? DEFAULT_EASING
|
|
1964
|
+
};
|
|
1965
|
+
}
|
|
1966
|
+
if (spec.preset === "none") return fallback;
|
|
1967
|
+
const preset = PRESET_FRAMES[spec.preset ?? "fade"];
|
|
1968
|
+
return {
|
|
1969
|
+
frames: preset[phase],
|
|
1970
|
+
duration: spec.duration ?? DEFAULT_DURATION3,
|
|
1971
|
+
easing: spec.easing ?? DEFAULT_EASING
|
|
1972
|
+
};
|
|
1973
|
+
}
|
|
1974
|
+
function runAnchorTransition(el, spec, phase) {
|
|
1975
|
+
const respectReduced = typeof spec === "object" ? spec.respectReducedMotion !== false : true;
|
|
1976
|
+
if (respectReduced && prefersReducedMotion()) return INSTANT;
|
|
1977
|
+
const { frames, duration, easing } = resolveTransitionFrames(spec, phase);
|
|
1978
|
+
if (!frames || duration <= 0) return INSTANT;
|
|
1979
|
+
if (typeof el.animate !== "function") return INSTANT;
|
|
1980
|
+
const animation = el.animate(frames, {
|
|
1981
|
+
duration,
|
|
1982
|
+
easing,
|
|
1983
|
+
fill: "both"
|
|
1984
|
+
});
|
|
1985
|
+
const finished = animation.finished.then(() => void 0).catch(() => void 0);
|
|
1986
|
+
return {
|
|
1987
|
+
finished,
|
|
1988
|
+
cancel: () => {
|
|
1989
|
+
try {
|
|
1990
|
+
animation.cancel();
|
|
1991
|
+
} catch {
|
|
1992
|
+
return;
|
|
1993
|
+
}
|
|
1994
|
+
}
|
|
1995
|
+
};
|
|
1996
|
+
}
|
|
1997
|
+
|
|
1998
|
+
// src/core/features/sheet-anchors.ts
|
|
1999
|
+
function attachAnchor(deps, opts) {
|
|
2000
|
+
const doc = deps.host.ownerDocument;
|
|
2001
|
+
const wrapper = doc.createElement("div");
|
|
2002
|
+
wrapper.className = "bs-anchor";
|
|
2003
|
+
const interactive = opts.interactive ?? true;
|
|
2004
|
+
const position = opts.position ?? "sheet-top-right";
|
|
2005
|
+
const isDock = position === "dock-bottom" || position === "dock-top";
|
|
2006
|
+
const ws = wrapper.style;
|
|
2007
|
+
ws.position = "fixed";
|
|
2008
|
+
if (isDock) {
|
|
2009
|
+
ws.left = "0";
|
|
2010
|
+
ws.right = "0";
|
|
2011
|
+
if (position === "dock-bottom") {
|
|
2012
|
+
ws.bottom = "0";
|
|
2013
|
+
} else {
|
|
2014
|
+
ws.top = "0";
|
|
2015
|
+
}
|
|
2016
|
+
} else {
|
|
2017
|
+
applyOverlayPosition(ws, deps.mode, position, opts.inset ?? "16px");
|
|
2018
|
+
}
|
|
2019
|
+
if (opts.fadeRange) {
|
|
2020
|
+
const [r0, r1] = opts.fadeRange;
|
|
2021
|
+
const span = Math.max(r1 - r0, 1e-4);
|
|
2022
|
+
ws.opacity = `clamp(0, calc((var(--bs-progress, 0) - ${r0}) / ${span}), 1)`;
|
|
2023
|
+
}
|
|
2024
|
+
wrapper.appendChild(opts.element);
|
|
2025
|
+
deps.host.appendChild(wrapper);
|
|
2026
|
+
let visible = null;
|
|
2027
|
+
let inFlight = null;
|
|
2028
|
+
const shouldShow = (state) => {
|
|
2029
|
+
if (typeof opts.showOn === "function") return opts.showOn(state);
|
|
2030
|
+
if (Array.isArray(opts.showOn)) return opts.showOn.includes(state.activeId);
|
|
2031
|
+
return isDock || state.size > 0;
|
|
2032
|
+
};
|
|
2033
|
+
const applyVisibility = (next, animate) => {
|
|
2034
|
+
if (next === visible) return;
|
|
2035
|
+
visible = next;
|
|
2036
|
+
inFlight?.cancel();
|
|
2037
|
+
inFlight = null;
|
|
2038
|
+
wrapper.style.pointerEvents = next && interactive ? "auto" : "none";
|
|
2039
|
+
if (next) {
|
|
2040
|
+
wrapper.style.visibility = "";
|
|
2041
|
+
if (animate) {
|
|
2042
|
+
inFlight = runAnchorTransition(opts.element, opts.animation, "enter");
|
|
2043
|
+
}
|
|
2044
|
+
return;
|
|
2045
|
+
}
|
|
2046
|
+
if (!animate) {
|
|
2047
|
+
wrapper.style.visibility = "hidden";
|
|
2048
|
+
return;
|
|
2049
|
+
}
|
|
2050
|
+
const handle = runAnchorTransition(opts.element, opts.animation, "exit");
|
|
2051
|
+
inFlight = handle;
|
|
2052
|
+
void handle.finished.then(() => {
|
|
2053
|
+
if (inFlight === handle && visible === false) {
|
|
2054
|
+
wrapper.style.visibility = "hidden";
|
|
2055
|
+
}
|
|
2056
|
+
});
|
|
2057
|
+
};
|
|
2058
|
+
const evaluate = (animate) => {
|
|
2059
|
+
if (deps.isDestroyed()) return;
|
|
2060
|
+
applyVisibility(shouldShow(deps.getState()), animate);
|
|
2061
|
+
};
|
|
2062
|
+
const offs = [
|
|
2063
|
+
deps.on("snap", () => evaluate(true)),
|
|
2064
|
+
deps.on("open", () => evaluate(true)),
|
|
2065
|
+
deps.on("close", () => evaluate(true))
|
|
2066
|
+
];
|
|
2067
|
+
evaluate(false);
|
|
2068
|
+
return {
|
|
2069
|
+
wrapper,
|
|
2070
|
+
detach: () => {
|
|
2071
|
+
offs.forEach((off) => off());
|
|
2072
|
+
inFlight?.cancel();
|
|
2073
|
+
inFlight = null;
|
|
2074
|
+
if (wrapper.parentNode) wrapper.parentNode.removeChild(wrapper);
|
|
2075
|
+
},
|
|
2076
|
+
syncZ: (z) => {
|
|
2077
|
+
wrapper.style.zIndex = String(z);
|
|
2078
|
+
}
|
|
2079
|
+
};
|
|
2080
|
+
}
|
|
2081
|
+
|
|
2082
|
+
// src/core/features/scrim-stages.ts
|
|
2083
|
+
var matchesId = (def, activeId) => {
|
|
2084
|
+
if (def.for === void 0) return false;
|
|
2085
|
+
return Array.isArray(def.for) ? def.for.includes(activeId) : def.for === activeId;
|
|
2086
|
+
};
|
|
2087
|
+
var matchesRange = (def, progress) => {
|
|
2088
|
+
if (!def.forRange) return false;
|
|
2089
|
+
const [from, to] = def.forRange;
|
|
2090
|
+
return progress >= from && progress <= to;
|
|
2091
|
+
};
|
|
2092
|
+
function installScrimStages(deps, opts) {
|
|
2093
|
+
const doc = deps.host.ownerDocument;
|
|
2094
|
+
const entries = opts.stages.map((def) => {
|
|
2095
|
+
const wrapper = doc.createElement("div");
|
|
2096
|
+
wrapper.className = "bs-scrim-stage";
|
|
2097
|
+
const ws = wrapper.style;
|
|
2098
|
+
ws.position = "absolute";
|
|
2099
|
+
applyOverlayPosition(
|
|
2100
|
+
ws,
|
|
2101
|
+
deps.mode,
|
|
2102
|
+
def.position ?? opts.position ?? "center",
|
|
2103
|
+
def.inset ?? opts.inset ?? "16px"
|
|
2104
|
+
);
|
|
2105
|
+
ws.visibility = "hidden";
|
|
2106
|
+
ws.pointerEvents = "none";
|
|
2107
|
+
wrapper.appendChild(def.element);
|
|
2108
|
+
deps.host.appendChild(wrapper);
|
|
2109
|
+
return { def, wrapper, inFlight: null };
|
|
2110
|
+
});
|
|
2111
|
+
let active = null;
|
|
2112
|
+
const resolveActive = () => {
|
|
2113
|
+
const state = deps.getState();
|
|
2114
|
+
if (state.size === 0) {
|
|
2115
|
+
return entries.find((e) => matchesId(e.def, state.activeId)) ?? null;
|
|
2116
|
+
}
|
|
2117
|
+
return entries.find((e) => matchesId(e.def, state.activeId)) ?? entries.find((e) => matchesRange(e.def, state.progress)) ?? null;
|
|
2118
|
+
};
|
|
2119
|
+
const hide = (entry, animate) => {
|
|
2120
|
+
entry.inFlight?.cancel();
|
|
2121
|
+
entry.wrapper.style.pointerEvents = "none";
|
|
2122
|
+
if (!animate) {
|
|
2123
|
+
entry.inFlight = null;
|
|
2124
|
+
entry.wrapper.style.visibility = "hidden";
|
|
2125
|
+
return;
|
|
2126
|
+
}
|
|
2127
|
+
const handle = runAnchorTransition(
|
|
2128
|
+
entry.def.element,
|
|
2129
|
+
entry.def.animation ?? opts.animation,
|
|
2130
|
+
"exit"
|
|
2131
|
+
);
|
|
2132
|
+
entry.inFlight = handle;
|
|
2133
|
+
void handle.finished.then(() => {
|
|
2134
|
+
if (entry.inFlight === handle && active !== entry) {
|
|
2135
|
+
entry.wrapper.style.visibility = "hidden";
|
|
2136
|
+
}
|
|
2137
|
+
});
|
|
2138
|
+
};
|
|
2139
|
+
const show = (entry, animate) => {
|
|
2140
|
+
entry.inFlight?.cancel();
|
|
2141
|
+
entry.inFlight = null;
|
|
2142
|
+
entry.wrapper.style.visibility = "";
|
|
2143
|
+
entry.wrapper.style.pointerEvents = entry.def.interactive ?? opts.interactive ?? false ? "auto" : "none";
|
|
2144
|
+
if (animate) {
|
|
2145
|
+
entry.inFlight = runAnchorTransition(
|
|
2146
|
+
entry.def.element,
|
|
2147
|
+
entry.def.animation ?? opts.animation,
|
|
2148
|
+
"enter"
|
|
2149
|
+
);
|
|
2150
|
+
}
|
|
2151
|
+
};
|
|
2152
|
+
const update = (animate) => {
|
|
2153
|
+
if (deps.isDestroyed()) return;
|
|
2154
|
+
const next = resolveActive();
|
|
2155
|
+
if (next === active) return;
|
|
2156
|
+
const prev = active;
|
|
2157
|
+
active = next;
|
|
2158
|
+
if (prev) hide(prev, animate);
|
|
2159
|
+
if (next) show(next, animate);
|
|
2160
|
+
};
|
|
2161
|
+
const offs = [
|
|
2162
|
+
deps.on("snap", () => update(true)),
|
|
2163
|
+
deps.on("open", () => update(true)),
|
|
2164
|
+
deps.on("close", () => update(true))
|
|
2165
|
+
];
|
|
2166
|
+
if (entries.some((e) => e.def.forRange)) {
|
|
2167
|
+
offs.push(deps.on("progress", () => update(true)));
|
|
2168
|
+
}
|
|
2169
|
+
update(false);
|
|
2170
|
+
return () => {
|
|
2171
|
+
offs.forEach((off) => off());
|
|
2172
|
+
for (const entry of entries) {
|
|
2173
|
+
entry.inFlight?.cancel();
|
|
2174
|
+
entry.inFlight = null;
|
|
2175
|
+
if (entry.wrapper.parentNode) {
|
|
2176
|
+
entry.wrapper.parentNode.removeChild(entry.wrapper);
|
|
2177
|
+
}
|
|
2178
|
+
}
|
|
2179
|
+
active = null;
|
|
2180
|
+
};
|
|
2181
|
+
}
|
|
2182
|
+
|
|
1825
2183
|
// src/core/primitives/engine-options.ts
|
|
1826
2184
|
var DEFAULT_FLICK_VELOCITY = 0.65;
|
|
1827
2185
|
var DEFAULT_DRAG_THRESHOLD = 18;
|
|
@@ -1938,6 +2296,12 @@ var BottomSheetEngine = class {
|
|
|
1938
2296
|
__publicField(this, "linkedSheets", []);
|
|
1939
2297
|
__publicField(this, "scrollCache");
|
|
1940
2298
|
__publicField(this, "teardowns", new TeardownStack());
|
|
2299
|
+
__publicField(this, "anchors", []);
|
|
2300
|
+
__publicField(this, "anchorHost", null);
|
|
2301
|
+
__publicField(this, "stackZ", 100);
|
|
2302
|
+
__publicField(this, "detachScrimStages", null);
|
|
2303
|
+
__publicField(this, "stackEffectEnabled", false);
|
|
2304
|
+
__publicField(this, "stackEffectPrimed", false);
|
|
1941
2305
|
__publicField(this, "transformTemplate");
|
|
1942
2306
|
const resolved = resolveEngineOptions(opts, {
|
|
1943
2307
|
shouldApplyInertSiblings: () => {
|
|
@@ -1971,6 +2335,9 @@ var BottomSheetEngine = class {
|
|
|
1971
2335
|
getResolvedSnaps: () => this.snaps.getResolvedSnaps().slice(),
|
|
1972
2336
|
snapTo: (id) => {
|
|
1973
2337
|
void this.snapTo(id);
|
|
2338
|
+
},
|
|
2339
|
+
close: () => {
|
|
2340
|
+
void this.close();
|
|
1974
2341
|
}
|
|
1975
2342
|
},
|
|
1976
2343
|
resolved.scrim
|
|
@@ -1994,6 +2361,7 @@ var BottomSheetEngine = class {
|
|
|
1994
2361
|
);
|
|
1995
2362
|
this.closeOnBack = resolved.closeOnBack;
|
|
1996
2363
|
this.routedTo = opts.routedTo;
|
|
2364
|
+
this.stackEffectEnabled = opts.stackEffect ?? false;
|
|
1997
2365
|
this.snapPointsRaw = opts.snapPoints;
|
|
1998
2366
|
this.persistKey = opts.persistKey;
|
|
1999
2367
|
if (opts.linkedSheets) {
|
|
@@ -2006,7 +2374,7 @@ var BottomSheetEngine = class {
|
|
|
2006
2374
|
this.snapPointsRaw,
|
|
2007
2375
|
resolved.initialAllowed,
|
|
2008
2376
|
this.mode,
|
|
2009
|
-
() => this.handle.offsetHeight,
|
|
2377
|
+
() => layoutAxis(this.mode) === "width" ? this.handle.offsetWidth : this.handle.offsetHeight,
|
|
2010
2378
|
(maxAxisSize) => {
|
|
2011
2379
|
this.element.style[layoutAxis(this.mode)] = `${maxAxisSize}px`;
|
|
2012
2380
|
}
|
|
@@ -2216,11 +2584,6 @@ var BottomSheetEngine = class {
|
|
|
2216
2584
|
}
|
|
2217
2585
|
setAllowed(ids, snap) {
|
|
2218
2586
|
if (this.destroyed) return;
|
|
2219
|
-
const willSnap = snap !== void 0 && ids.includes(snap) || !ids.includes(this.activeId) && ids.length > 0;
|
|
2220
|
-
if (!willSnap) {
|
|
2221
|
-
this.animation.cancel();
|
|
2222
|
-
this.newCycle();
|
|
2223
|
-
}
|
|
2224
2587
|
this.snaps.setAllowedIds(ids);
|
|
2225
2588
|
this.updateAriaSlider();
|
|
2226
2589
|
if (snap && ids.includes(snap)) {
|
|
@@ -2260,6 +2623,79 @@ var BottomSheetEngine = class {
|
|
|
2260
2623
|
setScrimOverlay(opts) {
|
|
2261
2624
|
return this.scrim.setScrimOverlay(opts);
|
|
2262
2625
|
}
|
|
2626
|
+
addAnchor(opts) {
|
|
2627
|
+
if (this.destroyed || typeof document === "undefined") return () => {
|
|
2628
|
+
};
|
|
2629
|
+
if (!this.anchorHost) {
|
|
2630
|
+
this.anchorHost = this.rootEl ?? this.element.parentElement ?? document.body;
|
|
2631
|
+
this.anchorHost.style.setProperty("--bs-size", `${this.size}px`);
|
|
2632
|
+
this.anchorHost.style.setProperty(
|
|
2633
|
+
"--bs-progress",
|
|
2634
|
+
String(this.computeProgress(this.size))
|
|
2635
|
+
);
|
|
2636
|
+
}
|
|
2637
|
+
const handle = attachAnchor(
|
|
2638
|
+
{
|
|
2639
|
+
mode: this.mode,
|
|
2640
|
+
host: this.anchorHost,
|
|
2641
|
+
getState: () => ({
|
|
2642
|
+
activeId: this.activeId,
|
|
2643
|
+
size: this.size,
|
|
2644
|
+
progress: this.computeProgress(this.size)
|
|
2645
|
+
}),
|
|
2646
|
+
on: (event, fn) => this.on(event, fn),
|
|
2647
|
+
isDestroyed: () => this.destroyed
|
|
2648
|
+
},
|
|
2649
|
+
opts
|
|
2650
|
+
);
|
|
2651
|
+
handle.syncZ(this.stackZ + 1);
|
|
2652
|
+
this.anchors.push(handle);
|
|
2653
|
+
const detach = () => {
|
|
2654
|
+
const idx = this.anchors.indexOf(handle);
|
|
2655
|
+
if (idx === -1) return;
|
|
2656
|
+
this.anchors.splice(idx, 1);
|
|
2657
|
+
handle.detach();
|
|
2658
|
+
};
|
|
2659
|
+
this.teardowns.add(detach);
|
|
2660
|
+
return detach;
|
|
2661
|
+
}
|
|
2662
|
+
setScrimStages(opts) {
|
|
2663
|
+
if (this.destroyed || typeof document === "undefined") return () => {
|
|
2664
|
+
};
|
|
2665
|
+
this.detachScrimStages?.();
|
|
2666
|
+
this.detachScrimStages = null;
|
|
2667
|
+
if (!opts) return () => {
|
|
2668
|
+
};
|
|
2669
|
+
const host = this.screenComponent?.parentElement;
|
|
2670
|
+
if (!host) {
|
|
2671
|
+
console.warn(
|
|
2672
|
+
"[BottomSheet] setScrimStages: no scrim element mounted \u2014 pass `scrim` to the engine first."
|
|
2673
|
+
);
|
|
2674
|
+
return () => {
|
|
2675
|
+
};
|
|
2676
|
+
}
|
|
2677
|
+
const detachInstalled = installScrimStages(
|
|
2678
|
+
{
|
|
2679
|
+
mode: this.mode,
|
|
2680
|
+
host,
|
|
2681
|
+
getState: () => ({
|
|
2682
|
+
activeId: this.activeId,
|
|
2683
|
+
size: this.size,
|
|
2684
|
+
progress: this.computeProgress(this.size)
|
|
2685
|
+
}),
|
|
2686
|
+
on: (event, fn) => this.on(event, fn),
|
|
2687
|
+
isDestroyed: () => this.destroyed
|
|
2688
|
+
},
|
|
2689
|
+
opts
|
|
2690
|
+
);
|
|
2691
|
+
const detach = () => {
|
|
2692
|
+
if (this.detachScrimStages === detach) this.detachScrimStages = null;
|
|
2693
|
+
detachInstalled();
|
|
2694
|
+
};
|
|
2695
|
+
this.detachScrimStages = detach;
|
|
2696
|
+
this.teardowns.add(() => this.detachScrimStages?.());
|
|
2697
|
+
return detach;
|
|
2698
|
+
}
|
|
2263
2699
|
getScrimState() {
|
|
2264
2700
|
return { mode: this.scrim.scrimMode, enabled: this.scrim.scrimEnabled };
|
|
2265
2701
|
}
|
|
@@ -2346,24 +2782,45 @@ var BottomSheetEngine = class {
|
|
|
2346
2782
|
getAllowedRange() {
|
|
2347
2783
|
return this.snaps.getAllowedRange();
|
|
2348
2784
|
}
|
|
2785
|
+
allowedIdsBySize() {
|
|
2786
|
+
return this.snaps.getAllowedIds().slice().sort(
|
|
2787
|
+
(a, b) => (this.snaps.findById(a)?.size ?? 0) - (this.snaps.findById(b)?.size ?? 0)
|
|
2788
|
+
);
|
|
2789
|
+
}
|
|
2349
2790
|
updateAriaSlider() {
|
|
2350
|
-
this.aria.setValue(this.
|
|
2791
|
+
this.aria.setValue(this.allowedIdsBySize(), this.activeId);
|
|
2351
2792
|
}
|
|
2352
2793
|
registerInStack() {
|
|
2353
2794
|
this.teardowns.add(sheetStack.push({
|
|
2354
2795
|
id: this.id,
|
|
2355
2796
|
setZIndex: (z) => {
|
|
2797
|
+
this.stackZ = z;
|
|
2356
2798
|
this.element.style.zIndex = String(z);
|
|
2357
2799
|
if (this.backdrop) this.backdrop.style.zIndex = String(z - 1);
|
|
2800
|
+
for (const anchor of this.anchors) anchor.syncZ(z + 1);
|
|
2358
2801
|
},
|
|
2359
2802
|
setIsTop: (isTop) => {
|
|
2360
2803
|
this.isTopSheet = isTop;
|
|
2361
2804
|
if (this.backdrop) {
|
|
2362
2805
|
this.backdrop.style.display = isTop ? "" : "none";
|
|
2363
2806
|
}
|
|
2364
|
-
}
|
|
2807
|
+
},
|
|
2808
|
+
isOpen: () => this.size > 0,
|
|
2809
|
+
setDepth: (depth) => this.applyStackDepth(depth)
|
|
2365
2810
|
}));
|
|
2366
2811
|
}
|
|
2812
|
+
applyStackDepth(depth) {
|
|
2813
|
+
if (!this.stackEffectEnabled) return;
|
|
2814
|
+
this.element.setAttribute("data-stack-depth", String(depth));
|
|
2815
|
+
if (!this.stackEffectPrimed) {
|
|
2816
|
+
this.stackEffectPrimed = true;
|
|
2817
|
+
const isVertical = this.mode === "bottom" || this.mode === "top";
|
|
2818
|
+
this.element.style.transformOrigin = isVertical ? "50% 100%" : "0% 50%";
|
|
2819
|
+
this.element.style.transition = "scale 320ms cubic-bezier(0.29, 1.04, 0.84, 0.99)";
|
|
2820
|
+
}
|
|
2821
|
+
const scale = Math.max(1 - depth * 0.04, 0.86);
|
|
2822
|
+
this.element.style.scale = scale === 1 ? "" : String(scale);
|
|
2823
|
+
}
|
|
2367
2824
|
attach() {
|
|
2368
2825
|
this.gesture = new GestureController({
|
|
2369
2826
|
handle: this.handle,
|
|
@@ -2423,7 +2880,7 @@ var BottomSheetEngine = class {
|
|
|
2423
2880
|
container: this.scrollContainer,
|
|
2424
2881
|
isDragging: () => this.gesture?.isDragging ?? false,
|
|
2425
2882
|
isAnimating: () => this.animation.isAnimating,
|
|
2426
|
-
getAllowedIds: () => this.
|
|
2883
|
+
getAllowedIds: () => this.allowedIdsBySize(),
|
|
2427
2884
|
getActiveId: () => this.activeId,
|
|
2428
2885
|
snapTo: (id) => {
|
|
2429
2886
|
void this.snapTo(id);
|
|
@@ -2452,11 +2909,13 @@ var BottomSheetEngine = class {
|
|
|
2452
2909
|
},
|
|
2453
2910
|
newCycle: () => {
|
|
2454
2911
|
this.newCycle();
|
|
2455
|
-
}
|
|
2912
|
+
},
|
|
2913
|
+
isAnimating: () => this.animation.isAnimating,
|
|
2914
|
+
resyncAfterCancel: () => this.resyncAfterResize()
|
|
2456
2915
|
}));
|
|
2457
2916
|
if (this.lifecycle.closeOnEscape) {
|
|
2458
2917
|
const onKey = (e) => {
|
|
2459
|
-
if (this.destroyed) return;
|
|
2918
|
+
if (this.destroyed || e.defaultPrevented) return;
|
|
2460
2919
|
if (e.key === "Escape" && this.isTopSheet && this.size > 0) {
|
|
2461
2920
|
void this.close();
|
|
2462
2921
|
}
|
|
@@ -2488,7 +2947,7 @@ var BottomSheetEngine = class {
|
|
|
2488
2947
|
handle: this.handle,
|
|
2489
2948
|
mode: this.mode,
|
|
2490
2949
|
isDestroyed: () => this.destroyed,
|
|
2491
|
-
getAllowedIds: () => this.
|
|
2950
|
+
getAllowedIds: () => this.allowedIdsBySize(),
|
|
2492
2951
|
getActiveId: () => this.activeId,
|
|
2493
2952
|
snapTo: (id) => {
|
|
2494
2953
|
void this.snapTo(id);
|
|
@@ -2509,6 +2968,7 @@ var BottomSheetEngine = class {
|
|
|
2509
2968
|
});
|
|
2510
2969
|
if (!target) return;
|
|
2511
2970
|
const previousId = this.activeId;
|
|
2971
|
+
if (target.id === previousId && target.size === this.size) return;
|
|
2512
2972
|
if (this.emitBeforeSnap(target, previousId)) {
|
|
2513
2973
|
const restore = this.snaps.findById(previousId);
|
|
2514
2974
|
if (restore) {
|
|
@@ -2517,6 +2977,7 @@ var BottomSheetEngine = class {
|
|
|
2517
2977
|
return;
|
|
2518
2978
|
}
|
|
2519
2979
|
const previousSize = this.size;
|
|
2980
|
+
const previousSnapSize = this.snaps.findById(previousId)?.size;
|
|
2520
2981
|
this.scrollCache.cache(previousId, previousSize, target.size);
|
|
2521
2982
|
this.activeId = target.id;
|
|
2522
2983
|
void this.animation.animateTo(target.size, velocity).then(() => {
|
|
@@ -2525,9 +2986,10 @@ var BottomSheetEngine = class {
|
|
|
2525
2986
|
this.updateAriaSlider();
|
|
2526
2987
|
this.emit("snap", { id: target.id, size: target.size });
|
|
2527
2988
|
this.haptic();
|
|
2528
|
-
if (
|
|
2989
|
+
if (previousSnapSize === 0 && target.size > 0) {
|
|
2529
2990
|
this.emit("open", { id: target.id });
|
|
2530
2991
|
this.handleOpen();
|
|
2992
|
+
notifyLinkedSheets(this.linkedSheets, this);
|
|
2531
2993
|
}
|
|
2532
2994
|
if (target.size === 0) {
|
|
2533
2995
|
this.emit("close", void 0);
|
|
@@ -2553,6 +3015,9 @@ var BottomSheetEngine = class {
|
|
|
2553
3015
|
if (this.scrimParent) {
|
|
2554
3016
|
this.scrimParent.style.setProperty("--bs-size", `${size}px`);
|
|
2555
3017
|
}
|
|
3018
|
+
if (this.anchorHost && this.anchorHost !== this.scrimParent) {
|
|
3019
|
+
this.anchorHost.style.setProperty("--bs-size", `${size}px`);
|
|
3020
|
+
}
|
|
2556
3021
|
}
|
|
2557
3022
|
const progress = this.computeProgress(size);
|
|
2558
3023
|
const progressChanged = this.progressWriteSentinel.shouldWrite(
|
|
@@ -2561,6 +3026,9 @@ var BottomSheetEngine = class {
|
|
|
2561
3026
|
);
|
|
2562
3027
|
if (progressChanged) {
|
|
2563
3028
|
style.setProperty("--bs-progress", String(progress));
|
|
3029
|
+
if (this.anchorHost) {
|
|
3030
|
+
this.anchorHost.style.setProperty("--bs-progress", String(progress));
|
|
3031
|
+
}
|
|
2564
3032
|
}
|
|
2565
3033
|
this.scrim.applyOpacity(progress, progressChanged);
|
|
2566
3034
|
if (progressChanged && this.bus.listenerCount("progress") > 0) {
|
|
@@ -2575,6 +3043,7 @@ var BottomSheetEngine = class {
|
|
|
2575
3043
|
return Math.min(Math.max((size - min) / (max - min), 0), 1);
|
|
2576
3044
|
}
|
|
2577
3045
|
handleOpen() {
|
|
3046
|
+
sheetStack.promote(this.id);
|
|
2578
3047
|
try {
|
|
2579
3048
|
this.lifecycle.install();
|
|
2580
3049
|
} catch (err) {
|
|
@@ -2588,10 +3057,30 @@ var BottomSheetEngine = class {
|
|
|
2588
3057
|
});
|
|
2589
3058
|
}
|
|
2590
3059
|
}
|
|
3060
|
+
resyncAfterResize() {
|
|
3061
|
+
if (this.destroyed) return;
|
|
3062
|
+
const target = this.snaps.findById(this.activeId);
|
|
3063
|
+
if (!target) return;
|
|
3064
|
+
this.updateAriaSlider();
|
|
3065
|
+
this.emit("snap", { id: target.id, size: target.size });
|
|
3066
|
+
if (target.size > 0 && !this.lifecycle.isInstalled) {
|
|
3067
|
+
this.emit("open", { id: target.id });
|
|
3068
|
+
this.handleOpen();
|
|
3069
|
+
notifyLinkedSheets(this.linkedSheets, this);
|
|
3070
|
+
} else if (target.size === 0 && this.lifecycle.isInstalled) {
|
|
3071
|
+
this.emit("close", void 0);
|
|
3072
|
+
this.handleClose();
|
|
3073
|
+
}
|
|
3074
|
+
}
|
|
2591
3075
|
handleClose() {
|
|
2592
3076
|
this.lifecycle.release();
|
|
3077
|
+
sheetStack.update();
|
|
2593
3078
|
}
|
|
2594
3079
|
};
|
|
3080
|
+
|
|
3081
|
+
// src/solid/index.tsx
|
|
3082
|
+
var _tmpl$ = /* @__PURE__ */ template(`<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>`);
|
|
3083
|
+
var _tmpl$2 = /* @__PURE__ */ template(`<div class=bs-backdrop>`);
|
|
2595
3084
|
var BottomSheet = (props) => {
|
|
2596
3085
|
let sheetEl;
|
|
2597
3086
|
let handleEl;
|
|
@@ -2633,7 +3122,9 @@ var BottomSheet = (props) => {
|
|
|
2633
3122
|
const sync = () => {
|
|
2634
3123
|
if (!engine) return;
|
|
2635
3124
|
const s = engine.state;
|
|
2636
|
-
setState({
|
|
3125
|
+
setState({
|
|
3126
|
+
...s
|
|
3127
|
+
});
|
|
2637
3128
|
props.onChange?.(s);
|
|
2638
3129
|
};
|
|
2639
3130
|
sync();
|
|
@@ -2658,50 +3149,54 @@ var BottomSheet = (props) => {
|
|
|
2658
3149
|
engine = null;
|
|
2659
3150
|
props.engineRef?.(null);
|
|
2660
3151
|
});
|
|
3152
|
+
createEffect(on(() => props.snapPoints, (points, prev) => {
|
|
3153
|
+
if (!engine || prev === void 0) return;
|
|
3154
|
+
engine.setSnapPoints(points, props.allowed);
|
|
3155
|
+
}, {
|
|
3156
|
+
defer: true
|
|
3157
|
+
}));
|
|
3158
|
+
createEffect(on(() => props.allowed, (allowed, prev) => {
|
|
3159
|
+
if (!engine || prev === void 0) return;
|
|
3160
|
+
if (allowed) engine.setAllowed(allowed);
|
|
3161
|
+
}, {
|
|
3162
|
+
defer: true
|
|
3163
|
+
}));
|
|
2661
3164
|
const showBackdrop = createMemo(() => props.backdrop !== false);
|
|
2662
3165
|
const mode = createMemo(() => props.mode ?? "bottom");
|
|
2663
3166
|
const ariaLabel = createMemo(() => props.ariaLabel ?? "Bottom sheet");
|
|
2664
|
-
return
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
children: props.children
|
|
2698
|
-
}
|
|
2699
|
-
),
|
|
2700
|
-
/* @__PURE__ */ jsx("span", { class: "bs-sr-only", role: "status", "aria-live": "polite", children: state().activeId })
|
|
2701
|
-
]
|
|
2702
|
-
}
|
|
2703
|
-
)
|
|
2704
|
-
] });
|
|
3167
|
+
return (() => {
|
|
3168
|
+
var _el$ = _tmpl$(), _el$2 = _el$.firstChild, _el$3 = _el$2.nextSibling, _el$4 = _el$3.firstChild, _el$5 = _el$4.nextSibling, _el$6 = _el$5.nextSibling;
|
|
3169
|
+
insert(_el$, (() => {
|
|
3170
|
+
var _c$ = memo(() => !!showBackdrop());
|
|
3171
|
+
return () => _c$() ? (() => {
|
|
3172
|
+
var _el$7 = _tmpl$2();
|
|
3173
|
+
use((el) => backdropEl = el, _el$7);
|
|
3174
|
+
return _el$7;
|
|
3175
|
+
})() : null;
|
|
3176
|
+
})(), _el$2);
|
|
3177
|
+
use((el) => scrimEl = el, _el$2);
|
|
3178
|
+
insert(_el$2, () => props.screen);
|
|
3179
|
+
use((el) => sheetEl = el, _el$3);
|
|
3180
|
+
use((el) => handleEl = el, _el$4);
|
|
3181
|
+
insert(_el$4, () => props.header);
|
|
3182
|
+
use((el) => contentEl = el, _el$5);
|
|
3183
|
+
insert(_el$5, () => props.children);
|
|
3184
|
+
insert(_el$6, () => state().activeId);
|
|
3185
|
+
effect((_p$) => {
|
|
3186
|
+
var _v$ = mode(), _v$2 = state().activeId, _v$3 = props.focusTrap ? "true" : void 0, _v$4 = ariaLabel();
|
|
3187
|
+
_v$ !== _p$.e && setAttribute(_el$3, "data-mode", _p$.e = _v$);
|
|
3188
|
+
_v$2 !== _p$.t && setAttribute(_el$3, "data-active", _p$.t = _v$2);
|
|
3189
|
+
_v$3 !== _p$.a && setAttribute(_el$3, "aria-modal", _p$.a = _v$3);
|
|
3190
|
+
_v$4 !== _p$.o && setAttribute(_el$3, "aria-label", _p$.o = _v$4);
|
|
3191
|
+
return _p$;
|
|
3192
|
+
}, {
|
|
3193
|
+
e: void 0,
|
|
3194
|
+
t: void 0,
|
|
3195
|
+
a: void 0,
|
|
3196
|
+
o: void 0
|
|
3197
|
+
});
|
|
3198
|
+
return _el$;
|
|
3199
|
+
})();
|
|
2705
3200
|
};
|
|
2706
3201
|
|
|
2707
3202
|
export { BottomSheet };
|