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