@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/svelte.js
CHANGED
|
@@ -232,11 +232,6 @@ var SnapResolver = class {
|
|
|
232
232
|
this.allowedIds = allowed ?? raw.map((p) => p.id);
|
|
233
233
|
this.recompute();
|
|
234
234
|
}
|
|
235
|
-
/**
|
|
236
|
-
* Re-resolve raw → resolved against the current viewport / fit-measure,
|
|
237
|
-
* recompute maxAxisSize, invalidate range cache, notify engine. Called on
|
|
238
|
-
* resize, orientationchange, visualViewport changes, and snap-list swaps.
|
|
239
|
-
*/
|
|
240
235
|
recompute() {
|
|
241
236
|
this.resolved = resolveSnapList(this.raw, this.mode, this.measureFit);
|
|
242
237
|
this.maxAxisSize = this.resolved.reduce(
|
|
@@ -246,15 +241,10 @@ var SnapResolver = class {
|
|
|
246
241
|
this.rangeCache = null;
|
|
247
242
|
this.onMaxAxisSizeChange?.(this.maxAxisSize);
|
|
248
243
|
}
|
|
249
|
-
/** Replace the raw snap list and recompute. Engine calls on `setSnapPoints`. */
|
|
250
244
|
setRaw(raw) {
|
|
251
245
|
this.raw = raw;
|
|
252
246
|
this.recompute();
|
|
253
247
|
}
|
|
254
|
-
/**
|
|
255
|
-
* Replace the allow-list. Range cache depends on `(resolvedSnaps ×
|
|
256
|
-
* allowedIds)` so flipping ids alone invalidates without a full recompute.
|
|
257
|
-
*/
|
|
258
248
|
setAllowedIds(ids) {
|
|
259
249
|
this.allowedIds = ids;
|
|
260
250
|
this.rangeCache = null;
|
|
@@ -262,11 +252,6 @@ var SnapResolver = class {
|
|
|
262
252
|
findById(id) {
|
|
263
253
|
return findById(id, this.resolved);
|
|
264
254
|
}
|
|
265
|
-
/**
|
|
266
|
-
* Pure drag-settle target resolution. Engine passes the gesture-specific
|
|
267
|
-
* fields (delta, velocity, pointerKind, flickVelocity, dragThreshold) plus
|
|
268
|
-
* `size`/`activeId` since those are still engine-owned.
|
|
269
|
-
*/
|
|
270
255
|
findDragSettleTarget(args) {
|
|
271
256
|
return findDragSettleTarget({
|
|
272
257
|
...args,
|
|
@@ -275,18 +260,9 @@ var SnapResolver = class {
|
|
|
275
260
|
maxAxisSize: this.maxAxisSize
|
|
276
261
|
});
|
|
277
262
|
}
|
|
278
|
-
/**
|
|
279
|
-
* Memoised allowed-range query. Twice-per-drag-frame (gesture onMove +
|
|
280
|
-
* applySize→computeProgress); cache collapses 2× iteration of resolvedSnaps
|
|
281
|
-
* to one recompute per geometry/allow-list change.
|
|
282
|
-
*/
|
|
283
263
|
getAllowedRange() {
|
|
284
264
|
return this.rangeCache ?? (this.rangeCache = allowedRange(this.resolved, this.allowedIds));
|
|
285
265
|
}
|
|
286
|
-
/**
|
|
287
|
-
* Read-only view of resolved snaps. Returned as `readonly` to discourage
|
|
288
|
-
* accidental mutation by feature install sites that close over this list.
|
|
289
|
-
*/
|
|
290
266
|
getResolvedSnaps() {
|
|
291
267
|
return this.resolved;
|
|
292
268
|
}
|
|
@@ -296,18 +272,6 @@ var SnapResolver = class {
|
|
|
296
272
|
getMaxAxisSize() {
|
|
297
273
|
return this.maxAxisSize;
|
|
298
274
|
}
|
|
299
|
-
/**
|
|
300
|
-
* External clamp override. The resize-observer feature compares
|
|
301
|
-
* `getMaxAxisSize()` against the live viewport and shrinks if the largest
|
|
302
|
-
* resolved snap exceeds it (mobile address-bar collapse / soft-keyboard
|
|
303
|
-
* window resize). The next `recompute()` overwrites this clamp from the
|
|
304
|
-
* resolved-snap reduction.
|
|
305
|
-
*
|
|
306
|
-
* Does NOT invalidate the range cache — viewport clamping doesn't change
|
|
307
|
-
* `(resolvedSnaps × allowedIds) → range`. DOES fire `onMaxAxisSizeChange`
|
|
308
|
-
* so the resolver owns the layout-axis style write end-to-end (symmetric
|
|
309
|
-
* with `recompute()` — feature call sites no longer duplicate the write).
|
|
310
|
-
*/
|
|
311
275
|
setMaxAxisSize(n) {
|
|
312
276
|
this.maxAxisSize = n;
|
|
313
277
|
this.onMaxAxisSizeChange?.(n);
|
|
@@ -682,73 +646,49 @@ var WriteSentinel = class {
|
|
|
682
646
|
constructor() {
|
|
683
647
|
__publicField(this, "last", -1);
|
|
684
648
|
}
|
|
685
|
-
/**
|
|
686
|
-
* Returns `true` (and updates the cached value) if `next` differs from the
|
|
687
|
-
* cached `last` by more than `epsilon`. Returns `false` (and leaves the
|
|
688
|
-
* cache untouched) when the delta is within epsilon — caller skips the
|
|
689
|
-
* CSSOM write.
|
|
690
|
-
*/
|
|
691
649
|
shouldWrite(next, epsilon) {
|
|
692
650
|
if (Math.abs(next - this.last) <= epsilon) return false;
|
|
693
651
|
this.last = next;
|
|
694
652
|
return true;
|
|
695
653
|
}
|
|
696
|
-
/**
|
|
697
|
-
* Force the next `shouldWrite` to pass. Resets the cache to `-1` so any
|
|
698
|
-
* non-negative `next` exceeds the epsilon comparison. Called from setters
|
|
699
|
-
* that mutate state under the cache (range/mode/enabled flips that change
|
|
700
|
-
* the progress→opacity mapping but don't move `progress` itself).
|
|
701
|
-
*/
|
|
702
654
|
invalidate() {
|
|
703
655
|
this.last = -1;
|
|
704
656
|
}
|
|
705
|
-
/**
|
|
706
|
-
* Record `value` as the last-written without performing a write. Used
|
|
707
|
-
* when a setter writes a literal value through a different path (e.g.
|
|
708
|
-
* `setScrimMode("off")` writes `opacity: "0"` inline) and wants future
|
|
709
|
-
* `shouldWrite` calls to short-circuit against that known cached state.
|
|
710
|
-
*/
|
|
711
657
|
setLastWritten(value) {
|
|
712
658
|
this.last = value;
|
|
713
659
|
}
|
|
714
|
-
/** Read-only accessor for diagnostic / dedup-aware peek. */
|
|
715
660
|
get value() {
|
|
716
661
|
return this.last;
|
|
717
662
|
}
|
|
718
663
|
};
|
|
719
664
|
|
|
665
|
+
// src/core/primitives/devWarn.ts
|
|
666
|
+
function devWarn(...args) {
|
|
667
|
+
if (typeof process !== "undefined" && process.env && process.env.NODE_ENV !== "production" && typeof console !== "undefined") {
|
|
668
|
+
console.warn(...args);
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
|
|
720
672
|
// src/core/controllers/scrim-controller.ts
|
|
673
|
+
var VALID_CSS_LENGTH = /^-?\d+(?:\.\d+)?(?:px|em|rem|%)$/;
|
|
721
674
|
var ScrimController = class {
|
|
722
675
|
constructor(deps, opts) {
|
|
723
|
-
// ── DOM refs (mirror engine's; cached for hot path) ─────────────────
|
|
724
676
|
__publicField(this, "screenComponent");
|
|
725
677
|
__publicField(this, "backdrop");
|
|
726
678
|
__publicField(this, "mode");
|
|
727
|
-
// ── Engine callbacks ────────────────────────────────────────────────
|
|
728
679
|
__publicField(this, "isDestroyed");
|
|
729
680
|
__publicField(this, "isTopSheet");
|
|
730
681
|
__publicField(this, "getAllowedIds");
|
|
731
682
|
__publicField(this, "getResolvedSnaps");
|
|
732
683
|
__publicField(this, "snapToFn");
|
|
733
|
-
// ── Mode + state ────────────────────────────────────────────────────
|
|
734
684
|
__publicField(this, "scrimMode");
|
|
735
685
|
__publicField(this, "backdropRange");
|
|
736
686
|
__publicField(this, "screenRange");
|
|
737
|
-
// setScrimEnabled toggle — gated through `scrimEnabled` rather than nuking
|
|
738
|
-
// ranges so re-enable can restore prior values without a remount. Public
|
|
739
|
-
// so tests / introspection can read it without an `as any` cast.
|
|
740
687
|
__publicField(this, "scrimEnabled", true);
|
|
741
688
|
__publicField(this, "savedScrimRanges", null);
|
|
742
|
-
// ── Tap-to-close ────────────────────────────────────────────────────
|
|
743
689
|
__publicField(this, "scrimTapToCloseEnabled", false);
|
|
744
690
|
__publicField(this, "detachScrimTap", null);
|
|
745
|
-
// ── Scrim overlay slot (positioned floating element) ────────────────
|
|
746
691
|
__publicField(this, "scrimOverlayTeardown", null);
|
|
747
|
-
// ── Hot-path opacity dedup caches (per-frame writes) ────────────────
|
|
748
|
-
// Numeric sentinels migrated to WriteSentinel primitive — single
|
|
749
|
-
// invalidation surface, shared with the engine's size/progress sentinels.
|
|
750
|
-
// The two string-typed sentinels (`Pointer`, `Display`) keep their inline
|
|
751
|
-
// pattern: equality on string union, no epsilon, different reset semantics.
|
|
752
692
|
__publicField(this, "backdropOpacitySentinel", new WriteSentinel());
|
|
753
693
|
__publicField(this, "screenOpacitySentinel", new WriteSentinel());
|
|
754
694
|
__publicField(this, "lastBackdropPointer", "");
|
|
@@ -783,41 +723,15 @@ var ScrimController = class {
|
|
|
783
723
|
}
|
|
784
724
|
}
|
|
785
725
|
}
|
|
786
|
-
/**
|
|
787
|
-
* Invalidate the opacity dedup caches. Called from any setter that mutates
|
|
788
|
-
* range/mode/enabled — opacity is a pure function of (progress, range,
|
|
789
|
-
* enabled), so a config change makes the cached values stale even if
|
|
790
|
-
* `progress` itself didn't move. Next `applyOpacity(progress, false)` call
|
|
791
|
-
* sees the -1 sentinel and re-runs the math instead of short-circuiting.
|
|
792
|
-
*
|
|
793
|
-
* Public for the engine: `setSnapPoints` mutates resolved geometry which
|
|
794
|
-
* shifts `progress→opacity` mapping under the cache; engine calls this to
|
|
795
|
-
* keep the next render frame correct on a static sheet.
|
|
796
|
-
* @internal
|
|
797
|
-
*/
|
|
798
726
|
invalidateOpacityCache() {
|
|
799
727
|
this.backdropOpacitySentinel.invalidate();
|
|
800
728
|
this.screenOpacitySentinel.invalidate();
|
|
801
729
|
}
|
|
802
|
-
/** Engine calls this when its `attach()` runs — installs scrim-tap-click if requested. */
|
|
803
730
|
attach() {
|
|
804
731
|
if (this.scrimTapToCloseEnabled) {
|
|
805
732
|
this.setScrimTapToClose(true);
|
|
806
733
|
}
|
|
807
734
|
}
|
|
808
|
-
// ── Hot-path: opacity computation called per-frame from engine.applySize ──
|
|
809
|
-
/**
|
|
810
|
-
* Per-frame opacity writer. Computes backdrop + screen opacity from the
|
|
811
|
-
* sheet's progress (0..1 within allowed range), gated by sub-pixel dedup
|
|
812
|
-
* caches so steady-state frames don't trigger style recalc.
|
|
813
|
-
*
|
|
814
|
-
* `progressChanged` is the engine's already-computed dedup gate — when
|
|
815
|
-
* `false`, opacity is by construction a pure function of `progress` so
|
|
816
|
-
* cached values are still valid; we short-circuit the Math.min/max +
|
|
817
|
-
* division work entirely. Setters that mutate ranges/mode/enabled
|
|
818
|
-
* invalidate the cache by writing -1 sentinels so the next call re-runs
|
|
819
|
-
* the math.
|
|
820
|
-
*/
|
|
821
735
|
applyOpacity(progress, progressChanged) {
|
|
822
736
|
if (!progressChanged && this.backdropOpacitySentinel.value !== -1 && this.screenOpacitySentinel.value !== -1) {
|
|
823
737
|
return;
|
|
@@ -863,80 +777,30 @@ var ScrimController = class {
|
|
|
863
777
|
}
|
|
864
778
|
}
|
|
865
779
|
}
|
|
866
|
-
// ── Public setters (engine forwards these 1:1) ─────────────────────
|
|
867
|
-
/**
|
|
868
|
-
* Replace the [start, end] progress window in which the backdrop fades 0→1.
|
|
869
|
-
* @param range - Tuple of two progress values in 0..1 (start <= end).
|
|
870
|
-
* @param applySize - Engine-supplied recompute hook; runs one applyOpacity pass.
|
|
871
|
-
* @example
|
|
872
|
-
* // Backdrop only starts darkening after the sheet crosses 30% open.
|
|
873
|
-
* engine.setBackdropRange([0.3, 1]);
|
|
874
|
-
*/
|
|
875
780
|
setBackdropRange(range, applySize) {
|
|
876
781
|
if (this.isDestroyed()) return;
|
|
877
782
|
this.backdropRange = range;
|
|
878
783
|
this.invalidateOpacityCache();
|
|
879
784
|
applySize();
|
|
880
785
|
}
|
|
881
|
-
/**
|
|
882
|
-
* Replace the [start, end] progress window in which the screen scrim fades 0→1.
|
|
883
|
-
* @param range - Tuple of two progress values in 0..1 (start <= end).
|
|
884
|
-
* @param applySize - Engine-supplied recompute hook; runs one applyOpacity pass.
|
|
885
|
-
* @example
|
|
886
|
-
* // Scrim is fully opaque only when the sheet is past 50% — softer feel.
|
|
887
|
-
* engine.setScreenRange([0, 0.5]);
|
|
888
|
-
*/
|
|
889
786
|
setScreenRange(range, applySize) {
|
|
890
787
|
if (this.isDestroyed()) return;
|
|
891
788
|
this.screenRange = range;
|
|
892
789
|
this.invalidateOpacityCache();
|
|
893
790
|
applySize();
|
|
894
791
|
}
|
|
895
|
-
/**
|
|
896
|
-
* Set the scrim background color. Pass `null`/`undefined` to clear the
|
|
897
|
-
* inline write and let consumer CSS take over.
|
|
898
|
-
* @param color - Any valid CSS color string, or `null`/`undefined` to clear.
|
|
899
|
-
* @example
|
|
900
|
-
* engine.setScrimColor("rgba(0, 0, 0, 0.6)");
|
|
901
|
-
* engine.setScrimColor(null); // hand back to consumer CSS
|
|
902
|
-
*/
|
|
903
792
|
setScrimColor(color) {
|
|
904
793
|
if (this.isDestroyed()) return;
|
|
905
794
|
this.applyScrimStyles({ color: color === void 0 ? null : color });
|
|
906
795
|
}
|
|
907
|
-
/**
|
|
908
|
-
* Set the scrim backdrop-filter blur radius. Pass `null`/`undefined` to clear.
|
|
909
|
-
* @param blur - CSS length (e.g. `"8px"`) consumed as `blur(<value>)`, or
|
|
910
|
-
* `null`/`undefined` to remove the filter.
|
|
911
|
-
* @example
|
|
912
|
-
* engine.setScrimBlur("12px"); // frosted-glass effect
|
|
913
|
-
* engine.setScrimBlur(null); // disable blur
|
|
914
|
-
*/
|
|
915
796
|
setScrimBlur(blur) {
|
|
916
797
|
if (this.isDestroyed()) return;
|
|
917
798
|
this.applyScrimStyles({ blur: blur === void 0 ? null : blur });
|
|
918
799
|
}
|
|
919
|
-
/**
|
|
920
|
-
* Toggle whether the scrim layer captures pointer events.
|
|
921
|
-
* @param interactive - `true` → `pointer-events: auto`; `false` → `none`.
|
|
922
|
-
* @example
|
|
923
|
-
* engine.setScrimInteractive(true); // scrim swallows clicks
|
|
924
|
-
* engine.setScrimInteractive(false); // clicks pass through to content below
|
|
925
|
-
*/
|
|
926
800
|
setScrimInteractive(interactive) {
|
|
927
801
|
if (this.isDestroyed()) return;
|
|
928
802
|
this.applyScrimStyles({ interactive });
|
|
929
803
|
}
|
|
930
|
-
/**
|
|
931
|
-
* Switch scrim positioning at runtime.
|
|
932
|
-
* @param mode - `"full"` (consumer CSS), `"above-sheet"` (engine-pinned inset
|
|
933
|
-
* so only the area NOT covered by the sheet is dimmed), or
|
|
934
|
-
* `"off"` (display:none + opacity:0 — no remount needed).
|
|
935
|
-
* @param applySize - Engine-supplied recompute hook; runs one applyOpacity pass.
|
|
936
|
-
* @example
|
|
937
|
-
* engine.setScrimMode("above-sheet"); // dim only the area above the sheet
|
|
938
|
-
* engine.setScrimMode("off"); // disable scrim layer
|
|
939
|
-
*/
|
|
940
804
|
setScrimMode(mode, applySize) {
|
|
941
805
|
if (this.isDestroyed()) return;
|
|
942
806
|
if (mode === this.scrimMode) return;
|
|
@@ -966,15 +830,6 @@ var ScrimController = class {
|
|
|
966
830
|
}
|
|
967
831
|
applySize();
|
|
968
832
|
}
|
|
969
|
-
/**
|
|
970
|
-
* Enable or disable click-on-scrim → snap to first non-zero allowed snap.
|
|
971
|
-
* Auto-promotes `pointer-events: auto` when scrim is non-interactive so the
|
|
972
|
-
* click listener actually fires.
|
|
973
|
-
* @param enabled - `true` installs the click listener; `false` removes it.
|
|
974
|
-
* @example
|
|
975
|
-
* engine.setScrimTapToClose(true); // tap outside sheet collapses it
|
|
976
|
-
* engine.setScrimTapToClose(false); // require explicit close button
|
|
977
|
-
*/
|
|
978
833
|
setScrimTapToClose(enabled) {
|
|
979
834
|
if (this.isDestroyed()) return;
|
|
980
835
|
if (!this.screenComponent) return;
|
|
@@ -1004,16 +859,6 @@ var ScrimController = class {
|
|
|
1004
859
|
this.scrimTapToCloseEnabled = false;
|
|
1005
860
|
}
|
|
1006
861
|
}
|
|
1007
|
-
/**
|
|
1008
|
-
* Toggle the scrim layer without remounting. Disabling stashes current
|
|
1009
|
-
* `screenRange`/`backdropRange` and degenerates them to `[1, 1]` (opacity
|
|
1010
|
-
* formula → 0 across the whole range); re-enabling restores the saved values.
|
|
1011
|
-
* @param enabled - `false` hides scrim, `true` restores prior ranges.
|
|
1012
|
-
* @param applySize - Engine-supplied recompute hook; runs one applyOpacity pass.
|
|
1013
|
-
* @example
|
|
1014
|
-
* engine.setScrimEnabled(false); // hide scrim, ranges remembered
|
|
1015
|
-
* engine.setScrimEnabled(true); // restore prior ranges (no remount)
|
|
1016
|
-
*/
|
|
1017
862
|
setScrimEnabled(enabled, applySize) {
|
|
1018
863
|
if (this.isDestroyed()) return;
|
|
1019
864
|
if (enabled === this.scrimEnabled) return;
|
|
@@ -1032,20 +877,6 @@ var ScrimController = class {
|
|
|
1032
877
|
}
|
|
1033
878
|
applySize();
|
|
1034
879
|
}
|
|
1035
|
-
/**
|
|
1036
|
-
* Batch-update multiple scrim fields with a single applySize() at the end.
|
|
1037
|
-
* If `preset` is set, it seeds color/blur/interactive/range first; explicit
|
|
1038
|
-
* fields override.
|
|
1039
|
-
* @param opts - Partial scrim config: preset, mode, enabled, tapToClose,
|
|
1040
|
-
* color, blur, interactive, range.
|
|
1041
|
-
* @param applySize - Engine-supplied recompute hook; runs ONCE per call.
|
|
1042
|
-
* @example
|
|
1043
|
-
* engine.setScrim({
|
|
1044
|
-
* preset: "frosted",
|
|
1045
|
-
* mode: "above-sheet",
|
|
1046
|
-
* tapToClose: true,
|
|
1047
|
-
* });
|
|
1048
|
-
*/
|
|
1049
880
|
setScrim(opts, applySize) {
|
|
1050
881
|
if (this.isDestroyed()) return;
|
|
1051
882
|
if (opts.preset) {
|
|
@@ -1068,27 +899,18 @@ var ScrimController = class {
|
|
|
1068
899
|
interactive: opts.interactive
|
|
1069
900
|
});
|
|
1070
901
|
if (opts.range !== void 0) {
|
|
1071
|
-
this.
|
|
902
|
+
if (!this.scrimEnabled && this.savedScrimRanges) {
|
|
903
|
+
this.savedScrimRanges = {
|
|
904
|
+
screen: opts.range,
|
|
905
|
+
backdrop: this.savedScrimRanges.backdrop
|
|
906
|
+
};
|
|
907
|
+
} else {
|
|
908
|
+
this.screenRange = opts.range;
|
|
909
|
+
}
|
|
1072
910
|
}
|
|
1073
911
|
this.invalidateOpacityCache();
|
|
1074
912
|
applySize();
|
|
1075
913
|
}
|
|
1076
|
-
/**
|
|
1077
|
-
* Inject a positioned floating element into the scrim layer (e.g. a close
|
|
1078
|
-
* button anchored top-right). Replaces any prior overlay so repeated calls
|
|
1079
|
-
* (reactive effects re-running) don't accumulate wrappers.
|
|
1080
|
-
* @param opts - Children element, optional `inset` (default `"16px"`),
|
|
1081
|
-
* `position` (9-way grid, default `"top-right"`), and
|
|
1082
|
-
* `interactive` flag (default `true`).
|
|
1083
|
-
* @returns Teardown function that removes the wrapper from the DOM.
|
|
1084
|
-
* @example
|
|
1085
|
-
* const teardown = engine.setScrimOverlay({
|
|
1086
|
-
* children: closeBtn,
|
|
1087
|
-
* position: "top-right",
|
|
1088
|
-
* inset: "20px",
|
|
1089
|
-
* });
|
|
1090
|
-
* // later: teardown(); // remove the floating button
|
|
1091
|
-
*/
|
|
1092
914
|
setScrimOverlay(opts) {
|
|
1093
915
|
if (this.isDestroyed()) return () => {
|
|
1094
916
|
};
|
|
@@ -1096,7 +918,18 @@ var ScrimController = class {
|
|
|
1096
918
|
};
|
|
1097
919
|
this.scrimOverlayTeardown?.();
|
|
1098
920
|
const screen = this.screenComponent;
|
|
1099
|
-
const
|
|
921
|
+
const insetRaw = opts.inset ?? "16px";
|
|
922
|
+
const inset = VALID_CSS_LENGTH.test(insetRaw) ? insetRaw : "16px";
|
|
923
|
+
if (inset !== insetRaw) {
|
|
924
|
+
devWarn(
|
|
925
|
+
`[bottom-sheet] setScrimOverlay: invalid inset ${JSON.stringify(insetRaw)}; expected a CSS length like "16px" / "1rem" / "5%". Falling back to "16px".`
|
|
926
|
+
);
|
|
927
|
+
}
|
|
928
|
+
if (opts.children.ownerDocument && opts.children.ownerDocument !== screen.ownerDocument) {
|
|
929
|
+
devWarn(
|
|
930
|
+
"[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."
|
|
931
|
+
);
|
|
932
|
+
}
|
|
1100
933
|
const position = opts.position ?? "top-right";
|
|
1101
934
|
const interactive = opts.interactive ?? true;
|
|
1102
935
|
const wrapper = screen.ownerDocument.createElement("div");
|
|
@@ -1145,12 +978,30 @@ var ScrimController = class {
|
|
|
1145
978
|
ws.bottom = inset;
|
|
1146
979
|
ws.right = inset;
|
|
1147
980
|
break;
|
|
981
|
+
case "sheet-top-left":
|
|
982
|
+
case "sheet-top-center":
|
|
983
|
+
case "sheet-top-right":
|
|
984
|
+
applySheetAnchoredPosition(
|
|
985
|
+
ws,
|
|
986
|
+
this.mode,
|
|
987
|
+
position,
|
|
988
|
+
inset
|
|
989
|
+
);
|
|
990
|
+
break;
|
|
1148
991
|
}
|
|
1149
992
|
if (interactive) {
|
|
1150
993
|
ws.pointerEvents = "auto";
|
|
1151
994
|
}
|
|
1152
995
|
wrapper.appendChild(opts.children);
|
|
1153
|
-
screen.
|
|
996
|
+
const host = screen.parentElement;
|
|
997
|
+
if (!host) {
|
|
998
|
+
devWarn(
|
|
999
|
+
"[bottom-sheet] setScrimOverlay: scrim element has no parent, skipping overlay injection. Mount the sheet root before calling setScrimOverlay."
|
|
1000
|
+
);
|
|
1001
|
+
return () => {
|
|
1002
|
+
};
|
|
1003
|
+
}
|
|
1004
|
+
host.appendChild(wrapper);
|
|
1154
1005
|
const teardown = () => {
|
|
1155
1006
|
if (wrapper.parentNode) wrapper.parentNode.removeChild(wrapper);
|
|
1156
1007
|
if (this.scrimOverlayTeardown === teardown) {
|
|
@@ -1160,7 +1011,6 @@ var ScrimController = class {
|
|
|
1160
1011
|
this.scrimOverlayTeardown = teardown;
|
|
1161
1012
|
return teardown;
|
|
1162
1013
|
}
|
|
1163
|
-
/** Tear down toggle-state listeners + remove any injected overlay wrapper. */
|
|
1164
1014
|
destroy() {
|
|
1165
1015
|
this.detachScrimTap?.();
|
|
1166
1016
|
this.detachScrimTap = null;
|
|
@@ -1179,8 +1029,6 @@ var ScrimController = class {
|
|
|
1179
1029
|
this.lastBackdropPointer = "";
|
|
1180
1030
|
this.lastScreenDisplay = "";
|
|
1181
1031
|
}
|
|
1182
|
-
// ── Private helpers ────────────────────────────────────────────────
|
|
1183
|
-
/** Centralized scrim style writer — atomic 3-property write across all setters. */
|
|
1184
1032
|
applyScrimStyles(opts) {
|
|
1185
1033
|
if (!this.screenComponent) return;
|
|
1186
1034
|
const s = this.screenComponent.style;
|
|
@@ -1202,7 +1050,6 @@ var ScrimController = class {
|
|
|
1202
1050
|
s.pointerEvents = opts.interactive ? "auto" : "none";
|
|
1203
1051
|
}
|
|
1204
1052
|
}
|
|
1205
|
-
/** Pin the screen overlay to the area NOT occupied by the sheet. */
|
|
1206
1053
|
applyAboveSheetInset() {
|
|
1207
1054
|
if (!this.screenComponent) return;
|
|
1208
1055
|
const insetByMode = {
|
|
@@ -1217,6 +1064,35 @@ var ScrimController = class {
|
|
|
1217
1064
|
s.pointerEvents = "none";
|
|
1218
1065
|
}
|
|
1219
1066
|
};
|
|
1067
|
+
function resolveSheetAnchoredStyle(mode, position, inset) {
|
|
1068
|
+
const sizeOffset = `calc(var(--bs-size, 0px) + ${inset})`;
|
|
1069
|
+
switch (mode) {
|
|
1070
|
+
case "bottom":
|
|
1071
|
+
if (position === "sheet-top-left") return { bottom: sizeOffset, left: inset };
|
|
1072
|
+
if (position === "sheet-top-right") return { bottom: sizeOffset, right: inset };
|
|
1073
|
+
return { bottom: sizeOffset, left: "50%", transform: "translateX(-50%)" };
|
|
1074
|
+
case "top":
|
|
1075
|
+
if (position === "sheet-top-left") return { top: sizeOffset, left: inset };
|
|
1076
|
+
if (position === "sheet-top-right") return { top: sizeOffset, right: inset };
|
|
1077
|
+
return { top: sizeOffset, left: "50%", transform: "translateX(-50%)" };
|
|
1078
|
+
case "left":
|
|
1079
|
+
if (position === "sheet-top-left") return { left: sizeOffset, top: inset };
|
|
1080
|
+
if (position === "sheet-top-right") return { left: sizeOffset, bottom: inset };
|
|
1081
|
+
return { left: sizeOffset, top: "50%", transform: "translateY(-50%)" };
|
|
1082
|
+
case "right":
|
|
1083
|
+
if (position === "sheet-top-left") return { right: sizeOffset, top: inset };
|
|
1084
|
+
if (position === "sheet-top-right") return { right: sizeOffset, bottom: inset };
|
|
1085
|
+
return { right: sizeOffset, top: "50%", transform: "translateY(-50%)" };
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
function applySheetAnchoredPosition(ws, mode, position, inset) {
|
|
1089
|
+
const style = resolveSheetAnchoredStyle(mode, position, inset);
|
|
1090
|
+
if (style.top !== void 0) ws.top = style.top;
|
|
1091
|
+
if (style.bottom !== void 0) ws.bottom = style.bottom;
|
|
1092
|
+
if (style.left !== void 0) ws.left = style.left;
|
|
1093
|
+
if (style.right !== void 0) ws.right = style.right;
|
|
1094
|
+
if (style.transform !== void 0) ws.transform = style.transform;
|
|
1095
|
+
}
|
|
1220
1096
|
|
|
1221
1097
|
// src/core/animation/animation.ts
|
|
1222
1098
|
var easeOutBack = (t) => {
|
|
@@ -1369,13 +1245,9 @@ var AnimationRunner = class {
|
|
|
1369
1245
|
__publicField(this, "duration");
|
|
1370
1246
|
__publicField(this, "easing");
|
|
1371
1247
|
__publicField(this, "respectReducedMotion");
|
|
1372
|
-
/** Live-tracked via mq listener so animateTo skips matchMedia per snap. */
|
|
1373
1248
|
__publicField(this, "reducedMotion", false);
|
|
1374
|
-
/** Disposes the matchMedia change listener — drained from destroy(). */
|
|
1375
1249
|
__publicField(this, "detachReducedMotion", null);
|
|
1376
|
-
/** Computed once — both inputs (option + API presence) stable for life. */
|
|
1377
1250
|
__publicField(this, "viewTransitionsAvailable");
|
|
1378
|
-
/** In-flight handles. Public for tests / debugging only — engine drives via cancel(). */
|
|
1379
1251
|
__publicField(this, "currentTween", null);
|
|
1380
1252
|
__publicField(this, "currentSpring", null);
|
|
1381
1253
|
this.element = deps.element;
|
|
@@ -1406,26 +1278,13 @@ var AnimationRunner = class {
|
|
|
1406
1278
|
}
|
|
1407
1279
|
}
|
|
1408
1280
|
}
|
|
1409
|
-
/**
|
|
1410
|
-
* Live derived flag — `true` whenever a spring/tween handle is in flight.
|
|
1411
|
-
* Reading the canonical handles (instead of mirroring into a separate
|
|
1412
|
-
* boolean) eliminates the reduced-motion early-return latent bug where
|
|
1413
|
-
* the flag stayed true forever, and removes the cross-controller
|
|
1414
|
-
* setIsAnimating callback.
|
|
1415
|
-
*/
|
|
1416
1281
|
get isAnimating() {
|
|
1417
1282
|
return this.currentTween !== null || this.currentSpring !== null;
|
|
1418
1283
|
}
|
|
1419
|
-
/** Cancel any in-flight tween/spring without touching engine state. */
|
|
1420
1284
|
cancel() {
|
|
1421
1285
|
this.currentTween?.cancel();
|
|
1422
1286
|
this.currentSpring?.cancel();
|
|
1423
1287
|
}
|
|
1424
|
-
/**
|
|
1425
|
-
* Animate from current size to `target`. Resolves when the animation
|
|
1426
|
-
* completes; resolves early if cancelled mid-flight (caller checks an
|
|
1427
|
-
* abort signal post-await for cycle-invariant correctness).
|
|
1428
|
-
*/
|
|
1429
1288
|
async animateTo(target, velocityPxPerMs) {
|
|
1430
1289
|
if (target === this.getSize()) return;
|
|
1431
1290
|
this.currentTween?.cancel();
|
|
@@ -1466,7 +1325,6 @@ var AnimationRunner = class {
|
|
|
1466
1325
|
if (!this.isDragging()) this.element.style.willChange = "auto";
|
|
1467
1326
|
}
|
|
1468
1327
|
}
|
|
1469
|
-
/** Tear down the matchMedia listener. Engine calls from destroy(). */
|
|
1470
1328
|
destroy() {
|
|
1471
1329
|
this.detachReducedMotion?.();
|
|
1472
1330
|
this.detachReducedMotion = null;
|
|
@@ -1626,12 +1484,8 @@ var LifecycleController = class {
|
|
|
1626
1484
|
__publicField(this, "inertSiblings");
|
|
1627
1485
|
__publicField(this, "shouldApplyInertSiblings");
|
|
1628
1486
|
__publicField(this, "returnFocus");
|
|
1629
|
-
/** Toggle-state teardowns — fire on close, NOT in destroy-only stack. */
|
|
1630
1487
|
__publicField(this, "releaseFocusTrap", null);
|
|
1631
1488
|
__publicField(this, "releaseScrollLock", null);
|
|
1632
|
-
/** True between install() and release(). Guards release()/destroy() from
|
|
1633
|
-
* re-running side effects (notably `returnFocus.focus()`) on already-
|
|
1634
|
-
* released or never-installed instances. */
|
|
1635
1489
|
__publicField(this, "installed", false);
|
|
1636
1490
|
__publicField(this, "destroyed", false);
|
|
1637
1491
|
this.element = deps.element;
|
|
@@ -1645,14 +1499,6 @@ var LifecycleController = class {
|
|
|
1645
1499
|
this.returnFocus = opts.returnFocus;
|
|
1646
1500
|
this.inertSiblings = createInertSiblings(() => this.element);
|
|
1647
1501
|
}
|
|
1648
|
-
/**
|
|
1649
|
-
* Run the open-time install steps. Idempotent: each step checks its
|
|
1650
|
-
* existing teardown ref so a re-open during a half-cancelled close
|
|
1651
|
-
* doesn't double-install. Sets `installed=true` BEFORE the first side
|
|
1652
|
-
* effect so a partial throw (detached / shadow-DOM target) leaves the
|
|
1653
|
-
* caller's `release()` rollback path armed to undo whatever did succeed.
|
|
1654
|
-
* No-op when destroyed.
|
|
1655
|
-
*/
|
|
1656
1502
|
install() {
|
|
1657
1503
|
if (this.destroyed) return;
|
|
1658
1504
|
this.installed = true;
|
|
@@ -1669,22 +1515,10 @@ var LifecycleController = class {
|
|
|
1669
1515
|
this.inertSiblings.apply();
|
|
1670
1516
|
}
|
|
1671
1517
|
}
|
|
1672
|
-
/**
|
|
1673
|
-
* Update the post-release focus target. Overlay re-binds this when the
|
|
1674
|
-
* consumer changes `returnFocus` after construction; the new value applies
|
|
1675
|
-
* on the next `release()`. No-op when destroyed.
|
|
1676
|
-
*/
|
|
1677
1518
|
setReturnFocus(target) {
|
|
1678
1519
|
if (this.destroyed) return;
|
|
1679
1520
|
this.returnFocus = target;
|
|
1680
1521
|
}
|
|
1681
|
-
/**
|
|
1682
|
-
* Release all install-time teardowns. Short-circuits when not installed,
|
|
1683
|
-
* so `close() → destroy()` (each routing through here) only restores
|
|
1684
|
-
* focus once. The `installed` guard lets `inertSiblings.remove()` and
|
|
1685
|
-
* the focus-trap/scroll-lock teardown nullings stay simple — they were
|
|
1686
|
-
* already idempotent, but `returnFocus.focus()` was firing on every call.
|
|
1687
|
-
*/
|
|
1688
1522
|
release() {
|
|
1689
1523
|
if (!this.installed) return;
|
|
1690
1524
|
this.installed = false;
|
|
@@ -1698,12 +1532,6 @@ var LifecycleController = class {
|
|
|
1698
1532
|
target?.focus?.();
|
|
1699
1533
|
}
|
|
1700
1534
|
}
|
|
1701
|
-
/**
|
|
1702
|
-
* Final teardown — releases any still-installed listeners and seals the
|
|
1703
|
-
* controller. After destroy(), install() is a no-op and setReturnFocus()
|
|
1704
|
-
* is rejected, so post-destroy mutations can't queue up a stale focus
|
|
1705
|
-
* restore.
|
|
1706
|
-
*/
|
|
1707
1535
|
destroy() {
|
|
1708
1536
|
this.release();
|
|
1709
1537
|
this.destroyed = true;
|
|
@@ -1713,12 +1541,10 @@ var LifecycleController = class {
|
|
|
1713
1541
|
// src/core/gestures.ts
|
|
1714
1542
|
var isAxisVertical = (mode) => mode === "bottom" || mode === "top";
|
|
1715
1543
|
var SampleRing = class {
|
|
1716
|
-
// current count, ≤ capacity
|
|
1717
1544
|
constructor(capacity) {
|
|
1718
1545
|
__publicField(this, "slots");
|
|
1719
1546
|
__publicField(this, "capacity");
|
|
1720
1547
|
__publicField(this, "head", 0);
|
|
1721
|
-
// next write index
|
|
1722
1548
|
__publicField(this, "size", 0);
|
|
1723
1549
|
this.capacity = capacity;
|
|
1724
1550
|
this.slots = new Array(capacity);
|
|
@@ -1731,12 +1557,6 @@ var SampleRing = class {
|
|
|
1731
1557
|
this.head = (this.head + 1) % this.capacity;
|
|
1732
1558
|
if (this.size < this.capacity) this.size++;
|
|
1733
1559
|
}
|
|
1734
|
-
/**
|
|
1735
|
-
* Drop oldest entries whose timestamp is below `cutoff`, but never shrink
|
|
1736
|
-
* below `minKeep`. Mirrors the original
|
|
1737
|
-
* `while (samples.length > minKeep && samples[0].t < cutoff) samples.shift()`
|
|
1738
|
-
* but without copying — just advances the logical tail.
|
|
1739
|
-
*/
|
|
1740
1560
|
pruneBefore(cutoff, minKeep) {
|
|
1741
1561
|
while (this.size > minKeep) {
|
|
1742
1562
|
const oldestIdx = (this.head - this.size + this.capacity) % this.capacity;
|
|
@@ -1872,28 +1692,14 @@ var GestureController = class {
|
|
|
1872
1692
|
__publicField(this, "detach", null);
|
|
1873
1693
|
__publicField(this, "isDragging_", false);
|
|
1874
1694
|
__publicField(this, "dragStartSize", 0);
|
|
1875
|
-
// Only "touch" gestures are eligible for soft-keyboard dismissal —
|
|
1876
|
-
// mouse/trackpad users don't have a keyboard to dismiss.
|
|
1877
1695
|
__publicField(this, "currentPointerKind", "touch");
|
|
1878
|
-
// One blur per drag — flipping focus every move event races the keyboard's
|
|
1879
|
-
// own animations on iOS and makes the page jitter.
|
|
1880
1696
|
__publicField(this, "keyboardDismissed", false);
|
|
1881
|
-
// Reused payload object for the "drag" event — mutated each onMove instead
|
|
1882
|
-
// of allocating a fresh `{size, delta}` per frame. At 60-120Hz a long drag
|
|
1883
|
-
// would otherwise churn tens of KB through the GC. Mirrors browser
|
|
1884
|
-
// PointerEvent semantics: consumers must NOT retain the reference across
|
|
1885
|
-
// frames (clone if needed). See SheetEventMap.drag JSDoc.
|
|
1886
1697
|
__publicField(this, "dragPayload", { size: 0, delta: 0 });
|
|
1887
1698
|
this.deps = deps;
|
|
1888
1699
|
}
|
|
1889
|
-
/** True between `dragstart` and `dragend`/`onCancel`. */
|
|
1890
1700
|
get isDragging() {
|
|
1891
1701
|
return this.isDragging_;
|
|
1892
1702
|
}
|
|
1893
|
-
/**
|
|
1894
|
-
* Bind pointer listeners on the handle and return a teardown. Engine pushes
|
|
1895
|
-
* the teardown into its TeardownStack so destroy() drains it once.
|
|
1896
|
-
*/
|
|
1897
1703
|
install() {
|
|
1898
1704
|
if (this.detach) return this.detach;
|
|
1899
1705
|
this.detach = installGestures(this.deps.handle, this.deps.mode, {
|
|
@@ -1950,11 +1756,6 @@ var GestureController = class {
|
|
|
1950
1756
|
});
|
|
1951
1757
|
return this.detach;
|
|
1952
1758
|
}
|
|
1953
|
-
/**
|
|
1954
|
-
* Force-clear drag visual state. Engine calls from destroy() when destroyed
|
|
1955
|
-
* mid-drag — gesture detach won't synthesize an onCancel, so we have to
|
|
1956
|
-
* roll back the data-attribute + will-change ourselves.
|
|
1957
|
-
*/
|
|
1958
1759
|
forceClearDragState() {
|
|
1959
1760
|
if (!this.isDragging_) return;
|
|
1960
1761
|
this.isDragging_ = false;
|
|
@@ -1973,11 +1774,6 @@ var AriaSliderWriter = class {
|
|
|
1973
1774
|
mode === "bottom" || mode === "top" ? "vertical" : "horizontal"
|
|
1974
1775
|
);
|
|
1975
1776
|
}
|
|
1976
|
-
/**
|
|
1977
|
-
* Update slider position. `allowedIds` length determines `aria-valuemax`;
|
|
1978
|
-
* `activeId` indexes into it for `aria-valuenow` + `aria-valuetext`.
|
|
1979
|
-
* Empty list → strip every dynamic attr so AT skips the handle entirely.
|
|
1980
|
-
*/
|
|
1981
1777
|
setValue(allowedIds, activeId) {
|
|
1982
1778
|
if (allowedIds.length === 0) {
|
|
1983
1779
|
this.handle.removeAttribute("aria-valuemin");
|
|
@@ -2051,9 +1847,6 @@ function resolveEngineOptions(opts, extras) {
|
|
|
2051
1847
|
scrimMode: opts.scrimMode,
|
|
2052
1848
|
scrimColor: opts.scrimColor,
|
|
2053
1849
|
scrimBlur: opts.scrimBlur,
|
|
2054
|
-
// Auto-promote pointer-events when tap-to-close is on so the click
|
|
2055
|
-
// listener actually receives events. Caller can still force `false`
|
|
2056
|
-
// explicitly to opt out — `??` only kicks in for `undefined`.
|
|
2057
1850
|
scrimInteractive: opts.scrimInteractive ?? (opts.scrimTapToClose ? true : void 0),
|
|
2058
1851
|
scrimTapToClose: opts.scrimTapToClose,
|
|
2059
1852
|
scrimPreset: opts.scrimPreset,
|
|
@@ -2074,10 +1867,6 @@ function resolveEngineOptions(opts, extras) {
|
|
|
2074
1867
|
closeOnEscape: opts.closeOnEscape,
|
|
2075
1868
|
lockBodyScroll: opts.lockBodyScroll,
|
|
2076
1869
|
inertSiblings: opts.inertSiblings,
|
|
2077
|
-
// Folded in from `extras` so the lifecycle bag is fully assembled at
|
|
2078
|
-
// the call site — engine no longer needs a spread+override at
|
|
2079
|
-
// controller construction. When `extras` is omitted, the field stays
|
|
2080
|
-
// undefined and the controller uses its own default predicate.
|
|
2081
1870
|
shouldApplyInertSiblings: extras?.shouldApplyInertSiblings
|
|
2082
1871
|
}
|
|
2083
1872
|
};
|
|
@@ -2112,6 +1901,7 @@ var BottomSheetEngine = class {
|
|
|
2112
1901
|
__publicField(this, "scrollContainer");
|
|
2113
1902
|
__publicField(this, "backdrop");
|
|
2114
1903
|
__publicField(this, "screenComponent");
|
|
1904
|
+
__publicField(this, "scrimParent", null);
|
|
2115
1905
|
__publicField(this, "mode");
|
|
2116
1906
|
__publicField(this, "flickVelocity");
|
|
2117
1907
|
__publicField(this, "dragThreshold");
|
|
@@ -2122,40 +1912,22 @@ var BottomSheetEngine = class {
|
|
|
2122
1912
|
__publicField(this, "lifecycle");
|
|
2123
1913
|
__publicField(this, "closeOnBack");
|
|
2124
1914
|
__publicField(this, "routedTo");
|
|
2125
|
-
// Engine retains `snapPointsRaw` for the "find a closed-id" query in
|
|
2126
|
-
// close() (raw input, not resolved geometry). Resolver owns geometry.
|
|
2127
1915
|
__publicField(this, "snapPointsRaw");
|
|
2128
1916
|
__publicField(this, "snaps");
|
|
2129
1917
|
__publicField(this, "activeId");
|
|
2130
1918
|
__publicField(this, "size", 0);
|
|
2131
|
-
// Constructed in attach(); a plugin's install() could read `state` before
|
|
2132
|
-
// attach completes if the constructor throws partway through. State getter
|
|
2133
|
-
// null-guards via `this.gesture?.isDragging ?? false`.
|
|
2134
1919
|
__publicField(this, "gesture");
|
|
2135
1920
|
__publicField(this, "rootEl", null);
|
|
2136
1921
|
__publicField(this, "destroyed", false);
|
|
2137
|
-
// In-flight ViewTransition handle. A second snapTo while a VT is in flight
|
|
2138
|
-
// would otherwise let Chromium reject the second's promise and flicker —
|
|
2139
|
-
// newCycle() calls skipTransition() to abort cleanly.
|
|
2140
1922
|
__publicField(this, "currentViewTransition", null);
|
|
2141
|
-
// Each cycle captures the signal at entry; when a newer cycle aborts the
|
|
2142
|
-
// controller, the captured signal flips to `aborted=true` and post-await
|
|
2143
|
-
// guards short-circuit (prevents stale snap/open/close emits).
|
|
2144
1923
|
__publicField(this, "currentAbort", new AbortController());
|
|
2145
|
-
// Sub-pixel `--bs-size` deltas and <1% `--bs-progress` deltas are not
|
|
2146
|
-
// visually distinguishable; gating CSSOM writes drops 30-50% of writes
|
|
2147
|
-
// during the spring's settle tail.
|
|
2148
1924
|
__publicField(this, "sizeWriteSentinel", new WriteSentinel());
|
|
2149
1925
|
__publicField(this, "progressWriteSentinel", new WriteSentinel());
|
|
2150
1926
|
__publicField(this, "isTopSheet", true);
|
|
2151
|
-
// Pooled payload — identity documented in SheetEventMap.progress JSDoc;
|
|
2152
|
-
// consumers must not retain across frames.
|
|
2153
1927
|
__publicField(this, "progressPayload", {
|
|
2154
1928
|
value: 0,
|
|
2155
1929
|
size: 0
|
|
2156
1930
|
});
|
|
2157
|
-
// Pooled buffer for `getDragContext()` — onMove calls this 60-120×/s.
|
|
2158
|
-
// Inner `range` object identity is also stable (mutated in place).
|
|
2159
1931
|
__publicField(this, "dragContextBuf", {
|
|
2160
1932
|
size: 0,
|
|
2161
1933
|
maxAxisSize: 0,
|
|
@@ -2166,13 +1938,7 @@ var BottomSheetEngine = class {
|
|
|
2166
1938
|
__publicField(this, "persistKey");
|
|
2167
1939
|
__publicField(this, "linkedSheets", []);
|
|
2168
1940
|
__publicField(this, "scrollCache");
|
|
2169
|
-
// Single LIFO stack for ALL destroy-only teardowns. Plugins (added last)
|
|
2170
|
-
// tear down first before the infrastructure they depend on. Toggle-semantic
|
|
2171
|
-
// listeners (focus-trap / scroll-lock / scrim tap-to-close) stay as named
|
|
2172
|
-
// fields on their controllers.
|
|
2173
1941
|
__publicField(this, "teardowns", new TeardownStack());
|
|
2174
|
-
// Pre-computed transform template — built once per engine since `mode` is
|
|
2175
|
-
// fixed for its lifetime. Avoids the 4-arm switch at 60-120 Hz.
|
|
2176
1942
|
__publicField(this, "transformTemplate");
|
|
2177
1943
|
const resolved = resolveEngineOptions(opts, {
|
|
2178
1944
|
shouldApplyInertSiblings: () => {
|
|
@@ -2187,7 +1953,8 @@ var BottomSheetEngine = class {
|
|
|
2187
1953
|
this.handle = opts.handle ?? opts.element;
|
|
2188
1954
|
this.scrollContainer = opts.scrollContainer;
|
|
2189
1955
|
this.backdrop = opts.backdrop;
|
|
2190
|
-
this.screenComponent = opts.screenComponent;
|
|
1956
|
+
this.screenComponent = opts.scrim ?? opts.screenComponent;
|
|
1957
|
+
this.scrimParent = this.screenComponent?.parentElement ?? null;
|
|
2191
1958
|
this.mode = resolved.mode;
|
|
2192
1959
|
this.transformTemplate = buildTransformTemplate(this.mode);
|
|
2193
1960
|
this.aria = new AriaSliderWriter(this.handle, this.mode);
|
|
@@ -2215,8 +1982,6 @@ var BottomSheetEngine = class {
|
|
|
2215
1982
|
getRootEl: () => this.rootEl,
|
|
2216
1983
|
applySize: (size) => this.applySize(size),
|
|
2217
1984
|
getSize: () => this.size,
|
|
2218
|
-
// Optional chain protects synthetic test paths that drive animateTo
|
|
2219
|
-
// before attach() (gesture is constructed there).
|
|
2220
1985
|
isDragging: () => this.gesture?.isDragging ?? false
|
|
2221
1986
|
},
|
|
2222
1987
|
resolved.animation
|
|
@@ -2321,21 +2086,6 @@ var BottomSheetEngine = class {
|
|
|
2321
2086
|
on(event, fn) {
|
|
2322
2087
|
return this.bus.on(event, fn);
|
|
2323
2088
|
}
|
|
2324
|
-
/**
|
|
2325
|
-
* Register a plugin. `install` runs synchronously; if it returns a function,
|
|
2326
|
-
* it's captured for teardown during `destroy()`. No-op if already destroyed
|
|
2327
|
-
* — installing into a torn-down engine would leak listeners.
|
|
2328
|
-
*
|
|
2329
|
-
* Throws from `plugin.install` are caught and rethrown via `queueMicrotask`
|
|
2330
|
-
* so a buggy plugin can't take the engine down with it: the engine stays
|
|
2331
|
-
* usable, sibling plugins still install, and the error surfaces in dev tools
|
|
2332
|
-
* on the next tick instead of being swallowed. Mirrors the per-fn isolation
|
|
2333
|
-
* model used for teardowns.
|
|
2334
|
-
*
|
|
2335
|
-
* Plugins that accept the second `scope` argument get transactional cleanup:
|
|
2336
|
-
* push partial-install cleanups via `scope.add(fn)` and the engine drains
|
|
2337
|
-
* them on throw, OR merges them into destroy-time teardowns on success.
|
|
2338
|
-
*/
|
|
2339
2089
|
use(plugin) {
|
|
2340
2090
|
if (this.destroyed) {
|
|
2341
2091
|
console.warn(
|
|
@@ -2345,9 +2095,6 @@ var BottomSheetEngine = class {
|
|
|
2345
2095
|
}
|
|
2346
2096
|
const scoped = [];
|
|
2347
2097
|
const scope = {
|
|
2348
|
-
// typeof check — not just truthiness — so a JS-only plugin pushing a
|
|
2349
|
-
// bogus value is silently rejected instead of queueing a confusing
|
|
2350
|
-
// TypeError on destroy() drain.
|
|
2351
2098
|
add: (fn) => {
|
|
2352
2099
|
if (typeof fn === "function") scoped.push(fn);
|
|
2353
2100
|
}
|
|
@@ -2376,36 +2123,13 @@ var BottomSheetEngine = class {
|
|
|
2376
2123
|
}
|
|
2377
2124
|
return this;
|
|
2378
2125
|
}
|
|
2379
|
-
/**
|
|
2380
|
-
* Replace the linked-sheets list at runtime. Use when peer engines aren't
|
|
2381
|
-
* available at construction time (mounted later in the tree). The wiring
|
|
2382
|
-
* to the `open` event is independent of this list — it reads `linkedSheets`
|
|
2383
|
-
* lazily on emit, so this setter is a simple field swap.
|
|
2384
|
-
*/
|
|
2385
2126
|
setLinkedSheets(sheets) {
|
|
2386
2127
|
if (this.destroyed) return;
|
|
2387
2128
|
this.linkedSheets = sheets;
|
|
2388
2129
|
}
|
|
2389
|
-
/** Read-only view of the current allow-list, for cross-sheet target negotiation. */
|
|
2390
2130
|
getAllowedIds() {
|
|
2391
2131
|
return this.snaps.getAllowedIds().slice();
|
|
2392
2132
|
}
|
|
2393
|
-
/**
|
|
2394
|
-
* Animate to a snap point by id. Resolves when the animation completes.
|
|
2395
|
-
*
|
|
2396
|
-
* Two call shapes:
|
|
2397
|
-
* ```ts
|
|
2398
|
-
* engine.snapTo("full"); // default velocity
|
|
2399
|
-
* engine.snapTo("full", 0.5); // px/ms initial velocity
|
|
2400
|
-
* engine.snapTo("full", { velocity: 0.5, signal }); // abortable
|
|
2401
|
-
* ```
|
|
2402
|
-
*
|
|
2403
|
-
* When `opts.signal` is provided, calling `controller.abort()` cancels the
|
|
2404
|
-
* in-flight tween/spring and the returned promise resolves without firing
|
|
2405
|
-
* `snap`. The captured `AbortSignal` is checked after each await so external
|
|
2406
|
-
* aborts ride the same cycle invariant as internal ones (resize, destroy,
|
|
2407
|
-
* concurrent snapTo).
|
|
2408
|
-
*/
|
|
2409
2133
|
async snapTo(id, velocityOrOpts = 0, _skipBeforeSnap = false) {
|
|
2410
2134
|
if (this.destroyed) return;
|
|
2411
2135
|
const opts = typeof velocityOrOpts === "object" ? velocityOrOpts : { velocity: velocityOrOpts };
|
|
@@ -2464,16 +2188,6 @@ var BottomSheetEngine = class {
|
|
|
2464
2188
|
this.handleClose();
|
|
2465
2189
|
}
|
|
2466
2190
|
}
|
|
2467
|
-
/**
|
|
2468
|
-
* Drive the sheet to an arbitrary px size, bypassing snap matching.
|
|
2469
|
-
* Useful for preview scrubs, animation chaining, or programmatic gestures.
|
|
2470
|
-
* Animates with the configured spring/tween. Resolves when the animation
|
|
2471
|
-
* completes. Does NOT update `activeId` — call `snapTo(id)` after to commit.
|
|
2472
|
-
*
|
|
2473
|
-
* Unlike `snapTo`, this does not fire `before-snap` (it isn't a snap commit)
|
|
2474
|
-
* nor `snap` (the sheet isn't settling to a known snap). `progress` events
|
|
2475
|
-
* still fire via applySize. Target is clamped to `[0, maxAxisSize]`.
|
|
2476
|
-
*/
|
|
2477
2191
|
async dragTo(targetSize, velocityOrOpts = 0) {
|
|
2478
2192
|
if (this.destroyed) return;
|
|
2479
2193
|
const opts = typeof velocityOrOpts === "object" ? velocityOrOpts : { velocity: velocityOrOpts };
|
|
@@ -2511,20 +2225,10 @@ var BottomSheetEngine = class {
|
|
|
2511
2225
|
this.snaps.setAllowedIds(ids);
|
|
2512
2226
|
this.updateAriaSlider();
|
|
2513
2227
|
if (snap && ids.includes(snap)) {
|
|
2514
|
-
void this.snapTo(
|
|
2515
|
-
snap,
|
|
2516
|
-
0,
|
|
2517
|
-
/* internal */
|
|
2518
|
-
true
|
|
2519
|
-
);
|
|
2228
|
+
void this.snapTo(snap, 0, true);
|
|
2520
2229
|
} else if (!ids.includes(this.activeId)) {
|
|
2521
2230
|
const fallback = ids[0];
|
|
2522
|
-
if (fallback) void this.snapTo(
|
|
2523
|
-
fallback,
|
|
2524
|
-
0,
|
|
2525
|
-
/* internal */
|
|
2526
|
-
true
|
|
2527
|
-
);
|
|
2231
|
+
if (fallback) void this.snapTo(fallback, 0, true);
|
|
2528
2232
|
}
|
|
2529
2233
|
}
|
|
2530
2234
|
setBackdropRange(range) {
|
|
@@ -2542,21 +2246,6 @@ var BottomSheetEngine = class {
|
|
|
2542
2246
|
setScrimInteractive(interactive) {
|
|
2543
2247
|
this.scrim.setScrimInteractive(interactive);
|
|
2544
2248
|
}
|
|
2545
|
-
/**
|
|
2546
|
-
* Batch-update multiple scrim fields in one call. Apply order is:
|
|
2547
|
-
* 1. `preset` — fills baseline color/blur/range/interactive.
|
|
2548
|
-
* 2. `mode` — re-positions the scrim (fixed inset / clear / hide).
|
|
2549
|
-
* 3. `enabled` — flips the opacity contribution on/off.
|
|
2550
|
-
* 4. `tapToClose` — installs/tears the click listener.
|
|
2551
|
-
* 5. `color` / `blur` / `interactive` / `range` — explicit overrides.
|
|
2552
|
-
* 6. ONE `applySize` so the per-frame opacity stays consistent.
|
|
2553
|
-
*
|
|
2554
|
-
* Performance: collecting changes here (vs calling individual setters)
|
|
2555
|
-
* avoids repeated `applySize` calls during a multi-field swap. Setters
|
|
2556
|
-
* called here suppress their own internal `applySize` either by passing
|
|
2557
|
-
* through fast-paths (mode/enabled no-op when value unchanged) or by
|
|
2558
|
-
* being visual-only (color/blur/interactive don't influence opacity).
|
|
2559
|
-
*/
|
|
2560
2249
|
setScrim(opts) {
|
|
2561
2250
|
this.scrim.setScrim(opts, () => this.applySize(this.size));
|
|
2562
2251
|
}
|
|
@@ -2572,11 +2261,6 @@ var BottomSheetEngine = class {
|
|
|
2572
2261
|
setScrimOverlay(opts) {
|
|
2573
2262
|
return this.scrim.setScrimOverlay(opts);
|
|
2574
2263
|
}
|
|
2575
|
-
/**
|
|
2576
|
-
* Read-only snapshot of scrim state. Use the `setScrim*` setters to mutate.
|
|
2577
|
-
* Stable public API — internals (e.g. cached opacity sentinels) are NOT
|
|
2578
|
-
* exposed so consumers can't accidentally couple to ScrimController shape.
|
|
2579
|
-
*/
|
|
2580
2264
|
getScrimState() {
|
|
2581
2265
|
return { mode: this.scrim.scrimMode, enabled: this.scrim.scrimEnabled };
|
|
2582
2266
|
}
|
|
@@ -2622,24 +2306,11 @@ var BottomSheetEngine = class {
|
|
|
2622
2306
|
emit(event, payload) {
|
|
2623
2307
|
this.bus.emit(event, payload);
|
|
2624
2308
|
}
|
|
2625
|
-
/**
|
|
2626
|
-
* Abort the current cycle's signal and replace the controller. Returns the
|
|
2627
|
-
* fresh signal so the caller can capture it locally before any await — when
|
|
2628
|
-
* a future newCycle() / destroy aborts our controller, the captured signal
|
|
2629
|
-
* flips to aborted and post-await guards short-circuit.
|
|
2630
|
-
*/
|
|
2631
2309
|
newCycle() {
|
|
2632
2310
|
this.currentAbort.abort();
|
|
2633
2311
|
this.currentAbort = new AbortController();
|
|
2634
2312
|
return this.currentAbort.signal;
|
|
2635
2313
|
}
|
|
2636
|
-
/**
|
|
2637
|
-
* Fire `before-snap` and report whether a listener cancelled it. The
|
|
2638
|
-
* `cancel()` callback exposed to listeners is frozen after the synchronous
|
|
2639
|
-
* emit phase so async callers can't silently miss — they get a console
|
|
2640
|
-
* warning. Returns `true` when cancelled so callers can early-return /
|
|
2641
|
-
* spring-back without re-implementing the cancel/frozen pattern.
|
|
2642
|
-
*/
|
|
2643
2314
|
emitBeforeSnap(target, previousId) {
|
|
2644
2315
|
let cancelled = false;
|
|
2645
2316
|
let frozen = false;
|
|
@@ -2673,30 +2344,9 @@ var BottomSheetEngine = class {
|
|
|
2673
2344
|
this.snaps.setRaw(this.snapPointsRaw);
|
|
2674
2345
|
this.scrim.invalidateOpacityCache();
|
|
2675
2346
|
}
|
|
2676
|
-
/**
|
|
2677
|
-
* Memoised `allowedRange()` — delegates to SnapResolver which owns the cache.
|
|
2678
|
-
* Engine wrapper kept so existing call sites don't all need updating;
|
|
2679
|
-
* resolver-level memoization survives across method invocations.
|
|
2680
|
-
*/
|
|
2681
2347
|
getAllowedRange() {
|
|
2682
2348
|
return this.snaps.getAllowedRange();
|
|
2683
2349
|
}
|
|
2684
|
-
/**
|
|
2685
|
-
* Write ARIA slider value attributes onto the handle so the engine itself
|
|
2686
|
-
* is the source of truth for screen-reader announcements. Called from the
|
|
2687
|
-
* constructor and from every code path that mutates `activeId` /
|
|
2688
|
-
* `allowedIds`. WAI-ARIA 1.2 requires `aria-valuenow` for `role="slider"` —
|
|
2689
|
-
* without it screen readers can't announce drag/snap progress to keyboard
|
|
2690
|
-
* + AT users (WCAG 4.1.2 Name, Role, Value).
|
|
2691
|
-
*
|
|
2692
|
-
* Engine does NOT set `role="slider"` itself — that's the adapter's or
|
|
2693
|
-
* consumer markup's responsibility. We only decorate with dynamic values.
|
|
2694
|
-
*
|
|
2695
|
-
* Empty allowed-list is malformed input (settable via `setAllowed([])`);
|
|
2696
|
-
* short-circuit to remove ARIA value attributes so screen readers see a
|
|
2697
|
-
* no-value slider rather than a degenerate `min=max=now=0` (WAI-ARIA 1.2
|
|
2698
|
-
* requires `valuemax > valuemin` for `role="slider"`).
|
|
2699
|
-
*/
|
|
2700
2350
|
updateAriaSlider() {
|
|
2701
2351
|
this.aria.setValue(this.snaps.getAllowedIds(), this.activeId);
|
|
2702
2352
|
}
|
|
@@ -2721,11 +2371,6 @@ var BottomSheetEngine = class {
|
|
|
2721
2371
|
element: this.element,
|
|
2722
2372
|
mode: this.mode,
|
|
2723
2373
|
getRoot: () => this.rootEl,
|
|
2724
|
-
// Single coalesced reader — narrows the DI surface and removes 3 getter
|
|
2725
|
-
// dispatches per onMove frame at 60-120Hz. Returns a SHARED buffer
|
|
2726
|
-
// (this.dragContextBuf) — see field JSDoc for the retention contract.
|
|
2727
|
-
// Inner `range` object is mutated in place too so callers caching its
|
|
2728
|
-
// identity between frames stay valid.
|
|
2729
2374
|
getDragContext: () => {
|
|
2730
2375
|
const buf = this.dragContextBuf;
|
|
2731
2376
|
const r = this.getAllowedRange();
|
|
@@ -2891,7 +2536,6 @@ var BottomSheetEngine = class {
|
|
|
2891
2536
|
}
|
|
2892
2537
|
});
|
|
2893
2538
|
}
|
|
2894
|
-
/** Trigger a brief haptic tick (iOS Safari + Android Chrome support). */
|
|
2895
2539
|
haptic() {
|
|
2896
2540
|
if (typeof navigator !== "undefined" && "vibrate" in navigator) {
|
|
2897
2541
|
try {
|
|
@@ -2907,6 +2551,9 @@ var BottomSheetEngine = class {
|
|
|
2907
2551
|
style.transform = this.transformTemplate(offset);
|
|
2908
2552
|
if (this.sizeWriteSentinel.shouldWrite(size, SIZE_WRITE_EPSILON)) {
|
|
2909
2553
|
style.setProperty("--bs-size", `${size}px`);
|
|
2554
|
+
if (this.scrimParent) {
|
|
2555
|
+
this.scrimParent.style.setProperty("--bs-size", `${size}px`);
|
|
2556
|
+
}
|
|
2910
2557
|
}
|
|
2911
2558
|
const progress = this.computeProgress(size);
|
|
2912
2559
|
const progressChanged = this.progressWriteSentinel.shouldWrite(
|
|
@@ -2998,14 +2645,14 @@ function createBottomSheet(opts) {
|
|
|
2998
2645
|
destroy: () => {
|
|
2999
2646
|
engine?.destroy();
|
|
3000
2647
|
engine = null;
|
|
3001
|
-
}
|
|
2648
|
+
},
|
|
2649
|
+
getEngine: () => engine
|
|
3002
2650
|
};
|
|
3003
2651
|
}
|
|
3004
2652
|
var root_1 = $2.from_html(`<div class="bs-backdrop" aria-hidden="true"></div>`);
|
|
3005
|
-
var root_2 = $2.from_html(`<div class="bs-screen"><!></div>`);
|
|
3006
2653
|
var root_3 = $2.from_html(`<div class="bs-button-slot" data-side="left"><!></div>`);
|
|
3007
2654
|
var root_4 = $2.from_html(`<div class="bs-button-slot" data-side="right"><!></div>`);
|
|
3008
|
-
var root = $2.from_html(`<div class="bs-root"><!>
|
|
2655
|
+
var root = $2.from_html(`<div class="bs-root"><!> <div class="bs-screen"><!></div> <section class="bs-sheet" role="dialog"><!> <!> <div class="bs-handle" role="slider" tabindex="0" aria-label="Resize sheet"><!></div> <div class="bs-content" tabindex="0" role="region" aria-label="Sheet content"><!></div> <span class="bs-sr-only" role="status" aria-live="polite"> </span></section></div>`);
|
|
3009
2656
|
function BottomSheet($$anchor, $$props) {
|
|
3010
2657
|
$2.push($$props, true);
|
|
3011
2658
|
let mode = $2.prop($$props, "mode", 3, "bottom"), animation = $2.prop($$props, "animation", 3, "spring"), focusTrap = $2.prop($$props, "focusTrap", 3, false), closeOnEscape = $2.prop($$props, "closeOnEscape", 3, true), closeOnBack = $2.prop($$props, "closeOnBack", 3, false), lockBodyScroll2 = $2.prop($$props, "lockBodyScroll", 3, true), rubberBand2 = $2.prop($$props, "rubberBand", 3, true), backdrop = $2.prop($$props, "backdrop", 3, true), closeOnBackdrop = $2.prop($$props, "closeOnBackdrop", 3, true), ariaLabel = $2.prop($$props, "ariaLabel", 3, "Bottom sheet");
|
|
@@ -3029,7 +2676,7 @@ function BottomSheet($$anchor, $$props) {
|
|
|
3029
2676
|
handle: $2.get(handleEl),
|
|
3030
2677
|
scrollContainer: $2.get(contentEl),
|
|
3031
2678
|
backdrop: $2.get(backdropEl),
|
|
3032
|
-
|
|
2679
|
+
scrim: $2.get(screenEl),
|
|
3033
2680
|
mode: mode(),
|
|
3034
2681
|
snapPoints: $$props.snapPoints,
|
|
3035
2682
|
allowed: $$props.allowed,
|
|
@@ -3066,8 +2713,26 @@ function BottomSheet($$anchor, $$props) {
|
|
|
3066
2713
|
const open = (id) => engine?.open(id) ?? Promise.resolve();
|
|
3067
2714
|
const close = () => engine?.close() ?? Promise.resolve();
|
|
3068
2715
|
const setAllowed = (ids, snap) => engine?.setAllowed(ids, snap);
|
|
2716
|
+
const setSnapPoints = (points, nextAllowed) => engine?.setSnapPoints(points, nextAllowed);
|
|
2717
|
+
const setScrim = (opts) => engine?.setScrim(opts);
|
|
2718
|
+
const setScrimOverlay = (opts) => engine?.setScrimOverlay(opts) ?? (() => {
|
|
2719
|
+
});
|
|
3069
2720
|
const getState = () => engine?.state ?? $2.get(viewState);
|
|
3070
|
-
|
|
2721
|
+
const getEngine = () => engine;
|
|
2722
|
+
let allowedIds = $2.derived(() => $$props.allowed && $$props.allowed.length > 0 ? $$props.allowed : $$props.snapPoints.map((s) => s.id));
|
|
2723
|
+
let activeIdx = $2.derived(() => $2.get(allowedIds).indexOf($2.get(viewState).activeId));
|
|
2724
|
+
let isVerticalAxis = $2.derived(() => mode() === "bottom" || mode() === "top");
|
|
2725
|
+
var $$exports = {
|
|
2726
|
+
snapTo,
|
|
2727
|
+
open,
|
|
2728
|
+
close,
|
|
2729
|
+
setAllowed,
|
|
2730
|
+
setSnapPoints,
|
|
2731
|
+
setScrim,
|
|
2732
|
+
setScrimOverlay,
|
|
2733
|
+
getState,
|
|
2734
|
+
getEngine
|
|
2735
|
+
};
|
|
3071
2736
|
var div = root();
|
|
3072
2737
|
var node = $2.child(div);
|
|
3073
2738
|
{
|
|
@@ -3083,21 +2748,22 @@ function BottomSheet($$anchor, $$props) {
|
|
|
3083
2748
|
if (backdrop()) $$render(consequent);
|
|
3084
2749
|
});
|
|
3085
2750
|
}
|
|
3086
|
-
var
|
|
2751
|
+
var div_2 = $2.sibling(node, 2);
|
|
2752
|
+
var node_1 = $2.child(div_2);
|
|
3087
2753
|
{
|
|
3088
2754
|
var consequent_1 = ($$anchor2) => {
|
|
3089
|
-
var
|
|
3090
|
-
var node_2 = $2.
|
|
2755
|
+
var fragment = $2.comment();
|
|
2756
|
+
var node_2 = $2.first_child(fragment);
|
|
3091
2757
|
$2.snippet(node_2, () => $$props.screen);
|
|
3092
|
-
$2.
|
|
3093
|
-
$2.bind_this(div_2, ($$value) => $2.set(screenEl, $$value), () => $2.get(screenEl));
|
|
3094
|
-
$2.append($$anchor2, div_2);
|
|
2758
|
+
$2.append($$anchor2, fragment);
|
|
3095
2759
|
};
|
|
3096
2760
|
$2.if(node_1, ($$render) => {
|
|
3097
2761
|
if ($$props.screen) $$render(consequent_1);
|
|
3098
2762
|
});
|
|
3099
2763
|
}
|
|
3100
|
-
|
|
2764
|
+
$2.reset(div_2);
|
|
2765
|
+
$2.bind_this(div_2, ($$value) => $2.set(screenEl, $$value), () => $2.get(screenEl));
|
|
2766
|
+
var section = $2.sibling(div_2, 2);
|
|
3101
2767
|
var node_3 = $2.child(section);
|
|
3102
2768
|
{
|
|
3103
2769
|
var consequent_2 = ($$anchor2) => {
|
|
@@ -3125,13 +2791,14 @@ function BottomSheet($$anchor, $$props) {
|
|
|
3125
2791
|
});
|
|
3126
2792
|
}
|
|
3127
2793
|
var div_5 = $2.sibling(node_5, 2);
|
|
2794
|
+
$2.set_attribute(div_5, "aria-valuemin", 0);
|
|
3128
2795
|
var node_7 = $2.child(div_5);
|
|
3129
2796
|
{
|
|
3130
2797
|
var consequent_4 = ($$anchor2) => {
|
|
3131
|
-
var
|
|
3132
|
-
var node_8 = $2.first_child(
|
|
2798
|
+
var fragment_1 = $2.comment();
|
|
2799
|
+
var node_8 = $2.first_child(fragment_1);
|
|
3133
2800
|
$2.snippet(node_8, () => $$props.header, () => $2.get(viewState));
|
|
3134
|
-
$2.append($$anchor2,
|
|
2801
|
+
$2.append($$anchor2, fragment_1);
|
|
3135
2802
|
};
|
|
3136
2803
|
$2.if(node_7, ($$render) => {
|
|
3137
2804
|
if ($$props.header) $$render(consequent_4);
|
|
@@ -3143,10 +2810,10 @@ function BottomSheet($$anchor, $$props) {
|
|
|
3143
2810
|
var node_9 = $2.child(div_6);
|
|
3144
2811
|
{
|
|
3145
2812
|
var consequent_5 = ($$anchor2) => {
|
|
3146
|
-
var
|
|
3147
|
-
var node_10 = $2.first_child(
|
|
2813
|
+
var fragment_2 = $2.comment();
|
|
2814
|
+
var node_10 = $2.first_child(fragment_2);
|
|
3148
2815
|
$2.snippet(node_10, () => $$props.children);
|
|
3149
|
-
$2.append($$anchor2,
|
|
2816
|
+
$2.append($$anchor2, fragment_2);
|
|
3150
2817
|
};
|
|
3151
2818
|
$2.if(node_9, ($$render) => {
|
|
3152
2819
|
if ($$props.children) $$render(consequent_5);
|
|
@@ -3160,13 +2827,23 @@ function BottomSheet($$anchor, $$props) {
|
|
|
3160
2827
|
$2.reset(section);
|
|
3161
2828
|
$2.bind_this(section, ($$value) => $2.set(sheetEl, $$value), () => $2.get(sheetEl));
|
|
3162
2829
|
$2.reset(div);
|
|
3163
|
-
$2.template_effect(
|
|
3164
|
-
$
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
2830
|
+
$2.template_effect(
|
|
2831
|
+
($0, $1) => {
|
|
2832
|
+
$2.set_attribute(section, "data-mode", mode());
|
|
2833
|
+
$2.set_attribute(section, "data-active", $2.get(viewState).activeId);
|
|
2834
|
+
$2.set_attribute(section, "aria-modal", focusTrap() ? "true" : void 0);
|
|
2835
|
+
$2.set_attribute(section, "aria-label", ariaLabel());
|
|
2836
|
+
$2.set_attribute(div_5, "aria-orientation", $2.get(isVerticalAxis) ? "vertical" : "horizontal");
|
|
2837
|
+
$2.set_attribute(div_5, "aria-valuemax", $0);
|
|
2838
|
+
$2.set_attribute(div_5, "aria-valuenow", $1);
|
|
2839
|
+
$2.set_attribute(div_5, "aria-valuetext", $2.get(viewState).activeId);
|
|
2840
|
+
$2.set_text(text, $2.get(viewState).activeId);
|
|
2841
|
+
},
|
|
2842
|
+
[
|
|
2843
|
+
() => Math.max(0, $2.get(allowedIds).length - 1),
|
|
2844
|
+
() => Math.max(0, $2.get(activeIdx))
|
|
2845
|
+
]
|
|
2846
|
+
);
|
|
3170
2847
|
$2.append($$anchor, div);
|
|
3171
2848
|
return $2.pop($$exports);
|
|
3172
2849
|
}
|