@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/react.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { forwardRef, useRef, useState, useEffect, useImperativeHandle, useMemo, useCallback, useSyncExternalStore, useLayoutEffect } from 'react';
|
|
2
|
+
import { createPortal } from 'react-dom';
|
|
2
3
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
4
|
|
|
4
5
|
var __defProp = Object.defineProperty;
|
|
@@ -23,6 +24,18 @@ var SheetStack = class {
|
|
|
23
24
|
this.entries.splice(idx, 1);
|
|
24
25
|
this.recompute();
|
|
25
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
|
+
}
|
|
26
39
|
size() {
|
|
27
40
|
return this.entries.length;
|
|
28
41
|
}
|
|
@@ -30,9 +43,24 @@ var SheetStack = class {
|
|
|
30
43
|
this.entries = [];
|
|
31
44
|
}
|
|
32
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
|
+
}
|
|
33
57
|
this.entries.forEach((entry, i) => {
|
|
34
58
|
entry.setZIndex(BASE_Z + i * STEP);
|
|
35
|
-
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
|
+
}
|
|
36
64
|
});
|
|
37
65
|
}
|
|
38
66
|
};
|
|
@@ -323,14 +351,17 @@ function installAutoCollapse(deps) {
|
|
|
323
351
|
const fire = () => {
|
|
324
352
|
if (deps.isDestroyed()) return;
|
|
325
353
|
if (deps.isDragging()) return;
|
|
326
|
-
const
|
|
327
|
-
|
|
354
|
+
const active = deps.resolveSnap(deps.getActiveId());
|
|
355
|
+
if (!active || active.size === 0) return;
|
|
356
|
+
let target = null;
|
|
357
|
+
for (const id of deps.getAllowedIds()) {
|
|
328
358
|
const snap = deps.resolveSnap(id);
|
|
329
|
-
|
|
330
|
-
|
|
359
|
+
if (!snap || snap.size <= 0) continue;
|
|
360
|
+
if (!target || snap.size < target.size) target = snap;
|
|
361
|
+
}
|
|
331
362
|
if (!target) return;
|
|
332
|
-
if (target ===
|
|
333
|
-
deps.snapTo(target);
|
|
363
|
+
if (target.id === active.id || target.size >= active.size) return;
|
|
364
|
+
deps.snapTo(target.id);
|
|
334
365
|
};
|
|
335
366
|
const reset = () => {
|
|
336
367
|
clearTimer();
|
|
@@ -341,6 +372,7 @@ function installAutoCollapse(deps) {
|
|
|
341
372
|
}, ms);
|
|
342
373
|
};
|
|
343
374
|
const unsubscribe = deps.on("snap", () => reset());
|
|
375
|
+
if ((deps.resolveSnap(deps.getActiveId())?.size ?? 0) > 0) reset();
|
|
344
376
|
return () => {
|
|
345
377
|
clearTimer();
|
|
346
378
|
unsubscribe();
|
|
@@ -353,6 +385,7 @@ function notifyLinkedSheets(sheets, self) {
|
|
|
353
385
|
for (const linked of sheets) {
|
|
354
386
|
if (linked === self) continue;
|
|
355
387
|
try {
|
|
388
|
+
if (linked.state.size === 0) continue;
|
|
356
389
|
const ids = linked.getAllowedIds();
|
|
357
390
|
const target = ids.find((id) => id !== "closed");
|
|
358
391
|
if (target && target !== linked.state.activeId) {
|
|
@@ -399,7 +432,7 @@ function installRoute(deps) {
|
|
|
399
432
|
const onPop = (event) => {
|
|
400
433
|
if (deps.isDestroyed()) return;
|
|
401
434
|
const state = event.state;
|
|
402
|
-
if (state
|
|
435
|
+
if ((!state || state.__bsRouted !== target) && deps.getSize() > 0) {
|
|
403
436
|
routePushed = false;
|
|
404
437
|
void deps.close();
|
|
405
438
|
}
|
|
@@ -553,13 +586,17 @@ function installResizeObserver(deps) {
|
|
|
553
586
|
if (viewportSize2 > 0 && viewportSize2 < max) {
|
|
554
587
|
deps.setMaxAxisSize(viewportSize2);
|
|
555
588
|
}
|
|
589
|
+
const wasAnimating = deps.isAnimating?.() ?? false;
|
|
556
590
|
deps.cancelInFlight();
|
|
557
591
|
deps.newCycle();
|
|
558
592
|
const current = deps.resolveActiveSnap();
|
|
559
593
|
const newMax = deps.getMaxAxisSize();
|
|
560
594
|
const targetSize = current ? Math.min(current.size, newMax) : Math.min(deps.getSize(), newMax);
|
|
561
595
|
deps.setSize(targetSize);
|
|
562
|
-
if (current && !deps.isDragging())
|
|
596
|
+
if (current && !deps.isDragging()) {
|
|
597
|
+
deps.applySize(targetSize);
|
|
598
|
+
if (wasAnimating) deps.resyncAfterCancel?.();
|
|
599
|
+
}
|
|
563
600
|
};
|
|
564
601
|
let resizeObserver = null;
|
|
565
602
|
if (typeof ResizeObserver !== "undefined") {
|
|
@@ -674,6 +711,85 @@ function devWarn(...args) {
|
|
|
674
711
|
}
|
|
675
712
|
}
|
|
676
713
|
|
|
714
|
+
// src/core/primitives/overlay-position.ts
|
|
715
|
+
function resolveSheetAnchoredStyle(mode, position, inset) {
|
|
716
|
+
const sizeOffset = `calc(var(--bs-size, 0px) + ${inset})`;
|
|
717
|
+
switch (mode) {
|
|
718
|
+
case "bottom":
|
|
719
|
+
if (position === "sheet-top-left") return { bottom: sizeOffset, left: inset };
|
|
720
|
+
if (position === "sheet-top-right") return { bottom: sizeOffset, right: inset };
|
|
721
|
+
return { bottom: sizeOffset, left: "50%", transform: "translateX(-50%)" };
|
|
722
|
+
case "top":
|
|
723
|
+
if (position === "sheet-top-left") return { top: sizeOffset, left: inset };
|
|
724
|
+
if (position === "sheet-top-right") return { top: sizeOffset, right: inset };
|
|
725
|
+
return { top: sizeOffset, left: "50%", transform: "translateX(-50%)" };
|
|
726
|
+
case "left":
|
|
727
|
+
if (position === "sheet-top-left") return { left: sizeOffset, top: inset };
|
|
728
|
+
if (position === "sheet-top-right") return { left: sizeOffset, bottom: inset };
|
|
729
|
+
return { left: sizeOffset, top: "50%", transform: "translateY(-50%)" };
|
|
730
|
+
case "right":
|
|
731
|
+
if (position === "sheet-top-left") return { right: sizeOffset, top: inset };
|
|
732
|
+
if (position === "sheet-top-right") return { right: sizeOffset, bottom: inset };
|
|
733
|
+
return { right: sizeOffset, top: "50%", transform: "translateY(-50%)" };
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
function applyOverlayPosition(ws, mode, position, inset) {
|
|
737
|
+
switch (position) {
|
|
738
|
+
case "top-left":
|
|
739
|
+
ws.top = inset;
|
|
740
|
+
ws.left = inset;
|
|
741
|
+
break;
|
|
742
|
+
case "top-center":
|
|
743
|
+
ws.top = inset;
|
|
744
|
+
ws.left = "50%";
|
|
745
|
+
ws.transform = "translateX(-50%)";
|
|
746
|
+
break;
|
|
747
|
+
case "top-right":
|
|
748
|
+
ws.top = inset;
|
|
749
|
+
ws.right = inset;
|
|
750
|
+
break;
|
|
751
|
+
case "center-left":
|
|
752
|
+
ws.top = "50%";
|
|
753
|
+
ws.left = inset;
|
|
754
|
+
ws.transform = "translateY(-50%)";
|
|
755
|
+
break;
|
|
756
|
+
case "center":
|
|
757
|
+
ws.top = "50%";
|
|
758
|
+
ws.left = "50%";
|
|
759
|
+
ws.transform = "translate(-50%, -50%)";
|
|
760
|
+
break;
|
|
761
|
+
case "center-right":
|
|
762
|
+
ws.top = "50%";
|
|
763
|
+
ws.right = inset;
|
|
764
|
+
ws.transform = "translateY(-50%)";
|
|
765
|
+
break;
|
|
766
|
+
case "bottom-left":
|
|
767
|
+
ws.bottom = inset;
|
|
768
|
+
ws.left = inset;
|
|
769
|
+
break;
|
|
770
|
+
case "bottom-center":
|
|
771
|
+
ws.bottom = inset;
|
|
772
|
+
ws.left = "50%";
|
|
773
|
+
ws.transform = "translateX(-50%)";
|
|
774
|
+
break;
|
|
775
|
+
case "bottom-right":
|
|
776
|
+
ws.bottom = inset;
|
|
777
|
+
ws.right = inset;
|
|
778
|
+
break;
|
|
779
|
+
case "sheet-top-left":
|
|
780
|
+
case "sheet-top-center":
|
|
781
|
+
case "sheet-top-right": {
|
|
782
|
+
const style = resolveSheetAnchoredStyle(mode, position, inset);
|
|
783
|
+
if (style.top !== void 0) ws.top = style.top;
|
|
784
|
+
if (style.bottom !== void 0) ws.bottom = style.bottom;
|
|
785
|
+
if (style.left !== void 0) ws.left = style.left;
|
|
786
|
+
if (style.right !== void 0) ws.right = style.right;
|
|
787
|
+
if (style.transform !== void 0) ws.transform = style.transform;
|
|
788
|
+
break;
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
|
|
677
793
|
// src/core/controllers/scrim-controller.ts
|
|
678
794
|
var VALID_CSS_LENGTH = /^-?\d+(?:\.\d+)?(?:px|em|rem|%)$/;
|
|
679
795
|
var ScrimController = class {
|
|
@@ -686,6 +802,8 @@ var ScrimController = class {
|
|
|
686
802
|
__publicField(this, "getAllowedIds");
|
|
687
803
|
__publicField(this, "getResolvedSnaps");
|
|
688
804
|
__publicField(this, "snapToFn");
|
|
805
|
+
__publicField(this, "closeFn");
|
|
806
|
+
__publicField(this, "scrimInteractive", false);
|
|
689
807
|
__publicField(this, "scrimMode");
|
|
690
808
|
__publicField(this, "backdropRange");
|
|
691
809
|
__publicField(this, "screenRange");
|
|
@@ -706,6 +824,7 @@ var ScrimController = class {
|
|
|
706
824
|
this.getAllowedIds = deps.getAllowedIds;
|
|
707
825
|
this.getResolvedSnaps = deps.getResolvedSnaps;
|
|
708
826
|
this.snapToFn = deps.snapTo;
|
|
827
|
+
this.closeFn = deps.close;
|
|
709
828
|
this.scrimMode = opts.scrimMode ?? "full";
|
|
710
829
|
const preset = opts.scrimPreset ? SCRIM_PRESETS[opts.scrimPreset] : null;
|
|
711
830
|
this.backdropRange = opts.backdropRange ?? preset?.range ?? [0, 1];
|
|
@@ -847,11 +966,15 @@ var ScrimController = class {
|
|
|
847
966
|
}
|
|
848
967
|
const onClick = () => {
|
|
849
968
|
if (this.isDestroyed()) return;
|
|
969
|
+
if (this.closeFn) {
|
|
970
|
+
this.closeFn();
|
|
971
|
+
return;
|
|
972
|
+
}
|
|
850
973
|
const allowed = this.getAllowedIds();
|
|
851
974
|
const snaps = this.getResolvedSnaps();
|
|
852
975
|
const fallback = allowed.find((id) => {
|
|
853
976
|
const snap = findById(id, snaps);
|
|
854
|
-
return snap !== null && snap.size
|
|
977
|
+
return snap !== null && snap.size === 0;
|
|
855
978
|
});
|
|
856
979
|
if (fallback) this.snapToFn(fallback);
|
|
857
980
|
};
|
|
@@ -868,6 +991,7 @@ var ScrimController = class {
|
|
|
868
991
|
if (this.isDestroyed()) return;
|
|
869
992
|
if (enabled === this.scrimEnabled) return;
|
|
870
993
|
this.scrimEnabled = enabled;
|
|
994
|
+
this.invalidateOpacityCache();
|
|
871
995
|
if (!enabled) {
|
|
872
996
|
this.savedScrimRanges = {
|
|
873
997
|
screen: this.screenRange,
|
|
@@ -891,7 +1015,12 @@ var ScrimController = class {
|
|
|
891
1015
|
blur: cfg.blur ?? null,
|
|
892
1016
|
interactive: cfg.interactive
|
|
893
1017
|
});
|
|
894
|
-
this.
|
|
1018
|
+
if (!this.scrimEnabled && this.savedScrimRanges) {
|
|
1019
|
+
this.savedScrimRanges = { screen: cfg.range, backdrop: cfg.range };
|
|
1020
|
+
} else {
|
|
1021
|
+
this.screenRange = cfg.range;
|
|
1022
|
+
this.backdropRange = cfg.range;
|
|
1023
|
+
}
|
|
895
1024
|
}
|
|
896
1025
|
const noop = () => {
|
|
897
1026
|
};
|
|
@@ -941,59 +1070,7 @@ var ScrimController = class {
|
|
|
941
1070
|
wrapper.className = "bs-scrim-overlay";
|
|
942
1071
|
const ws = wrapper.style;
|
|
943
1072
|
ws.position = "absolute";
|
|
944
|
-
|
|
945
|
-
case "top-left":
|
|
946
|
-
ws.top = inset;
|
|
947
|
-
ws.left = inset;
|
|
948
|
-
break;
|
|
949
|
-
case "top-center":
|
|
950
|
-
ws.top = inset;
|
|
951
|
-
ws.left = "50%";
|
|
952
|
-
ws.transform = "translateX(-50%)";
|
|
953
|
-
break;
|
|
954
|
-
case "top-right":
|
|
955
|
-
ws.top = inset;
|
|
956
|
-
ws.right = inset;
|
|
957
|
-
break;
|
|
958
|
-
case "center-left":
|
|
959
|
-
ws.top = "50%";
|
|
960
|
-
ws.left = inset;
|
|
961
|
-
ws.transform = "translateY(-50%)";
|
|
962
|
-
break;
|
|
963
|
-
case "center":
|
|
964
|
-
ws.top = "50%";
|
|
965
|
-
ws.left = "50%";
|
|
966
|
-
ws.transform = "translate(-50%, -50%)";
|
|
967
|
-
break;
|
|
968
|
-
case "center-right":
|
|
969
|
-
ws.top = "50%";
|
|
970
|
-
ws.right = inset;
|
|
971
|
-
ws.transform = "translateY(-50%)";
|
|
972
|
-
break;
|
|
973
|
-
case "bottom-left":
|
|
974
|
-
ws.bottom = inset;
|
|
975
|
-
ws.left = inset;
|
|
976
|
-
break;
|
|
977
|
-
case "bottom-center":
|
|
978
|
-
ws.bottom = inset;
|
|
979
|
-
ws.left = "50%";
|
|
980
|
-
ws.transform = "translateX(-50%)";
|
|
981
|
-
break;
|
|
982
|
-
case "bottom-right":
|
|
983
|
-
ws.bottom = inset;
|
|
984
|
-
ws.right = inset;
|
|
985
|
-
break;
|
|
986
|
-
case "sheet-top-left":
|
|
987
|
-
case "sheet-top-center":
|
|
988
|
-
case "sheet-top-right":
|
|
989
|
-
applySheetAnchoredPosition(
|
|
990
|
-
ws,
|
|
991
|
-
this.mode,
|
|
992
|
-
position,
|
|
993
|
-
inset
|
|
994
|
-
);
|
|
995
|
-
break;
|
|
996
|
-
}
|
|
1073
|
+
applyOverlayPosition(ws, this.mode, position, inset);
|
|
997
1074
|
if (interactive) {
|
|
998
1075
|
ws.pointerEvents = "auto";
|
|
999
1076
|
}
|
|
@@ -1052,6 +1129,7 @@ var ScrimController = class {
|
|
|
1052
1129
|
}
|
|
1053
1130
|
}
|
|
1054
1131
|
if (opts.interactive !== void 0) {
|
|
1132
|
+
this.scrimInteractive = opts.interactive;
|
|
1055
1133
|
s.pointerEvents = opts.interactive ? "auto" : "none";
|
|
1056
1134
|
}
|
|
1057
1135
|
}
|
|
@@ -1066,38 +1144,9 @@ var ScrimController = class {
|
|
|
1066
1144
|
const s = this.screenComponent.style;
|
|
1067
1145
|
s.position = "fixed";
|
|
1068
1146
|
s.inset = insetByMode[this.mode];
|
|
1069
|
-
s.pointerEvents = "none";
|
|
1147
|
+
s.pointerEvents = this.scrimInteractive || this.scrimTapToCloseEnabled ? "auto" : "none";
|
|
1070
1148
|
}
|
|
1071
1149
|
};
|
|
1072
|
-
function resolveSheetAnchoredStyle(mode, position, inset) {
|
|
1073
|
-
const sizeOffset = `calc(var(--bs-size, 0px) + ${inset})`;
|
|
1074
|
-
switch (mode) {
|
|
1075
|
-
case "bottom":
|
|
1076
|
-
if (position === "sheet-top-left") return { bottom: sizeOffset, left: inset };
|
|
1077
|
-
if (position === "sheet-top-right") return { bottom: sizeOffset, right: inset };
|
|
1078
|
-
return { bottom: sizeOffset, left: "50%", transform: "translateX(-50%)" };
|
|
1079
|
-
case "top":
|
|
1080
|
-
if (position === "sheet-top-left") return { top: sizeOffset, left: inset };
|
|
1081
|
-
if (position === "sheet-top-right") return { top: sizeOffset, right: inset };
|
|
1082
|
-
return { top: sizeOffset, left: "50%", transform: "translateX(-50%)" };
|
|
1083
|
-
case "left":
|
|
1084
|
-
if (position === "sheet-top-left") return { left: sizeOffset, top: inset };
|
|
1085
|
-
if (position === "sheet-top-right") return { left: sizeOffset, bottom: inset };
|
|
1086
|
-
return { left: sizeOffset, top: "50%", transform: "translateY(-50%)" };
|
|
1087
|
-
case "right":
|
|
1088
|
-
if (position === "sheet-top-left") return { right: sizeOffset, top: inset };
|
|
1089
|
-
if (position === "sheet-top-right") return { right: sizeOffset, bottom: inset };
|
|
1090
|
-
return { right: sizeOffset, top: "50%", transform: "translateY(-50%)" };
|
|
1091
|
-
}
|
|
1092
|
-
}
|
|
1093
|
-
function applySheetAnchoredPosition(ws, mode, position, inset) {
|
|
1094
|
-
const style = resolveSheetAnchoredStyle(mode, position, inset);
|
|
1095
|
-
if (style.top !== void 0) ws.top = style.top;
|
|
1096
|
-
if (style.bottom !== void 0) ws.bottom = style.bottom;
|
|
1097
|
-
if (style.left !== void 0) ws.left = style.left;
|
|
1098
|
-
if (style.right !== void 0) ws.right = style.right;
|
|
1099
|
-
if (style.transform !== void 0) ws.transform = style.transform;
|
|
1100
|
-
}
|
|
1101
1150
|
|
|
1102
1151
|
// src/core/animation/animation.ts
|
|
1103
1152
|
var easeOutBack = (t) => {
|
|
@@ -1149,6 +1198,10 @@ var tween = ({
|
|
|
1149
1198
|
promise
|
|
1150
1199
|
};
|
|
1151
1200
|
};
|
|
1201
|
+
var prefersReducedMotion = () => {
|
|
1202
|
+
if (typeof window === "undefined" || !window.matchMedia) return false;
|
|
1203
|
+
return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
1204
|
+
};
|
|
1152
1205
|
|
|
1153
1206
|
// src/core/animation/spring.ts
|
|
1154
1207
|
var DEFAULT_SPRING = {
|
|
@@ -1179,14 +1232,20 @@ var runSpring = ({
|
|
|
1179
1232
|
if (cancelled) return;
|
|
1180
1233
|
const dt = Math.min((now - lastTime) / 1e3, MAX_DT);
|
|
1181
1234
|
lastTime = now;
|
|
1182
|
-
const
|
|
1183
|
-
|
|
1235
|
+
const steps = Math.max(1, Math.ceil(dt * 240));
|
|
1236
|
+
const subDt = dt / steps;
|
|
1237
|
+
let stepsLeft = steps;
|
|
1184
1238
|
while (stepsLeft-- > 0) {
|
|
1185
1239
|
const force = -cfg.stiffness * (x - to) - cfg.damping * v;
|
|
1186
1240
|
const accel = force / cfg.mass;
|
|
1187
1241
|
v += accel * subDt;
|
|
1188
1242
|
x += v * subDt;
|
|
1189
1243
|
}
|
|
1244
|
+
if (!Number.isFinite(x) || !Number.isFinite(v)) {
|
|
1245
|
+
onUpdate(to, 0);
|
|
1246
|
+
resolve();
|
|
1247
|
+
return;
|
|
1248
|
+
}
|
|
1190
1249
|
onUpdate(x, v);
|
|
1191
1250
|
const isAtRest = Math.abs(to - x) < (cfg.restDelta ?? 0.5) && Math.abs(v) < (cfg.restSpeed ?? 0.5);
|
|
1192
1251
|
if (isAtRest) {
|
|
@@ -1361,9 +1420,13 @@ var isVisible = (el) => {
|
|
|
1361
1420
|
var focusables = (root) => Array.from(root.querySelectorAll(FOCUSABLE)).filter(
|
|
1362
1421
|
(el) => !el.hasAttribute("inert") && isVisible(el) && !el.matches("[aria-hidden='true']")
|
|
1363
1422
|
);
|
|
1423
|
+
var trapStack = [];
|
|
1364
1424
|
var installFocusTrap = (container, options = {}) => {
|
|
1365
1425
|
if (typeof document === "undefined") return () => {
|
|
1366
1426
|
};
|
|
1427
|
+
const token = {};
|
|
1428
|
+
trapStack.push(token);
|
|
1429
|
+
const isActive = () => trapStack[trapStack.length - 1] === token;
|
|
1367
1430
|
const previouslyFocused = document.activeElement;
|
|
1368
1431
|
const focusInitial = () => {
|
|
1369
1432
|
const initial = typeof options.initialFocus === "string" ? container.querySelector(options.initialFocus) : options.initialFocus ?? focusables(container)[0] ?? container;
|
|
@@ -1371,6 +1434,7 @@ var installFocusTrap = (container, options = {}) => {
|
|
|
1371
1434
|
};
|
|
1372
1435
|
focusInitial();
|
|
1373
1436
|
const handleKey = (e) => {
|
|
1437
|
+
if (!isActive()) return;
|
|
1374
1438
|
if (e.key === "Escape" && options.onEscape) {
|
|
1375
1439
|
options.onEscape();
|
|
1376
1440
|
return;
|
|
@@ -1393,6 +1457,7 @@ var installFocusTrap = (container, options = {}) => {
|
|
|
1393
1457
|
}
|
|
1394
1458
|
};
|
|
1395
1459
|
const handleFocusIn = (e) => {
|
|
1460
|
+
if (!isActive()) return;
|
|
1396
1461
|
const target = e.target;
|
|
1397
1462
|
if (target && !container.contains(target)) {
|
|
1398
1463
|
const list = focusables(container);
|
|
@@ -1405,6 +1470,8 @@ var installFocusTrap = (container, options = {}) => {
|
|
|
1405
1470
|
return () => {
|
|
1406
1471
|
if (released) return;
|
|
1407
1472
|
released = true;
|
|
1473
|
+
const idx = trapStack.indexOf(token);
|
|
1474
|
+
if (idx !== -1) trapStack.splice(idx, 1);
|
|
1408
1475
|
document.removeEventListener("keydown", handleKey, true);
|
|
1409
1476
|
document.removeEventListener("focusin", handleFocusIn, true);
|
|
1410
1477
|
if (previouslyFocused && document.contains(previouslyFocused)) {
|
|
@@ -1460,11 +1527,17 @@ function createInertSiblings(rootProvider) {
|
|
|
1460
1527
|
return {
|
|
1461
1528
|
apply() {
|
|
1462
1529
|
if (typeof document === "undefined") return;
|
|
1463
|
-
|
|
1464
|
-
|
|
1530
|
+
let top = rootProvider();
|
|
1531
|
+
while (top.parentElement && top.parentElement !== document.body) {
|
|
1532
|
+
top = top.parentElement;
|
|
1533
|
+
}
|
|
1534
|
+
const parent = top.parentElement ?? document.body;
|
|
1465
1535
|
for (const child of Array.from(parent.children)) {
|
|
1466
|
-
if (child ===
|
|
1536
|
+
if (child === top) continue;
|
|
1467
1537
|
if (child.hasAttribute("inert")) continue;
|
|
1538
|
+
if (child.classList.contains("bs-backdrop") || child.classList.contains("bs-screen") || child.classList.contains("bs-root")) {
|
|
1539
|
+
continue;
|
|
1540
|
+
}
|
|
1468
1541
|
child.setAttribute("inert", "");
|
|
1469
1542
|
tracked.push(child);
|
|
1470
1543
|
}
|
|
@@ -1480,7 +1553,6 @@ function createInertSiblings(rootProvider) {
|
|
|
1480
1553
|
var LifecycleController = class {
|
|
1481
1554
|
constructor(deps, opts) {
|
|
1482
1555
|
__publicField(this, "element");
|
|
1483
|
-
__publicField(this, "closeFn");
|
|
1484
1556
|
__publicField(this, "focusTrapEnabled");
|
|
1485
1557
|
__publicField(this, "initialFocus");
|
|
1486
1558
|
__publicField(this, "closeOnEscape");
|
|
@@ -1494,7 +1566,6 @@ var LifecycleController = class {
|
|
|
1494
1566
|
__publicField(this, "installed", false);
|
|
1495
1567
|
__publicField(this, "destroyed", false);
|
|
1496
1568
|
this.element = deps.element;
|
|
1497
|
-
this.closeFn = deps.close;
|
|
1498
1569
|
this.focusTrapEnabled = opts.focusTrap ?? false;
|
|
1499
1570
|
this.initialFocus = opts.initialFocus;
|
|
1500
1571
|
this.closeOnEscape = opts.closeOnEscape ?? true;
|
|
@@ -1504,6 +1575,9 @@ var LifecycleController = class {
|
|
|
1504
1575
|
this.returnFocus = opts.returnFocus;
|
|
1505
1576
|
this.inertSiblings = createInertSiblings(() => this.element);
|
|
1506
1577
|
}
|
|
1578
|
+
get isInstalled() {
|
|
1579
|
+
return this.installed;
|
|
1580
|
+
}
|
|
1507
1581
|
install() {
|
|
1508
1582
|
if (this.destroyed) return;
|
|
1509
1583
|
this.installed = true;
|
|
@@ -1512,8 +1586,7 @@ var LifecycleController = class {
|
|
|
1512
1586
|
}
|
|
1513
1587
|
if (this.focusTrapEnabled && !this.releaseFocusTrap) {
|
|
1514
1588
|
this.releaseFocusTrap = installFocusTrap(this.element, {
|
|
1515
|
-
initialFocus: this.initialFocus
|
|
1516
|
-
onEscape: this.closeOnEscape ? () => void this.closeFn() : void 0
|
|
1589
|
+
initialFocus: this.initialFocus
|
|
1517
1590
|
});
|
|
1518
1591
|
}
|
|
1519
1592
|
if (this.inertSiblingsEnabled && this.shouldApplyInertSiblings()) {
|
|
@@ -1667,10 +1740,11 @@ var installGestures = (handle, mode, callbacks) => {
|
|
|
1667
1740
|
};
|
|
1668
1741
|
|
|
1669
1742
|
// src/core/primitives/rubber-band.ts
|
|
1670
|
-
var RUBBER_BAND_FACTOR = 0.55;
|
|
1671
1743
|
function rubberBand(overshoot, maxAxisSize) {
|
|
1672
1744
|
const cap = Math.min(maxAxisSize * 0.15, 80);
|
|
1673
|
-
|
|
1745
|
+
if (cap <= 0) return 0;
|
|
1746
|
+
const abs = Math.abs(overshoot);
|
|
1747
|
+
return Math.sign(overshoot) * (cap * abs / (abs + cap));
|
|
1674
1748
|
}
|
|
1675
1749
|
|
|
1676
1750
|
// src/core/features/soft-keyboard.ts
|
|
@@ -1755,6 +1829,10 @@ var GestureController = class {
|
|
|
1755
1829
|
this.isDragging_ = false;
|
|
1756
1830
|
this.keyboardDismissed = false;
|
|
1757
1831
|
this.deps.getRoot()?.removeAttribute("data-dragging");
|
|
1832
|
+
this.deps.emit("dragend", {
|
|
1833
|
+
size: this.deps.getDragContext().size,
|
|
1834
|
+
velocity: 0
|
|
1835
|
+
});
|
|
1758
1836
|
const restoreTo = this.dragStartSize;
|
|
1759
1837
|
void this.deps.animateTo(restoreTo, 0);
|
|
1760
1838
|
}
|
|
@@ -1828,6 +1906,287 @@ function createScrollCache(deps) {
|
|
|
1828
1906
|
};
|
|
1829
1907
|
}
|
|
1830
1908
|
|
|
1909
|
+
// src/core/primitives/anchor-animations.ts
|
|
1910
|
+
var DEFAULT_DURATION3 = 200;
|
|
1911
|
+
var DEFAULT_EASING = "cubic-bezier(0.22, 1, 0.36, 1)";
|
|
1912
|
+
var PRESET_FRAMES = {
|
|
1913
|
+
fade: {
|
|
1914
|
+
enter: [{ opacity: 0 }, { opacity: 1 }],
|
|
1915
|
+
exit: [{ opacity: 1 }, { opacity: 0 }]
|
|
1916
|
+
},
|
|
1917
|
+
scale: {
|
|
1918
|
+
enter: [
|
|
1919
|
+
{ opacity: 0, transform: "scale(0.85)" },
|
|
1920
|
+
{ opacity: 1, transform: "scale(1)" }
|
|
1921
|
+
],
|
|
1922
|
+
exit: [
|
|
1923
|
+
{ opacity: 1, transform: "scale(1)" },
|
|
1924
|
+
{ opacity: 0, transform: "scale(0.85)" }
|
|
1925
|
+
]
|
|
1926
|
+
},
|
|
1927
|
+
slide: {
|
|
1928
|
+
enter: [
|
|
1929
|
+
{ opacity: 0, transform: "translateY(10px)" },
|
|
1930
|
+
{ opacity: 1, transform: "translateY(0)" }
|
|
1931
|
+
],
|
|
1932
|
+
exit: [
|
|
1933
|
+
{ opacity: 1, transform: "translateY(0)" },
|
|
1934
|
+
{ opacity: 0, transform: "translateY(10px)" }
|
|
1935
|
+
]
|
|
1936
|
+
},
|
|
1937
|
+
pop: {
|
|
1938
|
+
enter: [
|
|
1939
|
+
{ opacity: 0, transform: "scale(0.6)", offset: 0 },
|
|
1940
|
+
{ opacity: 1, transform: "scale(1.06)", offset: 0.7 },
|
|
1941
|
+
{ opacity: 1, transform: "scale(1)", offset: 1 }
|
|
1942
|
+
],
|
|
1943
|
+
exit: [
|
|
1944
|
+
{ opacity: 1, transform: "scale(1)" },
|
|
1945
|
+
{ opacity: 0, transform: "scale(0.6)" }
|
|
1946
|
+
]
|
|
1947
|
+
}
|
|
1948
|
+
};
|
|
1949
|
+
var INSTANT = {
|
|
1950
|
+
finished: Promise.resolve(),
|
|
1951
|
+
cancel: () => {
|
|
1952
|
+
}
|
|
1953
|
+
};
|
|
1954
|
+
function resolveTransitionFrames(spec, phase) {
|
|
1955
|
+
const fallback = { frames: null, duration: 0, easing: DEFAULT_EASING };
|
|
1956
|
+
if (spec === "none") return fallback;
|
|
1957
|
+
if (spec === void 0 || typeof spec === "string") {
|
|
1958
|
+
const preset2 = PRESET_FRAMES[spec ?? "fade"];
|
|
1959
|
+
return {
|
|
1960
|
+
frames: preset2[phase],
|
|
1961
|
+
duration: DEFAULT_DURATION3,
|
|
1962
|
+
easing: DEFAULT_EASING
|
|
1963
|
+
};
|
|
1964
|
+
}
|
|
1965
|
+
const custom = phase === "enter" ? spec.enter : spec.exit;
|
|
1966
|
+
if (custom) {
|
|
1967
|
+
return {
|
|
1968
|
+
frames: custom,
|
|
1969
|
+
duration: spec.duration ?? DEFAULT_DURATION3,
|
|
1970
|
+
easing: spec.easing ?? DEFAULT_EASING
|
|
1971
|
+
};
|
|
1972
|
+
}
|
|
1973
|
+
if (spec.preset === "none") return fallback;
|
|
1974
|
+
const preset = PRESET_FRAMES[spec.preset ?? "fade"];
|
|
1975
|
+
return {
|
|
1976
|
+
frames: preset[phase],
|
|
1977
|
+
duration: spec.duration ?? DEFAULT_DURATION3,
|
|
1978
|
+
easing: spec.easing ?? DEFAULT_EASING
|
|
1979
|
+
};
|
|
1980
|
+
}
|
|
1981
|
+
function runAnchorTransition(el, spec, phase) {
|
|
1982
|
+
const respectReduced = typeof spec === "object" ? spec.respectReducedMotion !== false : true;
|
|
1983
|
+
if (respectReduced && prefersReducedMotion()) return INSTANT;
|
|
1984
|
+
const { frames, duration, easing } = resolveTransitionFrames(spec, phase);
|
|
1985
|
+
if (!frames || duration <= 0) return INSTANT;
|
|
1986
|
+
if (typeof el.animate !== "function") return INSTANT;
|
|
1987
|
+
const animation = el.animate(frames, {
|
|
1988
|
+
duration,
|
|
1989
|
+
easing,
|
|
1990
|
+
fill: "both"
|
|
1991
|
+
});
|
|
1992
|
+
const finished = animation.finished.then(() => void 0).catch(() => void 0);
|
|
1993
|
+
return {
|
|
1994
|
+
finished,
|
|
1995
|
+
cancel: () => {
|
|
1996
|
+
try {
|
|
1997
|
+
animation.cancel();
|
|
1998
|
+
} catch {
|
|
1999
|
+
return;
|
|
2000
|
+
}
|
|
2001
|
+
}
|
|
2002
|
+
};
|
|
2003
|
+
}
|
|
2004
|
+
|
|
2005
|
+
// src/core/features/sheet-anchors.ts
|
|
2006
|
+
function attachAnchor(deps, opts) {
|
|
2007
|
+
const doc = deps.host.ownerDocument;
|
|
2008
|
+
const wrapper = doc.createElement("div");
|
|
2009
|
+
wrapper.className = "bs-anchor";
|
|
2010
|
+
const interactive = opts.interactive ?? true;
|
|
2011
|
+
const position = opts.position ?? "sheet-top-right";
|
|
2012
|
+
const isDock = position === "dock-bottom" || position === "dock-top";
|
|
2013
|
+
const ws = wrapper.style;
|
|
2014
|
+
ws.position = "fixed";
|
|
2015
|
+
if (isDock) {
|
|
2016
|
+
ws.left = "0";
|
|
2017
|
+
ws.right = "0";
|
|
2018
|
+
if (position === "dock-bottom") {
|
|
2019
|
+
ws.bottom = "0";
|
|
2020
|
+
} else {
|
|
2021
|
+
ws.top = "0";
|
|
2022
|
+
}
|
|
2023
|
+
} else {
|
|
2024
|
+
applyOverlayPosition(ws, deps.mode, position, opts.inset ?? "16px");
|
|
2025
|
+
}
|
|
2026
|
+
if (opts.fadeRange) {
|
|
2027
|
+
const [r0, r1] = opts.fadeRange;
|
|
2028
|
+
const span = Math.max(r1 - r0, 1e-4);
|
|
2029
|
+
ws.opacity = `clamp(0, calc((var(--bs-progress, 0) - ${r0}) / ${span}), 1)`;
|
|
2030
|
+
}
|
|
2031
|
+
wrapper.appendChild(opts.element);
|
|
2032
|
+
deps.host.appendChild(wrapper);
|
|
2033
|
+
let visible = null;
|
|
2034
|
+
let inFlight = null;
|
|
2035
|
+
const shouldShow = (state) => {
|
|
2036
|
+
if (typeof opts.showOn === "function") return opts.showOn(state);
|
|
2037
|
+
if (Array.isArray(opts.showOn)) return opts.showOn.includes(state.activeId);
|
|
2038
|
+
return isDock || state.size > 0;
|
|
2039
|
+
};
|
|
2040
|
+
const applyVisibility = (next, animate) => {
|
|
2041
|
+
if (next === visible) return;
|
|
2042
|
+
visible = next;
|
|
2043
|
+
inFlight?.cancel();
|
|
2044
|
+
inFlight = null;
|
|
2045
|
+
wrapper.style.pointerEvents = next && interactive ? "auto" : "none";
|
|
2046
|
+
if (next) {
|
|
2047
|
+
wrapper.style.visibility = "";
|
|
2048
|
+
if (animate) {
|
|
2049
|
+
inFlight = runAnchorTransition(opts.element, opts.animation, "enter");
|
|
2050
|
+
}
|
|
2051
|
+
return;
|
|
2052
|
+
}
|
|
2053
|
+
if (!animate) {
|
|
2054
|
+
wrapper.style.visibility = "hidden";
|
|
2055
|
+
return;
|
|
2056
|
+
}
|
|
2057
|
+
const handle = runAnchorTransition(opts.element, opts.animation, "exit");
|
|
2058
|
+
inFlight = handle;
|
|
2059
|
+
void handle.finished.then(() => {
|
|
2060
|
+
if (inFlight === handle && visible === false) {
|
|
2061
|
+
wrapper.style.visibility = "hidden";
|
|
2062
|
+
}
|
|
2063
|
+
});
|
|
2064
|
+
};
|
|
2065
|
+
const evaluate = (animate) => {
|
|
2066
|
+
if (deps.isDestroyed()) return;
|
|
2067
|
+
applyVisibility(shouldShow(deps.getState()), animate);
|
|
2068
|
+
};
|
|
2069
|
+
const offs = [
|
|
2070
|
+
deps.on("snap", () => evaluate(true)),
|
|
2071
|
+
deps.on("open", () => evaluate(true)),
|
|
2072
|
+
deps.on("close", () => evaluate(true))
|
|
2073
|
+
];
|
|
2074
|
+
evaluate(false);
|
|
2075
|
+
return {
|
|
2076
|
+
wrapper,
|
|
2077
|
+
detach: () => {
|
|
2078
|
+
offs.forEach((off) => off());
|
|
2079
|
+
inFlight?.cancel();
|
|
2080
|
+
inFlight = null;
|
|
2081
|
+
if (wrapper.parentNode) wrapper.parentNode.removeChild(wrapper);
|
|
2082
|
+
},
|
|
2083
|
+
syncZ: (z) => {
|
|
2084
|
+
wrapper.style.zIndex = String(z);
|
|
2085
|
+
}
|
|
2086
|
+
};
|
|
2087
|
+
}
|
|
2088
|
+
|
|
2089
|
+
// src/core/features/scrim-stages.ts
|
|
2090
|
+
var matchesId = (def, activeId) => {
|
|
2091
|
+
if (def.for === void 0) return false;
|
|
2092
|
+
return Array.isArray(def.for) ? def.for.includes(activeId) : def.for === activeId;
|
|
2093
|
+
};
|
|
2094
|
+
var matchesRange = (def, progress) => {
|
|
2095
|
+
if (!def.forRange) return false;
|
|
2096
|
+
const [from, to] = def.forRange;
|
|
2097
|
+
return progress >= from && progress <= to;
|
|
2098
|
+
};
|
|
2099
|
+
function installScrimStages(deps, opts) {
|
|
2100
|
+
const doc = deps.host.ownerDocument;
|
|
2101
|
+
const entries = opts.stages.map((def) => {
|
|
2102
|
+
const wrapper = doc.createElement("div");
|
|
2103
|
+
wrapper.className = "bs-scrim-stage";
|
|
2104
|
+
const ws = wrapper.style;
|
|
2105
|
+
ws.position = "absolute";
|
|
2106
|
+
applyOverlayPosition(
|
|
2107
|
+
ws,
|
|
2108
|
+
deps.mode,
|
|
2109
|
+
def.position ?? opts.position ?? "center",
|
|
2110
|
+
def.inset ?? opts.inset ?? "16px"
|
|
2111
|
+
);
|
|
2112
|
+
ws.visibility = "hidden";
|
|
2113
|
+
ws.pointerEvents = "none";
|
|
2114
|
+
wrapper.appendChild(def.element);
|
|
2115
|
+
deps.host.appendChild(wrapper);
|
|
2116
|
+
return { def, wrapper, inFlight: null };
|
|
2117
|
+
});
|
|
2118
|
+
let active = null;
|
|
2119
|
+
const resolveActive = () => {
|
|
2120
|
+
const state = deps.getState();
|
|
2121
|
+
if (state.size === 0) {
|
|
2122
|
+
return entries.find((e) => matchesId(e.def, state.activeId)) ?? null;
|
|
2123
|
+
}
|
|
2124
|
+
return entries.find((e) => matchesId(e.def, state.activeId)) ?? entries.find((e) => matchesRange(e.def, state.progress)) ?? null;
|
|
2125
|
+
};
|
|
2126
|
+
const hide = (entry, animate) => {
|
|
2127
|
+
entry.inFlight?.cancel();
|
|
2128
|
+
entry.wrapper.style.pointerEvents = "none";
|
|
2129
|
+
if (!animate) {
|
|
2130
|
+
entry.inFlight = null;
|
|
2131
|
+
entry.wrapper.style.visibility = "hidden";
|
|
2132
|
+
return;
|
|
2133
|
+
}
|
|
2134
|
+
const handle = runAnchorTransition(
|
|
2135
|
+
entry.def.element,
|
|
2136
|
+
entry.def.animation ?? opts.animation,
|
|
2137
|
+
"exit"
|
|
2138
|
+
);
|
|
2139
|
+
entry.inFlight = handle;
|
|
2140
|
+
void handle.finished.then(() => {
|
|
2141
|
+
if (entry.inFlight === handle && active !== entry) {
|
|
2142
|
+
entry.wrapper.style.visibility = "hidden";
|
|
2143
|
+
}
|
|
2144
|
+
});
|
|
2145
|
+
};
|
|
2146
|
+
const show = (entry, animate) => {
|
|
2147
|
+
entry.inFlight?.cancel();
|
|
2148
|
+
entry.inFlight = null;
|
|
2149
|
+
entry.wrapper.style.visibility = "";
|
|
2150
|
+
entry.wrapper.style.pointerEvents = entry.def.interactive ?? opts.interactive ?? false ? "auto" : "none";
|
|
2151
|
+
if (animate) {
|
|
2152
|
+
entry.inFlight = runAnchorTransition(
|
|
2153
|
+
entry.def.element,
|
|
2154
|
+
entry.def.animation ?? opts.animation,
|
|
2155
|
+
"enter"
|
|
2156
|
+
);
|
|
2157
|
+
}
|
|
2158
|
+
};
|
|
2159
|
+
const update = (animate) => {
|
|
2160
|
+
if (deps.isDestroyed()) return;
|
|
2161
|
+
const next = resolveActive();
|
|
2162
|
+
if (next === active) return;
|
|
2163
|
+
const prev = active;
|
|
2164
|
+
active = next;
|
|
2165
|
+
if (prev) hide(prev, animate);
|
|
2166
|
+
if (next) show(next, animate);
|
|
2167
|
+
};
|
|
2168
|
+
const offs = [
|
|
2169
|
+
deps.on("snap", () => update(true)),
|
|
2170
|
+
deps.on("open", () => update(true)),
|
|
2171
|
+
deps.on("close", () => update(true))
|
|
2172
|
+
];
|
|
2173
|
+
if (entries.some((e) => e.def.forRange)) {
|
|
2174
|
+
offs.push(deps.on("progress", () => update(true)));
|
|
2175
|
+
}
|
|
2176
|
+
update(false);
|
|
2177
|
+
return () => {
|
|
2178
|
+
offs.forEach((off) => off());
|
|
2179
|
+
for (const entry of entries) {
|
|
2180
|
+
entry.inFlight?.cancel();
|
|
2181
|
+
entry.inFlight = null;
|
|
2182
|
+
if (entry.wrapper.parentNode) {
|
|
2183
|
+
entry.wrapper.parentNode.removeChild(entry.wrapper);
|
|
2184
|
+
}
|
|
2185
|
+
}
|
|
2186
|
+
active = null;
|
|
2187
|
+
};
|
|
2188
|
+
}
|
|
2189
|
+
|
|
1831
2190
|
// src/core/primitives/engine-options.ts
|
|
1832
2191
|
var DEFAULT_FLICK_VELOCITY = 0.65;
|
|
1833
2192
|
var DEFAULT_DRAG_THRESHOLD = 18;
|
|
@@ -1944,6 +2303,12 @@ var BottomSheetEngine = class {
|
|
|
1944
2303
|
__publicField(this, "linkedSheets", []);
|
|
1945
2304
|
__publicField(this, "scrollCache");
|
|
1946
2305
|
__publicField(this, "teardowns", new TeardownStack());
|
|
2306
|
+
__publicField(this, "anchors", []);
|
|
2307
|
+
__publicField(this, "anchorHost", null);
|
|
2308
|
+
__publicField(this, "stackZ", 100);
|
|
2309
|
+
__publicField(this, "detachScrimStages", null);
|
|
2310
|
+
__publicField(this, "stackEffectEnabled", false);
|
|
2311
|
+
__publicField(this, "stackEffectPrimed", false);
|
|
1947
2312
|
__publicField(this, "transformTemplate");
|
|
1948
2313
|
const resolved = resolveEngineOptions(opts, {
|
|
1949
2314
|
shouldApplyInertSiblings: () => {
|
|
@@ -1977,6 +2342,9 @@ var BottomSheetEngine = class {
|
|
|
1977
2342
|
getResolvedSnaps: () => this.snaps.getResolvedSnaps().slice(),
|
|
1978
2343
|
snapTo: (id) => {
|
|
1979
2344
|
void this.snapTo(id);
|
|
2345
|
+
},
|
|
2346
|
+
close: () => {
|
|
2347
|
+
void this.close();
|
|
1980
2348
|
}
|
|
1981
2349
|
},
|
|
1982
2350
|
resolved.scrim
|
|
@@ -2000,6 +2368,7 @@ var BottomSheetEngine = class {
|
|
|
2000
2368
|
);
|
|
2001
2369
|
this.closeOnBack = resolved.closeOnBack;
|
|
2002
2370
|
this.routedTo = opts.routedTo;
|
|
2371
|
+
this.stackEffectEnabled = opts.stackEffect ?? false;
|
|
2003
2372
|
this.snapPointsRaw = opts.snapPoints;
|
|
2004
2373
|
this.persistKey = opts.persistKey;
|
|
2005
2374
|
if (opts.linkedSheets) {
|
|
@@ -2012,7 +2381,7 @@ var BottomSheetEngine = class {
|
|
|
2012
2381
|
this.snapPointsRaw,
|
|
2013
2382
|
resolved.initialAllowed,
|
|
2014
2383
|
this.mode,
|
|
2015
|
-
() => this.handle.offsetHeight,
|
|
2384
|
+
() => layoutAxis(this.mode) === "width" ? this.handle.offsetWidth : this.handle.offsetHeight,
|
|
2016
2385
|
(maxAxisSize) => {
|
|
2017
2386
|
this.element.style[layoutAxis(this.mode)] = `${maxAxisSize}px`;
|
|
2018
2387
|
}
|
|
@@ -2222,11 +2591,6 @@ var BottomSheetEngine = class {
|
|
|
2222
2591
|
}
|
|
2223
2592
|
setAllowed(ids, snap) {
|
|
2224
2593
|
if (this.destroyed) return;
|
|
2225
|
-
const willSnap = snap !== void 0 && ids.includes(snap) || !ids.includes(this.activeId) && ids.length > 0;
|
|
2226
|
-
if (!willSnap) {
|
|
2227
|
-
this.animation.cancel();
|
|
2228
|
-
this.newCycle();
|
|
2229
|
-
}
|
|
2230
2594
|
this.snaps.setAllowedIds(ids);
|
|
2231
2595
|
this.updateAriaSlider();
|
|
2232
2596
|
if (snap && ids.includes(snap)) {
|
|
@@ -2266,6 +2630,79 @@ var BottomSheetEngine = class {
|
|
|
2266
2630
|
setScrimOverlay(opts) {
|
|
2267
2631
|
return this.scrim.setScrimOverlay(opts);
|
|
2268
2632
|
}
|
|
2633
|
+
addAnchor(opts) {
|
|
2634
|
+
if (this.destroyed || typeof document === "undefined") return () => {
|
|
2635
|
+
};
|
|
2636
|
+
if (!this.anchorHost) {
|
|
2637
|
+
this.anchorHost = this.rootEl ?? this.element.parentElement ?? document.body;
|
|
2638
|
+
this.anchorHost.style.setProperty("--bs-size", `${this.size}px`);
|
|
2639
|
+
this.anchorHost.style.setProperty(
|
|
2640
|
+
"--bs-progress",
|
|
2641
|
+
String(this.computeProgress(this.size))
|
|
2642
|
+
);
|
|
2643
|
+
}
|
|
2644
|
+
const handle = attachAnchor(
|
|
2645
|
+
{
|
|
2646
|
+
mode: this.mode,
|
|
2647
|
+
host: this.anchorHost,
|
|
2648
|
+
getState: () => ({
|
|
2649
|
+
activeId: this.activeId,
|
|
2650
|
+
size: this.size,
|
|
2651
|
+
progress: this.computeProgress(this.size)
|
|
2652
|
+
}),
|
|
2653
|
+
on: (event, fn) => this.on(event, fn),
|
|
2654
|
+
isDestroyed: () => this.destroyed
|
|
2655
|
+
},
|
|
2656
|
+
opts
|
|
2657
|
+
);
|
|
2658
|
+
handle.syncZ(this.stackZ + 1);
|
|
2659
|
+
this.anchors.push(handle);
|
|
2660
|
+
const detach = () => {
|
|
2661
|
+
const idx = this.anchors.indexOf(handle);
|
|
2662
|
+
if (idx === -1) return;
|
|
2663
|
+
this.anchors.splice(idx, 1);
|
|
2664
|
+
handle.detach();
|
|
2665
|
+
};
|
|
2666
|
+
this.teardowns.add(detach);
|
|
2667
|
+
return detach;
|
|
2668
|
+
}
|
|
2669
|
+
setScrimStages(opts) {
|
|
2670
|
+
if (this.destroyed || typeof document === "undefined") return () => {
|
|
2671
|
+
};
|
|
2672
|
+
this.detachScrimStages?.();
|
|
2673
|
+
this.detachScrimStages = null;
|
|
2674
|
+
if (!opts) return () => {
|
|
2675
|
+
};
|
|
2676
|
+
const host = this.screenComponent?.parentElement;
|
|
2677
|
+
if (!host) {
|
|
2678
|
+
console.warn(
|
|
2679
|
+
"[BottomSheet] setScrimStages: no scrim element mounted \u2014 pass `scrim` to the engine first."
|
|
2680
|
+
);
|
|
2681
|
+
return () => {
|
|
2682
|
+
};
|
|
2683
|
+
}
|
|
2684
|
+
const detachInstalled = installScrimStages(
|
|
2685
|
+
{
|
|
2686
|
+
mode: this.mode,
|
|
2687
|
+
host,
|
|
2688
|
+
getState: () => ({
|
|
2689
|
+
activeId: this.activeId,
|
|
2690
|
+
size: this.size,
|
|
2691
|
+
progress: this.computeProgress(this.size)
|
|
2692
|
+
}),
|
|
2693
|
+
on: (event, fn) => this.on(event, fn),
|
|
2694
|
+
isDestroyed: () => this.destroyed
|
|
2695
|
+
},
|
|
2696
|
+
opts
|
|
2697
|
+
);
|
|
2698
|
+
const detach = () => {
|
|
2699
|
+
if (this.detachScrimStages === detach) this.detachScrimStages = null;
|
|
2700
|
+
detachInstalled();
|
|
2701
|
+
};
|
|
2702
|
+
this.detachScrimStages = detach;
|
|
2703
|
+
this.teardowns.add(() => this.detachScrimStages?.());
|
|
2704
|
+
return detach;
|
|
2705
|
+
}
|
|
2269
2706
|
getScrimState() {
|
|
2270
2707
|
return { mode: this.scrim.scrimMode, enabled: this.scrim.scrimEnabled };
|
|
2271
2708
|
}
|
|
@@ -2352,24 +2789,45 @@ var BottomSheetEngine = class {
|
|
|
2352
2789
|
getAllowedRange() {
|
|
2353
2790
|
return this.snaps.getAllowedRange();
|
|
2354
2791
|
}
|
|
2792
|
+
allowedIdsBySize() {
|
|
2793
|
+
return this.snaps.getAllowedIds().slice().sort(
|
|
2794
|
+
(a, b) => (this.snaps.findById(a)?.size ?? 0) - (this.snaps.findById(b)?.size ?? 0)
|
|
2795
|
+
);
|
|
2796
|
+
}
|
|
2355
2797
|
updateAriaSlider() {
|
|
2356
|
-
this.aria.setValue(this.
|
|
2798
|
+
this.aria.setValue(this.allowedIdsBySize(), this.activeId);
|
|
2357
2799
|
}
|
|
2358
2800
|
registerInStack() {
|
|
2359
2801
|
this.teardowns.add(sheetStack.push({
|
|
2360
2802
|
id: this.id,
|
|
2361
2803
|
setZIndex: (z) => {
|
|
2804
|
+
this.stackZ = z;
|
|
2362
2805
|
this.element.style.zIndex = String(z);
|
|
2363
2806
|
if (this.backdrop) this.backdrop.style.zIndex = String(z - 1);
|
|
2807
|
+
for (const anchor of this.anchors) anchor.syncZ(z + 1);
|
|
2364
2808
|
},
|
|
2365
2809
|
setIsTop: (isTop) => {
|
|
2366
2810
|
this.isTopSheet = isTop;
|
|
2367
2811
|
if (this.backdrop) {
|
|
2368
2812
|
this.backdrop.style.display = isTop ? "" : "none";
|
|
2369
2813
|
}
|
|
2370
|
-
}
|
|
2814
|
+
},
|
|
2815
|
+
isOpen: () => this.size > 0,
|
|
2816
|
+
setDepth: (depth) => this.applyStackDepth(depth)
|
|
2371
2817
|
}));
|
|
2372
2818
|
}
|
|
2819
|
+
applyStackDepth(depth) {
|
|
2820
|
+
if (!this.stackEffectEnabled) return;
|
|
2821
|
+
this.element.setAttribute("data-stack-depth", String(depth));
|
|
2822
|
+
if (!this.stackEffectPrimed) {
|
|
2823
|
+
this.stackEffectPrimed = true;
|
|
2824
|
+
const isVertical = this.mode === "bottom" || this.mode === "top";
|
|
2825
|
+
this.element.style.transformOrigin = isVertical ? "50% 100%" : "0% 50%";
|
|
2826
|
+
this.element.style.transition = "scale 320ms cubic-bezier(0.29, 1.04, 0.84, 0.99)";
|
|
2827
|
+
}
|
|
2828
|
+
const scale = Math.max(1 - depth * 0.04, 0.86);
|
|
2829
|
+
this.element.style.scale = scale === 1 ? "" : String(scale);
|
|
2830
|
+
}
|
|
2373
2831
|
attach() {
|
|
2374
2832
|
this.gesture = new GestureController({
|
|
2375
2833
|
handle: this.handle,
|
|
@@ -2429,7 +2887,7 @@ var BottomSheetEngine = class {
|
|
|
2429
2887
|
container: this.scrollContainer,
|
|
2430
2888
|
isDragging: () => this.gesture?.isDragging ?? false,
|
|
2431
2889
|
isAnimating: () => this.animation.isAnimating,
|
|
2432
|
-
getAllowedIds: () => this.
|
|
2890
|
+
getAllowedIds: () => this.allowedIdsBySize(),
|
|
2433
2891
|
getActiveId: () => this.activeId,
|
|
2434
2892
|
snapTo: (id) => {
|
|
2435
2893
|
void this.snapTo(id);
|
|
@@ -2458,11 +2916,13 @@ var BottomSheetEngine = class {
|
|
|
2458
2916
|
},
|
|
2459
2917
|
newCycle: () => {
|
|
2460
2918
|
this.newCycle();
|
|
2461
|
-
}
|
|
2919
|
+
},
|
|
2920
|
+
isAnimating: () => this.animation.isAnimating,
|
|
2921
|
+
resyncAfterCancel: () => this.resyncAfterResize()
|
|
2462
2922
|
}));
|
|
2463
2923
|
if (this.lifecycle.closeOnEscape) {
|
|
2464
2924
|
const onKey = (e) => {
|
|
2465
|
-
if (this.destroyed) return;
|
|
2925
|
+
if (this.destroyed || e.defaultPrevented) return;
|
|
2466
2926
|
if (e.key === "Escape" && this.isTopSheet && this.size > 0) {
|
|
2467
2927
|
void this.close();
|
|
2468
2928
|
}
|
|
@@ -2494,7 +2954,7 @@ var BottomSheetEngine = class {
|
|
|
2494
2954
|
handle: this.handle,
|
|
2495
2955
|
mode: this.mode,
|
|
2496
2956
|
isDestroyed: () => this.destroyed,
|
|
2497
|
-
getAllowedIds: () => this.
|
|
2957
|
+
getAllowedIds: () => this.allowedIdsBySize(),
|
|
2498
2958
|
getActiveId: () => this.activeId,
|
|
2499
2959
|
snapTo: (id) => {
|
|
2500
2960
|
void this.snapTo(id);
|
|
@@ -2515,6 +2975,7 @@ var BottomSheetEngine = class {
|
|
|
2515
2975
|
});
|
|
2516
2976
|
if (!target) return;
|
|
2517
2977
|
const previousId = this.activeId;
|
|
2978
|
+
if (target.id === previousId && target.size === this.size) return;
|
|
2518
2979
|
if (this.emitBeforeSnap(target, previousId)) {
|
|
2519
2980
|
const restore = this.snaps.findById(previousId);
|
|
2520
2981
|
if (restore) {
|
|
@@ -2523,6 +2984,7 @@ var BottomSheetEngine = class {
|
|
|
2523
2984
|
return;
|
|
2524
2985
|
}
|
|
2525
2986
|
const previousSize = this.size;
|
|
2987
|
+
const previousSnapSize = this.snaps.findById(previousId)?.size;
|
|
2526
2988
|
this.scrollCache.cache(previousId, previousSize, target.size);
|
|
2527
2989
|
this.activeId = target.id;
|
|
2528
2990
|
void this.animation.animateTo(target.size, velocity).then(() => {
|
|
@@ -2531,9 +2993,10 @@ var BottomSheetEngine = class {
|
|
|
2531
2993
|
this.updateAriaSlider();
|
|
2532
2994
|
this.emit("snap", { id: target.id, size: target.size });
|
|
2533
2995
|
this.haptic();
|
|
2534
|
-
if (
|
|
2996
|
+
if (previousSnapSize === 0 && target.size > 0) {
|
|
2535
2997
|
this.emit("open", { id: target.id });
|
|
2536
2998
|
this.handleOpen();
|
|
2999
|
+
notifyLinkedSheets(this.linkedSheets, this);
|
|
2537
3000
|
}
|
|
2538
3001
|
if (target.size === 0) {
|
|
2539
3002
|
this.emit("close", void 0);
|
|
@@ -2559,6 +3022,9 @@ var BottomSheetEngine = class {
|
|
|
2559
3022
|
if (this.scrimParent) {
|
|
2560
3023
|
this.scrimParent.style.setProperty("--bs-size", `${size}px`);
|
|
2561
3024
|
}
|
|
3025
|
+
if (this.anchorHost && this.anchorHost !== this.scrimParent) {
|
|
3026
|
+
this.anchorHost.style.setProperty("--bs-size", `${size}px`);
|
|
3027
|
+
}
|
|
2562
3028
|
}
|
|
2563
3029
|
const progress = this.computeProgress(size);
|
|
2564
3030
|
const progressChanged = this.progressWriteSentinel.shouldWrite(
|
|
@@ -2567,6 +3033,9 @@ var BottomSheetEngine = class {
|
|
|
2567
3033
|
);
|
|
2568
3034
|
if (progressChanged) {
|
|
2569
3035
|
style.setProperty("--bs-progress", String(progress));
|
|
3036
|
+
if (this.anchorHost) {
|
|
3037
|
+
this.anchorHost.style.setProperty("--bs-progress", String(progress));
|
|
3038
|
+
}
|
|
2570
3039
|
}
|
|
2571
3040
|
this.scrim.applyOpacity(progress, progressChanged);
|
|
2572
3041
|
if (progressChanged && this.bus.listenerCount("progress") > 0) {
|
|
@@ -2581,6 +3050,7 @@ var BottomSheetEngine = class {
|
|
|
2581
3050
|
return Math.min(Math.max((size - min) / (max - min), 0), 1);
|
|
2582
3051
|
}
|
|
2583
3052
|
handleOpen() {
|
|
3053
|
+
sheetStack.promote(this.id);
|
|
2584
3054
|
try {
|
|
2585
3055
|
this.lifecycle.install();
|
|
2586
3056
|
} catch (err) {
|
|
@@ -2594,8 +3064,24 @@ var BottomSheetEngine = class {
|
|
|
2594
3064
|
});
|
|
2595
3065
|
}
|
|
2596
3066
|
}
|
|
3067
|
+
resyncAfterResize() {
|
|
3068
|
+
if (this.destroyed) return;
|
|
3069
|
+
const target = this.snaps.findById(this.activeId);
|
|
3070
|
+
if (!target) return;
|
|
3071
|
+
this.updateAriaSlider();
|
|
3072
|
+
this.emit("snap", { id: target.id, size: target.size });
|
|
3073
|
+
if (target.size > 0 && !this.lifecycle.isInstalled) {
|
|
3074
|
+
this.emit("open", { id: target.id });
|
|
3075
|
+
this.handleOpen();
|
|
3076
|
+
notifyLinkedSheets(this.linkedSheets, this);
|
|
3077
|
+
} else if (target.size === 0 && this.lifecycle.isInstalled) {
|
|
3078
|
+
this.emit("close", void 0);
|
|
3079
|
+
this.handleClose();
|
|
3080
|
+
}
|
|
3081
|
+
}
|
|
2597
3082
|
handleClose() {
|
|
2598
3083
|
this.lifecycle.release();
|
|
3084
|
+
sheetStack.update();
|
|
2599
3085
|
}
|
|
2600
3086
|
};
|
|
2601
3087
|
|
|
@@ -2689,6 +3175,16 @@ function useBottomSheet(opts) {
|
|
|
2689
3175
|
engineRef.current?.setAllowed(ids, snap);
|
|
2690
3176
|
}, []);
|
|
2691
3177
|
const getEngine = useCallback(() => engineRef.current, []);
|
|
3178
|
+
const addAnchor = useCallback(
|
|
3179
|
+
(anchorOpts) => engineRef.current?.addAnchor(anchorOpts) ?? (() => {
|
|
3180
|
+
}),
|
|
3181
|
+
[]
|
|
3182
|
+
);
|
|
3183
|
+
const setScrimStages = useCallback(
|
|
3184
|
+
(stagesOpts) => engineRef.current?.setScrimStages(stagesOpts) ?? (() => {
|
|
3185
|
+
}),
|
|
3186
|
+
[]
|
|
3187
|
+
);
|
|
2692
3188
|
return useMemo(
|
|
2693
3189
|
() => ({
|
|
2694
3190
|
sheetRef,
|
|
@@ -2701,10 +3197,12 @@ function useBottomSheet(opts) {
|
|
|
2701
3197
|
open,
|
|
2702
3198
|
close,
|
|
2703
3199
|
setAllowed,
|
|
3200
|
+
addAnchor,
|
|
3201
|
+
setScrimStages,
|
|
2704
3202
|
engine: engineRef.current,
|
|
2705
3203
|
getEngine
|
|
2706
3204
|
}),
|
|
2707
|
-
[state, snapTo, open, close, setAllowed, getEngine]
|
|
3205
|
+
[state, snapTo, open, close, setAllowed, addAnchor, setScrimStages, getEngine]
|
|
2708
3206
|
);
|
|
2709
3207
|
}
|
|
2710
3208
|
var useHasMounted = () => {
|
|
@@ -2724,6 +3222,8 @@ var BottomSheet = forwardRef(
|
|
|
2724
3222
|
leftButton,
|
|
2725
3223
|
rightButton,
|
|
2726
3224
|
screen,
|
|
3225
|
+
anchors,
|
|
3226
|
+
scrimStages,
|
|
2727
3227
|
onChange,
|
|
2728
3228
|
ariaLabel = "Bottom sheet",
|
|
2729
3229
|
ariaLabelledBy,
|
|
@@ -2744,10 +3244,7 @@ var BottomSheet = forwardRef(
|
|
|
2744
3244
|
setAllowed,
|
|
2745
3245
|
getEngine
|
|
2746
3246
|
} = useBottomSheet(engineOpts);
|
|
2747
|
-
const isVerticalAxis = (engineOpts.mode ?? "bottom") === "bottom" || (engineOpts.mode ?? "bottom") === "top";
|
|
2748
3247
|
const ariaModal = engineOpts.focusTrap === true;
|
|
2749
|
-
const allowedIds = engineOpts.allowed ?? engineOpts.snapPoints.map((p) => p.id);
|
|
2750
|
-
const activeIdx = allowedIds.indexOf(state.activeId);
|
|
2751
3248
|
const lastAnnouncedRef = useRef("");
|
|
2752
3249
|
const [announce, setAnnounce] = useState("");
|
|
2753
3250
|
useEffect(() => {
|
|
@@ -2767,6 +3264,10 @@ var BottomSheet = forwardRef(
|
|
|
2767
3264
|
setScrim: (opts) => getEngine()?.setScrim(opts),
|
|
2768
3265
|
setScrimOverlay: (opts) => getEngine()?.setScrimOverlay(opts) ?? (() => {
|
|
2769
3266
|
}),
|
|
3267
|
+
addAnchor: (opts) => getEngine()?.addAnchor(opts) ?? (() => {
|
|
3268
|
+
}),
|
|
3269
|
+
setScrimStages: (opts) => getEngine()?.setScrimStages(opts) ?? (() => {
|
|
3270
|
+
}),
|
|
2770
3271
|
getEngine,
|
|
2771
3272
|
get state() {
|
|
2772
3273
|
return getEngine()?.state ?? state;
|
|
@@ -2777,6 +3278,61 @@ var BottomSheet = forwardRef(
|
|
|
2777
3278
|
useEffect(() => {
|
|
2778
3279
|
onChange?.(state);
|
|
2779
3280
|
}, [state, onChange]);
|
|
3281
|
+
const [anchorHosts, setAnchorHosts] = useState([]);
|
|
3282
|
+
const anchorsKey = anchors ? JSON.stringify(
|
|
3283
|
+
anchors.map((a) => [
|
|
3284
|
+
a.position,
|
|
3285
|
+
a.inset,
|
|
3286
|
+
Array.isArray(a.showOn) ? a.showOn : a.showOn ? "fn" : null,
|
|
3287
|
+
a.fadeRange,
|
|
3288
|
+
a.interactive,
|
|
3289
|
+
typeof a.animation === "string" ? a.animation : a.animation ? "custom" : null
|
|
3290
|
+
])
|
|
3291
|
+
) : "";
|
|
3292
|
+
useEffect(() => {
|
|
3293
|
+
const engine = getEngine();
|
|
3294
|
+
if (!engine || !anchors || anchors.length === 0) return;
|
|
3295
|
+
const hosts = [];
|
|
3296
|
+
const detachers = anchors.map((a) => {
|
|
3297
|
+
const host = document.createElement("div");
|
|
3298
|
+
hosts.push(host);
|
|
3299
|
+
const { node: _node, ...rest } = a;
|
|
3300
|
+
return engine.addAnchor({ ...rest, element: host });
|
|
3301
|
+
});
|
|
3302
|
+
setAnchorHosts(hosts);
|
|
3303
|
+
return () => {
|
|
3304
|
+
detachers.forEach((d) => d());
|
|
3305
|
+
setAnchorHosts([]);
|
|
3306
|
+
};
|
|
3307
|
+
}, [getEngine, anchorsKey]);
|
|
3308
|
+
const [stageHosts, setStageHosts] = useState([]);
|
|
3309
|
+
const stagesKey = scrimStages ? JSON.stringify(
|
|
3310
|
+
scrimStages.stages.map((s) => [
|
|
3311
|
+
s.for,
|
|
3312
|
+
s.forRange,
|
|
3313
|
+
s.position,
|
|
3314
|
+
s.inset,
|
|
3315
|
+
s.interactive,
|
|
3316
|
+
typeof s.animation === "string" ? s.animation : s.animation ? "custom" : null
|
|
3317
|
+
])
|
|
3318
|
+
) : "";
|
|
3319
|
+
useEffect(() => {
|
|
3320
|
+
const engine = getEngine();
|
|
3321
|
+
if (!engine || !scrimStages || scrimStages.stages.length === 0) return;
|
|
3322
|
+
const hosts = [];
|
|
3323
|
+
const defs = scrimStages.stages.map((s) => {
|
|
3324
|
+
const host = document.createElement("div");
|
|
3325
|
+
hosts.push(host);
|
|
3326
|
+
const { node: _node, ...rest } = s;
|
|
3327
|
+
return { ...rest, element: host };
|
|
3328
|
+
});
|
|
3329
|
+
const detach = engine.setScrimStages({ ...scrimStages, stages: defs });
|
|
3330
|
+
setStageHosts(hosts);
|
|
3331
|
+
return () => {
|
|
3332
|
+
detach();
|
|
3333
|
+
setStageHosts([]);
|
|
3334
|
+
};
|
|
3335
|
+
}, [getEngine, stagesKey]);
|
|
2780
3336
|
if (noSSR && !mounted) return null;
|
|
2781
3337
|
return /* @__PURE__ */ jsxs("div", { className: "bs-root", children: [
|
|
2782
3338
|
backdrop && /* @__PURE__ */ jsx(
|
|
@@ -2817,11 +3373,6 @@ var BottomSheet = forwardRef(
|
|
|
2817
3373
|
className: "bs-handle",
|
|
2818
3374
|
role: "slider",
|
|
2819
3375
|
tabIndex: 0,
|
|
2820
|
-
"aria-orientation": isVerticalAxis ? "vertical" : "horizontal",
|
|
2821
|
-
"aria-valuemin": 0,
|
|
2822
|
-
"aria-valuemax": Math.max(0, allowedIds.length - 1),
|
|
2823
|
-
"aria-valuenow": Math.max(0, activeIdx),
|
|
2824
|
-
"aria-valuetext": state.activeId,
|
|
2825
3376
|
"aria-label": "Resize sheet",
|
|
2826
3377
|
children: typeof header === "function" ? header(state) : header
|
|
2827
3378
|
}
|
|
@@ -2840,6 +3391,12 @@ var BottomSheet = forwardRef(
|
|
|
2840
3391
|
/* @__PURE__ */ jsx("span", { className: "bs-sr-only", role: "status", "aria-live": "polite", children: announce })
|
|
2841
3392
|
]
|
|
2842
3393
|
}
|
|
3394
|
+
),
|
|
3395
|
+
anchorHosts.map(
|
|
3396
|
+
(host, i) => anchors?.[i] ? createPortal(anchors[i].node, host) : null
|
|
3397
|
+
),
|
|
3398
|
+
stageHosts.map(
|
|
3399
|
+
(host, i) => scrimStages?.stages[i] ? createPortal(scrimStages.stages[i].node, host) : null
|
|
2843
3400
|
)
|
|
2844
3401
|
] });
|
|
2845
3402
|
}
|
|
@@ -2924,6 +3481,10 @@ var OverlayEngine = class {
|
|
|
2924
3481
|
__publicField(this, "closeOnOutsidePointerEnabled");
|
|
2925
3482
|
__publicField(this, "detachOutsidePointer", null);
|
|
2926
3483
|
__publicField(this, "detachSwipe", null);
|
|
3484
|
+
__publicField(this, "respectReducedMotionEnabled");
|
|
3485
|
+
__publicField(this, "isTop", true);
|
|
3486
|
+
__publicField(this, "backPushed", false);
|
|
3487
|
+
__publicField(this, "movedToTarget", false);
|
|
2927
3488
|
__publicField(this, "onOpenCb");
|
|
2928
3489
|
__publicField(this, "onCloseCb");
|
|
2929
3490
|
__publicField(this, "isOpen_", false);
|
|
@@ -2960,6 +3521,7 @@ var OverlayEngine = class {
|
|
|
2960
3521
|
this.mountTarget = opts.mountTo;
|
|
2961
3522
|
this.peekRaw = opts.peek;
|
|
2962
3523
|
this.closeOnOutsidePointerEnabled = opts.closeOnOutsidePointer ?? false;
|
|
3524
|
+
this.respectReducedMotionEnabled = opts.respectReducedMotion ?? true;
|
|
2963
3525
|
this.onOpenCb = opts.onOpen;
|
|
2964
3526
|
this.onCloseCb = opts.onClose;
|
|
2965
3527
|
if (this.peekRaw !== void 0 && this.edge !== "bottom") {
|
|
@@ -3007,15 +3569,17 @@ var OverlayEngine = class {
|
|
|
3007
3569
|
this.emit("before-open", void 0);
|
|
3008
3570
|
this.isOpen_ = true;
|
|
3009
3571
|
this.isAnimating_ = true;
|
|
3572
|
+
sheetStack.promote(this.id);
|
|
3010
3573
|
this.element.removeAttribute("hidden");
|
|
3011
3574
|
this.element.setAttribute("data-state", "entering");
|
|
3012
3575
|
if (this.focusTrapEnabled) {
|
|
3013
3576
|
this.element.setAttribute("aria-modal", "true");
|
|
3014
3577
|
}
|
|
3015
|
-
const
|
|
3578
|
+
const dur = this.effectiveDuration();
|
|
3579
|
+
const transitionStr = `transform ${dur}ms ${this.enterEasing}, opacity ${dur}ms ease-out`;
|
|
3016
3580
|
this.element.style.transition = transitionStr;
|
|
3017
3581
|
if (this.backdrop) {
|
|
3018
|
-
this.backdrop.style.transition = `opacity ${
|
|
3582
|
+
this.backdrop.style.transition = `opacity ${dur}ms ease-out`;
|
|
3019
3583
|
}
|
|
3020
3584
|
const cycle = ++this.cycleNonce;
|
|
3021
3585
|
return new Promise((resolve) => {
|
|
@@ -3027,7 +3591,7 @@ var OverlayEngine = class {
|
|
|
3027
3591
|
this.element.style.opacity = "1";
|
|
3028
3592
|
if (this.backdrop) {
|
|
3029
3593
|
this.backdrop.style.opacity = String(this.backdropOpacity);
|
|
3030
|
-
this.backdrop.style.pointerEvents = "auto";
|
|
3594
|
+
this.backdrop.style.pointerEvents = this.backdropOpacity > 0 ? "auto" : "none";
|
|
3031
3595
|
if (this.backdropFilter) {
|
|
3032
3596
|
this.backdrop.style.backdropFilter = this.backdropFilter;
|
|
3033
3597
|
this.backdrop.style.webkitBackdropFilter = this.backdropFilter;
|
|
@@ -3063,7 +3627,10 @@ var OverlayEngine = class {
|
|
|
3063
3627
|
});
|
|
3064
3628
|
return resolve();
|
|
3065
3629
|
}
|
|
3066
|
-
this.awaitTransition(
|
|
3630
|
+
this.awaitTransition(
|
|
3631
|
+
cycle,
|
|
3632
|
+
this.enterAnimation === "fade" ? "opacity" : "transform"
|
|
3633
|
+
).then(() => {
|
|
3067
3634
|
if (this.destroyed || cycle !== this.cycleNonce) return resolve();
|
|
3068
3635
|
this.isAnimating_ = false;
|
|
3069
3636
|
this.element.setAttribute("data-state", "open");
|
|
@@ -3080,11 +3647,14 @@ var OverlayEngine = class {
|
|
|
3080
3647
|
this.emit("before-close", void 0);
|
|
3081
3648
|
this.isOpen_ = false;
|
|
3082
3649
|
this.isAnimating_ = true;
|
|
3650
|
+
sheetStack.update();
|
|
3651
|
+
this.popBackMarker(reason);
|
|
3083
3652
|
this.element.setAttribute("data-state", "exiting");
|
|
3084
|
-
const
|
|
3653
|
+
const dur = this.effectiveDuration();
|
|
3654
|
+
const transitionStr = `transform ${dur}ms ${this.exitEasing}, opacity ${dur}ms ease-in`;
|
|
3085
3655
|
this.element.style.transition = transitionStr;
|
|
3086
3656
|
if (this.backdrop) {
|
|
3087
|
-
this.backdrop.style.transition = `opacity ${
|
|
3657
|
+
this.backdrop.style.transition = `opacity ${dur}ms ease-in`;
|
|
3088
3658
|
}
|
|
3089
3659
|
const cycle = ++this.cycleNonce;
|
|
3090
3660
|
return new Promise((resolve) => {
|
|
@@ -3095,7 +3665,7 @@ var OverlayEngine = class {
|
|
|
3095
3665
|
this.exitAnimation,
|
|
3096
3666
|
this.peekPx
|
|
3097
3667
|
);
|
|
3098
|
-
this.element.style.opacity = "0";
|
|
3668
|
+
this.element.style.opacity = this.peekPx !== void 0 ? "1" : "0";
|
|
3099
3669
|
if (this.backdrop) {
|
|
3100
3670
|
this.backdrop.style.opacity = "0";
|
|
3101
3671
|
this.backdrop.style.pointerEvents = "none";
|
|
@@ -3105,7 +3675,10 @@ var OverlayEngine = class {
|
|
|
3105
3675
|
}
|
|
3106
3676
|
}
|
|
3107
3677
|
this.releaseInteractiveListeners();
|
|
3108
|
-
this.awaitTransition(
|
|
3678
|
+
this.awaitTransition(
|
|
3679
|
+
cycle,
|
|
3680
|
+
this.exitAnimation === "fade" ? "opacity" : "transform"
|
|
3681
|
+
).then(() => {
|
|
3109
3682
|
if (this.destroyed || cycle !== this.cycleNonce) return resolve();
|
|
3110
3683
|
this.isAnimating_ = false;
|
|
3111
3684
|
if (this.peekPx === void 0) {
|
|
@@ -3133,7 +3706,11 @@ var OverlayEngine = class {
|
|
|
3133
3706
|
this.releaseInteractiveListeners();
|
|
3134
3707
|
this.releaseStackEntry?.();
|
|
3135
3708
|
this.releaseStackEntry = null;
|
|
3709
|
+
const hadOriginalParent = this.originalParent !== null;
|
|
3136
3710
|
this.restoreMount();
|
|
3711
|
+
if (this.movedToTarget && !hadOriginalParent && this.element.parentNode) {
|
|
3712
|
+
this.element.parentNode.removeChild(this.element);
|
|
3713
|
+
}
|
|
3137
3714
|
}
|
|
3138
3715
|
setBackdropOpacity(opacity) {
|
|
3139
3716
|
if (this.destroyed) return;
|
|
@@ -3234,6 +3811,36 @@ var OverlayEngine = class {
|
|
|
3234
3811
|
}
|
|
3235
3812
|
}
|
|
3236
3813
|
}
|
|
3814
|
+
if (opts.duration !== void 0) this.duration = opts.duration;
|
|
3815
|
+
if (opts.enterEasing !== void 0) this.enterEasing = opts.enterEasing;
|
|
3816
|
+
if (opts.exitEasing !== void 0) this.exitEasing = opts.exitEasing;
|
|
3817
|
+
if (opts.closeOnEscape !== void 0) {
|
|
3818
|
+
this.closeOnEscape = opts.closeOnEscape;
|
|
3819
|
+
if (!opts.closeOnEscape) {
|
|
3820
|
+
this.detachEscape?.();
|
|
3821
|
+
this.detachEscape = null;
|
|
3822
|
+
} else if (this.isOpen_) {
|
|
3823
|
+
this.installInteractiveListeners();
|
|
3824
|
+
}
|
|
3825
|
+
}
|
|
3826
|
+
if (opts.closeOnBackdrop !== void 0) {
|
|
3827
|
+
this.closeOnBackdropEnabled = opts.closeOnBackdrop;
|
|
3828
|
+
if (!opts.closeOnBackdrop) {
|
|
3829
|
+
this.detachBackdrop?.();
|
|
3830
|
+
this.detachBackdrop = null;
|
|
3831
|
+
} else if (this.isOpen_) {
|
|
3832
|
+
this.installInteractiveListeners();
|
|
3833
|
+
}
|
|
3834
|
+
}
|
|
3835
|
+
if (opts.closeOnOutsidePointer !== void 0) {
|
|
3836
|
+
this.closeOnOutsidePointerEnabled = opts.closeOnOutsidePointer;
|
|
3837
|
+
if (!opts.closeOnOutsidePointer) {
|
|
3838
|
+
this.detachOutsidePointer?.();
|
|
3839
|
+
this.detachOutsidePointer = null;
|
|
3840
|
+
} else if (this.isOpen_) {
|
|
3841
|
+
this.installInteractiveListeners();
|
|
3842
|
+
}
|
|
3843
|
+
}
|
|
3237
3844
|
if (opts.children !== void 0) {
|
|
3238
3845
|
if (opts.children === null) {
|
|
3239
3846
|
this.clearOverlayChildren();
|
|
@@ -3267,6 +3874,22 @@ var OverlayEngine = class {
|
|
|
3267
3874
|
emit(event, payload) {
|
|
3268
3875
|
this.bus.emit(event, payload);
|
|
3269
3876
|
}
|
|
3877
|
+
effectiveDuration() {
|
|
3878
|
+
return this.respectReducedMotionEnabled && prefersReducedMotion() ? 0 : this.duration;
|
|
3879
|
+
}
|
|
3880
|
+
popBackMarker(reason) {
|
|
3881
|
+
if (!this.backPushed) return;
|
|
3882
|
+
this.backPushed = false;
|
|
3883
|
+
if (reason === "back") return;
|
|
3884
|
+
const state = history.state;
|
|
3885
|
+
if (state && state.__bsOverlay === this.id) {
|
|
3886
|
+
try {
|
|
3887
|
+
history.back();
|
|
3888
|
+
} catch {
|
|
3889
|
+
return;
|
|
3890
|
+
}
|
|
3891
|
+
}
|
|
3892
|
+
}
|
|
3270
3893
|
resolvePeekPx(raw) {
|
|
3271
3894
|
if (typeof raw === "number") return Math.max(0, raw);
|
|
3272
3895
|
try {
|
|
@@ -3288,6 +3911,7 @@ var OverlayEngine = class {
|
|
|
3288
3911
|
this.originalParent = this.element.parentNode;
|
|
3289
3912
|
this.originalNextSibling = this.element.nextSibling;
|
|
3290
3913
|
target.appendChild(this.element);
|
|
3914
|
+
this.movedToTarget = true;
|
|
3291
3915
|
this.mounted = true;
|
|
3292
3916
|
}
|
|
3293
3917
|
restoreMount() {
|
|
@@ -3321,7 +3945,7 @@ var OverlayEngine = class {
|
|
|
3321
3945
|
this.backdrop.style.willChange = "opacity";
|
|
3322
3946
|
}
|
|
3323
3947
|
}
|
|
3324
|
-
awaitTransition(cycle) {
|
|
3948
|
+
awaitTransition(cycle, property = "transform") {
|
|
3325
3949
|
return new Promise((resolve) => {
|
|
3326
3950
|
let done = false;
|
|
3327
3951
|
const finish = () => {
|
|
@@ -3336,10 +3960,10 @@ var OverlayEngine = class {
|
|
|
3336
3960
|
finish();
|
|
3337
3961
|
return;
|
|
3338
3962
|
}
|
|
3339
|
-
if (e.propertyName ===
|
|
3963
|
+
if (e.target === this.element && e.propertyName === property) finish();
|
|
3340
3964
|
};
|
|
3341
3965
|
this.element.addEventListener("transitionend", onEnd);
|
|
3342
|
-
const timer = window.setTimeout(finish, this.
|
|
3966
|
+
const timer = window.setTimeout(finish, this.effectiveDuration() + 50);
|
|
3343
3967
|
});
|
|
3344
3968
|
}
|
|
3345
3969
|
installInteractiveListeners() {
|
|
@@ -3349,7 +3973,10 @@ var OverlayEngine = class {
|
|
|
3349
3973
|
}
|
|
3350
3974
|
if (this.closeOnEscape && !this.detachEscape) {
|
|
3351
3975
|
const handler = (e) => {
|
|
3352
|
-
if (e.
|
|
3976
|
+
if (e.defaultPrevented) return;
|
|
3977
|
+
if (e.key === "Escape" && this.isOpen_ && this.isTop) {
|
|
3978
|
+
void this.close("escape");
|
|
3979
|
+
}
|
|
3353
3980
|
};
|
|
3354
3981
|
document.addEventListener("keydown", handler);
|
|
3355
3982
|
this.detachEscape = () => document.removeEventListener("keydown", handler);
|
|
@@ -3362,10 +3989,14 @@ var OverlayEngine = class {
|
|
|
3362
3989
|
if (this.closeOnBackEnabled && typeof window !== "undefined" && !this.detachHardwareBack) {
|
|
3363
3990
|
try {
|
|
3364
3991
|
history.pushState({ __bsOverlay: this.id }, "");
|
|
3992
|
+
this.backPushed = true;
|
|
3365
3993
|
} catch {
|
|
3366
3994
|
}
|
|
3367
3995
|
const onPop = () => {
|
|
3368
|
-
if (this.isOpen_
|
|
3996
|
+
if (this.isOpen_ && this.isTop) {
|
|
3997
|
+
this.backPushed = false;
|
|
3998
|
+
void this.close("back");
|
|
3999
|
+
}
|
|
3369
4000
|
};
|
|
3370
4001
|
window.addEventListener("popstate", onPop);
|
|
3371
4002
|
this.detachHardwareBack = () => window.removeEventListener("popstate", onPop);
|
|
@@ -3401,43 +4032,52 @@ var OverlayEngine = class {
|
|
|
3401
4032
|
const edge = this.edge;
|
|
3402
4033
|
const isVertical = edge === "bottom" || edge === "top";
|
|
3403
4034
|
const sign = edge === "bottom" || edge === "right" ? 1 : -1;
|
|
3404
|
-
const
|
|
3405
|
-
const velocityThreshold = this.swipeVelocityThreshold;
|
|
4035
|
+
const SLOP = 8;
|
|
3406
4036
|
let startX = 0;
|
|
3407
4037
|
let startY = 0;
|
|
3408
4038
|
let startT = 0;
|
|
4039
|
+
let tracking = false;
|
|
3409
4040
|
let dragging = false;
|
|
3410
4041
|
let pointerId = null;
|
|
4042
|
+
const previousTouchAction = el.style.touchAction;
|
|
4043
|
+
el.style.touchAction = isVertical ? "pan-x" : "pan-y";
|
|
3411
4044
|
const onDown = (e) => {
|
|
3412
4045
|
if (e.button !== void 0 && e.button !== 0) return;
|
|
3413
4046
|
pointerId = e.pointerId;
|
|
3414
4047
|
startX = e.clientX;
|
|
3415
4048
|
startY = e.clientY;
|
|
3416
4049
|
startT = performance.now();
|
|
3417
|
-
|
|
3418
|
-
|
|
3419
|
-
try {
|
|
3420
|
-
el.setPointerCapture(e.pointerId);
|
|
3421
|
-
} catch {
|
|
3422
|
-
}
|
|
4050
|
+
tracking = true;
|
|
4051
|
+
dragging = false;
|
|
3423
4052
|
};
|
|
3424
4053
|
const onMove = (e) => {
|
|
3425
|
-
if (!
|
|
4054
|
+
if (!tracking || e.pointerId !== pointerId) return;
|
|
3426
4055
|
const delta = isVertical ? e.clientY - startY : e.clientX - startX;
|
|
4056
|
+
if (!dragging) {
|
|
4057
|
+
if (Math.abs(delta) < SLOP) return;
|
|
4058
|
+
dragging = true;
|
|
4059
|
+
el.style.transition = "none";
|
|
4060
|
+
try {
|
|
4061
|
+
el.setPointerCapture(e.pointerId);
|
|
4062
|
+
} catch {
|
|
4063
|
+
}
|
|
4064
|
+
}
|
|
3427
4065
|
const offset = Math.max(0, sign * delta);
|
|
3428
4066
|
el.style.transform = isVertical ? `translate3d(0, ${sign * offset}px, 0)` : `translate3d(${sign * offset}px, 0, 0)`;
|
|
3429
4067
|
};
|
|
3430
4068
|
const finish = (e) => {
|
|
3431
|
-
if (!
|
|
3432
|
-
|
|
4069
|
+
if (!tracking || e.pointerId !== pointerId) return;
|
|
4070
|
+
tracking = false;
|
|
3433
4071
|
pointerId = null;
|
|
4072
|
+
if (!dragging) return;
|
|
4073
|
+
dragging = false;
|
|
3434
4074
|
const dt = performance.now() - startT || 1;
|
|
3435
4075
|
const delta = isVertical ? e.clientY - startY : e.clientX - startX;
|
|
3436
4076
|
const offset = Math.max(0, sign * delta);
|
|
3437
4077
|
const velocity = sign * delta / dt;
|
|
3438
4078
|
const size = isVertical ? el.offsetHeight : el.offsetWidth;
|
|
3439
|
-
const past = offset > size *
|
|
3440
|
-
el.style.transition = `transform ${this.
|
|
4079
|
+
const past = offset > size * this.swipeThreshold || velocity > this.swipeVelocityThreshold;
|
|
4080
|
+
el.style.transition = `transform ${this.effectiveDuration()}ms ${this.exitEasing}`;
|
|
3441
4081
|
if (past) {
|
|
3442
4082
|
void this.close("swipe");
|
|
3443
4083
|
} else {
|
|
@@ -3449,6 +4089,7 @@ var OverlayEngine = class {
|
|
|
3449
4089
|
el.addEventListener("pointerup", finish);
|
|
3450
4090
|
el.addEventListener("pointercancel", finish);
|
|
3451
4091
|
return () => {
|
|
4092
|
+
el.style.touchAction = previousTouchAction;
|
|
3452
4093
|
el.removeEventListener("pointerdown", onDown);
|
|
3453
4094
|
el.removeEventListener("pointermove", onMove);
|
|
3454
4095
|
el.removeEventListener("pointerup", finish);
|
|
@@ -3463,10 +4104,12 @@ var OverlayEngine = class {
|
|
|
3463
4104
|
if (this.backdrop) this.backdrop.style.zIndex = String(z - 1);
|
|
3464
4105
|
},
|
|
3465
4106
|
setIsTop: (isTop) => {
|
|
4107
|
+
this.isTop = isTop;
|
|
3466
4108
|
if (this.backdrop) {
|
|
3467
4109
|
this.backdrop.style.display = isTop ? "" : "none";
|
|
3468
4110
|
}
|
|
3469
|
-
}
|
|
4111
|
+
},
|
|
4112
|
+
isOpen: () => this.isOpen_
|
|
3470
4113
|
});
|
|
3471
4114
|
}
|
|
3472
4115
|
};
|
|
@@ -3552,7 +4195,7 @@ var Overlay = forwardRef(function Overlay2(props, ref) {
|
|
|
3552
4195
|
if (openProp === void 0) return;
|
|
3553
4196
|
if (openProp && !state.isOpen) void open();
|
|
3554
4197
|
else if (!openProp && state.isOpen) void close();
|
|
3555
|
-
}, [openProp]);
|
|
4198
|
+
}, [openProp, state.isOpen]);
|
|
3556
4199
|
useEffect(() => {
|
|
3557
4200
|
onChange?.(state);
|
|
3558
4201
|
}, [state, onChange]);
|
|
@@ -3684,46 +4327,34 @@ var BottomSheetFromConfig = forwardRef(function BottomSheetFromConfig2(props, re
|
|
|
3684
4327
|
() => sheetRef.current,
|
|
3685
4328
|
[]
|
|
3686
4329
|
);
|
|
3687
|
-
const
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
const
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
const hs = handlersRef.current;
|
|
3694
|
-
if (evs.onSnap) {
|
|
3695
|
-
const fn = hs[evs.onSnap];
|
|
3696
|
-
if (typeof fn === "function") {
|
|
3697
|
-
fn(next);
|
|
3698
|
-
} else {
|
|
3699
|
-
console.warn(
|
|
3700
|
-
`[BottomSheetFromConfig] eventHandlers["${evs.onSnap}"] is not a function; onSnap is a no-op.`
|
|
3701
|
-
);
|
|
3702
|
-
}
|
|
3703
|
-
}
|
|
3704
|
-
const isClosedNext = next === "" || next === "closed";
|
|
3705
|
-
const isClosedPrev = prev === null || prev === "" || prev === "closed";
|
|
3706
|
-
if (isClosedPrev && !isClosedNext && evs.onOpen) {
|
|
3707
|
-
const fn = hs[evs.onOpen];
|
|
3708
|
-
if (typeof fn === "function") {
|
|
3709
|
-
fn(next);
|
|
3710
|
-
} else {
|
|
3711
|
-
console.warn(
|
|
3712
|
-
`[BottomSheetFromConfig] eventHandlers["${evs.onOpen}"] is not a function; onOpen is a no-op.`
|
|
3713
|
-
);
|
|
3714
|
-
}
|
|
3715
|
-
}
|
|
3716
|
-
if (!isClosedPrev && isClosedNext && evs.onClose) {
|
|
3717
|
-
const fn = hs[evs.onClose];
|
|
3718
|
-
if (typeof fn === "function") {
|
|
4330
|
+
const invoke = (key, arg) => {
|
|
4331
|
+
const evName = eventsRef.current[key];
|
|
4332
|
+
if (!evName) return;
|
|
4333
|
+
const fn = handlersRef.current[evName];
|
|
4334
|
+
if (typeof fn === "function") {
|
|
4335
|
+
if (arg === void 0) {
|
|
3719
4336
|
fn();
|
|
3720
4337
|
} else {
|
|
3721
|
-
|
|
3722
|
-
`[BottomSheetFromConfig] eventHandlers["${evs.onClose}"] is not a function; onClose is a no-op.`
|
|
3723
|
-
);
|
|
4338
|
+
fn(arg);
|
|
3724
4339
|
}
|
|
4340
|
+
} else {
|
|
4341
|
+
console.warn(
|
|
4342
|
+
`[BottomSheetFromConfig] eventHandlers["${evName}"] is not a function; ${key} is a no-op.`
|
|
4343
|
+
);
|
|
3725
4344
|
}
|
|
3726
4345
|
};
|
|
4346
|
+
const invokeRef = useRef(invoke);
|
|
4347
|
+
invokeRef.current = invoke;
|
|
4348
|
+
useEffect(() => {
|
|
4349
|
+
const engine = sheetRef.current?.getEngine();
|
|
4350
|
+
if (!engine) return;
|
|
4351
|
+
const offs = [
|
|
4352
|
+
engine.on("snap", (p) => invokeRef.current("onSnap", p.id)),
|
|
4353
|
+
engine.on("open", (p) => invokeRef.current("onOpen", p.id)),
|
|
4354
|
+
engine.on("close", () => invokeRef.current("onClose"))
|
|
4355
|
+
];
|
|
4356
|
+
return () => offs.forEach((off) => off());
|
|
4357
|
+
}, []);
|
|
3727
4358
|
return /* @__PURE__ */ jsx(
|
|
3728
4359
|
BottomSheet,
|
|
3729
4360
|
{
|
|
@@ -3739,7 +4370,6 @@ var BottomSheetFromConfig = forwardRef(function BottomSheetFromConfig2(props, re
|
|
|
3739
4370
|
closeOnBackdrop: derived.behavior.closeOnBackdrop,
|
|
3740
4371
|
lockBodyScroll: derived.behavior.lockBodyScroll,
|
|
3741
4372
|
rubberBand: derived.behavior.rubberBand,
|
|
3742
|
-
onChange: handleChange,
|
|
3743
4373
|
header: slotContent?.header,
|
|
3744
4374
|
children: slotContent?.body
|
|
3745
4375
|
}
|