@surdeddd/bottom-sheet 0.1.0 → 0.2.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 +6 -0
- package/dist/BottomSheetEngine-CIT9Htti.d.cts +219 -0
- package/dist/BottomSheetEngine-Df9MwBbm.d.ts +219 -0
- package/dist/element.cjs +95 -440
- package/dist/element.d.cts +3 -56
- package/dist/element.d.ts +3 -56
- package/dist/element.iife.global.js +2 -2
- package/dist/element.js +95 -440
- package/dist/index.cjs +84 -494
- package/dist/index.d.cts +3 -84
- package/dist/index.d.ts +3 -84
- package/dist/index.js +84 -494
- package/dist/integrations/formik.d.cts +2 -8
- package/dist/integrations/formik.d.ts +2 -8
- package/dist/integrations/react-hook-form.d.cts +2 -11
- package/dist/integrations/react-hook-form.d.ts +2 -11
- package/dist/overlay.cjs +0 -87
- package/dist/overlay.d.cts +1 -137
- package/dist/overlay.d.ts +1 -137
- package/dist/overlay.js +0 -87
- package/dist/preact.d.cts +2 -2
- package/dist/preact.d.ts +2 -2
- package/dist/preact.js +0 -1
- package/dist/qwik.cjs +87 -439
- package/dist/qwik.d.cts +3 -24
- package/dist/qwik.d.ts +3 -24
- package/dist/qwik.js +87 -439
- package/dist/react.cjs +91 -496
- package/dist/react.d.cts +16 -158
- package/dist/react.d.ts +16 -158
- package/dist/react.js +91 -496
- package/dist/solid.cjs +87 -439
- package/dist/solid.d.cts +4 -31
- package/dist/solid.d.ts +4 -31
- package/dist/solid.js +87 -439
- package/dist/styles.css +27 -102
- package/dist/svelte.cjs +139 -462
- package/dist/svelte.d.ts +9 -2
- package/dist/svelte.js +139 -462
- package/dist/themes/ios.css +0 -3
- package/dist/themes/material.css +0 -3
- package/dist/themes/vercel.css +0 -3
- package/dist/{transform-Brkf-wzo.d.cts → transform-jVfAikE9.d.cts} +0 -1
- package/dist/{transform-Brkf-wzo.d.ts → transform-jVfAikE9.d.ts} +0 -1
- package/dist/vue.cjs +104 -446
- package/dist/vue.d.ts +7 -1
- package/dist/vue.js +105 -447
- package/package.json +3 -3
- package/dist/BottomSheetEngine-CvSVbo6c.d.cts +0 -704
- package/dist/BottomSheetEngine-DbO8rW_3.d.ts +0 -704
package/dist/vue.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ref, reactive, onMounted, onBeforeUnmount, openBlock, createElementBlock, createCommentVNode,
|
|
1
|
+
import { ref, reactive, onMounted, onBeforeUnmount, openBlock, createElementBlock, createCommentVNode, createElementVNode, renderSlot, normalizeClass, toDisplayString, defineComponent, watch, computed, readonly } from 'vue';
|
|
2
2
|
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
4
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
@@ -230,11 +230,6 @@ var SnapResolver = class {
|
|
|
230
230
|
this.allowedIds = allowed ?? raw.map((p) => p.id);
|
|
231
231
|
this.recompute();
|
|
232
232
|
}
|
|
233
|
-
/**
|
|
234
|
-
* Re-resolve raw → resolved against the current viewport / fit-measure,
|
|
235
|
-
* recompute maxAxisSize, invalidate range cache, notify engine. Called on
|
|
236
|
-
* resize, orientationchange, visualViewport changes, and snap-list swaps.
|
|
237
|
-
*/
|
|
238
233
|
recompute() {
|
|
239
234
|
this.resolved = resolveSnapList(this.raw, this.mode, this.measureFit);
|
|
240
235
|
this.maxAxisSize = this.resolved.reduce(
|
|
@@ -244,15 +239,10 @@ var SnapResolver = class {
|
|
|
244
239
|
this.rangeCache = null;
|
|
245
240
|
this.onMaxAxisSizeChange?.(this.maxAxisSize);
|
|
246
241
|
}
|
|
247
|
-
/** Replace the raw snap list and recompute. Engine calls on `setSnapPoints`. */
|
|
248
242
|
setRaw(raw) {
|
|
249
243
|
this.raw = raw;
|
|
250
244
|
this.recompute();
|
|
251
245
|
}
|
|
252
|
-
/**
|
|
253
|
-
* Replace the allow-list. Range cache depends on `(resolvedSnaps ×
|
|
254
|
-
* allowedIds)` so flipping ids alone invalidates without a full recompute.
|
|
255
|
-
*/
|
|
256
246
|
setAllowedIds(ids) {
|
|
257
247
|
this.allowedIds = ids;
|
|
258
248
|
this.rangeCache = null;
|
|
@@ -260,11 +250,6 @@ var SnapResolver = class {
|
|
|
260
250
|
findById(id) {
|
|
261
251
|
return findById(id, this.resolved);
|
|
262
252
|
}
|
|
263
|
-
/**
|
|
264
|
-
* Pure drag-settle target resolution. Engine passes the gesture-specific
|
|
265
|
-
* fields (delta, velocity, pointerKind, flickVelocity, dragThreshold) plus
|
|
266
|
-
* `size`/`activeId` since those are still engine-owned.
|
|
267
|
-
*/
|
|
268
253
|
findDragSettleTarget(args) {
|
|
269
254
|
return findDragSettleTarget({
|
|
270
255
|
...args,
|
|
@@ -273,18 +258,9 @@ var SnapResolver = class {
|
|
|
273
258
|
maxAxisSize: this.maxAxisSize
|
|
274
259
|
});
|
|
275
260
|
}
|
|
276
|
-
/**
|
|
277
|
-
* Memoised allowed-range query. Twice-per-drag-frame (gesture onMove +
|
|
278
|
-
* applySize→computeProgress); cache collapses 2× iteration of resolvedSnaps
|
|
279
|
-
* to one recompute per geometry/allow-list change.
|
|
280
|
-
*/
|
|
281
261
|
getAllowedRange() {
|
|
282
262
|
return this.rangeCache ?? (this.rangeCache = allowedRange(this.resolved, this.allowedIds));
|
|
283
263
|
}
|
|
284
|
-
/**
|
|
285
|
-
* Read-only view of resolved snaps. Returned as `readonly` to discourage
|
|
286
|
-
* accidental mutation by feature install sites that close over this list.
|
|
287
|
-
*/
|
|
288
264
|
getResolvedSnaps() {
|
|
289
265
|
return this.resolved;
|
|
290
266
|
}
|
|
@@ -294,18 +270,6 @@ var SnapResolver = class {
|
|
|
294
270
|
getMaxAxisSize() {
|
|
295
271
|
return this.maxAxisSize;
|
|
296
272
|
}
|
|
297
|
-
/**
|
|
298
|
-
* External clamp override. The resize-observer feature compares
|
|
299
|
-
* `getMaxAxisSize()` against the live viewport and shrinks if the largest
|
|
300
|
-
* resolved snap exceeds it (mobile address-bar collapse / soft-keyboard
|
|
301
|
-
* window resize). The next `recompute()` overwrites this clamp from the
|
|
302
|
-
* resolved-snap reduction.
|
|
303
|
-
*
|
|
304
|
-
* Does NOT invalidate the range cache — viewport clamping doesn't change
|
|
305
|
-
* `(resolvedSnaps × allowedIds) → range`. DOES fire `onMaxAxisSizeChange`
|
|
306
|
-
* so the resolver owns the layout-axis style write end-to-end (symmetric
|
|
307
|
-
* with `recompute()` — feature call sites no longer duplicate the write).
|
|
308
|
-
*/
|
|
309
273
|
setMaxAxisSize(n) {
|
|
310
274
|
this.maxAxisSize = n;
|
|
311
275
|
this.onMaxAxisSizeChange?.(n);
|
|
@@ -680,73 +644,49 @@ var WriteSentinel = class {
|
|
|
680
644
|
constructor() {
|
|
681
645
|
__publicField(this, "last", -1);
|
|
682
646
|
}
|
|
683
|
-
/**
|
|
684
|
-
* Returns `true` (and updates the cached value) if `next` differs from the
|
|
685
|
-
* cached `last` by more than `epsilon`. Returns `false` (and leaves the
|
|
686
|
-
* cache untouched) when the delta is within epsilon — caller skips the
|
|
687
|
-
* CSSOM write.
|
|
688
|
-
*/
|
|
689
647
|
shouldWrite(next, epsilon) {
|
|
690
648
|
if (Math.abs(next - this.last) <= epsilon) return false;
|
|
691
649
|
this.last = next;
|
|
692
650
|
return true;
|
|
693
651
|
}
|
|
694
|
-
/**
|
|
695
|
-
* Force the next `shouldWrite` to pass. Resets the cache to `-1` so any
|
|
696
|
-
* non-negative `next` exceeds the epsilon comparison. Called from setters
|
|
697
|
-
* that mutate state under the cache (range/mode/enabled flips that change
|
|
698
|
-
* the progress→opacity mapping but don't move `progress` itself).
|
|
699
|
-
*/
|
|
700
652
|
invalidate() {
|
|
701
653
|
this.last = -1;
|
|
702
654
|
}
|
|
703
|
-
/**
|
|
704
|
-
* Record `value` as the last-written without performing a write. Used
|
|
705
|
-
* when a setter writes a literal value through a different path (e.g.
|
|
706
|
-
* `setScrimMode("off")` writes `opacity: "0"` inline) and wants future
|
|
707
|
-
* `shouldWrite` calls to short-circuit against that known cached state.
|
|
708
|
-
*/
|
|
709
655
|
setLastWritten(value) {
|
|
710
656
|
this.last = value;
|
|
711
657
|
}
|
|
712
|
-
/** Read-only accessor for diagnostic / dedup-aware peek. */
|
|
713
658
|
get value() {
|
|
714
659
|
return this.last;
|
|
715
660
|
}
|
|
716
661
|
};
|
|
717
662
|
|
|
663
|
+
// src/core/primitives/devWarn.ts
|
|
664
|
+
function devWarn(...args) {
|
|
665
|
+
if (typeof process !== "undefined" && process.env && process.env.NODE_ENV !== "production" && typeof console !== "undefined") {
|
|
666
|
+
console.warn(...args);
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
|
|
718
670
|
// src/core/controllers/scrim-controller.ts
|
|
671
|
+
var VALID_CSS_LENGTH = /^-?\d+(?:\.\d+)?(?:px|em|rem|%)$/;
|
|
719
672
|
var ScrimController = class {
|
|
720
673
|
constructor(deps, opts) {
|
|
721
|
-
// ── DOM refs (mirror engine's; cached for hot path) ─────────────────
|
|
722
674
|
__publicField(this, "screenComponent");
|
|
723
675
|
__publicField(this, "backdrop");
|
|
724
676
|
__publicField(this, "mode");
|
|
725
|
-
// ── Engine callbacks ────────────────────────────────────────────────
|
|
726
677
|
__publicField(this, "isDestroyed");
|
|
727
678
|
__publicField(this, "isTopSheet");
|
|
728
679
|
__publicField(this, "getAllowedIds");
|
|
729
680
|
__publicField(this, "getResolvedSnaps");
|
|
730
681
|
__publicField(this, "snapToFn");
|
|
731
|
-
// ── Mode + state ────────────────────────────────────────────────────
|
|
732
682
|
__publicField(this, "scrimMode");
|
|
733
683
|
__publicField(this, "backdropRange");
|
|
734
684
|
__publicField(this, "screenRange");
|
|
735
|
-
// setScrimEnabled toggle — gated through `scrimEnabled` rather than nuking
|
|
736
|
-
// ranges so re-enable can restore prior values without a remount. Public
|
|
737
|
-
// so tests / introspection can read it without an `as any` cast.
|
|
738
685
|
__publicField(this, "scrimEnabled", true);
|
|
739
686
|
__publicField(this, "savedScrimRanges", null);
|
|
740
|
-
// ── Tap-to-close ────────────────────────────────────────────────────
|
|
741
687
|
__publicField(this, "scrimTapToCloseEnabled", false);
|
|
742
688
|
__publicField(this, "detachScrimTap", null);
|
|
743
|
-
// ── Scrim overlay slot (positioned floating element) ────────────────
|
|
744
689
|
__publicField(this, "scrimOverlayTeardown", null);
|
|
745
|
-
// ── Hot-path opacity dedup caches (per-frame writes) ────────────────
|
|
746
|
-
// Numeric sentinels migrated to WriteSentinel primitive — single
|
|
747
|
-
// invalidation surface, shared with the engine's size/progress sentinels.
|
|
748
|
-
// The two string-typed sentinels (`Pointer`, `Display`) keep their inline
|
|
749
|
-
// pattern: equality on string union, no epsilon, different reset semantics.
|
|
750
690
|
__publicField(this, "backdropOpacitySentinel", new WriteSentinel());
|
|
751
691
|
__publicField(this, "screenOpacitySentinel", new WriteSentinel());
|
|
752
692
|
__publicField(this, "lastBackdropPointer", "");
|
|
@@ -781,41 +721,15 @@ var ScrimController = class {
|
|
|
781
721
|
}
|
|
782
722
|
}
|
|
783
723
|
}
|
|
784
|
-
/**
|
|
785
|
-
* Invalidate the opacity dedup caches. Called from any setter that mutates
|
|
786
|
-
* range/mode/enabled — opacity is a pure function of (progress, range,
|
|
787
|
-
* enabled), so a config change makes the cached values stale even if
|
|
788
|
-
* `progress` itself didn't move. Next `applyOpacity(progress, false)` call
|
|
789
|
-
* sees the -1 sentinel and re-runs the math instead of short-circuiting.
|
|
790
|
-
*
|
|
791
|
-
* Public for the engine: `setSnapPoints` mutates resolved geometry which
|
|
792
|
-
* shifts `progress→opacity` mapping under the cache; engine calls this to
|
|
793
|
-
* keep the next render frame correct on a static sheet.
|
|
794
|
-
* @internal
|
|
795
|
-
*/
|
|
796
724
|
invalidateOpacityCache() {
|
|
797
725
|
this.backdropOpacitySentinel.invalidate();
|
|
798
726
|
this.screenOpacitySentinel.invalidate();
|
|
799
727
|
}
|
|
800
|
-
/** Engine calls this when its `attach()` runs — installs scrim-tap-click if requested. */
|
|
801
728
|
attach() {
|
|
802
729
|
if (this.scrimTapToCloseEnabled) {
|
|
803
730
|
this.setScrimTapToClose(true);
|
|
804
731
|
}
|
|
805
732
|
}
|
|
806
|
-
// ── Hot-path: opacity computation called per-frame from engine.applySize ──
|
|
807
|
-
/**
|
|
808
|
-
* Per-frame opacity writer. Computes backdrop + screen opacity from the
|
|
809
|
-
* sheet's progress (0..1 within allowed range), gated by sub-pixel dedup
|
|
810
|
-
* caches so steady-state frames don't trigger style recalc.
|
|
811
|
-
*
|
|
812
|
-
* `progressChanged` is the engine's already-computed dedup gate — when
|
|
813
|
-
* `false`, opacity is by construction a pure function of `progress` so
|
|
814
|
-
* cached values are still valid; we short-circuit the Math.min/max +
|
|
815
|
-
* division work entirely. Setters that mutate ranges/mode/enabled
|
|
816
|
-
* invalidate the cache by writing -1 sentinels so the next call re-runs
|
|
817
|
-
* the math.
|
|
818
|
-
*/
|
|
819
733
|
applyOpacity(progress, progressChanged) {
|
|
820
734
|
if (!progressChanged && this.backdropOpacitySentinel.value !== -1 && this.screenOpacitySentinel.value !== -1) {
|
|
821
735
|
return;
|
|
@@ -861,80 +775,30 @@ var ScrimController = class {
|
|
|
861
775
|
}
|
|
862
776
|
}
|
|
863
777
|
}
|
|
864
|
-
// ── Public setters (engine forwards these 1:1) ─────────────────────
|
|
865
|
-
/**
|
|
866
|
-
* Replace the [start, end] progress window in which the backdrop fades 0→1.
|
|
867
|
-
* @param range - Tuple of two progress values in 0..1 (start <= end).
|
|
868
|
-
* @param applySize - Engine-supplied recompute hook; runs one applyOpacity pass.
|
|
869
|
-
* @example
|
|
870
|
-
* // Backdrop only starts darkening after the sheet crosses 30% open.
|
|
871
|
-
* engine.setBackdropRange([0.3, 1]);
|
|
872
|
-
*/
|
|
873
778
|
setBackdropRange(range, applySize) {
|
|
874
779
|
if (this.isDestroyed()) return;
|
|
875
780
|
this.backdropRange = range;
|
|
876
781
|
this.invalidateOpacityCache();
|
|
877
782
|
applySize();
|
|
878
783
|
}
|
|
879
|
-
/**
|
|
880
|
-
* Replace the [start, end] progress window in which the screen scrim fades 0→1.
|
|
881
|
-
* @param range - Tuple of two progress values in 0..1 (start <= end).
|
|
882
|
-
* @param applySize - Engine-supplied recompute hook; runs one applyOpacity pass.
|
|
883
|
-
* @example
|
|
884
|
-
* // Scrim is fully opaque only when the sheet is past 50% — softer feel.
|
|
885
|
-
* engine.setScreenRange([0, 0.5]);
|
|
886
|
-
*/
|
|
887
784
|
setScreenRange(range, applySize) {
|
|
888
785
|
if (this.isDestroyed()) return;
|
|
889
786
|
this.screenRange = range;
|
|
890
787
|
this.invalidateOpacityCache();
|
|
891
788
|
applySize();
|
|
892
789
|
}
|
|
893
|
-
/**
|
|
894
|
-
* Set the scrim background color. Pass `null`/`undefined` to clear the
|
|
895
|
-
* inline write and let consumer CSS take over.
|
|
896
|
-
* @param color - Any valid CSS color string, or `null`/`undefined` to clear.
|
|
897
|
-
* @example
|
|
898
|
-
* engine.setScrimColor("rgba(0, 0, 0, 0.6)");
|
|
899
|
-
* engine.setScrimColor(null); // hand back to consumer CSS
|
|
900
|
-
*/
|
|
901
790
|
setScrimColor(color) {
|
|
902
791
|
if (this.isDestroyed()) return;
|
|
903
792
|
this.applyScrimStyles({ color: color === void 0 ? null : color });
|
|
904
793
|
}
|
|
905
|
-
/**
|
|
906
|
-
* Set the scrim backdrop-filter blur radius. Pass `null`/`undefined` to clear.
|
|
907
|
-
* @param blur - CSS length (e.g. `"8px"`) consumed as `blur(<value>)`, or
|
|
908
|
-
* `null`/`undefined` to remove the filter.
|
|
909
|
-
* @example
|
|
910
|
-
* engine.setScrimBlur("12px"); // frosted-glass effect
|
|
911
|
-
* engine.setScrimBlur(null); // disable blur
|
|
912
|
-
*/
|
|
913
794
|
setScrimBlur(blur) {
|
|
914
795
|
if (this.isDestroyed()) return;
|
|
915
796
|
this.applyScrimStyles({ blur: blur === void 0 ? null : blur });
|
|
916
797
|
}
|
|
917
|
-
/**
|
|
918
|
-
* Toggle whether the scrim layer captures pointer events.
|
|
919
|
-
* @param interactive - `true` → `pointer-events: auto`; `false` → `none`.
|
|
920
|
-
* @example
|
|
921
|
-
* engine.setScrimInteractive(true); // scrim swallows clicks
|
|
922
|
-
* engine.setScrimInteractive(false); // clicks pass through to content below
|
|
923
|
-
*/
|
|
924
798
|
setScrimInteractive(interactive) {
|
|
925
799
|
if (this.isDestroyed()) return;
|
|
926
800
|
this.applyScrimStyles({ interactive });
|
|
927
801
|
}
|
|
928
|
-
/**
|
|
929
|
-
* Switch scrim positioning at runtime.
|
|
930
|
-
* @param mode - `"full"` (consumer CSS), `"above-sheet"` (engine-pinned inset
|
|
931
|
-
* so only the area NOT covered by the sheet is dimmed), or
|
|
932
|
-
* `"off"` (display:none + opacity:0 — no remount needed).
|
|
933
|
-
* @param applySize - Engine-supplied recompute hook; runs one applyOpacity pass.
|
|
934
|
-
* @example
|
|
935
|
-
* engine.setScrimMode("above-sheet"); // dim only the area above the sheet
|
|
936
|
-
* engine.setScrimMode("off"); // disable scrim layer
|
|
937
|
-
*/
|
|
938
802
|
setScrimMode(mode, applySize) {
|
|
939
803
|
if (this.isDestroyed()) return;
|
|
940
804
|
if (mode === this.scrimMode) return;
|
|
@@ -964,15 +828,6 @@ var ScrimController = class {
|
|
|
964
828
|
}
|
|
965
829
|
applySize();
|
|
966
830
|
}
|
|
967
|
-
/**
|
|
968
|
-
* Enable or disable click-on-scrim → snap to first non-zero allowed snap.
|
|
969
|
-
* Auto-promotes `pointer-events: auto` when scrim is non-interactive so the
|
|
970
|
-
* click listener actually fires.
|
|
971
|
-
* @param enabled - `true` installs the click listener; `false` removes it.
|
|
972
|
-
* @example
|
|
973
|
-
* engine.setScrimTapToClose(true); // tap outside sheet collapses it
|
|
974
|
-
* engine.setScrimTapToClose(false); // require explicit close button
|
|
975
|
-
*/
|
|
976
831
|
setScrimTapToClose(enabled) {
|
|
977
832
|
if (this.isDestroyed()) return;
|
|
978
833
|
if (!this.screenComponent) return;
|
|
@@ -1002,16 +857,6 @@ var ScrimController = class {
|
|
|
1002
857
|
this.scrimTapToCloseEnabled = false;
|
|
1003
858
|
}
|
|
1004
859
|
}
|
|
1005
|
-
/**
|
|
1006
|
-
* Toggle the scrim layer without remounting. Disabling stashes current
|
|
1007
|
-
* `screenRange`/`backdropRange` and degenerates them to `[1, 1]` (opacity
|
|
1008
|
-
* formula → 0 across the whole range); re-enabling restores the saved values.
|
|
1009
|
-
* @param enabled - `false` hides scrim, `true` restores prior ranges.
|
|
1010
|
-
* @param applySize - Engine-supplied recompute hook; runs one applyOpacity pass.
|
|
1011
|
-
* @example
|
|
1012
|
-
* engine.setScrimEnabled(false); // hide scrim, ranges remembered
|
|
1013
|
-
* engine.setScrimEnabled(true); // restore prior ranges (no remount)
|
|
1014
|
-
*/
|
|
1015
860
|
setScrimEnabled(enabled, applySize) {
|
|
1016
861
|
if (this.isDestroyed()) return;
|
|
1017
862
|
if (enabled === this.scrimEnabled) return;
|
|
@@ -1030,20 +875,6 @@ var ScrimController = class {
|
|
|
1030
875
|
}
|
|
1031
876
|
applySize();
|
|
1032
877
|
}
|
|
1033
|
-
/**
|
|
1034
|
-
* Batch-update multiple scrim fields with a single applySize() at the end.
|
|
1035
|
-
* If `preset` is set, it seeds color/blur/interactive/range first; explicit
|
|
1036
|
-
* fields override.
|
|
1037
|
-
* @param opts - Partial scrim config: preset, mode, enabled, tapToClose,
|
|
1038
|
-
* color, blur, interactive, range.
|
|
1039
|
-
* @param applySize - Engine-supplied recompute hook; runs ONCE per call.
|
|
1040
|
-
* @example
|
|
1041
|
-
* engine.setScrim({
|
|
1042
|
-
* preset: "frosted",
|
|
1043
|
-
* mode: "above-sheet",
|
|
1044
|
-
* tapToClose: true,
|
|
1045
|
-
* });
|
|
1046
|
-
*/
|
|
1047
878
|
setScrim(opts, applySize) {
|
|
1048
879
|
if (this.isDestroyed()) return;
|
|
1049
880
|
if (opts.preset) {
|
|
@@ -1066,27 +897,18 @@ var ScrimController = class {
|
|
|
1066
897
|
interactive: opts.interactive
|
|
1067
898
|
});
|
|
1068
899
|
if (opts.range !== void 0) {
|
|
1069
|
-
this.
|
|
900
|
+
if (!this.scrimEnabled && this.savedScrimRanges) {
|
|
901
|
+
this.savedScrimRanges = {
|
|
902
|
+
screen: opts.range,
|
|
903
|
+
backdrop: this.savedScrimRanges.backdrop
|
|
904
|
+
};
|
|
905
|
+
} else {
|
|
906
|
+
this.screenRange = opts.range;
|
|
907
|
+
}
|
|
1070
908
|
}
|
|
1071
909
|
this.invalidateOpacityCache();
|
|
1072
910
|
applySize();
|
|
1073
911
|
}
|
|
1074
|
-
/**
|
|
1075
|
-
* Inject a positioned floating element into the scrim layer (e.g. a close
|
|
1076
|
-
* button anchored top-right). Replaces any prior overlay so repeated calls
|
|
1077
|
-
* (reactive effects re-running) don't accumulate wrappers.
|
|
1078
|
-
* @param opts - Children element, optional `inset` (default `"16px"`),
|
|
1079
|
-
* `position` (9-way grid, default `"top-right"`), and
|
|
1080
|
-
* `interactive` flag (default `true`).
|
|
1081
|
-
* @returns Teardown function that removes the wrapper from the DOM.
|
|
1082
|
-
* @example
|
|
1083
|
-
* const teardown = engine.setScrimOverlay({
|
|
1084
|
-
* children: closeBtn,
|
|
1085
|
-
* position: "top-right",
|
|
1086
|
-
* inset: "20px",
|
|
1087
|
-
* });
|
|
1088
|
-
* // later: teardown(); // remove the floating button
|
|
1089
|
-
*/
|
|
1090
912
|
setScrimOverlay(opts) {
|
|
1091
913
|
if (this.isDestroyed()) return () => {
|
|
1092
914
|
};
|
|
@@ -1094,7 +916,18 @@ var ScrimController = class {
|
|
|
1094
916
|
};
|
|
1095
917
|
this.scrimOverlayTeardown?.();
|
|
1096
918
|
const screen = this.screenComponent;
|
|
1097
|
-
const
|
|
919
|
+
const insetRaw = opts.inset ?? "16px";
|
|
920
|
+
const inset = VALID_CSS_LENGTH.test(insetRaw) ? insetRaw : "16px";
|
|
921
|
+
if (inset !== insetRaw) {
|
|
922
|
+
devWarn(
|
|
923
|
+
`[bottom-sheet] setScrimOverlay: invalid inset ${JSON.stringify(insetRaw)}; expected a CSS length like "16px" / "1rem" / "5%". Falling back to "16px".`
|
|
924
|
+
);
|
|
925
|
+
}
|
|
926
|
+
if (opts.children.ownerDocument && opts.children.ownerDocument !== screen.ownerDocument) {
|
|
927
|
+
devWarn(
|
|
928
|
+
"[bottom-sheet] setScrimOverlay: children belong to a different document than the scrim. Cross-document adoption can drop event listeners; construct children via the same document as the sheet root."
|
|
929
|
+
);
|
|
930
|
+
}
|
|
1098
931
|
const position = opts.position ?? "top-right";
|
|
1099
932
|
const interactive = opts.interactive ?? true;
|
|
1100
933
|
const wrapper = screen.ownerDocument.createElement("div");
|
|
@@ -1143,12 +976,30 @@ var ScrimController = class {
|
|
|
1143
976
|
ws.bottom = inset;
|
|
1144
977
|
ws.right = inset;
|
|
1145
978
|
break;
|
|
979
|
+
case "sheet-top-left":
|
|
980
|
+
case "sheet-top-center":
|
|
981
|
+
case "sheet-top-right":
|
|
982
|
+
applySheetAnchoredPosition(
|
|
983
|
+
ws,
|
|
984
|
+
this.mode,
|
|
985
|
+
position,
|
|
986
|
+
inset
|
|
987
|
+
);
|
|
988
|
+
break;
|
|
1146
989
|
}
|
|
1147
990
|
if (interactive) {
|
|
1148
991
|
ws.pointerEvents = "auto";
|
|
1149
992
|
}
|
|
1150
993
|
wrapper.appendChild(opts.children);
|
|
1151
|
-
screen.
|
|
994
|
+
const host = screen.parentElement;
|
|
995
|
+
if (!host) {
|
|
996
|
+
devWarn(
|
|
997
|
+
"[bottom-sheet] setScrimOverlay: scrim element has no parent, skipping overlay injection. Mount the sheet root before calling setScrimOverlay."
|
|
998
|
+
);
|
|
999
|
+
return () => {
|
|
1000
|
+
};
|
|
1001
|
+
}
|
|
1002
|
+
host.appendChild(wrapper);
|
|
1152
1003
|
const teardown = () => {
|
|
1153
1004
|
if (wrapper.parentNode) wrapper.parentNode.removeChild(wrapper);
|
|
1154
1005
|
if (this.scrimOverlayTeardown === teardown) {
|
|
@@ -1158,7 +1009,6 @@ var ScrimController = class {
|
|
|
1158
1009
|
this.scrimOverlayTeardown = teardown;
|
|
1159
1010
|
return teardown;
|
|
1160
1011
|
}
|
|
1161
|
-
/** Tear down toggle-state listeners + remove any injected overlay wrapper. */
|
|
1162
1012
|
destroy() {
|
|
1163
1013
|
this.detachScrimTap?.();
|
|
1164
1014
|
this.detachScrimTap = null;
|
|
@@ -1177,8 +1027,6 @@ var ScrimController = class {
|
|
|
1177
1027
|
this.lastBackdropPointer = "";
|
|
1178
1028
|
this.lastScreenDisplay = "";
|
|
1179
1029
|
}
|
|
1180
|
-
// ── Private helpers ────────────────────────────────────────────────
|
|
1181
|
-
/** Centralized scrim style writer — atomic 3-property write across all setters. */
|
|
1182
1030
|
applyScrimStyles(opts) {
|
|
1183
1031
|
if (!this.screenComponent) return;
|
|
1184
1032
|
const s = this.screenComponent.style;
|
|
@@ -1200,7 +1048,6 @@ var ScrimController = class {
|
|
|
1200
1048
|
s.pointerEvents = opts.interactive ? "auto" : "none";
|
|
1201
1049
|
}
|
|
1202
1050
|
}
|
|
1203
|
-
/** Pin the screen overlay to the area NOT occupied by the sheet. */
|
|
1204
1051
|
applyAboveSheetInset() {
|
|
1205
1052
|
if (!this.screenComponent) return;
|
|
1206
1053
|
const insetByMode = {
|
|
@@ -1215,6 +1062,35 @@ var ScrimController = class {
|
|
|
1215
1062
|
s.pointerEvents = "none";
|
|
1216
1063
|
}
|
|
1217
1064
|
};
|
|
1065
|
+
function resolveSheetAnchoredStyle(mode, position, inset) {
|
|
1066
|
+
const sizeOffset = `calc(var(--bs-size, 0px) + ${inset})`;
|
|
1067
|
+
switch (mode) {
|
|
1068
|
+
case "bottom":
|
|
1069
|
+
if (position === "sheet-top-left") return { bottom: sizeOffset, left: inset };
|
|
1070
|
+
if (position === "sheet-top-right") return { bottom: sizeOffset, right: inset };
|
|
1071
|
+
return { bottom: sizeOffset, left: "50%", transform: "translateX(-50%)" };
|
|
1072
|
+
case "top":
|
|
1073
|
+
if (position === "sheet-top-left") return { top: sizeOffset, left: inset };
|
|
1074
|
+
if (position === "sheet-top-right") return { top: sizeOffset, right: inset };
|
|
1075
|
+
return { top: sizeOffset, left: "50%", transform: "translateX(-50%)" };
|
|
1076
|
+
case "left":
|
|
1077
|
+
if (position === "sheet-top-left") return { left: sizeOffset, top: inset };
|
|
1078
|
+
if (position === "sheet-top-right") return { left: sizeOffset, bottom: inset };
|
|
1079
|
+
return { left: sizeOffset, top: "50%", transform: "translateY(-50%)" };
|
|
1080
|
+
case "right":
|
|
1081
|
+
if (position === "sheet-top-left") return { right: sizeOffset, top: inset };
|
|
1082
|
+
if (position === "sheet-top-right") return { right: sizeOffset, bottom: inset };
|
|
1083
|
+
return { right: sizeOffset, top: "50%", transform: "translateY(-50%)" };
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
function applySheetAnchoredPosition(ws, mode, position, inset) {
|
|
1087
|
+
const style = resolveSheetAnchoredStyle(mode, position, inset);
|
|
1088
|
+
if (style.top !== void 0) ws.top = style.top;
|
|
1089
|
+
if (style.bottom !== void 0) ws.bottom = style.bottom;
|
|
1090
|
+
if (style.left !== void 0) ws.left = style.left;
|
|
1091
|
+
if (style.right !== void 0) ws.right = style.right;
|
|
1092
|
+
if (style.transform !== void 0) ws.transform = style.transform;
|
|
1093
|
+
}
|
|
1218
1094
|
|
|
1219
1095
|
// src/core/animation/animation.ts
|
|
1220
1096
|
var easeOutBack = (t) => {
|
|
@@ -1367,13 +1243,9 @@ var AnimationRunner = class {
|
|
|
1367
1243
|
__publicField(this, "duration");
|
|
1368
1244
|
__publicField(this, "easing");
|
|
1369
1245
|
__publicField(this, "respectReducedMotion");
|
|
1370
|
-
/** Live-tracked via mq listener so animateTo skips matchMedia per snap. */
|
|
1371
1246
|
__publicField(this, "reducedMotion", false);
|
|
1372
|
-
/** Disposes the matchMedia change listener — drained from destroy(). */
|
|
1373
1247
|
__publicField(this, "detachReducedMotion", null);
|
|
1374
|
-
/** Computed once — both inputs (option + API presence) stable for life. */
|
|
1375
1248
|
__publicField(this, "viewTransitionsAvailable");
|
|
1376
|
-
/** In-flight handles. Public for tests / debugging only — engine drives via cancel(). */
|
|
1377
1249
|
__publicField(this, "currentTween", null);
|
|
1378
1250
|
__publicField(this, "currentSpring", null);
|
|
1379
1251
|
this.element = deps.element;
|
|
@@ -1404,26 +1276,13 @@ var AnimationRunner = class {
|
|
|
1404
1276
|
}
|
|
1405
1277
|
}
|
|
1406
1278
|
}
|
|
1407
|
-
/**
|
|
1408
|
-
* Live derived flag — `true` whenever a spring/tween handle is in flight.
|
|
1409
|
-
* Reading the canonical handles (instead of mirroring into a separate
|
|
1410
|
-
* boolean) eliminates the reduced-motion early-return latent bug where
|
|
1411
|
-
* the flag stayed true forever, and removes the cross-controller
|
|
1412
|
-
* setIsAnimating callback.
|
|
1413
|
-
*/
|
|
1414
1279
|
get isAnimating() {
|
|
1415
1280
|
return this.currentTween !== null || this.currentSpring !== null;
|
|
1416
1281
|
}
|
|
1417
|
-
/** Cancel any in-flight tween/spring without touching engine state. */
|
|
1418
1282
|
cancel() {
|
|
1419
1283
|
this.currentTween?.cancel();
|
|
1420
1284
|
this.currentSpring?.cancel();
|
|
1421
1285
|
}
|
|
1422
|
-
/**
|
|
1423
|
-
* Animate from current size to `target`. Resolves when the animation
|
|
1424
|
-
* completes; resolves early if cancelled mid-flight (caller checks an
|
|
1425
|
-
* abort signal post-await for cycle-invariant correctness).
|
|
1426
|
-
*/
|
|
1427
1286
|
async animateTo(target, velocityPxPerMs) {
|
|
1428
1287
|
if (target === this.getSize()) return;
|
|
1429
1288
|
this.currentTween?.cancel();
|
|
@@ -1464,7 +1323,6 @@ var AnimationRunner = class {
|
|
|
1464
1323
|
if (!this.isDragging()) this.element.style.willChange = "auto";
|
|
1465
1324
|
}
|
|
1466
1325
|
}
|
|
1467
|
-
/** Tear down the matchMedia listener. Engine calls from destroy(). */
|
|
1468
1326
|
destroy() {
|
|
1469
1327
|
this.detachReducedMotion?.();
|
|
1470
1328
|
this.detachReducedMotion = null;
|
|
@@ -1624,12 +1482,8 @@ var LifecycleController = class {
|
|
|
1624
1482
|
__publicField(this, "inertSiblings");
|
|
1625
1483
|
__publicField(this, "shouldApplyInertSiblings");
|
|
1626
1484
|
__publicField(this, "returnFocus");
|
|
1627
|
-
/** Toggle-state teardowns — fire on close, NOT in destroy-only stack. */
|
|
1628
1485
|
__publicField(this, "releaseFocusTrap", null);
|
|
1629
1486
|
__publicField(this, "releaseScrollLock", null);
|
|
1630
|
-
/** True between install() and release(). Guards release()/destroy() from
|
|
1631
|
-
* re-running side effects (notably `returnFocus.focus()`) on already-
|
|
1632
|
-
* released or never-installed instances. */
|
|
1633
1487
|
__publicField(this, "installed", false);
|
|
1634
1488
|
__publicField(this, "destroyed", false);
|
|
1635
1489
|
this.element = deps.element;
|
|
@@ -1643,14 +1497,6 @@ var LifecycleController = class {
|
|
|
1643
1497
|
this.returnFocus = opts.returnFocus;
|
|
1644
1498
|
this.inertSiblings = createInertSiblings(() => this.element);
|
|
1645
1499
|
}
|
|
1646
|
-
/**
|
|
1647
|
-
* Run the open-time install steps. Idempotent: each step checks its
|
|
1648
|
-
* existing teardown ref so a re-open during a half-cancelled close
|
|
1649
|
-
* doesn't double-install. Sets `installed=true` BEFORE the first side
|
|
1650
|
-
* effect so a partial throw (detached / shadow-DOM target) leaves the
|
|
1651
|
-
* caller's `release()` rollback path armed to undo whatever did succeed.
|
|
1652
|
-
* No-op when destroyed.
|
|
1653
|
-
*/
|
|
1654
1500
|
install() {
|
|
1655
1501
|
if (this.destroyed) return;
|
|
1656
1502
|
this.installed = true;
|
|
@@ -1667,22 +1513,10 @@ var LifecycleController = class {
|
|
|
1667
1513
|
this.inertSiblings.apply();
|
|
1668
1514
|
}
|
|
1669
1515
|
}
|
|
1670
|
-
/**
|
|
1671
|
-
* Update the post-release focus target. Overlay re-binds this when the
|
|
1672
|
-
* consumer changes `returnFocus` after construction; the new value applies
|
|
1673
|
-
* on the next `release()`. No-op when destroyed.
|
|
1674
|
-
*/
|
|
1675
1516
|
setReturnFocus(target) {
|
|
1676
1517
|
if (this.destroyed) return;
|
|
1677
1518
|
this.returnFocus = target;
|
|
1678
1519
|
}
|
|
1679
|
-
/**
|
|
1680
|
-
* Release all install-time teardowns. Short-circuits when not installed,
|
|
1681
|
-
* so `close() → destroy()` (each routing through here) only restores
|
|
1682
|
-
* focus once. The `installed` guard lets `inertSiblings.remove()` and
|
|
1683
|
-
* the focus-trap/scroll-lock teardown nullings stay simple — they were
|
|
1684
|
-
* already idempotent, but `returnFocus.focus()` was firing on every call.
|
|
1685
|
-
*/
|
|
1686
1520
|
release() {
|
|
1687
1521
|
if (!this.installed) return;
|
|
1688
1522
|
this.installed = false;
|
|
@@ -1696,12 +1530,6 @@ var LifecycleController = class {
|
|
|
1696
1530
|
target?.focus?.();
|
|
1697
1531
|
}
|
|
1698
1532
|
}
|
|
1699
|
-
/**
|
|
1700
|
-
* Final teardown — releases any still-installed listeners and seals the
|
|
1701
|
-
* controller. After destroy(), install() is a no-op and setReturnFocus()
|
|
1702
|
-
* is rejected, so post-destroy mutations can't queue up a stale focus
|
|
1703
|
-
* restore.
|
|
1704
|
-
*/
|
|
1705
1533
|
destroy() {
|
|
1706
1534
|
this.release();
|
|
1707
1535
|
this.destroyed = true;
|
|
@@ -1711,12 +1539,10 @@ var LifecycleController = class {
|
|
|
1711
1539
|
// src/core/gestures.ts
|
|
1712
1540
|
var isAxisVertical = (mode) => mode === "bottom" || mode === "top";
|
|
1713
1541
|
var SampleRing = class {
|
|
1714
|
-
// current count, ≤ capacity
|
|
1715
1542
|
constructor(capacity) {
|
|
1716
1543
|
__publicField(this, "slots");
|
|
1717
1544
|
__publicField(this, "capacity");
|
|
1718
1545
|
__publicField(this, "head", 0);
|
|
1719
|
-
// next write index
|
|
1720
1546
|
__publicField(this, "size", 0);
|
|
1721
1547
|
this.capacity = capacity;
|
|
1722
1548
|
this.slots = new Array(capacity);
|
|
@@ -1729,12 +1555,6 @@ var SampleRing = class {
|
|
|
1729
1555
|
this.head = (this.head + 1) % this.capacity;
|
|
1730
1556
|
if (this.size < this.capacity) this.size++;
|
|
1731
1557
|
}
|
|
1732
|
-
/**
|
|
1733
|
-
* Drop oldest entries whose timestamp is below `cutoff`, but never shrink
|
|
1734
|
-
* below `minKeep`. Mirrors the original
|
|
1735
|
-
* `while (samples.length > minKeep && samples[0].t < cutoff) samples.shift()`
|
|
1736
|
-
* but without copying — just advances the logical tail.
|
|
1737
|
-
*/
|
|
1738
1558
|
pruneBefore(cutoff, minKeep) {
|
|
1739
1559
|
while (this.size > minKeep) {
|
|
1740
1560
|
const oldestIdx = (this.head - this.size + this.capacity) % this.capacity;
|
|
@@ -1870,28 +1690,14 @@ var GestureController = class {
|
|
|
1870
1690
|
__publicField(this, "detach", null);
|
|
1871
1691
|
__publicField(this, "isDragging_", false);
|
|
1872
1692
|
__publicField(this, "dragStartSize", 0);
|
|
1873
|
-
// Only "touch" gestures are eligible for soft-keyboard dismissal —
|
|
1874
|
-
// mouse/trackpad users don't have a keyboard to dismiss.
|
|
1875
1693
|
__publicField(this, "currentPointerKind", "touch");
|
|
1876
|
-
// One blur per drag — flipping focus every move event races the keyboard's
|
|
1877
|
-
// own animations on iOS and makes the page jitter.
|
|
1878
1694
|
__publicField(this, "keyboardDismissed", false);
|
|
1879
|
-
// Reused payload object for the "drag" event — mutated each onMove instead
|
|
1880
|
-
// of allocating a fresh `{size, delta}` per frame. At 60-120Hz a long drag
|
|
1881
|
-
// would otherwise churn tens of KB through the GC. Mirrors browser
|
|
1882
|
-
// PointerEvent semantics: consumers must NOT retain the reference across
|
|
1883
|
-
// frames (clone if needed). See SheetEventMap.drag JSDoc.
|
|
1884
1695
|
__publicField(this, "dragPayload", { size: 0, delta: 0 });
|
|
1885
1696
|
this.deps = deps;
|
|
1886
1697
|
}
|
|
1887
|
-
/** True between `dragstart` and `dragend`/`onCancel`. */
|
|
1888
1698
|
get isDragging() {
|
|
1889
1699
|
return this.isDragging_;
|
|
1890
1700
|
}
|
|
1891
|
-
/**
|
|
1892
|
-
* Bind pointer listeners on the handle and return a teardown. Engine pushes
|
|
1893
|
-
* the teardown into its TeardownStack so destroy() drains it once.
|
|
1894
|
-
*/
|
|
1895
1701
|
install() {
|
|
1896
1702
|
if (this.detach) return this.detach;
|
|
1897
1703
|
this.detach = installGestures(this.deps.handle, this.deps.mode, {
|
|
@@ -1948,11 +1754,6 @@ var GestureController = class {
|
|
|
1948
1754
|
});
|
|
1949
1755
|
return this.detach;
|
|
1950
1756
|
}
|
|
1951
|
-
/**
|
|
1952
|
-
* Force-clear drag visual state. Engine calls from destroy() when destroyed
|
|
1953
|
-
* mid-drag — gesture detach won't synthesize an onCancel, so we have to
|
|
1954
|
-
* roll back the data-attribute + will-change ourselves.
|
|
1955
|
-
*/
|
|
1956
1757
|
forceClearDragState() {
|
|
1957
1758
|
if (!this.isDragging_) return;
|
|
1958
1759
|
this.isDragging_ = false;
|
|
@@ -1971,11 +1772,6 @@ var AriaSliderWriter = class {
|
|
|
1971
1772
|
mode === "bottom" || mode === "top" ? "vertical" : "horizontal"
|
|
1972
1773
|
);
|
|
1973
1774
|
}
|
|
1974
|
-
/**
|
|
1975
|
-
* Update slider position. `allowedIds` length determines `aria-valuemax`;
|
|
1976
|
-
* `activeId` indexes into it for `aria-valuenow` + `aria-valuetext`.
|
|
1977
|
-
* Empty list → strip every dynamic attr so AT skips the handle entirely.
|
|
1978
|
-
*/
|
|
1979
1775
|
setValue(allowedIds, activeId) {
|
|
1980
1776
|
if (allowedIds.length === 0) {
|
|
1981
1777
|
this.handle.removeAttribute("aria-valuemin");
|
|
@@ -2049,9 +1845,6 @@ function resolveEngineOptions(opts, extras) {
|
|
|
2049
1845
|
scrimMode: opts.scrimMode,
|
|
2050
1846
|
scrimColor: opts.scrimColor,
|
|
2051
1847
|
scrimBlur: opts.scrimBlur,
|
|
2052
|
-
// Auto-promote pointer-events when tap-to-close is on so the click
|
|
2053
|
-
// listener actually receives events. Caller can still force `false`
|
|
2054
|
-
// explicitly to opt out — `??` only kicks in for `undefined`.
|
|
2055
1848
|
scrimInteractive: opts.scrimInteractive ?? (opts.scrimTapToClose ? true : void 0),
|
|
2056
1849
|
scrimTapToClose: opts.scrimTapToClose,
|
|
2057
1850
|
scrimPreset: opts.scrimPreset,
|
|
@@ -2072,10 +1865,6 @@ function resolveEngineOptions(opts, extras) {
|
|
|
2072
1865
|
closeOnEscape: opts.closeOnEscape,
|
|
2073
1866
|
lockBodyScroll: opts.lockBodyScroll,
|
|
2074
1867
|
inertSiblings: opts.inertSiblings,
|
|
2075
|
-
// Folded in from `extras` so the lifecycle bag is fully assembled at
|
|
2076
|
-
// the call site — engine no longer needs a spread+override at
|
|
2077
|
-
// controller construction. When `extras` is omitted, the field stays
|
|
2078
|
-
// undefined and the controller uses its own default predicate.
|
|
2079
1868
|
shouldApplyInertSiblings: extras?.shouldApplyInertSiblings
|
|
2080
1869
|
}
|
|
2081
1870
|
};
|
|
@@ -2110,6 +1899,7 @@ var BottomSheetEngine = class {
|
|
|
2110
1899
|
__publicField(this, "scrollContainer");
|
|
2111
1900
|
__publicField(this, "backdrop");
|
|
2112
1901
|
__publicField(this, "screenComponent");
|
|
1902
|
+
__publicField(this, "scrimParent", null);
|
|
2113
1903
|
__publicField(this, "mode");
|
|
2114
1904
|
__publicField(this, "flickVelocity");
|
|
2115
1905
|
__publicField(this, "dragThreshold");
|
|
@@ -2120,40 +1910,22 @@ var BottomSheetEngine = class {
|
|
|
2120
1910
|
__publicField(this, "lifecycle");
|
|
2121
1911
|
__publicField(this, "closeOnBack");
|
|
2122
1912
|
__publicField(this, "routedTo");
|
|
2123
|
-
// Engine retains `snapPointsRaw` for the "find a closed-id" query in
|
|
2124
|
-
// close() (raw input, not resolved geometry). Resolver owns geometry.
|
|
2125
1913
|
__publicField(this, "snapPointsRaw");
|
|
2126
1914
|
__publicField(this, "snaps");
|
|
2127
1915
|
__publicField(this, "activeId");
|
|
2128
1916
|
__publicField(this, "size", 0);
|
|
2129
|
-
// Constructed in attach(); a plugin's install() could read `state` before
|
|
2130
|
-
// attach completes if the constructor throws partway through. State getter
|
|
2131
|
-
// null-guards via `this.gesture?.isDragging ?? false`.
|
|
2132
1917
|
__publicField(this, "gesture");
|
|
2133
1918
|
__publicField(this, "rootEl", null);
|
|
2134
1919
|
__publicField(this, "destroyed", false);
|
|
2135
|
-
// In-flight ViewTransition handle. A second snapTo while a VT is in flight
|
|
2136
|
-
// would otherwise let Chromium reject the second's promise and flicker —
|
|
2137
|
-
// newCycle() calls skipTransition() to abort cleanly.
|
|
2138
1920
|
__publicField(this, "currentViewTransition", null);
|
|
2139
|
-
// Each cycle captures the signal at entry; when a newer cycle aborts the
|
|
2140
|
-
// controller, the captured signal flips to `aborted=true` and post-await
|
|
2141
|
-
// guards short-circuit (prevents stale snap/open/close emits).
|
|
2142
1921
|
__publicField(this, "currentAbort", new AbortController());
|
|
2143
|
-
// Sub-pixel `--bs-size` deltas and <1% `--bs-progress` deltas are not
|
|
2144
|
-
// visually distinguishable; gating CSSOM writes drops 30-50% of writes
|
|
2145
|
-
// during the spring's settle tail.
|
|
2146
1922
|
__publicField(this, "sizeWriteSentinel", new WriteSentinel());
|
|
2147
1923
|
__publicField(this, "progressWriteSentinel", new WriteSentinel());
|
|
2148
1924
|
__publicField(this, "isTopSheet", true);
|
|
2149
|
-
// Pooled payload — identity documented in SheetEventMap.progress JSDoc;
|
|
2150
|
-
// consumers must not retain across frames.
|
|
2151
1925
|
__publicField(this, "progressPayload", {
|
|
2152
1926
|
value: 0,
|
|
2153
1927
|
size: 0
|
|
2154
1928
|
});
|
|
2155
|
-
// Pooled buffer for `getDragContext()` — onMove calls this 60-120×/s.
|
|
2156
|
-
// Inner `range` object identity is also stable (mutated in place).
|
|
2157
1929
|
__publicField(this, "dragContextBuf", {
|
|
2158
1930
|
size: 0,
|
|
2159
1931
|
maxAxisSize: 0,
|
|
@@ -2164,13 +1936,7 @@ var BottomSheetEngine = class {
|
|
|
2164
1936
|
__publicField(this, "persistKey");
|
|
2165
1937
|
__publicField(this, "linkedSheets", []);
|
|
2166
1938
|
__publicField(this, "scrollCache");
|
|
2167
|
-
// Single LIFO stack for ALL destroy-only teardowns. Plugins (added last)
|
|
2168
|
-
// tear down first before the infrastructure they depend on. Toggle-semantic
|
|
2169
|
-
// listeners (focus-trap / scroll-lock / scrim tap-to-close) stay as named
|
|
2170
|
-
// fields on their controllers.
|
|
2171
1939
|
__publicField(this, "teardowns", new TeardownStack());
|
|
2172
|
-
// Pre-computed transform template — built once per engine since `mode` is
|
|
2173
|
-
// fixed for its lifetime. Avoids the 4-arm switch at 60-120 Hz.
|
|
2174
1940
|
__publicField(this, "transformTemplate");
|
|
2175
1941
|
const resolved = resolveEngineOptions(opts, {
|
|
2176
1942
|
shouldApplyInertSiblings: () => {
|
|
@@ -2185,7 +1951,8 @@ var BottomSheetEngine = class {
|
|
|
2185
1951
|
this.handle = opts.handle ?? opts.element;
|
|
2186
1952
|
this.scrollContainer = opts.scrollContainer;
|
|
2187
1953
|
this.backdrop = opts.backdrop;
|
|
2188
|
-
this.screenComponent = opts.screenComponent;
|
|
1954
|
+
this.screenComponent = opts.scrim ?? opts.screenComponent;
|
|
1955
|
+
this.scrimParent = this.screenComponent?.parentElement ?? null;
|
|
2189
1956
|
this.mode = resolved.mode;
|
|
2190
1957
|
this.transformTemplate = buildTransformTemplate(this.mode);
|
|
2191
1958
|
this.aria = new AriaSliderWriter(this.handle, this.mode);
|
|
@@ -2213,8 +1980,6 @@ var BottomSheetEngine = class {
|
|
|
2213
1980
|
getRootEl: () => this.rootEl,
|
|
2214
1981
|
applySize: (size) => this.applySize(size),
|
|
2215
1982
|
getSize: () => this.size,
|
|
2216
|
-
// Optional chain protects synthetic test paths that drive animateTo
|
|
2217
|
-
// before attach() (gesture is constructed there).
|
|
2218
1983
|
isDragging: () => this.gesture?.isDragging ?? false
|
|
2219
1984
|
},
|
|
2220
1985
|
resolved.animation
|
|
@@ -2319,21 +2084,6 @@ var BottomSheetEngine = class {
|
|
|
2319
2084
|
on(event, fn) {
|
|
2320
2085
|
return this.bus.on(event, fn);
|
|
2321
2086
|
}
|
|
2322
|
-
/**
|
|
2323
|
-
* Register a plugin. `install` runs synchronously; if it returns a function,
|
|
2324
|
-
* it's captured for teardown during `destroy()`. No-op if already destroyed
|
|
2325
|
-
* — installing into a torn-down engine would leak listeners.
|
|
2326
|
-
*
|
|
2327
|
-
* Throws from `plugin.install` are caught and rethrown via `queueMicrotask`
|
|
2328
|
-
* so a buggy plugin can't take the engine down with it: the engine stays
|
|
2329
|
-
* usable, sibling plugins still install, and the error surfaces in dev tools
|
|
2330
|
-
* on the next tick instead of being swallowed. Mirrors the per-fn isolation
|
|
2331
|
-
* model used for teardowns.
|
|
2332
|
-
*
|
|
2333
|
-
* Plugins that accept the second `scope` argument get transactional cleanup:
|
|
2334
|
-
* push partial-install cleanups via `scope.add(fn)` and the engine drains
|
|
2335
|
-
* them on throw, OR merges them into destroy-time teardowns on success.
|
|
2336
|
-
*/
|
|
2337
2087
|
use(plugin) {
|
|
2338
2088
|
if (this.destroyed) {
|
|
2339
2089
|
console.warn(
|
|
@@ -2343,9 +2093,6 @@ var BottomSheetEngine = class {
|
|
|
2343
2093
|
}
|
|
2344
2094
|
const scoped = [];
|
|
2345
2095
|
const scope = {
|
|
2346
|
-
// typeof check — not just truthiness — so a JS-only plugin pushing a
|
|
2347
|
-
// bogus value is silently rejected instead of queueing a confusing
|
|
2348
|
-
// TypeError on destroy() drain.
|
|
2349
2096
|
add: (fn) => {
|
|
2350
2097
|
if (typeof fn === "function") scoped.push(fn);
|
|
2351
2098
|
}
|
|
@@ -2374,36 +2121,13 @@ var BottomSheetEngine = class {
|
|
|
2374
2121
|
}
|
|
2375
2122
|
return this;
|
|
2376
2123
|
}
|
|
2377
|
-
/**
|
|
2378
|
-
* Replace the linked-sheets list at runtime. Use when peer engines aren't
|
|
2379
|
-
* available at construction time (mounted later in the tree). The wiring
|
|
2380
|
-
* to the `open` event is independent of this list — it reads `linkedSheets`
|
|
2381
|
-
* lazily on emit, so this setter is a simple field swap.
|
|
2382
|
-
*/
|
|
2383
2124
|
setLinkedSheets(sheets) {
|
|
2384
2125
|
if (this.destroyed) return;
|
|
2385
2126
|
this.linkedSheets = sheets;
|
|
2386
2127
|
}
|
|
2387
|
-
/** Read-only view of the current allow-list, for cross-sheet target negotiation. */
|
|
2388
2128
|
getAllowedIds() {
|
|
2389
2129
|
return this.snaps.getAllowedIds().slice();
|
|
2390
2130
|
}
|
|
2391
|
-
/**
|
|
2392
|
-
* Animate to a snap point by id. Resolves when the animation completes.
|
|
2393
|
-
*
|
|
2394
|
-
* Two call shapes:
|
|
2395
|
-
* ```ts
|
|
2396
|
-
* engine.snapTo("full"); // default velocity
|
|
2397
|
-
* engine.snapTo("full", 0.5); // px/ms initial velocity
|
|
2398
|
-
* engine.snapTo("full", { velocity: 0.5, signal }); // abortable
|
|
2399
|
-
* ```
|
|
2400
|
-
*
|
|
2401
|
-
* When `opts.signal` is provided, calling `controller.abort()` cancels the
|
|
2402
|
-
* in-flight tween/spring and the returned promise resolves without firing
|
|
2403
|
-
* `snap`. The captured `AbortSignal` is checked after each await so external
|
|
2404
|
-
* aborts ride the same cycle invariant as internal ones (resize, destroy,
|
|
2405
|
-
* concurrent snapTo).
|
|
2406
|
-
*/
|
|
2407
2131
|
async snapTo(id, velocityOrOpts = 0, _skipBeforeSnap = false) {
|
|
2408
2132
|
if (this.destroyed) return;
|
|
2409
2133
|
const opts = typeof velocityOrOpts === "object" ? velocityOrOpts : { velocity: velocityOrOpts };
|
|
@@ -2462,16 +2186,6 @@ var BottomSheetEngine = class {
|
|
|
2462
2186
|
this.handleClose();
|
|
2463
2187
|
}
|
|
2464
2188
|
}
|
|
2465
|
-
/**
|
|
2466
|
-
* Drive the sheet to an arbitrary px size, bypassing snap matching.
|
|
2467
|
-
* Useful for preview scrubs, animation chaining, or programmatic gestures.
|
|
2468
|
-
* Animates with the configured spring/tween. Resolves when the animation
|
|
2469
|
-
* completes. Does NOT update `activeId` — call `snapTo(id)` after to commit.
|
|
2470
|
-
*
|
|
2471
|
-
* Unlike `snapTo`, this does not fire `before-snap` (it isn't a snap commit)
|
|
2472
|
-
* nor `snap` (the sheet isn't settling to a known snap). `progress` events
|
|
2473
|
-
* still fire via applySize. Target is clamped to `[0, maxAxisSize]`.
|
|
2474
|
-
*/
|
|
2475
2189
|
async dragTo(targetSize, velocityOrOpts = 0) {
|
|
2476
2190
|
if (this.destroyed) return;
|
|
2477
2191
|
const opts = typeof velocityOrOpts === "object" ? velocityOrOpts : { velocity: velocityOrOpts };
|
|
@@ -2509,20 +2223,10 @@ var BottomSheetEngine = class {
|
|
|
2509
2223
|
this.snaps.setAllowedIds(ids);
|
|
2510
2224
|
this.updateAriaSlider();
|
|
2511
2225
|
if (snap && ids.includes(snap)) {
|
|
2512
|
-
void this.snapTo(
|
|
2513
|
-
snap,
|
|
2514
|
-
0,
|
|
2515
|
-
/* internal */
|
|
2516
|
-
true
|
|
2517
|
-
);
|
|
2226
|
+
void this.snapTo(snap, 0, true);
|
|
2518
2227
|
} else if (!ids.includes(this.activeId)) {
|
|
2519
2228
|
const fallback = ids[0];
|
|
2520
|
-
if (fallback) void this.snapTo(
|
|
2521
|
-
fallback,
|
|
2522
|
-
0,
|
|
2523
|
-
/* internal */
|
|
2524
|
-
true
|
|
2525
|
-
);
|
|
2229
|
+
if (fallback) void this.snapTo(fallback, 0, true);
|
|
2526
2230
|
}
|
|
2527
2231
|
}
|
|
2528
2232
|
setBackdropRange(range) {
|
|
@@ -2540,21 +2244,6 @@ var BottomSheetEngine = class {
|
|
|
2540
2244
|
setScrimInteractive(interactive) {
|
|
2541
2245
|
this.scrim.setScrimInteractive(interactive);
|
|
2542
2246
|
}
|
|
2543
|
-
/**
|
|
2544
|
-
* Batch-update multiple scrim fields in one call. Apply order is:
|
|
2545
|
-
* 1. `preset` — fills baseline color/blur/range/interactive.
|
|
2546
|
-
* 2. `mode` — re-positions the scrim (fixed inset / clear / hide).
|
|
2547
|
-
* 3. `enabled` — flips the opacity contribution on/off.
|
|
2548
|
-
* 4. `tapToClose` — installs/tears the click listener.
|
|
2549
|
-
* 5. `color` / `blur` / `interactive` / `range` — explicit overrides.
|
|
2550
|
-
* 6. ONE `applySize` so the per-frame opacity stays consistent.
|
|
2551
|
-
*
|
|
2552
|
-
* Performance: collecting changes here (vs calling individual setters)
|
|
2553
|
-
* avoids repeated `applySize` calls during a multi-field swap. Setters
|
|
2554
|
-
* called here suppress their own internal `applySize` either by passing
|
|
2555
|
-
* through fast-paths (mode/enabled no-op when value unchanged) or by
|
|
2556
|
-
* being visual-only (color/blur/interactive don't influence opacity).
|
|
2557
|
-
*/
|
|
2558
2247
|
setScrim(opts) {
|
|
2559
2248
|
this.scrim.setScrim(opts, () => this.applySize(this.size));
|
|
2560
2249
|
}
|
|
@@ -2570,11 +2259,6 @@ var BottomSheetEngine = class {
|
|
|
2570
2259
|
setScrimOverlay(opts) {
|
|
2571
2260
|
return this.scrim.setScrimOverlay(opts);
|
|
2572
2261
|
}
|
|
2573
|
-
/**
|
|
2574
|
-
* Read-only snapshot of scrim state. Use the `setScrim*` setters to mutate.
|
|
2575
|
-
* Stable public API — internals (e.g. cached opacity sentinels) are NOT
|
|
2576
|
-
* exposed so consumers can't accidentally couple to ScrimController shape.
|
|
2577
|
-
*/
|
|
2578
2262
|
getScrimState() {
|
|
2579
2263
|
return { mode: this.scrim.scrimMode, enabled: this.scrim.scrimEnabled };
|
|
2580
2264
|
}
|
|
@@ -2620,24 +2304,11 @@ var BottomSheetEngine = class {
|
|
|
2620
2304
|
emit(event, payload) {
|
|
2621
2305
|
this.bus.emit(event, payload);
|
|
2622
2306
|
}
|
|
2623
|
-
/**
|
|
2624
|
-
* Abort the current cycle's signal and replace the controller. Returns the
|
|
2625
|
-
* fresh signal so the caller can capture it locally before any await — when
|
|
2626
|
-
* a future newCycle() / destroy aborts our controller, the captured signal
|
|
2627
|
-
* flips to aborted and post-await guards short-circuit.
|
|
2628
|
-
*/
|
|
2629
2307
|
newCycle() {
|
|
2630
2308
|
this.currentAbort.abort();
|
|
2631
2309
|
this.currentAbort = new AbortController();
|
|
2632
2310
|
return this.currentAbort.signal;
|
|
2633
2311
|
}
|
|
2634
|
-
/**
|
|
2635
|
-
* Fire `before-snap` and report whether a listener cancelled it. The
|
|
2636
|
-
* `cancel()` callback exposed to listeners is frozen after the synchronous
|
|
2637
|
-
* emit phase so async callers can't silently miss — they get a console
|
|
2638
|
-
* warning. Returns `true` when cancelled so callers can early-return /
|
|
2639
|
-
* spring-back without re-implementing the cancel/frozen pattern.
|
|
2640
|
-
*/
|
|
2641
2312
|
emitBeforeSnap(target, previousId) {
|
|
2642
2313
|
let cancelled = false;
|
|
2643
2314
|
let frozen = false;
|
|
@@ -2671,30 +2342,9 @@ var BottomSheetEngine = class {
|
|
|
2671
2342
|
this.snaps.setRaw(this.snapPointsRaw);
|
|
2672
2343
|
this.scrim.invalidateOpacityCache();
|
|
2673
2344
|
}
|
|
2674
|
-
/**
|
|
2675
|
-
* Memoised `allowedRange()` — delegates to SnapResolver which owns the cache.
|
|
2676
|
-
* Engine wrapper kept so existing call sites don't all need updating;
|
|
2677
|
-
* resolver-level memoization survives across method invocations.
|
|
2678
|
-
*/
|
|
2679
2345
|
getAllowedRange() {
|
|
2680
2346
|
return this.snaps.getAllowedRange();
|
|
2681
2347
|
}
|
|
2682
|
-
/**
|
|
2683
|
-
* Write ARIA slider value attributes onto the handle so the engine itself
|
|
2684
|
-
* is the source of truth for screen-reader announcements. Called from the
|
|
2685
|
-
* constructor and from every code path that mutates `activeId` /
|
|
2686
|
-
* `allowedIds`. WAI-ARIA 1.2 requires `aria-valuenow` for `role="slider"` —
|
|
2687
|
-
* without it screen readers can't announce drag/snap progress to keyboard
|
|
2688
|
-
* + AT users (WCAG 4.1.2 Name, Role, Value).
|
|
2689
|
-
*
|
|
2690
|
-
* Engine does NOT set `role="slider"` itself — that's the adapter's or
|
|
2691
|
-
* consumer markup's responsibility. We only decorate with dynamic values.
|
|
2692
|
-
*
|
|
2693
|
-
* Empty allowed-list is malformed input (settable via `setAllowed([])`);
|
|
2694
|
-
* short-circuit to remove ARIA value attributes so screen readers see a
|
|
2695
|
-
* no-value slider rather than a degenerate `min=max=now=0` (WAI-ARIA 1.2
|
|
2696
|
-
* requires `valuemax > valuemin` for `role="slider"`).
|
|
2697
|
-
*/
|
|
2698
2348
|
updateAriaSlider() {
|
|
2699
2349
|
this.aria.setValue(this.snaps.getAllowedIds(), this.activeId);
|
|
2700
2350
|
}
|
|
@@ -2719,11 +2369,6 @@ var BottomSheetEngine = class {
|
|
|
2719
2369
|
element: this.element,
|
|
2720
2370
|
mode: this.mode,
|
|
2721
2371
|
getRoot: () => this.rootEl,
|
|
2722
|
-
// Single coalesced reader — narrows the DI surface and removes 3 getter
|
|
2723
|
-
// dispatches per onMove frame at 60-120Hz. Returns a SHARED buffer
|
|
2724
|
-
// (this.dragContextBuf) — see field JSDoc for the retention contract.
|
|
2725
|
-
// Inner `range` object is mutated in place too so callers caching its
|
|
2726
|
-
// identity between frames stay valid.
|
|
2727
2372
|
getDragContext: () => {
|
|
2728
2373
|
const buf = this.dragContextBuf;
|
|
2729
2374
|
const r = this.getAllowedRange();
|
|
@@ -2889,7 +2534,6 @@ var BottomSheetEngine = class {
|
|
|
2889
2534
|
}
|
|
2890
2535
|
});
|
|
2891
2536
|
}
|
|
2892
|
-
/** Trigger a brief haptic tick (iOS Safari + Android Chrome support). */
|
|
2893
2537
|
haptic() {
|
|
2894
2538
|
if (typeof navigator !== "undefined" && "vibrate" in navigator) {
|
|
2895
2539
|
try {
|
|
@@ -2905,6 +2549,9 @@ var BottomSheetEngine = class {
|
|
|
2905
2549
|
style.transform = this.transformTemplate(offset);
|
|
2906
2550
|
if (this.sizeWriteSentinel.shouldWrite(size, SIZE_WRITE_EPSILON)) {
|
|
2907
2551
|
style.setProperty("--bs-size", `${size}px`);
|
|
2552
|
+
if (this.scrimParent) {
|
|
2553
|
+
this.scrimParent.style.setProperty("--bs-size", `${size}px`);
|
|
2554
|
+
}
|
|
2908
2555
|
}
|
|
2909
2556
|
const progress = this.computeProgress(size);
|
|
2910
2557
|
const progressChanged = this.progressWriteSentinel.shouldWrite(
|
|
@@ -2974,7 +2621,7 @@ function useBottomSheet(opts) {
|
|
|
2974
2621
|
handle: handleRef.value ?? void 0,
|
|
2975
2622
|
scrollContainer: contentRef.value ?? void 0,
|
|
2976
2623
|
backdrop: backdropRef.value ?? void 0,
|
|
2977
|
-
|
|
2624
|
+
scrim: screenRef.value ?? void 0
|
|
2978
2625
|
});
|
|
2979
2626
|
sync();
|
|
2980
2627
|
engine.on("snap", (payload) => {
|
|
@@ -3007,6 +2654,9 @@ function useBottomSheet(opts) {
|
|
|
3007
2654
|
close: () => engine?.close() ?? Promise.resolve(),
|
|
3008
2655
|
setAllowed: (ids, snap) => engine?.setAllowed(ids, snap),
|
|
3009
2656
|
setSnapPoints: (points, allowed) => engine?.setSnapPoints(points, allowed),
|
|
2657
|
+
setScrim: (opts2) => engine?.setScrim(opts2),
|
|
2658
|
+
setScrimOverlay: (opts2) => engine?.setScrimOverlay(opts2) ?? (() => {
|
|
2659
|
+
}),
|
|
3010
2660
|
on: (event, fn) => {
|
|
3011
2661
|
if (engine) return engine.on(event, fn);
|
|
3012
2662
|
const entry = {
|
|
@@ -3024,7 +2674,8 @@ function useBottomSheet(opts) {
|
|
|
3024
2674
|
if (idx !== -1) pending.splice(idx, 1);
|
|
3025
2675
|
}
|
|
3026
2676
|
};
|
|
3027
|
-
}
|
|
2677
|
+
},
|
|
2678
|
+
getEngine: () => engine
|
|
3028
2679
|
};
|
|
3029
2680
|
}
|
|
3030
2681
|
|
|
@@ -3041,6 +2692,10 @@ var export_helper_default = (sfc, props) => {
|
|
|
3041
2692
|
var _sfc_main = /* @__PURE__ */ defineComponent({
|
|
3042
2693
|
__name: "BottomSheet",
|
|
3043
2694
|
props: {
|
|
2695
|
+
screenComponent: {
|
|
2696
|
+
type: null,
|
|
2697
|
+
required: false
|
|
2698
|
+
},
|
|
3044
2699
|
mode: {
|
|
3045
2700
|
type: String,
|
|
3046
2701
|
required: false
|
|
@@ -3194,7 +2849,7 @@ var _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
3194
2849
|
setup(__props, { expose: __expose, emit: __emit }) {
|
|
3195
2850
|
const props = __props;
|
|
3196
2851
|
const emit = __emit;
|
|
3197
|
-
const { sheetRef, handleRef, contentRef, backdropRef, screenRef, state, snapTo, open, close, setAllowed, setSnapPoints, on } = useBottomSheet(props);
|
|
2852
|
+
const { sheetRef, handleRef, contentRef, backdropRef, screenRef, state, snapTo, open, close, setAllowed, setSnapPoints, setScrim, setScrimOverlay, on, getEngine } = useBottomSheet(props);
|
|
3198
2853
|
watch(() => ({ ...state }), (next) => emit("change", next), { deep: false });
|
|
3199
2854
|
on("snap", (payload) => emit("snap", payload.id));
|
|
3200
2855
|
on("open", (payload) => emit("open", payload.id));
|
|
@@ -3215,10 +2870,10 @@ var _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
3215
2870
|
close,
|
|
3216
2871
|
setAllowed,
|
|
3217
2872
|
setSnapPoints,
|
|
2873
|
+
setScrim,
|
|
2874
|
+
setScrimOverlay,
|
|
3218
2875
|
on,
|
|
3219
|
-
|
|
3220
|
-
// that would desync the local view-state proxy from the engine's truth.
|
|
3221
|
-
// Mirrors React's getter-based exposure and Svelte's getState() snapshot.
|
|
2876
|
+
getEngine,
|
|
3222
2877
|
state: readonly(state)
|
|
3223
2878
|
});
|
|
3224
2879
|
const __returned__ = {
|
|
@@ -3235,7 +2890,10 @@ var _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
3235
2890
|
close,
|
|
3236
2891
|
setAllowed,
|
|
3237
2892
|
setSnapPoints,
|
|
2893
|
+
setScrim,
|
|
2894
|
+
setScrimOverlay,
|
|
3238
2895
|
on,
|
|
2896
|
+
getEngine,
|
|
3239
2897
|
isVerticalAxis,
|
|
3240
2898
|
allowedIds,
|
|
3241
2899
|
activeIdx,
|
|
@@ -3250,7 +2908,6 @@ var _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
3250
2908
|
});
|
|
3251
2909
|
var _hoisted_1 = { class: "bs-root" };
|
|
3252
2910
|
var _hoisted_2 = {
|
|
3253
|
-
key: 1,
|
|
3254
2911
|
ref: "screenRef",
|
|
3255
2912
|
class: "bs-screen"
|
|
3256
2913
|
};
|
|
@@ -3304,13 +2961,14 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
3304
2961
|
512
|
|
3305
2962
|
/* NEED_PATCH */
|
|
3306
2963
|
)) : createCommentVNode("v-if", true),
|
|
3307
|
-
|
|
2964
|
+
createCommentVNode("\n Scrim surface always renders so the engine can host scrim presets\n (color/blur via setScrim), overlay injections (setScrimOverlay),\n and progress-driven opacity. The `screen` slot, when used, renders\n inside as user content. Without a slot it stays an empty positioning\n context.\n "),
|
|
2965
|
+
createElementVNode(
|
|
3308
2966
|
"div",
|
|
3309
2967
|
_hoisted_2,
|
|
3310
2968
|
[renderSlot(_ctx.$slots, "screen")],
|
|
3311
2969
|
512
|
|
3312
2970
|
/* NEED_PATCH */
|
|
3313
|
-
)
|
|
2971
|
+
),
|
|
3314
2972
|
createElementVNode("section", {
|
|
3315
2973
|
ref: "sheetRef",
|
|
3316
2974
|
class: normalizeClass(["bs-sheet"]),
|