@surdeddd/bottom-sheet 0.9.1 → 0.10.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 +108 -66
- package/dist/{BottomSheetEngine-CBRcBwV-.d.ts → BottomSheetEngine-DRjCU73e.d.ts} +6 -5
- package/dist/{BottomSheetEngine-BcyruNP1.d.cts → BottomSheetEngine-DzsIwD28.d.cts} +6 -5
- package/dist/element.cjs +161 -99
- package/dist/element.d.cts +1 -1
- package/dist/element.d.ts +1 -1
- package/dist/element.iife.global.js +2 -2
- package/dist/element.js +161 -99
- package/dist/index.cjs +155 -115
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +155 -115
- 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 +34 -25
- package/dist/overlay.d.cts +3 -0
- package/dist/overlay.d.ts +3 -0
- package/dist/overlay.js +34 -25
- package/dist/preact.d.cts +2 -1
- package/dist/preact.d.ts +2 -1
- package/dist/qwik.cjs +179 -93
- package/dist/qwik.d.cts +11 -2
- package/dist/qwik.d.ts +11 -2
- package/dist/qwik.js +179 -93
- package/dist/react.cjs +266 -181
- package/dist/react.d.cts +26 -4
- package/dist/react.d.ts +26 -4
- package/dist/react.js +266 -181
- package/dist/solid.cjs +145 -92
- package/dist/solid.d.cts +14 -4
- package/dist/solid.d.ts +14 -4
- package/dist/solid.js +145 -92
- package/dist/solid.source.jsx +145 -92
- package/dist/styles.css +17 -1
- package/dist/svelte-core.cjs +128 -90
- package/dist/svelte-core.js +128 -90
- package/dist/svelte-src/BottomSheet.svelte +6 -0
- package/dist/svelte.cjs +130 -90
- package/dist/svelte.d.cts +2 -0
- package/dist/svelte.d.ts +2 -0
- package/dist/svelte.js +130 -90
- package/dist/teleport-7uYNiEAT.d.cts +3 -0
- package/dist/teleport-7uYNiEAT.d.ts +3 -0
- package/dist/vue.cjs +136 -91
- package/dist/vue.d.cts +3 -1
- package/dist/vue.d.ts +3 -1
- package/dist/vue.js +136 -91
- package/package.json +6 -6
package/dist/react.js
CHANGED
|
@@ -191,11 +191,18 @@ var resolveSnap = (point, mode, measureFit) => {
|
|
|
191
191
|
return Math.max(0, el.getBoundingClientRect().width);
|
|
192
192
|
};
|
|
193
193
|
|
|
194
|
+
// src/core/primitives/devWarn.ts
|
|
195
|
+
function devWarn(...args) {
|
|
196
|
+
if (typeof process !== "undefined" && process.env && process.env.NODE_ENV !== "production" && typeof console !== "undefined") {
|
|
197
|
+
console.warn(...args);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
194
201
|
// src/core/primitives/snap-points.ts
|
|
195
202
|
var resolveSnapList = (points, mode, measureFit) => points.map((p) => {
|
|
196
203
|
const raw = resolveSnap(p.size, mode, measureFit);
|
|
197
204
|
if (!Number.isFinite(raw) || raw < 0) {
|
|
198
|
-
|
|
205
|
+
devWarn(
|
|
199
206
|
`[BottomSheet] snap "${p.id}" resolved to invalid size (${String(p.size)} \u2192 ${raw}); clamped to 0.`
|
|
200
207
|
);
|
|
201
208
|
return { id: p.id, size: 0 };
|
|
@@ -207,7 +214,7 @@ var auditVhUsage = (points) => {
|
|
|
207
214
|
for (const p of points) {
|
|
208
215
|
if (typeof p.size !== "string") continue;
|
|
209
216
|
if (!VH_NOT_DVH.test(p.size)) continue;
|
|
210
|
-
|
|
217
|
+
devWarn(
|
|
211
218
|
`[BottomSheet] snap "${p.id}" uses "vh" \u2014 prefer "dvh" on mobile (iOS Safari URL bar makes vh unstable). See https://web.dev/blog/viewport-units`
|
|
212
219
|
);
|
|
213
220
|
}
|
|
@@ -261,6 +268,26 @@ var findDragSettleTarget = (input) => {
|
|
|
261
268
|
);
|
|
262
269
|
};
|
|
263
270
|
|
|
271
|
+
// src/core/primitives/cancelable-emit.ts
|
|
272
|
+
function emitCancelable(emit, base, warnLabel) {
|
|
273
|
+
let cancelled = false;
|
|
274
|
+
let frozen = false;
|
|
275
|
+
emit({
|
|
276
|
+
...base,
|
|
277
|
+
cancel: () => {
|
|
278
|
+
if (frozen) {
|
|
279
|
+
devWarn(
|
|
280
|
+
`[BottomSheet] ${warnLabel}.cancel() called asynchronously \u2014 ignored. cancel() must be invoked synchronously inside the listener.`
|
|
281
|
+
);
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
cancelled = true;
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
frozen = true;
|
|
288
|
+
return cancelled;
|
|
289
|
+
}
|
|
290
|
+
|
|
264
291
|
// src/core/primitives/snap-resolver.ts
|
|
265
292
|
var SnapResolver = class {
|
|
266
293
|
constructor(raw, allowed, mode, measureFit, onMaxAxisSizeChange) {
|
|
@@ -405,7 +432,9 @@ function notifyLinkedSheets(sheets, self) {
|
|
|
405
432
|
try {
|
|
406
433
|
if (linked.state.size === 0) continue;
|
|
407
434
|
const ids = linked.getAllowedIds();
|
|
408
|
-
const
|
|
435
|
+
const resolved = linked.getResolvedSnaps();
|
|
436
|
+
const sizeOf = (id) => resolved.find((s) => s.id === id)?.size ?? 0;
|
|
437
|
+
const target = ids.find((id) => sizeOf(id) > 0);
|
|
409
438
|
if (target && target !== linked.state.activeId) {
|
|
410
439
|
void linked.snapTo(target);
|
|
411
440
|
}
|
|
@@ -622,11 +651,15 @@ function installVisualViewport(deps) {
|
|
|
622
651
|
if (clamp < deps.getMaxAxisSize()) {
|
|
623
652
|
deps.setMaxAxisSize(clamp);
|
|
624
653
|
}
|
|
654
|
+
const wasAnimating = deps.isAnimating?.() ?? false;
|
|
655
|
+
deps.cancelInFlight();
|
|
656
|
+
deps.newCycle();
|
|
625
657
|
const max = deps.getMaxAxisSize();
|
|
626
658
|
deps.setSize(Math.min(deps.getSize(), max));
|
|
627
659
|
const current = deps.resolveActiveSnap();
|
|
628
660
|
if (current && !deps.isDragging()) {
|
|
629
661
|
deps.applySize(Math.min(current.size, max));
|
|
662
|
+
if (wasAnimating) deps.resyncAfterCancel?.();
|
|
630
663
|
} else {
|
|
631
664
|
deps.applySize(deps.getSize());
|
|
632
665
|
}
|
|
@@ -767,6 +800,54 @@ function installFitObserver(deps) {
|
|
|
767
800
|
};
|
|
768
801
|
}
|
|
769
802
|
|
|
803
|
+
// src/core/features/max-height-controller.ts
|
|
804
|
+
function createMaxHeightController(deps) {
|
|
805
|
+
let maxHeightCap;
|
|
806
|
+
let maxHeightRaw;
|
|
807
|
+
const resolveCap = () => {
|
|
808
|
+
const raw = maxHeightRaw;
|
|
809
|
+
if (raw === void 0) {
|
|
810
|
+
maxHeightCap = void 0;
|
|
811
|
+
return;
|
|
812
|
+
}
|
|
813
|
+
if (typeof raw === "number") {
|
|
814
|
+
maxHeightCap = raw;
|
|
815
|
+
return;
|
|
816
|
+
}
|
|
817
|
+
if (typeof window === "undefined") return;
|
|
818
|
+
const measured = resolveSnap(raw, deps.mode);
|
|
819
|
+
maxHeightCap = measured > 0 ? measured : void 0;
|
|
820
|
+
};
|
|
821
|
+
const clampTo = () => {
|
|
822
|
+
if (maxHeightCap === void 0) return;
|
|
823
|
+
if (deps.getMaxAxisSize() > maxHeightCap) {
|
|
824
|
+
deps.setMaxAxisSize(maxHeightCap);
|
|
825
|
+
}
|
|
826
|
+
};
|
|
827
|
+
return {
|
|
828
|
+
setRadius(r) {
|
|
829
|
+
deps.element.style.setProperty(
|
|
830
|
+
"--bs-radius",
|
|
831
|
+
typeof r === "number" ? `${r}px` : r
|
|
832
|
+
);
|
|
833
|
+
},
|
|
834
|
+
setMaxHeight(h) {
|
|
835
|
+
const value = typeof h === "number" ? `${h}px` : h;
|
|
836
|
+
const axis = layoutAxis(deps.mode);
|
|
837
|
+
deps.element.style.setProperty(
|
|
838
|
+
axis === "height" ? "max-height" : "max-width",
|
|
839
|
+
value
|
|
840
|
+
);
|
|
841
|
+
maxHeightRaw = h;
|
|
842
|
+
resolveCap();
|
|
843
|
+
deps.recompute();
|
|
844
|
+
},
|
|
845
|
+
resolveCap,
|
|
846
|
+
clampTo,
|
|
847
|
+
getCap: () => maxHeightCap
|
|
848
|
+
};
|
|
849
|
+
}
|
|
850
|
+
|
|
770
851
|
// src/core/features/fit-measurement.ts
|
|
771
852
|
var measureSheetNatural = (element, content, vertical) => {
|
|
772
853
|
if (!content) {
|
|
@@ -898,13 +979,6 @@ var WriteSentinel = class {
|
|
|
898
979
|
}
|
|
899
980
|
};
|
|
900
981
|
|
|
901
|
-
// src/core/primitives/devWarn.ts
|
|
902
|
-
function devWarn(...args) {
|
|
903
|
-
if (typeof process !== "undefined" && process.env && process.env.NODE_ENV !== "production" && typeof console !== "undefined") {
|
|
904
|
-
console.warn(...args);
|
|
905
|
-
}
|
|
906
|
-
}
|
|
907
|
-
|
|
908
982
|
// src/core/primitives/overlay-position.ts
|
|
909
983
|
function resolveSheetAnchoredStyle(mode, position, inset) {
|
|
910
984
|
const sizeOffset = `calc(var(--bs-size, 0px) + ${inset})`;
|
|
@@ -2550,8 +2624,7 @@ var BottomSheetEngine = class {
|
|
|
2550
2624
|
__publicField(this, "disableCloseFlag");
|
|
2551
2625
|
__publicField(this, "disableDragFlag");
|
|
2552
2626
|
__publicField(this, "closeOnRouteChange");
|
|
2553
|
-
__publicField(this, "
|
|
2554
|
-
__publicField(this, "maxHeightRaw");
|
|
2627
|
+
__publicField(this, "maxHeight");
|
|
2555
2628
|
__publicField(this, "snapPointsRaw");
|
|
2556
2629
|
__publicField(this, "snaps");
|
|
2557
2630
|
__publicField(this, "activeId");
|
|
@@ -2662,11 +2735,20 @@ var BottomSheetEngine = class {
|
|
|
2662
2735
|
auditVhUsage(this.snapPointsRaw);
|
|
2663
2736
|
this.auditDuplicateSnapIds(this.snapPointsRaw);
|
|
2664
2737
|
this.rootEl = this.element.closest(".bs-root");
|
|
2738
|
+
this.maxHeight = createMaxHeightController({
|
|
2739
|
+
element: this.element,
|
|
2740
|
+
mode: this.mode,
|
|
2741
|
+
getMaxAxisSize: () => this.snaps.getMaxAxisSize(),
|
|
2742
|
+
setMaxAxisSize: (size) => {
|
|
2743
|
+
this.snaps.setMaxAxisSize(size);
|
|
2744
|
+
},
|
|
2745
|
+
recompute: () => this.recompute()
|
|
2746
|
+
});
|
|
2665
2747
|
this.fitDeps = {
|
|
2666
2748
|
element: this.element,
|
|
2667
2749
|
scrollContainer: this.scrollContainer,
|
|
2668
2750
|
mode: this.mode,
|
|
2669
|
-
getMaxHeightCap: () => this.
|
|
2751
|
+
getMaxHeightCap: () => this.maxHeight.getCap()
|
|
2670
2752
|
};
|
|
2671
2753
|
this.snaps = new SnapResolver(
|
|
2672
2754
|
this.snapPointsRaw,
|
|
@@ -2777,7 +2859,7 @@ var BottomSheetEngine = class {
|
|
|
2777
2859
|
}
|
|
2778
2860
|
use(plugin) {
|
|
2779
2861
|
if (this.destroyed) {
|
|
2780
|
-
|
|
2862
|
+
devWarn(
|
|
2781
2863
|
`[BottomSheet] use("${plugin.name}") called on destroyed engine \u2014 ignored.`
|
|
2782
2864
|
);
|
|
2783
2865
|
return this;
|
|
@@ -2819,6 +2901,9 @@ var BottomSheetEngine = class {
|
|
|
2819
2901
|
getAllowedIds() {
|
|
2820
2902
|
return this.snaps.getAllowedIds().slice();
|
|
2821
2903
|
}
|
|
2904
|
+
getResolvedSnaps() {
|
|
2905
|
+
return this.snaps.getResolvedSnaps();
|
|
2906
|
+
}
|
|
2822
2907
|
async snapTo(id, velocityOrOpts = 0, _skipBeforeSnap = false) {
|
|
2823
2908
|
if (this.destroyed) return;
|
|
2824
2909
|
const opts = typeof velocityOrOpts === "object" ? velocityOrOpts : { velocity: velocityOrOpts };
|
|
@@ -2827,11 +2912,11 @@ var BottomSheetEngine = class {
|
|
|
2827
2912
|
if (externalSignal?.aborted) return;
|
|
2828
2913
|
const target = this.snaps.findById(id);
|
|
2829
2914
|
if (!target) {
|
|
2830
|
-
|
|
2915
|
+
devWarn(`[BottomSheet] unknown snap id: ${id}`);
|
|
2831
2916
|
return;
|
|
2832
2917
|
}
|
|
2833
2918
|
if (!this.snaps.getAllowedIds().includes(id)) {
|
|
2834
|
-
|
|
2919
|
+
devWarn(`[BottomSheet] snap "${id}" is not in allowed list`);
|
|
2835
2920
|
return;
|
|
2836
2921
|
}
|
|
2837
2922
|
if (!_skipBeforeSnap && this.emitBeforeSnap(target, this.activeId)) {
|
|
@@ -2963,42 +3048,11 @@ var BottomSheetEngine = class {
|
|
|
2963
3048
|
}
|
|
2964
3049
|
setRadius(r) {
|
|
2965
3050
|
if (this.destroyed) return;
|
|
2966
|
-
this.
|
|
2967
|
-
"--bs-radius",
|
|
2968
|
-
typeof r === "number" ? `${r}px` : r
|
|
2969
|
-
);
|
|
3051
|
+
this.maxHeight.setRadius(r);
|
|
2970
3052
|
}
|
|
2971
3053
|
setMaxHeight(h) {
|
|
2972
3054
|
if (this.destroyed) return;
|
|
2973
|
-
|
|
2974
|
-
const axis = layoutAxis(this.mode);
|
|
2975
|
-
this.element.style.setProperty(
|
|
2976
|
-
axis === "height" ? "max-height" : "max-width",
|
|
2977
|
-
value
|
|
2978
|
-
);
|
|
2979
|
-
this.maxHeightRaw = h;
|
|
2980
|
-
this.resolveMaxHeightCap();
|
|
2981
|
-
this.recompute();
|
|
2982
|
-
}
|
|
2983
|
-
resolveMaxHeightCap() {
|
|
2984
|
-
const raw = this.maxHeightRaw;
|
|
2985
|
-
if (raw === void 0) {
|
|
2986
|
-
this.maxHeightCap = void 0;
|
|
2987
|
-
return;
|
|
2988
|
-
}
|
|
2989
|
-
if (typeof raw === "number") {
|
|
2990
|
-
this.maxHeightCap = raw;
|
|
2991
|
-
return;
|
|
2992
|
-
}
|
|
2993
|
-
if (typeof window === "undefined") return;
|
|
2994
|
-
const measured = resolveSnap(raw, this.mode);
|
|
2995
|
-
this.maxHeightCap = measured > 0 ? measured : void 0;
|
|
2996
|
-
}
|
|
2997
|
-
clampToMaxHeight() {
|
|
2998
|
-
if (this.maxHeightCap === void 0) return;
|
|
2999
|
-
if (this.snaps.getMaxAxisSize() > this.maxHeightCap) {
|
|
3000
|
-
this.snaps.setMaxAxisSize(this.maxHeightCap);
|
|
3001
|
-
}
|
|
3055
|
+
this.maxHeight.setMaxHeight(h);
|
|
3002
3056
|
}
|
|
3003
3057
|
setAllowed(ids, snap) {
|
|
3004
3058
|
if (this.destroyed) return;
|
|
@@ -3086,7 +3140,7 @@ var BottomSheetEngine = class {
|
|
|
3086
3140
|
};
|
|
3087
3141
|
const host = this.screenComponent?.parentElement;
|
|
3088
3142
|
if (!host) {
|
|
3089
|
-
|
|
3143
|
+
devWarn(
|
|
3090
3144
|
"[BottomSheet] setScrimStages: no scrim element mounted \u2014 pass `scrim` to the engine first."
|
|
3091
3145
|
);
|
|
3092
3146
|
return () => {
|
|
@@ -3136,9 +3190,9 @@ var BottomSheetEngine = class {
|
|
|
3136
3190
|
}
|
|
3137
3191
|
recompute() {
|
|
3138
3192
|
if (this.destroyed) return;
|
|
3139
|
-
this.
|
|
3193
|
+
this.maxHeight.resolveCap();
|
|
3140
3194
|
this.snaps.recompute();
|
|
3141
|
-
this.
|
|
3195
|
+
this.maxHeight.clampTo();
|
|
3142
3196
|
this.scrim.invalidateOpacityCache();
|
|
3143
3197
|
if (this.gesture?.isDragging) return;
|
|
3144
3198
|
const current = this.snaps.findById(this.activeId);
|
|
@@ -3188,42 +3242,18 @@ var BottomSheetEngine = class {
|
|
|
3188
3242
|
return this.currentAbort.signal;
|
|
3189
3243
|
}
|
|
3190
3244
|
emitBeforeSnap(target, previousId) {
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
previousId,
|
|
3197
|
-
cancel: () => {
|
|
3198
|
-
if (frozen) {
|
|
3199
|
-
console.warn(
|
|
3200
|
-
"[BottomSheet] before-snap.cancel() called asynchronously \u2014 ignored. cancel() must be invoked synchronously inside the listener."
|
|
3201
|
-
);
|
|
3202
|
-
return;
|
|
3203
|
-
}
|
|
3204
|
-
cancelled = true;
|
|
3205
|
-
}
|
|
3206
|
-
});
|
|
3207
|
-
frozen = true;
|
|
3208
|
-
return cancelled;
|
|
3245
|
+
return emitCancelable(
|
|
3246
|
+
(payload) => this.emit("before-snap", payload),
|
|
3247
|
+
{ id: target.id, size: target.size, previousId },
|
|
3248
|
+
"before-snap"
|
|
3249
|
+
);
|
|
3209
3250
|
}
|
|
3210
3251
|
emitBeforeClose(reason) {
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
if (frozen) {
|
|
3217
|
-
console.warn(
|
|
3218
|
-
"[BottomSheet] before-close.cancel() called asynchronously \u2014 ignored. cancel() must be invoked synchronously inside the listener."
|
|
3219
|
-
);
|
|
3220
|
-
return;
|
|
3221
|
-
}
|
|
3222
|
-
cancelled = true;
|
|
3223
|
-
}
|
|
3224
|
-
});
|
|
3225
|
-
frozen = true;
|
|
3226
|
-
return cancelled;
|
|
3252
|
+
return emitCancelable(
|
|
3253
|
+
(payload) => this.emit("before-close", payload),
|
|
3254
|
+
{ reason },
|
|
3255
|
+
"before-close"
|
|
3256
|
+
);
|
|
3227
3257
|
}
|
|
3228
3258
|
applyAutoAriaLabelledBy() {
|
|
3229
3259
|
if (typeof document === "undefined") return;
|
|
@@ -3238,16 +3268,16 @@ var BottomSheetEngine = class {
|
|
|
3238
3268
|
this.element.setAttribute("aria-labelledby", titled.id);
|
|
3239
3269
|
}
|
|
3240
3270
|
recomputeSnaps() {
|
|
3241
|
-
this.
|
|
3271
|
+
this.maxHeight.resolveCap();
|
|
3242
3272
|
this.snaps.setRaw(this.snapPointsRaw);
|
|
3243
|
-
this.
|
|
3273
|
+
this.maxHeight.clampTo();
|
|
3244
3274
|
this.scrim.invalidateOpacityCache();
|
|
3245
3275
|
}
|
|
3246
3276
|
auditDuplicateSnapIds(points) {
|
|
3247
3277
|
const seen = /* @__PURE__ */ new Set();
|
|
3248
3278
|
for (const p of points) {
|
|
3249
3279
|
if (seen.has(p.id)) {
|
|
3250
|
-
|
|
3280
|
+
devWarn(
|
|
3251
3281
|
`[BottomSheet] duplicate snap id "${p.id}" \u2014 only the first occurrence is reachable.`
|
|
3252
3282
|
);
|
|
3253
3283
|
}
|
|
@@ -3414,7 +3444,15 @@ var BottomSheetEngine = class {
|
|
|
3414
3444
|
setSize: (size) => {
|
|
3415
3445
|
this.size = size;
|
|
3416
3446
|
},
|
|
3417
|
-
applySize: (size) => this.applySize(size)
|
|
3447
|
+
applySize: (size) => this.applySize(size),
|
|
3448
|
+
cancelInFlight: () => {
|
|
3449
|
+
this.animation.cancel();
|
|
3450
|
+
},
|
|
3451
|
+
newCycle: () => {
|
|
3452
|
+
this.newCycle();
|
|
3453
|
+
},
|
|
3454
|
+
isAnimating: () => this.animation.isAnimating,
|
|
3455
|
+
resyncAfterCancel: () => this.resyncAfterResize()
|
|
3418
3456
|
}));
|
|
3419
3457
|
}
|
|
3420
3458
|
this.teardowns.add(installSliderKeyboard({
|
|
@@ -3575,6 +3613,72 @@ var BottomSheetEngine = class {
|
|
|
3575
3613
|
sheetStack.update();
|
|
3576
3614
|
}
|
|
3577
3615
|
};
|
|
3616
|
+
function useEnginePropSync(engineRef, opts) {
|
|
3617
|
+
const optsRef = useRef(opts);
|
|
3618
|
+
optsRef.current = opts;
|
|
3619
|
+
const allowedKey = (opts.allowed ?? opts.snapPoints.map((p) => p.id)).join(
|
|
3620
|
+
"\0"
|
|
3621
|
+
);
|
|
3622
|
+
const defKey = opts.snapPoints.map((p) => `${p.id}${String(p.size)}`).join("\0");
|
|
3623
|
+
const defApplied = useRef(false);
|
|
3624
|
+
useEffect(() => {
|
|
3625
|
+
if (!defApplied.current) {
|
|
3626
|
+
defApplied.current = true;
|
|
3627
|
+
return;
|
|
3628
|
+
}
|
|
3629
|
+
const engine = engineRef.current;
|
|
3630
|
+
if (!engine) return;
|
|
3631
|
+
const current = optsRef.current;
|
|
3632
|
+
engine.setSnapPoints(
|
|
3633
|
+
current.snapPoints,
|
|
3634
|
+
current.allowed ? Array.from(current.allowed) : void 0
|
|
3635
|
+
);
|
|
3636
|
+
}, [defKey]);
|
|
3637
|
+
useEffect(() => {
|
|
3638
|
+
if (!engineRef.current) return;
|
|
3639
|
+
const ids = opts.allowed ? Array.from(opts.allowed) : opts.snapPoints.map((p) => p.id);
|
|
3640
|
+
engineRef.current.setAllowed(ids);
|
|
3641
|
+
}, [allowedKey]);
|
|
3642
|
+
useEffect(() => {
|
|
3643
|
+
if (!engineRef.current) return;
|
|
3644
|
+
if (opts.backdropColor !== void 0) {
|
|
3645
|
+
engineRef.current.setScrimColor(opts.backdropColor);
|
|
3646
|
+
}
|
|
3647
|
+
}, [opts.backdropColor]);
|
|
3648
|
+
useEffect(() => {
|
|
3649
|
+
if (!engineRef.current) return;
|
|
3650
|
+
if (opts.backdropOpacity !== void 0) {
|
|
3651
|
+
engineRef.current.setBackdropRange([0, opts.backdropOpacity]);
|
|
3652
|
+
}
|
|
3653
|
+
}, [opts.backdropOpacity]);
|
|
3654
|
+
useEffect(() => {
|
|
3655
|
+
if (!engineRef.current) return;
|
|
3656
|
+
if (opts.radius !== void 0) {
|
|
3657
|
+
engineRef.current.setRadius(opts.radius);
|
|
3658
|
+
}
|
|
3659
|
+
}, [opts.radius]);
|
|
3660
|
+
useEffect(() => {
|
|
3661
|
+
if (!engineRef.current) return;
|
|
3662
|
+
if (opts.maxHeight !== void 0) {
|
|
3663
|
+
engineRef.current.setMaxHeight(opts.maxHeight);
|
|
3664
|
+
}
|
|
3665
|
+
}, [opts.maxHeight]);
|
|
3666
|
+
useEffect(() => {
|
|
3667
|
+
if (opts.persistent !== void 0) {
|
|
3668
|
+
engineRef.current?.setPersistent(opts.persistent);
|
|
3669
|
+
}
|
|
3670
|
+
}, [opts.persistent]);
|
|
3671
|
+
useEffect(() => {
|
|
3672
|
+
if (opts.disableClose !== void 0) {
|
|
3673
|
+
engineRef.current?.setDisableClose(opts.disableClose);
|
|
3674
|
+
}
|
|
3675
|
+
}, [opts.disableClose]);
|
|
3676
|
+
useEffect(() => {
|
|
3677
|
+
if (opts.disableDrag !== void 0) {
|
|
3678
|
+
engineRef.current?.setDisableDrag(opts.disableDrag);
|
|
3679
|
+
}
|
|
3680
|
+
}, [opts.disableDrag]);
|
|
3681
|
+
}
|
|
3578
3682
|
|
|
3579
3683
|
// src/core/features/teleport.ts
|
|
3580
3684
|
var resolveTeleportTarget = (target) => {
|
|
@@ -3669,6 +3773,12 @@ function useBottomSheet(opts) {
|
|
|
3669
3773
|
engine.on("before-close", (payload) => {
|
|
3670
3774
|
optsRef.current.onBeforeClose?.(payload);
|
|
3671
3775
|
}),
|
|
3776
|
+
engine.on("open", (payload) => {
|
|
3777
|
+
optsRef.current.onOpen?.(payload.id);
|
|
3778
|
+
}),
|
|
3779
|
+
engine.on("close", () => {
|
|
3780
|
+
optsRef.current.onClose?.();
|
|
3781
|
+
}),
|
|
3672
3782
|
engine.on("opened", (payload) => {
|
|
3673
3783
|
optsRef.current.onOpened?.(payload.id);
|
|
3674
3784
|
}),
|
|
@@ -3684,6 +3794,20 @@ function useBottomSheet(opts) {
|
|
|
3684
3794
|
optsRef.current.onDragEnd?.(payload);
|
|
3685
3795
|
})
|
|
3686
3796
|
];
|
|
3797
|
+
if (optsRef.current.onDrag) {
|
|
3798
|
+
offs.push(
|
|
3799
|
+
engine.on("drag", (payload) => {
|
|
3800
|
+
optsRef.current.onDrag?.(payload);
|
|
3801
|
+
})
|
|
3802
|
+
);
|
|
3803
|
+
}
|
|
3804
|
+
if (optsRef.current.onProgress) {
|
|
3805
|
+
offs.push(
|
|
3806
|
+
engine.on("progress", (payload) => {
|
|
3807
|
+
optsRef.current.onProgress?.(payload);
|
|
3808
|
+
})
|
|
3809
|
+
);
|
|
3810
|
+
}
|
|
3687
3811
|
return () => {
|
|
3688
3812
|
offs.forEach((off) => off());
|
|
3689
3813
|
restoreTeleport?.();
|
|
@@ -3693,68 +3817,17 @@ function useBottomSheet(opts) {
|
|
|
3693
3817
|
setMounted((n) => n + 1);
|
|
3694
3818
|
};
|
|
3695
3819
|
}, []);
|
|
3696
|
-
|
|
3697
|
-
|
|
3698
|
-
|
|
3699
|
-
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
|
|
3705
|
-
|
|
3706
|
-
|
|
3707
|
-
if (!engine) return;
|
|
3708
|
-
const current = optsRef.current;
|
|
3709
|
-
engine.setSnapPoints(
|
|
3710
|
-
current.snapPoints,
|
|
3711
|
-
current.allowed ? Array.from(current.allowed) : void 0
|
|
3712
|
-
);
|
|
3713
|
-
}, [defKey]);
|
|
3714
|
-
useEffect(() => {
|
|
3715
|
-
if (!engineRef.current) return;
|
|
3716
|
-
const ids = opts.allowed ? Array.from(opts.allowed) : opts.snapPoints.map((p) => p.id);
|
|
3717
|
-
engineRef.current.setAllowed(ids);
|
|
3718
|
-
}, [allowedKey]);
|
|
3719
|
-
useEffect(() => {
|
|
3720
|
-
if (!engineRef.current) return;
|
|
3721
|
-
if (opts.backdropColor !== void 0) {
|
|
3722
|
-
engineRef.current.setScrimColor(opts.backdropColor);
|
|
3723
|
-
}
|
|
3724
|
-
}, [opts.backdropColor]);
|
|
3725
|
-
useEffect(() => {
|
|
3726
|
-
if (!engineRef.current) return;
|
|
3727
|
-
if (opts.backdropOpacity !== void 0) {
|
|
3728
|
-
engineRef.current.setBackdropRange([0, opts.backdropOpacity]);
|
|
3729
|
-
}
|
|
3730
|
-
}, [opts.backdropOpacity]);
|
|
3731
|
-
useEffect(() => {
|
|
3732
|
-
if (!engineRef.current) return;
|
|
3733
|
-
if (opts.radius !== void 0) {
|
|
3734
|
-
engineRef.current.setRadius(opts.radius);
|
|
3735
|
-
}
|
|
3736
|
-
}, [opts.radius]);
|
|
3737
|
-
useEffect(() => {
|
|
3738
|
-
if (!engineRef.current) return;
|
|
3739
|
-
if (opts.maxHeight !== void 0) {
|
|
3740
|
-
engineRef.current.setMaxHeight(opts.maxHeight);
|
|
3741
|
-
}
|
|
3742
|
-
}, [opts.maxHeight]);
|
|
3743
|
-
useEffect(() => {
|
|
3744
|
-
if (opts.persistent !== void 0) {
|
|
3745
|
-
engineRef.current?.setPersistent(opts.persistent);
|
|
3746
|
-
}
|
|
3747
|
-
}, [opts.persistent]);
|
|
3748
|
-
useEffect(() => {
|
|
3749
|
-
if (opts.disableClose !== void 0) {
|
|
3750
|
-
engineRef.current?.setDisableClose(opts.disableClose);
|
|
3751
|
-
}
|
|
3752
|
-
}, [opts.disableClose]);
|
|
3753
|
-
useEffect(() => {
|
|
3754
|
-
if (opts.disableDrag !== void 0) {
|
|
3755
|
-
engineRef.current?.setDisableDrag(opts.disableDrag);
|
|
3756
|
-
}
|
|
3757
|
-
}, [opts.disableDrag]);
|
|
3820
|
+
useEnginePropSync(engineRef, {
|
|
3821
|
+
snapPoints: opts.snapPoints,
|
|
3822
|
+
allowed: opts.allowed,
|
|
3823
|
+
backdropColor: opts.backdropColor,
|
|
3824
|
+
backdropOpacity: opts.backdropOpacity,
|
|
3825
|
+
radius: opts.radius,
|
|
3826
|
+
maxHeight: opts.maxHeight,
|
|
3827
|
+
persistent: opts.persistent,
|
|
3828
|
+
disableClose: opts.disableClose,
|
|
3829
|
+
disableDrag: opts.disableDrag
|
|
3830
|
+
});
|
|
3758
3831
|
const subscribe = useCallback((fn) => {
|
|
3759
3832
|
subscribersRef.current.add(fn);
|
|
3760
3833
|
return () => subscribersRef.current.delete(fn);
|
|
@@ -3863,10 +3936,14 @@ var BottomSheet = forwardRef(
|
|
|
3863
3936
|
scrimStages,
|
|
3864
3937
|
onChange,
|
|
3865
3938
|
onBeforeClose,
|
|
3939
|
+
onOpen,
|
|
3940
|
+
onClose,
|
|
3866
3941
|
onOpened,
|
|
3867
3942
|
onClosed,
|
|
3868
3943
|
onDragStart,
|
|
3869
3944
|
onDragEnd,
|
|
3945
|
+
onDrag,
|
|
3946
|
+
onProgress,
|
|
3870
3947
|
ariaLabel = "Bottom sheet",
|
|
3871
3948
|
ariaLabelledBy,
|
|
3872
3949
|
noSSR = false,
|
|
@@ -3892,10 +3969,14 @@ var BottomSheet = forwardRef(
|
|
|
3892
3969
|
} = useBottomSheet({
|
|
3893
3970
|
...engineOpts,
|
|
3894
3971
|
onBeforeClose,
|
|
3972
|
+
onOpen,
|
|
3973
|
+
onClose,
|
|
3895
3974
|
onOpened,
|
|
3896
3975
|
onClosed,
|
|
3897
3976
|
onDragStart,
|
|
3898
|
-
onDragEnd
|
|
3977
|
+
onDragEnd,
|
|
3978
|
+
onDrag,
|
|
3979
|
+
onProgress
|
|
3899
3980
|
});
|
|
3900
3981
|
const ariaModal = engineOpts.focusTrap === true;
|
|
3901
3982
|
const lastAnnouncedRef = useRef("");
|
|
@@ -4179,7 +4260,7 @@ function installOverlaySwipe(deps) {
|
|
|
4179
4260
|
};
|
|
4180
4261
|
}
|
|
4181
4262
|
|
|
4182
|
-
// src/core/overlay.ts
|
|
4263
|
+
// src/core/overlay-options.ts
|
|
4183
4264
|
var OVERLAY_PRESETS = Object.freeze({
|
|
4184
4265
|
sheet: Object.freeze({
|
|
4185
4266
|
enterAnimation: "slide",
|
|
@@ -4210,6 +4291,8 @@ var OVERLAY_PRESETS = Object.freeze({
|
|
|
4210
4291
|
swipeToClose: false
|
|
4211
4292
|
})
|
|
4212
4293
|
});
|
|
4294
|
+
|
|
4295
|
+
// src/core/overlay.ts
|
|
4213
4296
|
var OverlayEngine = class {
|
|
4214
4297
|
constructor(opts) {
|
|
4215
4298
|
__publicField(this, "id", nextInstanceId("ovl"));
|
|
@@ -4286,7 +4369,7 @@ var OverlayEngine = class {
|
|
|
4286
4369
|
this.onOpenCb = opts.onOpen;
|
|
4287
4370
|
this.onCloseCb = opts.onClose;
|
|
4288
4371
|
if (this.peekRaw !== void 0 && this.edge !== "bottom") {
|
|
4289
|
-
|
|
4372
|
+
devWarn(
|
|
4290
4373
|
"[OverlayEngine] `peek` is only supported on edge: 'bottom' \u2014 ignoring."
|
|
4291
4374
|
);
|
|
4292
4375
|
this.peekRaw = void 0;
|
|
@@ -4353,10 +4436,9 @@ var OverlayEngine = class {
|
|
|
4353
4436
|
this.element.style.opacity = "1";
|
|
4354
4437
|
if (this.backdrop) {
|
|
4355
4438
|
this.backdrop.style.opacity = String(this.backdropOpacity);
|
|
4356
|
-
this.
|
|
4439
|
+
this.syncBackdropPointerEvents();
|
|
4357
4440
|
if (this.backdropFilter) {
|
|
4358
|
-
this.
|
|
4359
|
-
this.backdrop.style.webkitBackdropFilter = this.backdropFilter;
|
|
4441
|
+
this.applyBackdropFilter(this.backdropFilter);
|
|
4360
4442
|
}
|
|
4361
4443
|
}
|
|
4362
4444
|
try {
|
|
@@ -4376,8 +4458,7 @@ var OverlayEngine = class {
|
|
|
4376
4458
|
this.backdrop.style.opacity = "0";
|
|
4377
4459
|
this.backdrop.style.pointerEvents = "none";
|
|
4378
4460
|
if (this.backdropFilter) {
|
|
4379
|
-
this.
|
|
4380
|
-
this.backdrop.style.webkitBackdropFilter = "";
|
|
4461
|
+
this.applyBackdropFilter(void 0);
|
|
4381
4462
|
}
|
|
4382
4463
|
}
|
|
4383
4464
|
this.element.setAttribute("data-state", "closed");
|
|
@@ -4435,8 +4516,7 @@ var OverlayEngine = class {
|
|
|
4435
4516
|
this.backdrop.style.opacity = "0";
|
|
4436
4517
|
this.backdrop.style.pointerEvents = "none";
|
|
4437
4518
|
if (this.backdropFilter) {
|
|
4438
|
-
this.
|
|
4439
|
-
this.backdrop.style.webkitBackdropFilter = "";
|
|
4519
|
+
this.applyBackdropFilter(void 0);
|
|
4440
4520
|
}
|
|
4441
4521
|
}
|
|
4442
4522
|
this.releaseInteractiveListeners();
|
|
@@ -4484,20 +4564,14 @@ var OverlayEngine = class {
|
|
|
4484
4564
|
this.backdropOpacity = opacity;
|
|
4485
4565
|
if (this.isOpen_ && this.backdrop) {
|
|
4486
4566
|
this.backdrop.style.opacity = String(opacity);
|
|
4567
|
+
this.syncBackdropPointerEvents();
|
|
4487
4568
|
}
|
|
4488
4569
|
}
|
|
4489
4570
|
setBackdropFilter(filter) {
|
|
4490
4571
|
if (this.destroyed) return;
|
|
4491
4572
|
this.backdropFilter = filter;
|
|
4492
4573
|
if (!this.isOpen_ || !this.backdrop) return;
|
|
4493
|
-
|
|
4494
|
-
if (filter) {
|
|
4495
|
-
this.backdrop.style.backdropFilter = filter;
|
|
4496
|
-
style.webkitBackdropFilter = filter;
|
|
4497
|
-
} else {
|
|
4498
|
-
this.backdrop.style.backdropFilter = "";
|
|
4499
|
-
style.webkitBackdropFilter = "";
|
|
4500
|
-
}
|
|
4574
|
+
this.applyBackdropFilter(filter);
|
|
4501
4575
|
}
|
|
4502
4576
|
setSwipeToClose(config) {
|
|
4503
4577
|
if (this.destroyed) return;
|
|
@@ -4566,16 +4640,10 @@ var OverlayEngine = class {
|
|
|
4566
4640
|
if (this.isOpen_ && this.backdrop) {
|
|
4567
4641
|
if (merged.backdropOpacity !== void 0) {
|
|
4568
4642
|
this.backdrop.style.opacity = String(this.backdropOpacity);
|
|
4643
|
+
this.syncBackdropPointerEvents();
|
|
4569
4644
|
}
|
|
4570
4645
|
if (merged.backdropFilter !== void 0) {
|
|
4571
|
-
|
|
4572
|
-
if (this.backdropFilter) {
|
|
4573
|
-
this.backdrop.style.backdropFilter = this.backdropFilter;
|
|
4574
|
-
style.webkitBackdropFilter = this.backdropFilter;
|
|
4575
|
-
} else {
|
|
4576
|
-
this.backdrop.style.backdropFilter = "";
|
|
4577
|
-
style.webkitBackdropFilter = "";
|
|
4578
|
-
}
|
|
4646
|
+
this.applyBackdropFilter(this.backdropFilter);
|
|
4579
4647
|
}
|
|
4580
4648
|
}
|
|
4581
4649
|
if (opts.duration !== void 0) this.duration = opts.duration;
|
|
@@ -4710,6 +4778,21 @@ var OverlayEngine = class {
|
|
|
4710
4778
|
this.backdrop.style.pointerEvents = "none";
|
|
4711
4779
|
}
|
|
4712
4780
|
}
|
|
4781
|
+
syncBackdropPointerEvents() {
|
|
4782
|
+
if (!this.backdrop) return;
|
|
4783
|
+
this.backdrop.style.pointerEvents = this.backdropOpacity > 0 ? "auto" : "none";
|
|
4784
|
+
}
|
|
4785
|
+
applyBackdropFilter(filter) {
|
|
4786
|
+
if (!this.backdrop) return;
|
|
4787
|
+
const style = this.backdrop.style;
|
|
4788
|
+
if (filter) {
|
|
4789
|
+
this.backdrop.style.backdropFilter = filter;
|
|
4790
|
+
style.webkitBackdropFilter = filter;
|
|
4791
|
+
} else {
|
|
4792
|
+
this.backdrop.style.backdropFilter = "";
|
|
4793
|
+
style.webkitBackdropFilter = "";
|
|
4794
|
+
}
|
|
4795
|
+
}
|
|
4713
4796
|
setWillChange(on) {
|
|
4714
4797
|
this.element.style.willChange = on ? "transform, opacity" : "";
|
|
4715
4798
|
if (this.backdrop) {
|
|
@@ -4942,6 +5025,8 @@ var Overlay = forwardRef(function Overlay2(props, ref) {
|
|
|
4942
5025
|
)
|
|
4943
5026
|
] });
|
|
4944
5027
|
});
|
|
5028
|
+
|
|
5029
|
+
// src/react/config-validation.ts
|
|
4945
5030
|
var SUPPORTED_VERSION = 1;
|
|
4946
5031
|
var TOP_LEVEL_KEYS = /* @__PURE__ */ new Set([
|
|
4947
5032
|
"version",
|
|
@@ -4966,7 +5051,7 @@ var warnUnknownKeys = (obj, allowed, context) => {
|
|
|
4966
5051
|
if (!obj || typeof obj !== "object") return;
|
|
4967
5052
|
const unknown = Object.keys(obj).filter((k) => !allowed.has(k));
|
|
4968
5053
|
if (unknown.length === 0) return;
|
|
4969
|
-
|
|
5054
|
+
devWarn(
|
|
4970
5055
|
`[BottomSheetFromConfig] Unknown ${unknown.length === 1 ? "key" : "keys"} in ${context}: ${unknown.map((k) => `"${k}"`).join(", ")}. Allowed: ${[...allowed].join(", ")}. Likely a typo \u2014 values ignored.`
|
|
4971
5056
|
);
|
|
4972
5057
|
};
|
|
@@ -4976,7 +5061,7 @@ function validateConfig(config) {
|
|
|
4976
5061
|
validatedConfigs.add(config);
|
|
4977
5062
|
let ok = true;
|
|
4978
5063
|
if (config.version !== SUPPORTED_VERSION) {
|
|
4979
|
-
|
|
5064
|
+
devWarn(
|
|
4980
5065
|
`[BottomSheetFromConfig] Unsupported config version ${String(
|
|
4981
5066
|
config.version
|
|
4982
5067
|
)}; expected ${SUPPORTED_VERSION}. Falling back to defaults.`
|
|
@@ -4984,7 +5069,7 @@ function validateConfig(config) {
|
|
|
4984
5069
|
return false;
|
|
4985
5070
|
}
|
|
4986
5071
|
if (!Array.isArray(config.snapPoints) || config.snapPoints.length === 0) {
|
|
4987
|
-
|
|
5072
|
+
devWarn(
|
|
4988
5073
|
"[BottomSheetFromConfig] config.snapPoints is missing or empty; using a single full-height fallback snap."
|
|
4989
5074
|
);
|
|
4990
5075
|
ok = false;
|