@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/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,6 +24,18 @@ 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
|
}
|
|
@@ -31,9 +43,24 @@ var SheetStack = class {
|
|
|
31
43
|
this.entries = [];
|
|
32
44
|
}
|
|
33
45
|
recompute() {
|
|
46
|
+
let top = null;
|
|
47
|
+
const open = [];
|
|
48
|
+
for (const entry of this.entries) {
|
|
49
|
+
if (!entry.isOpen || entry.isOpen()) {
|
|
50
|
+
top = entry;
|
|
51
|
+
open.push(entry);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if (!top && this.entries.length > 0) {
|
|
55
|
+
top = this.entries[this.entries.length - 1];
|
|
56
|
+
}
|
|
34
57
|
this.entries.forEach((entry, i) => {
|
|
35
58
|
entry.setZIndex(BASE_Z + i * STEP);
|
|
36
|
-
entry.setIsTop(
|
|
59
|
+
entry.setIsTop(entry === top);
|
|
60
|
+
if (entry.setDepth) {
|
|
61
|
+
const openIdx = open.indexOf(entry);
|
|
62
|
+
entry.setDepth(openIdx === -1 ? 0 : open.length - 1 - openIdx);
|
|
63
|
+
}
|
|
37
64
|
});
|
|
38
65
|
}
|
|
39
66
|
};
|
|
@@ -318,14 +345,17 @@ function installAutoCollapse(deps) {
|
|
|
318
345
|
const fire = () => {
|
|
319
346
|
if (deps.isDestroyed()) return;
|
|
320
347
|
if (deps.isDragging()) return;
|
|
321
|
-
const
|
|
322
|
-
|
|
348
|
+
const active = deps.resolveSnap(deps.getActiveId());
|
|
349
|
+
if (!active || active.size === 0) return;
|
|
350
|
+
let target = null;
|
|
351
|
+
for (const id of deps.getAllowedIds()) {
|
|
323
352
|
const snap = deps.resolveSnap(id);
|
|
324
|
-
|
|
325
|
-
|
|
353
|
+
if (!snap || snap.size <= 0) continue;
|
|
354
|
+
if (!target || snap.size < target.size) target = snap;
|
|
355
|
+
}
|
|
326
356
|
if (!target) return;
|
|
327
|
-
if (target ===
|
|
328
|
-
deps.snapTo(target);
|
|
357
|
+
if (target.id === active.id || target.size >= active.size) return;
|
|
358
|
+
deps.snapTo(target.id);
|
|
329
359
|
};
|
|
330
360
|
const reset2 = () => {
|
|
331
361
|
clearTimer();
|
|
@@ -336,6 +366,7 @@ function installAutoCollapse(deps) {
|
|
|
336
366
|
}, ms);
|
|
337
367
|
};
|
|
338
368
|
const unsubscribe = deps.on("snap", () => reset2());
|
|
369
|
+
if ((deps.resolveSnap(deps.getActiveId())?.size ?? 0) > 0) reset2();
|
|
339
370
|
return () => {
|
|
340
371
|
clearTimer();
|
|
341
372
|
unsubscribe();
|
|
@@ -348,6 +379,7 @@ function notifyLinkedSheets(sheets, self) {
|
|
|
348
379
|
for (const linked of sheets) {
|
|
349
380
|
if (linked === self) continue;
|
|
350
381
|
try {
|
|
382
|
+
if (linked.state.size === 0) continue;
|
|
351
383
|
const ids = linked.getAllowedIds();
|
|
352
384
|
const target = ids.find((id) => id !== "closed");
|
|
353
385
|
if (target && target !== linked.state.activeId) {
|
|
@@ -394,7 +426,7 @@ function installRoute(deps) {
|
|
|
394
426
|
const onPop = (event) => {
|
|
395
427
|
if (deps.isDestroyed()) return;
|
|
396
428
|
const state2 = event.state;
|
|
397
|
-
if (state2
|
|
429
|
+
if ((!state2 || state2.__bsRouted !== target) && deps.getSize() > 0) {
|
|
398
430
|
routePushed = false;
|
|
399
431
|
void deps.close();
|
|
400
432
|
}
|
|
@@ -548,13 +580,17 @@ function installResizeObserver(deps) {
|
|
|
548
580
|
if (viewportSize2 > 0 && viewportSize2 < max) {
|
|
549
581
|
deps.setMaxAxisSize(viewportSize2);
|
|
550
582
|
}
|
|
583
|
+
const wasAnimating = deps.isAnimating?.() ?? false;
|
|
551
584
|
deps.cancelInFlight();
|
|
552
585
|
deps.newCycle();
|
|
553
586
|
const current = deps.resolveActiveSnap();
|
|
554
587
|
const newMax = deps.getMaxAxisSize();
|
|
555
588
|
const targetSize = current ? Math.min(current.size, newMax) : Math.min(deps.getSize(), newMax);
|
|
556
589
|
deps.setSize(targetSize);
|
|
557
|
-
if (current && !deps.isDragging())
|
|
590
|
+
if (current && !deps.isDragging()) {
|
|
591
|
+
deps.applySize(targetSize);
|
|
592
|
+
if (wasAnimating) deps.resyncAfterCancel?.();
|
|
593
|
+
}
|
|
558
594
|
};
|
|
559
595
|
let resizeObserver = null;
|
|
560
596
|
if (typeof ResizeObserver !== "undefined") {
|
|
@@ -669,6 +705,85 @@ function devWarn(...args) {
|
|
|
669
705
|
}
|
|
670
706
|
}
|
|
671
707
|
|
|
708
|
+
// src/core/primitives/overlay-position.ts
|
|
709
|
+
function resolveSheetAnchoredStyle(mode, position, inset) {
|
|
710
|
+
const sizeOffset = `calc(var(--bs-size, 0px) + ${inset})`;
|
|
711
|
+
switch (mode) {
|
|
712
|
+
case "bottom":
|
|
713
|
+
if (position === "sheet-top-left") return { bottom: sizeOffset, left: inset };
|
|
714
|
+
if (position === "sheet-top-right") return { bottom: sizeOffset, right: inset };
|
|
715
|
+
return { bottom: sizeOffset, left: "50%", transform: "translateX(-50%)" };
|
|
716
|
+
case "top":
|
|
717
|
+
if (position === "sheet-top-left") return { top: sizeOffset, left: inset };
|
|
718
|
+
if (position === "sheet-top-right") return { top: sizeOffset, right: inset };
|
|
719
|
+
return { top: sizeOffset, left: "50%", transform: "translateX(-50%)" };
|
|
720
|
+
case "left":
|
|
721
|
+
if (position === "sheet-top-left") return { left: sizeOffset, top: inset };
|
|
722
|
+
if (position === "sheet-top-right") return { left: sizeOffset, bottom: inset };
|
|
723
|
+
return { left: sizeOffset, top: "50%", transform: "translateY(-50%)" };
|
|
724
|
+
case "right":
|
|
725
|
+
if (position === "sheet-top-left") return { right: sizeOffset, top: inset };
|
|
726
|
+
if (position === "sheet-top-right") return { right: sizeOffset, bottom: inset };
|
|
727
|
+
return { right: sizeOffset, top: "50%", transform: "translateY(-50%)" };
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
function applyOverlayPosition(ws, mode, position, inset) {
|
|
731
|
+
switch (position) {
|
|
732
|
+
case "top-left":
|
|
733
|
+
ws.top = inset;
|
|
734
|
+
ws.left = inset;
|
|
735
|
+
break;
|
|
736
|
+
case "top-center":
|
|
737
|
+
ws.top = inset;
|
|
738
|
+
ws.left = "50%";
|
|
739
|
+
ws.transform = "translateX(-50%)";
|
|
740
|
+
break;
|
|
741
|
+
case "top-right":
|
|
742
|
+
ws.top = inset;
|
|
743
|
+
ws.right = inset;
|
|
744
|
+
break;
|
|
745
|
+
case "center-left":
|
|
746
|
+
ws.top = "50%";
|
|
747
|
+
ws.left = inset;
|
|
748
|
+
ws.transform = "translateY(-50%)";
|
|
749
|
+
break;
|
|
750
|
+
case "center":
|
|
751
|
+
ws.top = "50%";
|
|
752
|
+
ws.left = "50%";
|
|
753
|
+
ws.transform = "translate(-50%, -50%)";
|
|
754
|
+
break;
|
|
755
|
+
case "center-right":
|
|
756
|
+
ws.top = "50%";
|
|
757
|
+
ws.right = inset;
|
|
758
|
+
ws.transform = "translateY(-50%)";
|
|
759
|
+
break;
|
|
760
|
+
case "bottom-left":
|
|
761
|
+
ws.bottom = inset;
|
|
762
|
+
ws.left = inset;
|
|
763
|
+
break;
|
|
764
|
+
case "bottom-center":
|
|
765
|
+
ws.bottom = inset;
|
|
766
|
+
ws.left = "50%";
|
|
767
|
+
ws.transform = "translateX(-50%)";
|
|
768
|
+
break;
|
|
769
|
+
case "bottom-right":
|
|
770
|
+
ws.bottom = inset;
|
|
771
|
+
ws.right = inset;
|
|
772
|
+
break;
|
|
773
|
+
case "sheet-top-left":
|
|
774
|
+
case "sheet-top-center":
|
|
775
|
+
case "sheet-top-right": {
|
|
776
|
+
const style = resolveSheetAnchoredStyle(mode, position, inset);
|
|
777
|
+
if (style.top !== void 0) ws.top = style.top;
|
|
778
|
+
if (style.bottom !== void 0) ws.bottom = style.bottom;
|
|
779
|
+
if (style.left !== void 0) ws.left = style.left;
|
|
780
|
+
if (style.right !== void 0) ws.right = style.right;
|
|
781
|
+
if (style.transform !== void 0) ws.transform = style.transform;
|
|
782
|
+
break;
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
|
|
672
787
|
// src/core/controllers/scrim-controller.ts
|
|
673
788
|
var VALID_CSS_LENGTH = /^-?\d+(?:\.\d+)?(?:px|em|rem|%)$/;
|
|
674
789
|
var ScrimController = class {
|
|
@@ -681,6 +796,8 @@ var ScrimController = class {
|
|
|
681
796
|
__publicField(this, "getAllowedIds");
|
|
682
797
|
__publicField(this, "getResolvedSnaps");
|
|
683
798
|
__publicField(this, "snapToFn");
|
|
799
|
+
__publicField(this, "closeFn");
|
|
800
|
+
__publicField(this, "scrimInteractive", false);
|
|
684
801
|
__publicField(this, "scrimMode");
|
|
685
802
|
__publicField(this, "backdropRange");
|
|
686
803
|
__publicField(this, "screenRange");
|
|
@@ -701,6 +818,7 @@ var ScrimController = class {
|
|
|
701
818
|
this.getAllowedIds = deps.getAllowedIds;
|
|
702
819
|
this.getResolvedSnaps = deps.getResolvedSnaps;
|
|
703
820
|
this.snapToFn = deps.snapTo;
|
|
821
|
+
this.closeFn = deps.close;
|
|
704
822
|
this.scrimMode = opts.scrimMode ?? "full";
|
|
705
823
|
const preset = opts.scrimPreset ? SCRIM_PRESETS[opts.scrimPreset] : null;
|
|
706
824
|
this.backdropRange = opts.backdropRange ?? preset?.range ?? [0, 1];
|
|
@@ -842,11 +960,15 @@ var ScrimController = class {
|
|
|
842
960
|
}
|
|
843
961
|
const onClick = () => {
|
|
844
962
|
if (this.isDestroyed()) return;
|
|
963
|
+
if (this.closeFn) {
|
|
964
|
+
this.closeFn();
|
|
965
|
+
return;
|
|
966
|
+
}
|
|
845
967
|
const allowed = this.getAllowedIds();
|
|
846
968
|
const snaps = this.getResolvedSnaps();
|
|
847
969
|
const fallback = allowed.find((id) => {
|
|
848
970
|
const snap = findById(id, snaps);
|
|
849
|
-
return snap !== null && snap.size
|
|
971
|
+
return snap !== null && snap.size === 0;
|
|
850
972
|
});
|
|
851
973
|
if (fallback) this.snapToFn(fallback);
|
|
852
974
|
};
|
|
@@ -863,6 +985,7 @@ var ScrimController = class {
|
|
|
863
985
|
if (this.isDestroyed()) return;
|
|
864
986
|
if (enabled === this.scrimEnabled) return;
|
|
865
987
|
this.scrimEnabled = enabled;
|
|
988
|
+
this.invalidateOpacityCache();
|
|
866
989
|
if (!enabled) {
|
|
867
990
|
this.savedScrimRanges = {
|
|
868
991
|
screen: this.screenRange,
|
|
@@ -886,7 +1009,12 @@ var ScrimController = class {
|
|
|
886
1009
|
blur: cfg.blur ?? null,
|
|
887
1010
|
interactive: cfg.interactive
|
|
888
1011
|
});
|
|
889
|
-
this.
|
|
1012
|
+
if (!this.scrimEnabled && this.savedScrimRanges) {
|
|
1013
|
+
this.savedScrimRanges = { screen: cfg.range, backdrop: cfg.range };
|
|
1014
|
+
} else {
|
|
1015
|
+
this.screenRange = cfg.range;
|
|
1016
|
+
this.backdropRange = cfg.range;
|
|
1017
|
+
}
|
|
890
1018
|
}
|
|
891
1019
|
const noop = () => {
|
|
892
1020
|
};
|
|
@@ -936,59 +1064,7 @@ var ScrimController = class {
|
|
|
936
1064
|
wrapper.className = "bs-scrim-overlay";
|
|
937
1065
|
const ws = wrapper.style;
|
|
938
1066
|
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
|
-
}
|
|
1067
|
+
applyOverlayPosition(ws, this.mode, position, inset);
|
|
992
1068
|
if (interactive) {
|
|
993
1069
|
ws.pointerEvents = "auto";
|
|
994
1070
|
}
|
|
@@ -1047,6 +1123,7 @@ var ScrimController = class {
|
|
|
1047
1123
|
}
|
|
1048
1124
|
}
|
|
1049
1125
|
if (opts.interactive !== void 0) {
|
|
1126
|
+
this.scrimInteractive = opts.interactive;
|
|
1050
1127
|
s.pointerEvents = opts.interactive ? "auto" : "none";
|
|
1051
1128
|
}
|
|
1052
1129
|
}
|
|
@@ -1061,38 +1138,9 @@ var ScrimController = class {
|
|
|
1061
1138
|
const s = this.screenComponent.style;
|
|
1062
1139
|
s.position = "fixed";
|
|
1063
1140
|
s.inset = insetByMode[this.mode];
|
|
1064
|
-
s.pointerEvents = "none";
|
|
1141
|
+
s.pointerEvents = this.scrimInteractive || this.scrimTapToCloseEnabled ? "auto" : "none";
|
|
1065
1142
|
}
|
|
1066
1143
|
};
|
|
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
1144
|
|
|
1097
1145
|
// src/core/animation/animation.ts
|
|
1098
1146
|
var easeOutBack = (t) => {
|
|
@@ -1144,6 +1192,10 @@ var tween = ({
|
|
|
1144
1192
|
promise
|
|
1145
1193
|
};
|
|
1146
1194
|
};
|
|
1195
|
+
var prefersReducedMotion = () => {
|
|
1196
|
+
if (typeof window === "undefined" || !window.matchMedia) return false;
|
|
1197
|
+
return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
1198
|
+
};
|
|
1147
1199
|
|
|
1148
1200
|
// src/core/animation/spring.ts
|
|
1149
1201
|
var DEFAULT_SPRING = {
|
|
@@ -1174,14 +1226,20 @@ var runSpring = ({
|
|
|
1174
1226
|
if (cancelled) return;
|
|
1175
1227
|
const dt = Math.min((now - lastTime) / 1e3, MAX_DT);
|
|
1176
1228
|
lastTime = now;
|
|
1177
|
-
const
|
|
1178
|
-
|
|
1229
|
+
const steps = Math.max(1, Math.ceil(dt * 240));
|
|
1230
|
+
const subDt = dt / steps;
|
|
1231
|
+
let stepsLeft = steps;
|
|
1179
1232
|
while (stepsLeft-- > 0) {
|
|
1180
1233
|
const force = -cfg.stiffness * (x - to) - cfg.damping * v;
|
|
1181
1234
|
const accel = force / cfg.mass;
|
|
1182
1235
|
v += accel * subDt;
|
|
1183
1236
|
x += v * subDt;
|
|
1184
1237
|
}
|
|
1238
|
+
if (!Number.isFinite(x) || !Number.isFinite(v)) {
|
|
1239
|
+
onUpdate(to, 0);
|
|
1240
|
+
resolve();
|
|
1241
|
+
return;
|
|
1242
|
+
}
|
|
1185
1243
|
onUpdate(x, v);
|
|
1186
1244
|
const isAtRest = Math.abs(to - x) < (cfg.restDelta ?? 0.5) && Math.abs(v) < (cfg.restSpeed ?? 0.5);
|
|
1187
1245
|
if (isAtRest) {
|
|
@@ -1356,9 +1414,13 @@ var isVisible = (el) => {
|
|
|
1356
1414
|
var focusables = (root2) => Array.from(root2.querySelectorAll(FOCUSABLE)).filter(
|
|
1357
1415
|
(el) => !el.hasAttribute("inert") && isVisible(el) && !el.matches("[aria-hidden='true']")
|
|
1358
1416
|
);
|
|
1417
|
+
var trapStack = [];
|
|
1359
1418
|
var installFocusTrap = (container, options = {}) => {
|
|
1360
1419
|
if (typeof document === "undefined") return () => {
|
|
1361
1420
|
};
|
|
1421
|
+
const token = {};
|
|
1422
|
+
trapStack.push(token);
|
|
1423
|
+
const isActive = () => trapStack[trapStack.length - 1] === token;
|
|
1362
1424
|
const previouslyFocused = document.activeElement;
|
|
1363
1425
|
const focusInitial = () => {
|
|
1364
1426
|
const initial = typeof options.initialFocus === "string" ? container.querySelector(options.initialFocus) : options.initialFocus ?? focusables(container)[0] ?? container;
|
|
@@ -1366,6 +1428,7 @@ var installFocusTrap = (container, options = {}) => {
|
|
|
1366
1428
|
};
|
|
1367
1429
|
focusInitial();
|
|
1368
1430
|
const handleKey = (e) => {
|
|
1431
|
+
if (!isActive()) return;
|
|
1369
1432
|
if (e.key === "Escape" && options.onEscape) {
|
|
1370
1433
|
options.onEscape();
|
|
1371
1434
|
return;
|
|
@@ -1388,6 +1451,7 @@ var installFocusTrap = (container, options = {}) => {
|
|
|
1388
1451
|
}
|
|
1389
1452
|
};
|
|
1390
1453
|
const handleFocusIn = (e) => {
|
|
1454
|
+
if (!isActive()) return;
|
|
1391
1455
|
const target = e.target;
|
|
1392
1456
|
if (target && !container.contains(target)) {
|
|
1393
1457
|
const list = focusables(container);
|
|
@@ -1400,6 +1464,8 @@ var installFocusTrap = (container, options = {}) => {
|
|
|
1400
1464
|
return () => {
|
|
1401
1465
|
if (released) return;
|
|
1402
1466
|
released = true;
|
|
1467
|
+
const idx = trapStack.indexOf(token);
|
|
1468
|
+
if (idx !== -1) trapStack.splice(idx, 1);
|
|
1403
1469
|
document.removeEventListener("keydown", handleKey, true);
|
|
1404
1470
|
document.removeEventListener("focusin", handleFocusIn, true);
|
|
1405
1471
|
if (previouslyFocused && document.contains(previouslyFocused)) {
|
|
@@ -1455,11 +1521,17 @@ function createInertSiblings(rootProvider) {
|
|
|
1455
1521
|
return {
|
|
1456
1522
|
apply() {
|
|
1457
1523
|
if (typeof document === "undefined") return;
|
|
1458
|
-
|
|
1459
|
-
|
|
1524
|
+
let top = rootProvider();
|
|
1525
|
+
while (top.parentElement && top.parentElement !== document.body) {
|
|
1526
|
+
top = top.parentElement;
|
|
1527
|
+
}
|
|
1528
|
+
const parent = top.parentElement ?? document.body;
|
|
1460
1529
|
for (const child2 of Array.from(parent.children)) {
|
|
1461
|
-
if (child2 ===
|
|
1530
|
+
if (child2 === top) continue;
|
|
1462
1531
|
if (child2.hasAttribute("inert")) continue;
|
|
1532
|
+
if (child2.classList.contains("bs-backdrop") || child2.classList.contains("bs-screen") || child2.classList.contains("bs-root")) {
|
|
1533
|
+
continue;
|
|
1534
|
+
}
|
|
1463
1535
|
child2.setAttribute("inert", "");
|
|
1464
1536
|
tracked.push(child2);
|
|
1465
1537
|
}
|
|
@@ -1475,7 +1547,6 @@ function createInertSiblings(rootProvider) {
|
|
|
1475
1547
|
var LifecycleController = class {
|
|
1476
1548
|
constructor(deps, opts) {
|
|
1477
1549
|
__publicField(this, "element");
|
|
1478
|
-
__publicField(this, "closeFn");
|
|
1479
1550
|
__publicField(this, "focusTrapEnabled");
|
|
1480
1551
|
__publicField(this, "initialFocus");
|
|
1481
1552
|
__publicField(this, "closeOnEscape");
|
|
@@ -1489,7 +1560,6 @@ var LifecycleController = class {
|
|
|
1489
1560
|
__publicField(this, "installed", false);
|
|
1490
1561
|
__publicField(this, "destroyed", false);
|
|
1491
1562
|
this.element = deps.element;
|
|
1492
|
-
this.closeFn = deps.close;
|
|
1493
1563
|
this.focusTrapEnabled = opts.focusTrap ?? false;
|
|
1494
1564
|
this.initialFocus = opts.initialFocus;
|
|
1495
1565
|
this.closeOnEscape = opts.closeOnEscape ?? true;
|
|
@@ -1499,6 +1569,9 @@ var LifecycleController = class {
|
|
|
1499
1569
|
this.returnFocus = opts.returnFocus;
|
|
1500
1570
|
this.inertSiblings = createInertSiblings(() => this.element);
|
|
1501
1571
|
}
|
|
1572
|
+
get isInstalled() {
|
|
1573
|
+
return this.installed;
|
|
1574
|
+
}
|
|
1502
1575
|
install() {
|
|
1503
1576
|
if (this.destroyed) return;
|
|
1504
1577
|
this.installed = true;
|
|
@@ -1507,8 +1580,7 @@ var LifecycleController = class {
|
|
|
1507
1580
|
}
|
|
1508
1581
|
if (this.focusTrapEnabled && !this.releaseFocusTrap) {
|
|
1509
1582
|
this.releaseFocusTrap = installFocusTrap(this.element, {
|
|
1510
|
-
initialFocus: this.initialFocus
|
|
1511
|
-
onEscape: this.closeOnEscape ? () => void this.closeFn() : void 0
|
|
1583
|
+
initialFocus: this.initialFocus
|
|
1512
1584
|
});
|
|
1513
1585
|
}
|
|
1514
1586
|
if (this.inertSiblingsEnabled && this.shouldApplyInertSiblings()) {
|
|
@@ -1662,10 +1734,11 @@ var installGestures = (handle, mode, callbacks) => {
|
|
|
1662
1734
|
};
|
|
1663
1735
|
|
|
1664
1736
|
// src/core/primitives/rubber-band.ts
|
|
1665
|
-
var RUBBER_BAND_FACTOR = 0.55;
|
|
1666
1737
|
function rubberBand(overshoot, maxAxisSize) {
|
|
1667
1738
|
const cap = Math.min(maxAxisSize * 0.15, 80);
|
|
1668
|
-
|
|
1739
|
+
if (cap <= 0) return 0;
|
|
1740
|
+
const abs = Math.abs(overshoot);
|
|
1741
|
+
return Math.sign(overshoot) * (cap * abs / (abs + cap));
|
|
1669
1742
|
}
|
|
1670
1743
|
|
|
1671
1744
|
// src/core/features/soft-keyboard.ts
|
|
@@ -1750,6 +1823,10 @@ var GestureController = class {
|
|
|
1750
1823
|
this.isDragging_ = false;
|
|
1751
1824
|
this.keyboardDismissed = false;
|
|
1752
1825
|
this.deps.getRoot()?.removeAttribute("data-dragging");
|
|
1826
|
+
this.deps.emit("dragend", {
|
|
1827
|
+
size: this.deps.getDragContext().size,
|
|
1828
|
+
velocity: 0
|
|
1829
|
+
});
|
|
1753
1830
|
const restoreTo = this.dragStartSize;
|
|
1754
1831
|
void this.deps.animateTo(restoreTo, 0);
|
|
1755
1832
|
}
|
|
@@ -1823,6 +1900,287 @@ function createScrollCache(deps) {
|
|
|
1823
1900
|
};
|
|
1824
1901
|
}
|
|
1825
1902
|
|
|
1903
|
+
// src/core/primitives/anchor-animations.ts
|
|
1904
|
+
var DEFAULT_DURATION3 = 200;
|
|
1905
|
+
var DEFAULT_EASING = "cubic-bezier(0.22, 1, 0.36, 1)";
|
|
1906
|
+
var PRESET_FRAMES = {
|
|
1907
|
+
fade: {
|
|
1908
|
+
enter: [{ opacity: 0 }, { opacity: 1 }],
|
|
1909
|
+
exit: [{ opacity: 1 }, { opacity: 0 }]
|
|
1910
|
+
},
|
|
1911
|
+
scale: {
|
|
1912
|
+
enter: [
|
|
1913
|
+
{ opacity: 0, transform: "scale(0.85)" },
|
|
1914
|
+
{ opacity: 1, transform: "scale(1)" }
|
|
1915
|
+
],
|
|
1916
|
+
exit: [
|
|
1917
|
+
{ opacity: 1, transform: "scale(1)" },
|
|
1918
|
+
{ opacity: 0, transform: "scale(0.85)" }
|
|
1919
|
+
]
|
|
1920
|
+
},
|
|
1921
|
+
slide: {
|
|
1922
|
+
enter: [
|
|
1923
|
+
{ opacity: 0, transform: "translateY(10px)" },
|
|
1924
|
+
{ opacity: 1, transform: "translateY(0)" }
|
|
1925
|
+
],
|
|
1926
|
+
exit: [
|
|
1927
|
+
{ opacity: 1, transform: "translateY(0)" },
|
|
1928
|
+
{ opacity: 0, transform: "translateY(10px)" }
|
|
1929
|
+
]
|
|
1930
|
+
},
|
|
1931
|
+
pop: {
|
|
1932
|
+
enter: [
|
|
1933
|
+
{ opacity: 0, transform: "scale(0.6)", offset: 0 },
|
|
1934
|
+
{ opacity: 1, transform: "scale(1.06)", offset: 0.7 },
|
|
1935
|
+
{ opacity: 1, transform: "scale(1)", offset: 1 }
|
|
1936
|
+
],
|
|
1937
|
+
exit: [
|
|
1938
|
+
{ opacity: 1, transform: "scale(1)" },
|
|
1939
|
+
{ opacity: 0, transform: "scale(0.6)" }
|
|
1940
|
+
]
|
|
1941
|
+
}
|
|
1942
|
+
};
|
|
1943
|
+
var INSTANT = {
|
|
1944
|
+
finished: Promise.resolve(),
|
|
1945
|
+
cancel: () => {
|
|
1946
|
+
}
|
|
1947
|
+
};
|
|
1948
|
+
function resolveTransitionFrames(spec, phase) {
|
|
1949
|
+
const fallback = { frames: null, duration: 0, easing: DEFAULT_EASING };
|
|
1950
|
+
if (spec === "none") return fallback;
|
|
1951
|
+
if (spec === void 0 || typeof spec === "string") {
|
|
1952
|
+
const preset2 = PRESET_FRAMES[spec ?? "fade"];
|
|
1953
|
+
return {
|
|
1954
|
+
frames: preset2[phase],
|
|
1955
|
+
duration: DEFAULT_DURATION3,
|
|
1956
|
+
easing: DEFAULT_EASING
|
|
1957
|
+
};
|
|
1958
|
+
}
|
|
1959
|
+
const custom = phase === "enter" ? spec.enter : spec.exit;
|
|
1960
|
+
if (custom) {
|
|
1961
|
+
return {
|
|
1962
|
+
frames: custom,
|
|
1963
|
+
duration: spec.duration ?? DEFAULT_DURATION3,
|
|
1964
|
+
easing: spec.easing ?? DEFAULT_EASING
|
|
1965
|
+
};
|
|
1966
|
+
}
|
|
1967
|
+
if (spec.preset === "none") return fallback;
|
|
1968
|
+
const preset = PRESET_FRAMES[spec.preset ?? "fade"];
|
|
1969
|
+
return {
|
|
1970
|
+
frames: preset[phase],
|
|
1971
|
+
duration: spec.duration ?? DEFAULT_DURATION3,
|
|
1972
|
+
easing: spec.easing ?? DEFAULT_EASING
|
|
1973
|
+
};
|
|
1974
|
+
}
|
|
1975
|
+
function runAnchorTransition(el, spec, phase) {
|
|
1976
|
+
const respectReduced = typeof spec === "object" ? spec.respectReducedMotion !== false : true;
|
|
1977
|
+
if (respectReduced && prefersReducedMotion()) return INSTANT;
|
|
1978
|
+
const { frames, duration, easing } = resolveTransitionFrames(spec, phase);
|
|
1979
|
+
if (!frames || duration <= 0) return INSTANT;
|
|
1980
|
+
if (typeof el.animate !== "function") return INSTANT;
|
|
1981
|
+
const animation = el.animate(frames, {
|
|
1982
|
+
duration,
|
|
1983
|
+
easing,
|
|
1984
|
+
fill: "both"
|
|
1985
|
+
});
|
|
1986
|
+
const finished = animation.finished.then(() => void 0).catch(() => void 0);
|
|
1987
|
+
return {
|
|
1988
|
+
finished,
|
|
1989
|
+
cancel: () => {
|
|
1990
|
+
try {
|
|
1991
|
+
animation.cancel();
|
|
1992
|
+
} catch {
|
|
1993
|
+
return;
|
|
1994
|
+
}
|
|
1995
|
+
}
|
|
1996
|
+
};
|
|
1997
|
+
}
|
|
1998
|
+
|
|
1999
|
+
// src/core/features/sheet-anchors.ts
|
|
2000
|
+
function attachAnchor(deps, opts) {
|
|
2001
|
+
const doc = deps.host.ownerDocument;
|
|
2002
|
+
const wrapper = doc.createElement("div");
|
|
2003
|
+
wrapper.className = "bs-anchor";
|
|
2004
|
+
const interactive = opts.interactive ?? true;
|
|
2005
|
+
const position = opts.position ?? "sheet-top-right";
|
|
2006
|
+
const isDock = position === "dock-bottom" || position === "dock-top";
|
|
2007
|
+
const ws = wrapper.style;
|
|
2008
|
+
ws.position = "fixed";
|
|
2009
|
+
if (isDock) {
|
|
2010
|
+
ws.left = "0";
|
|
2011
|
+
ws.right = "0";
|
|
2012
|
+
if (position === "dock-bottom") {
|
|
2013
|
+
ws.bottom = "0";
|
|
2014
|
+
} else {
|
|
2015
|
+
ws.top = "0";
|
|
2016
|
+
}
|
|
2017
|
+
} else {
|
|
2018
|
+
applyOverlayPosition(ws, deps.mode, position, opts.inset ?? "16px");
|
|
2019
|
+
}
|
|
2020
|
+
if (opts.fadeRange) {
|
|
2021
|
+
const [r0, r1] = opts.fadeRange;
|
|
2022
|
+
const span = Math.max(r1 - r0, 1e-4);
|
|
2023
|
+
ws.opacity = `clamp(0, calc((var(--bs-progress, 0) - ${r0}) / ${span}), 1)`;
|
|
2024
|
+
}
|
|
2025
|
+
wrapper.appendChild(opts.element);
|
|
2026
|
+
deps.host.appendChild(wrapper);
|
|
2027
|
+
let visible = null;
|
|
2028
|
+
let inFlight = null;
|
|
2029
|
+
const shouldShow = (state2) => {
|
|
2030
|
+
if (typeof opts.showOn === "function") return opts.showOn(state2);
|
|
2031
|
+
if (Array.isArray(opts.showOn)) return opts.showOn.includes(state2.activeId);
|
|
2032
|
+
return isDock || state2.size > 0;
|
|
2033
|
+
};
|
|
2034
|
+
const applyVisibility = (next, animate) => {
|
|
2035
|
+
if (next === visible) return;
|
|
2036
|
+
visible = next;
|
|
2037
|
+
inFlight?.cancel();
|
|
2038
|
+
inFlight = null;
|
|
2039
|
+
wrapper.style.pointerEvents = next && interactive ? "auto" : "none";
|
|
2040
|
+
if (next) {
|
|
2041
|
+
wrapper.style.visibility = "";
|
|
2042
|
+
if (animate) {
|
|
2043
|
+
inFlight = runAnchorTransition(opts.element, opts.animation, "enter");
|
|
2044
|
+
}
|
|
2045
|
+
return;
|
|
2046
|
+
}
|
|
2047
|
+
if (!animate) {
|
|
2048
|
+
wrapper.style.visibility = "hidden";
|
|
2049
|
+
return;
|
|
2050
|
+
}
|
|
2051
|
+
const handle = runAnchorTransition(opts.element, opts.animation, "exit");
|
|
2052
|
+
inFlight = handle;
|
|
2053
|
+
void handle.finished.then(() => {
|
|
2054
|
+
if (inFlight === handle && visible === false) {
|
|
2055
|
+
wrapper.style.visibility = "hidden";
|
|
2056
|
+
}
|
|
2057
|
+
});
|
|
2058
|
+
};
|
|
2059
|
+
const evaluate = (animate) => {
|
|
2060
|
+
if (deps.isDestroyed()) return;
|
|
2061
|
+
applyVisibility(shouldShow(deps.getState()), animate);
|
|
2062
|
+
};
|
|
2063
|
+
const offs = [
|
|
2064
|
+
deps.on("snap", () => evaluate(true)),
|
|
2065
|
+
deps.on("open", () => evaluate(true)),
|
|
2066
|
+
deps.on("close", () => evaluate(true))
|
|
2067
|
+
];
|
|
2068
|
+
evaluate(false);
|
|
2069
|
+
return {
|
|
2070
|
+
wrapper,
|
|
2071
|
+
detach: () => {
|
|
2072
|
+
offs.forEach((off) => off());
|
|
2073
|
+
inFlight?.cancel();
|
|
2074
|
+
inFlight = null;
|
|
2075
|
+
if (wrapper.parentNode) wrapper.parentNode.removeChild(wrapper);
|
|
2076
|
+
},
|
|
2077
|
+
syncZ: (z) => {
|
|
2078
|
+
wrapper.style.zIndex = String(z);
|
|
2079
|
+
}
|
|
2080
|
+
};
|
|
2081
|
+
}
|
|
2082
|
+
|
|
2083
|
+
// src/core/features/scrim-stages.ts
|
|
2084
|
+
var matchesId = (def, activeId) => {
|
|
2085
|
+
if (def.for === void 0) return false;
|
|
2086
|
+
return Array.isArray(def.for) ? def.for.includes(activeId) : def.for === activeId;
|
|
2087
|
+
};
|
|
2088
|
+
var matchesRange = (def, progress) => {
|
|
2089
|
+
if (!def.forRange) return false;
|
|
2090
|
+
const [from, to] = def.forRange;
|
|
2091
|
+
return progress >= from && progress <= to;
|
|
2092
|
+
};
|
|
2093
|
+
function installScrimStages(deps, opts) {
|
|
2094
|
+
const doc = deps.host.ownerDocument;
|
|
2095
|
+
const entries = opts.stages.map((def) => {
|
|
2096
|
+
const wrapper = doc.createElement("div");
|
|
2097
|
+
wrapper.className = "bs-scrim-stage";
|
|
2098
|
+
const ws = wrapper.style;
|
|
2099
|
+
ws.position = "absolute";
|
|
2100
|
+
applyOverlayPosition(
|
|
2101
|
+
ws,
|
|
2102
|
+
deps.mode,
|
|
2103
|
+
def.position ?? opts.position ?? "center",
|
|
2104
|
+
def.inset ?? opts.inset ?? "16px"
|
|
2105
|
+
);
|
|
2106
|
+
ws.visibility = "hidden";
|
|
2107
|
+
ws.pointerEvents = "none";
|
|
2108
|
+
wrapper.appendChild(def.element);
|
|
2109
|
+
deps.host.appendChild(wrapper);
|
|
2110
|
+
return { def, wrapper, inFlight: null };
|
|
2111
|
+
});
|
|
2112
|
+
let active = null;
|
|
2113
|
+
const resolveActive = () => {
|
|
2114
|
+
const state2 = deps.getState();
|
|
2115
|
+
if (state2.size === 0) {
|
|
2116
|
+
return entries.find((e) => matchesId(e.def, state2.activeId)) ?? null;
|
|
2117
|
+
}
|
|
2118
|
+
return entries.find((e) => matchesId(e.def, state2.activeId)) ?? entries.find((e) => matchesRange(e.def, state2.progress)) ?? null;
|
|
2119
|
+
};
|
|
2120
|
+
const hide = (entry, animate) => {
|
|
2121
|
+
entry.inFlight?.cancel();
|
|
2122
|
+
entry.wrapper.style.pointerEvents = "none";
|
|
2123
|
+
if (!animate) {
|
|
2124
|
+
entry.inFlight = null;
|
|
2125
|
+
entry.wrapper.style.visibility = "hidden";
|
|
2126
|
+
return;
|
|
2127
|
+
}
|
|
2128
|
+
const handle = runAnchorTransition(
|
|
2129
|
+
entry.def.element,
|
|
2130
|
+
entry.def.animation ?? opts.animation,
|
|
2131
|
+
"exit"
|
|
2132
|
+
);
|
|
2133
|
+
entry.inFlight = handle;
|
|
2134
|
+
void handle.finished.then(() => {
|
|
2135
|
+
if (entry.inFlight === handle && active !== entry) {
|
|
2136
|
+
entry.wrapper.style.visibility = "hidden";
|
|
2137
|
+
}
|
|
2138
|
+
});
|
|
2139
|
+
};
|
|
2140
|
+
const show = (entry, animate) => {
|
|
2141
|
+
entry.inFlight?.cancel();
|
|
2142
|
+
entry.inFlight = null;
|
|
2143
|
+
entry.wrapper.style.visibility = "";
|
|
2144
|
+
entry.wrapper.style.pointerEvents = entry.def.interactive ?? opts.interactive ?? false ? "auto" : "none";
|
|
2145
|
+
if (animate) {
|
|
2146
|
+
entry.inFlight = runAnchorTransition(
|
|
2147
|
+
entry.def.element,
|
|
2148
|
+
entry.def.animation ?? opts.animation,
|
|
2149
|
+
"enter"
|
|
2150
|
+
);
|
|
2151
|
+
}
|
|
2152
|
+
};
|
|
2153
|
+
const update = (animate) => {
|
|
2154
|
+
if (deps.isDestroyed()) return;
|
|
2155
|
+
const next = resolveActive();
|
|
2156
|
+
if (next === active) return;
|
|
2157
|
+
const prev = active;
|
|
2158
|
+
active = next;
|
|
2159
|
+
if (prev) hide(prev, animate);
|
|
2160
|
+
if (next) show(next, animate);
|
|
2161
|
+
};
|
|
2162
|
+
const offs = [
|
|
2163
|
+
deps.on("snap", () => update(true)),
|
|
2164
|
+
deps.on("open", () => update(true)),
|
|
2165
|
+
deps.on("close", () => update(true))
|
|
2166
|
+
];
|
|
2167
|
+
if (entries.some((e) => e.def.forRange)) {
|
|
2168
|
+
offs.push(deps.on("progress", () => update(true)));
|
|
2169
|
+
}
|
|
2170
|
+
update(false);
|
|
2171
|
+
return () => {
|
|
2172
|
+
offs.forEach((off) => off());
|
|
2173
|
+
for (const entry of entries) {
|
|
2174
|
+
entry.inFlight?.cancel();
|
|
2175
|
+
entry.inFlight = null;
|
|
2176
|
+
if (entry.wrapper.parentNode) {
|
|
2177
|
+
entry.wrapper.parentNode.removeChild(entry.wrapper);
|
|
2178
|
+
}
|
|
2179
|
+
}
|
|
2180
|
+
active = null;
|
|
2181
|
+
};
|
|
2182
|
+
}
|
|
2183
|
+
|
|
1826
2184
|
// src/core/primitives/engine-options.ts
|
|
1827
2185
|
var DEFAULT_FLICK_VELOCITY = 0.65;
|
|
1828
2186
|
var DEFAULT_DRAG_THRESHOLD = 18;
|
|
@@ -1939,6 +2297,12 @@ var BottomSheetEngine = class {
|
|
|
1939
2297
|
__publicField(this, "linkedSheets", []);
|
|
1940
2298
|
__publicField(this, "scrollCache");
|
|
1941
2299
|
__publicField(this, "teardowns", new TeardownStack());
|
|
2300
|
+
__publicField(this, "anchors", []);
|
|
2301
|
+
__publicField(this, "anchorHost", null);
|
|
2302
|
+
__publicField(this, "stackZ", 100);
|
|
2303
|
+
__publicField(this, "detachScrimStages", null);
|
|
2304
|
+
__publicField(this, "stackEffectEnabled", false);
|
|
2305
|
+
__publicField(this, "stackEffectPrimed", false);
|
|
1942
2306
|
__publicField(this, "transformTemplate");
|
|
1943
2307
|
const resolved = resolveEngineOptions(opts, {
|
|
1944
2308
|
shouldApplyInertSiblings: () => {
|
|
@@ -1972,6 +2336,9 @@ var BottomSheetEngine = class {
|
|
|
1972
2336
|
getResolvedSnaps: () => this.snaps.getResolvedSnaps().slice(),
|
|
1973
2337
|
snapTo: (id) => {
|
|
1974
2338
|
void this.snapTo(id);
|
|
2339
|
+
},
|
|
2340
|
+
close: () => {
|
|
2341
|
+
void this.close();
|
|
1975
2342
|
}
|
|
1976
2343
|
},
|
|
1977
2344
|
resolved.scrim
|
|
@@ -1995,6 +2362,7 @@ var BottomSheetEngine = class {
|
|
|
1995
2362
|
);
|
|
1996
2363
|
this.closeOnBack = resolved.closeOnBack;
|
|
1997
2364
|
this.routedTo = opts.routedTo;
|
|
2365
|
+
this.stackEffectEnabled = opts.stackEffect ?? false;
|
|
1998
2366
|
this.snapPointsRaw = opts.snapPoints;
|
|
1999
2367
|
this.persistKey = opts.persistKey;
|
|
2000
2368
|
if (opts.linkedSheets) {
|
|
@@ -2007,7 +2375,7 @@ var BottomSheetEngine = class {
|
|
|
2007
2375
|
this.snapPointsRaw,
|
|
2008
2376
|
resolved.initialAllowed,
|
|
2009
2377
|
this.mode,
|
|
2010
|
-
() => this.handle.offsetHeight,
|
|
2378
|
+
() => layoutAxis(this.mode) === "width" ? this.handle.offsetWidth : this.handle.offsetHeight,
|
|
2011
2379
|
(maxAxisSize) => {
|
|
2012
2380
|
this.element.style[layoutAxis(this.mode)] = `${maxAxisSize}px`;
|
|
2013
2381
|
}
|
|
@@ -2217,11 +2585,6 @@ var BottomSheetEngine = class {
|
|
|
2217
2585
|
}
|
|
2218
2586
|
setAllowed(ids, snap) {
|
|
2219
2587
|
if (this.destroyed) return;
|
|
2220
|
-
const willSnap = snap !== void 0 && ids.includes(snap) || !ids.includes(this.activeId) && ids.length > 0;
|
|
2221
|
-
if (!willSnap) {
|
|
2222
|
-
this.animation.cancel();
|
|
2223
|
-
this.newCycle();
|
|
2224
|
-
}
|
|
2225
2588
|
this.snaps.setAllowedIds(ids);
|
|
2226
2589
|
this.updateAriaSlider();
|
|
2227
2590
|
if (snap && ids.includes(snap)) {
|
|
@@ -2261,6 +2624,79 @@ var BottomSheetEngine = class {
|
|
|
2261
2624
|
setScrimOverlay(opts) {
|
|
2262
2625
|
return this.scrim.setScrimOverlay(opts);
|
|
2263
2626
|
}
|
|
2627
|
+
addAnchor(opts) {
|
|
2628
|
+
if (this.destroyed || typeof document === "undefined") return () => {
|
|
2629
|
+
};
|
|
2630
|
+
if (!this.anchorHost) {
|
|
2631
|
+
this.anchorHost = this.rootEl ?? this.element.parentElement ?? document.body;
|
|
2632
|
+
this.anchorHost.style.setProperty("--bs-size", `${this.size}px`);
|
|
2633
|
+
this.anchorHost.style.setProperty(
|
|
2634
|
+
"--bs-progress",
|
|
2635
|
+
String(this.computeProgress(this.size))
|
|
2636
|
+
);
|
|
2637
|
+
}
|
|
2638
|
+
const handle = attachAnchor(
|
|
2639
|
+
{
|
|
2640
|
+
mode: this.mode,
|
|
2641
|
+
host: this.anchorHost,
|
|
2642
|
+
getState: () => ({
|
|
2643
|
+
activeId: this.activeId,
|
|
2644
|
+
size: this.size,
|
|
2645
|
+
progress: this.computeProgress(this.size)
|
|
2646
|
+
}),
|
|
2647
|
+
on: (event, fn) => this.on(event, fn),
|
|
2648
|
+
isDestroyed: () => this.destroyed
|
|
2649
|
+
},
|
|
2650
|
+
opts
|
|
2651
|
+
);
|
|
2652
|
+
handle.syncZ(this.stackZ + 1);
|
|
2653
|
+
this.anchors.push(handle);
|
|
2654
|
+
const detach = () => {
|
|
2655
|
+
const idx = this.anchors.indexOf(handle);
|
|
2656
|
+
if (idx === -1) return;
|
|
2657
|
+
this.anchors.splice(idx, 1);
|
|
2658
|
+
handle.detach();
|
|
2659
|
+
};
|
|
2660
|
+
this.teardowns.add(detach);
|
|
2661
|
+
return detach;
|
|
2662
|
+
}
|
|
2663
|
+
setScrimStages(opts) {
|
|
2664
|
+
if (this.destroyed || typeof document === "undefined") return () => {
|
|
2665
|
+
};
|
|
2666
|
+
this.detachScrimStages?.();
|
|
2667
|
+
this.detachScrimStages = null;
|
|
2668
|
+
if (!opts) return () => {
|
|
2669
|
+
};
|
|
2670
|
+
const host = this.screenComponent?.parentElement;
|
|
2671
|
+
if (!host) {
|
|
2672
|
+
console.warn(
|
|
2673
|
+
"[BottomSheet] setScrimStages: no scrim element mounted \u2014 pass `scrim` to the engine first."
|
|
2674
|
+
);
|
|
2675
|
+
return () => {
|
|
2676
|
+
};
|
|
2677
|
+
}
|
|
2678
|
+
const detachInstalled = installScrimStages(
|
|
2679
|
+
{
|
|
2680
|
+
mode: this.mode,
|
|
2681
|
+
host,
|
|
2682
|
+
getState: () => ({
|
|
2683
|
+
activeId: this.activeId,
|
|
2684
|
+
size: this.size,
|
|
2685
|
+
progress: this.computeProgress(this.size)
|
|
2686
|
+
}),
|
|
2687
|
+
on: (event, fn) => this.on(event, fn),
|
|
2688
|
+
isDestroyed: () => this.destroyed
|
|
2689
|
+
},
|
|
2690
|
+
opts
|
|
2691
|
+
);
|
|
2692
|
+
const detach = () => {
|
|
2693
|
+
if (this.detachScrimStages === detach) this.detachScrimStages = null;
|
|
2694
|
+
detachInstalled();
|
|
2695
|
+
};
|
|
2696
|
+
this.detachScrimStages = detach;
|
|
2697
|
+
this.teardowns.add(() => this.detachScrimStages?.());
|
|
2698
|
+
return detach;
|
|
2699
|
+
}
|
|
2264
2700
|
getScrimState() {
|
|
2265
2701
|
return { mode: this.scrim.scrimMode, enabled: this.scrim.scrimEnabled };
|
|
2266
2702
|
}
|
|
@@ -2347,24 +2783,45 @@ var BottomSheetEngine = class {
|
|
|
2347
2783
|
getAllowedRange() {
|
|
2348
2784
|
return this.snaps.getAllowedRange();
|
|
2349
2785
|
}
|
|
2786
|
+
allowedIdsBySize() {
|
|
2787
|
+
return this.snaps.getAllowedIds().slice().sort(
|
|
2788
|
+
(a, b) => (this.snaps.findById(a)?.size ?? 0) - (this.snaps.findById(b)?.size ?? 0)
|
|
2789
|
+
);
|
|
2790
|
+
}
|
|
2350
2791
|
updateAriaSlider() {
|
|
2351
|
-
this.aria.setValue(this.
|
|
2792
|
+
this.aria.setValue(this.allowedIdsBySize(), this.activeId);
|
|
2352
2793
|
}
|
|
2353
2794
|
registerInStack() {
|
|
2354
2795
|
this.teardowns.add(sheetStack.push({
|
|
2355
2796
|
id: this.id,
|
|
2356
2797
|
setZIndex: (z) => {
|
|
2798
|
+
this.stackZ = z;
|
|
2357
2799
|
this.element.style.zIndex = String(z);
|
|
2358
2800
|
if (this.backdrop) this.backdrop.style.zIndex = String(z - 1);
|
|
2801
|
+
for (const anchor of this.anchors) anchor.syncZ(z + 1);
|
|
2359
2802
|
},
|
|
2360
2803
|
setIsTop: (isTop) => {
|
|
2361
2804
|
this.isTopSheet = isTop;
|
|
2362
2805
|
if (this.backdrop) {
|
|
2363
2806
|
this.backdrop.style.display = isTop ? "" : "none";
|
|
2364
2807
|
}
|
|
2365
|
-
}
|
|
2808
|
+
},
|
|
2809
|
+
isOpen: () => this.size > 0,
|
|
2810
|
+
setDepth: (depth) => this.applyStackDepth(depth)
|
|
2366
2811
|
}));
|
|
2367
2812
|
}
|
|
2813
|
+
applyStackDepth(depth) {
|
|
2814
|
+
if (!this.stackEffectEnabled) return;
|
|
2815
|
+
this.element.setAttribute("data-stack-depth", String(depth));
|
|
2816
|
+
if (!this.stackEffectPrimed) {
|
|
2817
|
+
this.stackEffectPrimed = true;
|
|
2818
|
+
const isVertical = this.mode === "bottom" || this.mode === "top";
|
|
2819
|
+
this.element.style.transformOrigin = isVertical ? "50% 100%" : "0% 50%";
|
|
2820
|
+
this.element.style.transition = "scale 320ms cubic-bezier(0.29, 1.04, 0.84, 0.99)";
|
|
2821
|
+
}
|
|
2822
|
+
const scale = Math.max(1 - depth * 0.04, 0.86);
|
|
2823
|
+
this.element.style.scale = scale === 1 ? "" : String(scale);
|
|
2824
|
+
}
|
|
2368
2825
|
attach() {
|
|
2369
2826
|
this.gesture = new GestureController({
|
|
2370
2827
|
handle: this.handle,
|
|
@@ -2424,7 +2881,7 @@ var BottomSheetEngine = class {
|
|
|
2424
2881
|
container: this.scrollContainer,
|
|
2425
2882
|
isDragging: () => this.gesture?.isDragging ?? false,
|
|
2426
2883
|
isAnimating: () => this.animation.isAnimating,
|
|
2427
|
-
getAllowedIds: () => this.
|
|
2884
|
+
getAllowedIds: () => this.allowedIdsBySize(),
|
|
2428
2885
|
getActiveId: () => this.activeId,
|
|
2429
2886
|
snapTo: (id) => {
|
|
2430
2887
|
void this.snapTo(id);
|
|
@@ -2453,11 +2910,13 @@ var BottomSheetEngine = class {
|
|
|
2453
2910
|
},
|
|
2454
2911
|
newCycle: () => {
|
|
2455
2912
|
this.newCycle();
|
|
2456
|
-
}
|
|
2913
|
+
},
|
|
2914
|
+
isAnimating: () => this.animation.isAnimating,
|
|
2915
|
+
resyncAfterCancel: () => this.resyncAfterResize()
|
|
2457
2916
|
}));
|
|
2458
2917
|
if (this.lifecycle.closeOnEscape) {
|
|
2459
2918
|
const onKey = (e) => {
|
|
2460
|
-
if (this.destroyed) return;
|
|
2919
|
+
if (this.destroyed || e.defaultPrevented) return;
|
|
2461
2920
|
if (e.key === "Escape" && this.isTopSheet && this.size > 0) {
|
|
2462
2921
|
void this.close();
|
|
2463
2922
|
}
|
|
@@ -2489,7 +2948,7 @@ var BottomSheetEngine = class {
|
|
|
2489
2948
|
handle: this.handle,
|
|
2490
2949
|
mode: this.mode,
|
|
2491
2950
|
isDestroyed: () => this.destroyed,
|
|
2492
|
-
getAllowedIds: () => this.
|
|
2951
|
+
getAllowedIds: () => this.allowedIdsBySize(),
|
|
2493
2952
|
getActiveId: () => this.activeId,
|
|
2494
2953
|
snapTo: (id) => {
|
|
2495
2954
|
void this.snapTo(id);
|
|
@@ -2510,6 +2969,7 @@ var BottomSheetEngine = class {
|
|
|
2510
2969
|
});
|
|
2511
2970
|
if (!target) return;
|
|
2512
2971
|
const previousId = this.activeId;
|
|
2972
|
+
if (target.id === previousId && target.size === this.size) return;
|
|
2513
2973
|
if (this.emitBeforeSnap(target, previousId)) {
|
|
2514
2974
|
const restore = this.snaps.findById(previousId);
|
|
2515
2975
|
if (restore) {
|
|
@@ -2518,6 +2978,7 @@ var BottomSheetEngine = class {
|
|
|
2518
2978
|
return;
|
|
2519
2979
|
}
|
|
2520
2980
|
const previousSize = this.size;
|
|
2981
|
+
const previousSnapSize = this.snaps.findById(previousId)?.size;
|
|
2521
2982
|
this.scrollCache.cache(previousId, previousSize, target.size);
|
|
2522
2983
|
this.activeId = target.id;
|
|
2523
2984
|
void this.animation.animateTo(target.size, velocity).then(() => {
|
|
@@ -2526,9 +2987,10 @@ var BottomSheetEngine = class {
|
|
|
2526
2987
|
this.updateAriaSlider();
|
|
2527
2988
|
this.emit("snap", { id: target.id, size: target.size });
|
|
2528
2989
|
this.haptic();
|
|
2529
|
-
if (
|
|
2990
|
+
if (previousSnapSize === 0 && target.size > 0) {
|
|
2530
2991
|
this.emit("open", { id: target.id });
|
|
2531
2992
|
this.handleOpen();
|
|
2993
|
+
notifyLinkedSheets(this.linkedSheets, this);
|
|
2532
2994
|
}
|
|
2533
2995
|
if (target.size === 0) {
|
|
2534
2996
|
this.emit("close", void 0);
|
|
@@ -2554,6 +3016,9 @@ var BottomSheetEngine = class {
|
|
|
2554
3016
|
if (this.scrimParent) {
|
|
2555
3017
|
this.scrimParent.style.setProperty("--bs-size", `${size}px`);
|
|
2556
3018
|
}
|
|
3019
|
+
if (this.anchorHost && this.anchorHost !== this.scrimParent) {
|
|
3020
|
+
this.anchorHost.style.setProperty("--bs-size", `${size}px`);
|
|
3021
|
+
}
|
|
2557
3022
|
}
|
|
2558
3023
|
const progress = this.computeProgress(size);
|
|
2559
3024
|
const progressChanged = this.progressWriteSentinel.shouldWrite(
|
|
@@ -2562,6 +3027,9 @@ var BottomSheetEngine = class {
|
|
|
2562
3027
|
);
|
|
2563
3028
|
if (progressChanged) {
|
|
2564
3029
|
style.setProperty("--bs-progress", String(progress));
|
|
3030
|
+
if (this.anchorHost) {
|
|
3031
|
+
this.anchorHost.style.setProperty("--bs-progress", String(progress));
|
|
3032
|
+
}
|
|
2565
3033
|
}
|
|
2566
3034
|
this.scrim.applyOpacity(progress, progressChanged);
|
|
2567
3035
|
if (progressChanged && this.bus.listenerCount("progress") > 0) {
|
|
@@ -2576,6 +3044,7 @@ var BottomSheetEngine = class {
|
|
|
2576
3044
|
return Math.min(Math.max((size - min) / (max - min), 0), 1);
|
|
2577
3045
|
}
|
|
2578
3046
|
handleOpen() {
|
|
3047
|
+
sheetStack.promote(this.id);
|
|
2579
3048
|
try {
|
|
2580
3049
|
this.lifecycle.install();
|
|
2581
3050
|
} catch (err) {
|
|
@@ -2589,8 +3058,24 @@ var BottomSheetEngine = class {
|
|
|
2589
3058
|
});
|
|
2590
3059
|
}
|
|
2591
3060
|
}
|
|
3061
|
+
resyncAfterResize() {
|
|
3062
|
+
if (this.destroyed) return;
|
|
3063
|
+
const target = this.snaps.findById(this.activeId);
|
|
3064
|
+
if (!target) return;
|
|
3065
|
+
this.updateAriaSlider();
|
|
3066
|
+
this.emit("snap", { id: target.id, size: target.size });
|
|
3067
|
+
if (target.size > 0 && !this.lifecycle.isInstalled) {
|
|
3068
|
+
this.emit("open", { id: target.id });
|
|
3069
|
+
this.handleOpen();
|
|
3070
|
+
notifyLinkedSheets(this.linkedSheets, this);
|
|
3071
|
+
} else if (target.size === 0 && this.lifecycle.isInstalled) {
|
|
3072
|
+
this.emit("close", void 0);
|
|
3073
|
+
this.handleClose();
|
|
3074
|
+
}
|
|
3075
|
+
}
|
|
2592
3076
|
handleClose() {
|
|
2593
3077
|
this.lifecycle.release();
|
|
3078
|
+
sheetStack.update();
|
|
2594
3079
|
}
|
|
2595
3080
|
};
|
|
2596
3081
|
|
|
@@ -2608,17 +3093,18 @@ function createBottomSheet(opts) {
|
|
|
2608
3093
|
const attach = (refs) => {
|
|
2609
3094
|
if (engine) engine.destroy();
|
|
2610
3095
|
const { onSnap, ...engineOpts } = opts;
|
|
2611
|
-
|
|
3096
|
+
const created = new BottomSheetEngine({ ...engineOpts, ...refs });
|
|
3097
|
+
engine = created;
|
|
2612
3098
|
if (onSnap) {
|
|
2613
|
-
|
|
3099
|
+
created.on("snap", (payload) => onSnap(payload.id));
|
|
2614
3100
|
}
|
|
2615
3101
|
for (const entry of pending) {
|
|
2616
|
-
entry.engineUnsub =
|
|
3102
|
+
entry.engineUnsub = created.on(entry.event, entry.fn);
|
|
2617
3103
|
}
|
|
2618
3104
|
pending.length = 0;
|
|
2619
3105
|
return () => {
|
|
2620
|
-
|
|
2621
|
-
engine = null;
|
|
3106
|
+
created.destroy();
|
|
3107
|
+
if (engine === created) engine = null;
|
|
2622
3108
|
};
|
|
2623
3109
|
};
|
|
2624
3110
|
return {
|
|
@@ -2642,6 +3128,14 @@ function createBottomSheet(opts) {
|
|
|
2642
3128
|
open: (id) => engine?.open(id) ?? Promise.resolve(),
|
|
2643
3129
|
close: () => engine?.close() ?? Promise.resolve(),
|
|
2644
3130
|
setAllowed: (ids, snap) => engine?.setAllowed(ids, snap),
|
|
3131
|
+
setSnapPoints: (points, allowed) => engine?.setSnapPoints(points, allowed),
|
|
3132
|
+
setScrim: (scrimOpts) => engine?.setScrim(scrimOpts),
|
|
3133
|
+
setScrimOverlay: (overlayOpts) => engine?.setScrimOverlay(overlayOpts) ?? (() => {
|
|
3134
|
+
}),
|
|
3135
|
+
addAnchor: (anchorOpts) => engine?.addAnchor(anchorOpts) ?? (() => {
|
|
3136
|
+
}),
|
|
3137
|
+
setScrimStages: (stagesOpts) => engine?.setScrimStages(stagesOpts) ?? (() => {
|
|
3138
|
+
}),
|
|
2645
3139
|
destroy: () => {
|
|
2646
3140
|
engine?.destroy();
|
|
2647
3141
|
engine = null;
|
|
@@ -2663,7 +3157,7 @@ function BottomSheet($$anchor, $$props) {
|
|
|
2663
3157
|
let screenEl = $2.state(void 0);
|
|
2664
3158
|
let viewState = $2.state($2.proxy({
|
|
2665
3159
|
size: 0,
|
|
2666
|
-
activeId: $$props.initial ?? $$props.snapPoints[0]?.id ?? "default",
|
|
3160
|
+
activeId: untrack(() => $$props.initial ?? $$props.snapPoints[0]?.id ?? "default"),
|
|
2667
3161
|
isDragging: false,
|
|
2668
3162
|
isAnimating: false,
|
|
2669
3163
|
progress: 0
|