@surdeddd/bottom-sheet 0.13.0 → 0.14.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 +33 -0
- package/dist/{BottomSheetCore-CsIjyq7C.d.cts → BottomSheetCore-Cp7dWy91.d.cts} +26 -1
- package/dist/{BottomSheetCore-D16lsa6g.d.ts → BottomSheetCore-DJYwWOqt.d.ts} +26 -1
- package/dist/{BottomSheetEngine-BYjAVrmd.d.cts → BottomSheetEngine-Lm7HIVHv.d.cts} +1 -1
- package/dist/{BottomSheetEngine-YuCNugZn.d.ts → BottomSheetEngine-O5PbeKfe.d.ts} +1 -1
- package/dist/core.cjs +231 -27
- package/dist/core.d.cts +2 -2
- package/dist/core.d.ts +2 -2
- package/dist/core.js +231 -27
- package/dist/debug.d.cts +1 -1
- package/dist/debug.d.ts +1 -1
- package/dist/element.cjs +300 -102
- package/dist/element.d.cts +2 -2
- package/dist/element.d.ts +2 -2
- package/dist/element.iife.global.js +2 -2
- package/dist/element.js +300 -102
- package/dist/features.cjs +6 -50
- package/dist/features.d.cts +2 -2
- package/dist/features.d.ts +2 -2
- package/dist/features.js +6 -50
- package/dist/index-Bb5TRmyg.d.cts +9 -0
- package/dist/index-Cl9ebCP2.d.ts +9 -0
- package/dist/index.cjs +238 -823
- package/dist/index.d.cts +42 -45
- package/dist/index.d.ts +42 -45
- package/dist/index.js +239 -810
- package/dist/integrations/formik.d.cts +1 -1
- package/dist/integrations/formik.d.ts +1 -1
- package/dist/integrations/react-hook-form.d.cts +1 -1
- package/dist/integrations/react-hook-form.d.ts +1 -1
- package/dist/overlay.cjs +5 -5
- package/dist/overlay.js +5 -5
- package/dist/preact.d.cts +2 -2
- package/dist/preact.d.ts +2 -2
- package/dist/qwik-lib/index.qwik.cjs +228 -77
- package/dist/qwik-lib/index.qwik.mjs +228 -77
- package/dist/qwik.cjs +245 -77
- package/dist/qwik.d.cts +4 -2
- package/dist/qwik.d.ts +4 -2
- package/dist/qwik.js +245 -77
- package/dist/react.cjs +250 -79
- package/dist/react.d.cts +3 -4
- package/dist/react.d.ts +3 -4
- package/dist/react.js +250 -79
- package/dist/solid.cjs +251 -77
- package/dist/solid.d.cts +27 -0
- package/dist/solid.d.ts +27 -0
- package/dist/solid.js +251 -77
- package/dist/solid.source.jsx +259 -77
- package/dist/styles.css +24 -4
- package/dist/svelte-core.cjs +237 -77
- package/dist/svelte-core.js +237 -77
- package/dist/svelte-src/BottomSheet.svelte +14 -0
- package/dist/svelte.cjs +247 -77
- package/dist/svelte.d.cts +2 -0
- package/dist/svelte.d.ts +2 -0
- package/dist/svelte.js +247 -77
- package/dist/vue.cjs +253 -77
- package/dist/vue.js +253 -77
- package/dist/webgl.cjs +583 -0
- package/dist/webgl.d.cts +17 -0
- package/dist/webgl.d.ts +17 -0
- package/dist/webgl.js +581 -0
- package/package.json +36 -12
- package/dist/index-DdYLOIIT.d.ts +0 -15
- package/dist/index-dfrzw-lI.d.cts +0 -15
package/dist/solid.source.jsx
CHANGED
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
Show
|
|
10
10
|
} from "solid-js";
|
|
11
11
|
|
|
12
|
-
// src/core/lifecycle/
|
|
12
|
+
// src/core/lifecycle/sheet-stack.ts
|
|
13
13
|
var BASE_Z = 100;
|
|
14
14
|
var STEP = 10;
|
|
15
15
|
var SheetStack = class {
|
|
@@ -132,7 +132,7 @@ function createEventBus() {
|
|
|
132
132
|
};
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
-
// src/core/primitives/
|
|
135
|
+
// src/core/primitives/css-length.ts
|
|
136
136
|
var probe = null;
|
|
137
137
|
var PROBE_ATTR = "data-bs-probe";
|
|
138
138
|
var ensureProbe = (axis) => {
|
|
@@ -186,7 +186,7 @@ var resolveSnap = (point, mode, measureFit) => {
|
|
|
186
186
|
return Math.max(0, el.getBoundingClientRect().width);
|
|
187
187
|
};
|
|
188
188
|
|
|
189
|
-
// src/core/primitives/
|
|
189
|
+
// src/core/primitives/dev-warn.ts
|
|
190
190
|
function devWarn(...args) {
|
|
191
191
|
if (typeof process !== "undefined" && process.env && process.env.NODE_ENV !== "production" && typeof console !== "undefined") {
|
|
192
192
|
console.warn(...args);
|
|
@@ -1520,7 +1520,7 @@ var AnimationRunner = class {
|
|
|
1520
1520
|
}
|
|
1521
1521
|
};
|
|
1522
1522
|
|
|
1523
|
-
// src/core/lifecycle/
|
|
1523
|
+
// src/core/lifecycle/focus-trap.ts
|
|
1524
1524
|
var FOCUSABLE = [
|
|
1525
1525
|
"a[href]",
|
|
1526
1526
|
"area[href]",
|
|
@@ -1638,7 +1638,7 @@ var installFocusTrap = (container, options = {}) => {
|
|
|
1638
1638
|
};
|
|
1639
1639
|
};
|
|
1640
1640
|
|
|
1641
|
-
// src/core/lifecycle/
|
|
1641
|
+
// src/core/lifecycle/scroll-lock.ts
|
|
1642
1642
|
var lockCount = 0;
|
|
1643
1643
|
var savedStyles = null;
|
|
1644
1644
|
var lockBodyScroll = () => {
|
|
@@ -1820,30 +1820,44 @@ var SampleRing = class {
|
|
|
1820
1820
|
this.size = 0;
|
|
1821
1821
|
}
|
|
1822
1822
|
};
|
|
1823
|
-
var installGestures = (handle, mode, callbacks) => {
|
|
1823
|
+
var installGestures = (handle, mode, callbacks, options = {}) => {
|
|
1824
1824
|
let activePointerId = null;
|
|
1825
1825
|
let activePointerType = "touch";
|
|
1826
1826
|
let startCoord = 0;
|
|
1827
1827
|
let lastCoord = 0;
|
|
1828
|
+
let pendingStart = false;
|
|
1828
1829
|
const VELOCITY_WINDOW_MS = (kind) => kind === "mouse" ? 160 : 120;
|
|
1829
1830
|
const MAX_SAMPLES = 32;
|
|
1830
1831
|
const samples = new SampleRing(MAX_SAMPLES);
|
|
1831
1832
|
const axis = isAxisVertical(mode) ? "Y" : "X";
|
|
1832
1833
|
const sign = mode === "bottom" || mode === "right" ? -1 : 1;
|
|
1833
1834
|
const coordOf = (e) => axis === "Y" ? e.clientY : e.clientX;
|
|
1835
|
+
const capture = (pointerId) => {
|
|
1836
|
+
try {
|
|
1837
|
+
handle.setPointerCapture(pointerId);
|
|
1838
|
+
} catch {
|
|
1839
|
+
}
|
|
1840
|
+
};
|
|
1841
|
+
const releaseTracking = () => {
|
|
1842
|
+
activePointerId = null;
|
|
1843
|
+
pendingStart = false;
|
|
1844
|
+
samples.reset();
|
|
1845
|
+
};
|
|
1834
1846
|
const onPointerDown = (e) => {
|
|
1835
1847
|
if (activePointerId !== null) return;
|
|
1836
1848
|
if (e.button !== void 0 && e.button !== 0) return;
|
|
1849
|
+
if (options.shouldStart && !options.shouldStart(e)) return;
|
|
1837
1850
|
activePointerId = e.pointerId;
|
|
1838
1851
|
activePointerType = e.pointerType || "touch";
|
|
1839
1852
|
startCoord = coordOf(e);
|
|
1840
1853
|
lastCoord = startCoord;
|
|
1841
1854
|
samples.reset();
|
|
1842
1855
|
samples.push(e.timeStamp, startCoord);
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1856
|
+
if (options.deferStart) {
|
|
1857
|
+
pendingStart = true;
|
|
1858
|
+
return;
|
|
1846
1859
|
}
|
|
1860
|
+
capture(e.pointerId);
|
|
1847
1861
|
callbacks.onStart(startCoord, activePointerType);
|
|
1848
1862
|
};
|
|
1849
1863
|
const onPointerMove = (e) => {
|
|
@@ -1851,6 +1865,22 @@ var installGestures = (handle, mode, callbacks) => {
|
|
|
1851
1865
|
const coord = coordOf(e);
|
|
1852
1866
|
const rawDelta = coord - startCoord;
|
|
1853
1867
|
const delta = rawDelta * sign;
|
|
1868
|
+
if (pendingStart) {
|
|
1869
|
+
const verdict = options.deferStart(e, delta);
|
|
1870
|
+
if (verdict === false) {
|
|
1871
|
+
releaseTracking();
|
|
1872
|
+
return;
|
|
1873
|
+
}
|
|
1874
|
+
if (verdict !== true) return;
|
|
1875
|
+
pendingStart = false;
|
|
1876
|
+
startCoord = coord;
|
|
1877
|
+
lastCoord = coord;
|
|
1878
|
+
samples.reset();
|
|
1879
|
+
samples.push(e.timeStamp, coord);
|
|
1880
|
+
capture(e.pointerId);
|
|
1881
|
+
callbacks.onStart(startCoord, activePointerType);
|
|
1882
|
+
return;
|
|
1883
|
+
}
|
|
1854
1884
|
lastCoord = coord;
|
|
1855
1885
|
samples.push(e.timeStamp, coord);
|
|
1856
1886
|
const cutoff = e.timeStamp - VELOCITY_WINDOW_MS(activePointerType);
|
|
@@ -1859,6 +1889,10 @@ var installGestures = (handle, mode, callbacks) => {
|
|
|
1859
1889
|
};
|
|
1860
1890
|
const finishGesture = (e) => {
|
|
1861
1891
|
if (e.pointerId !== activePointerId) return;
|
|
1892
|
+
if (pendingStart) {
|
|
1893
|
+
releaseTracking();
|
|
1894
|
+
return;
|
|
1895
|
+
}
|
|
1862
1896
|
const rawDelta = lastCoord - startCoord;
|
|
1863
1897
|
const delta = rawDelta * sign;
|
|
1864
1898
|
let velocity = 0;
|
|
@@ -1881,22 +1915,26 @@ var installGestures = (handle, mode, callbacks) => {
|
|
|
1881
1915
|
};
|
|
1882
1916
|
const onPointerCancel = (e) => {
|
|
1883
1917
|
if (e.pointerId !== activePointerId) return;
|
|
1884
|
-
|
|
1885
|
-
|
|
1918
|
+
const wasPending = pendingStart;
|
|
1919
|
+
releaseTracking();
|
|
1920
|
+
if (wasPending) return;
|
|
1886
1921
|
callbacks.onCancel?.();
|
|
1887
1922
|
};
|
|
1888
1923
|
handle.addEventListener("pointerdown", onPointerDown);
|
|
1889
1924
|
handle.addEventListener("pointermove", onPointerMove);
|
|
1890
1925
|
handle.addEventListener("pointerup", finishGesture);
|
|
1891
1926
|
handle.addEventListener("pointercancel", onPointerCancel);
|
|
1927
|
+
const managesTouchAction = options.manageTouchAction !== false;
|
|
1892
1928
|
const prevTouchAction = handle.style.touchAction;
|
|
1893
|
-
|
|
1929
|
+
if (managesTouchAction) {
|
|
1930
|
+
handle.style.touchAction = isAxisVertical(mode) ? "pan-x" : "pan-y";
|
|
1931
|
+
}
|
|
1894
1932
|
return () => {
|
|
1895
1933
|
handle.removeEventListener("pointerdown", onPointerDown);
|
|
1896
1934
|
handle.removeEventListener("pointermove", onPointerMove);
|
|
1897
1935
|
handle.removeEventListener("pointerup", finishGesture);
|
|
1898
1936
|
handle.removeEventListener("pointercancel", onPointerCancel);
|
|
1899
|
-
handle.style.touchAction = prevTouchAction;
|
|
1937
|
+
if (managesTouchAction) handle.style.touchAction = prevTouchAction;
|
|
1900
1938
|
if (activePointerId !== null && handle.hasPointerCapture(activePointerId)) {
|
|
1901
1939
|
handle.releasePointerCapture(activePointerId);
|
|
1902
1940
|
}
|
|
@@ -2015,7 +2053,7 @@ var GestureController = class {
|
|
|
2015
2053
|
const restoreTo = this.dragStartSize;
|
|
2016
2054
|
void this.deps.animateTo(restoreTo, 0);
|
|
2017
2055
|
}
|
|
2018
|
-
});
|
|
2056
|
+
}, this.deps.gestureOptions);
|
|
2019
2057
|
return this.detach;
|
|
2020
2058
|
}
|
|
2021
2059
|
forceClearDragState() {
|
|
@@ -2027,6 +2065,41 @@ var GestureController = class {
|
|
|
2027
2065
|
}
|
|
2028
2066
|
};
|
|
2029
2067
|
|
|
2068
|
+
// src/core/primitives/drag-zones.ts
|
|
2069
|
+
var DRAG_ZONE_SELECTOR = "[data-bs-drag]";
|
|
2070
|
+
var NO_DRAG_SELECTOR = "[data-bs-no-drag]";
|
|
2071
|
+
var asElement = (target) => {
|
|
2072
|
+
const candidate = target;
|
|
2073
|
+
return candidate && typeof candidate.closest === "function" ? candidate : null;
|
|
2074
|
+
};
|
|
2075
|
+
function isDragAllowedFrom(target, mode) {
|
|
2076
|
+
const el = asElement(target);
|
|
2077
|
+
if (!el) return mode !== "zones";
|
|
2078
|
+
if (el.closest(NO_DRAG_SELECTOR)) return false;
|
|
2079
|
+
if (mode === "zones") return el.closest(DRAG_ZONE_SELECTOR) !== null;
|
|
2080
|
+
return true;
|
|
2081
|
+
}
|
|
2082
|
+
|
|
2083
|
+
// src/core/primitives/content-gesture.ts
|
|
2084
|
+
var CONTENT_DRAG_SLOP = 6;
|
|
2085
|
+
function decideContentGesture(input) {
|
|
2086
|
+
const slop = input.slop ?? CONTENT_DRAG_SLOP;
|
|
2087
|
+
if (Math.abs(input.delta) < slop) return "pending";
|
|
2088
|
+
if (input.scrollTop > 0) return "scroll";
|
|
2089
|
+
if (input.delta > 0 && input.atMaxSnap) return "scroll";
|
|
2090
|
+
return "drag";
|
|
2091
|
+
}
|
|
2092
|
+
|
|
2093
|
+
// src/core/primitives/touch-scroll-guard.ts
|
|
2094
|
+
function installTouchScrollGuard(surface, isDragging) {
|
|
2095
|
+
const onTouchMove = (e) => {
|
|
2096
|
+
if (!isDragging()) return;
|
|
2097
|
+
if (e.cancelable) e.preventDefault();
|
|
2098
|
+
};
|
|
2099
|
+
surface.addEventListener("touchmove", onTouchMove, { passive: false });
|
|
2100
|
+
return () => surface.removeEventListener("touchmove", onTouchMove);
|
|
2101
|
+
}
|
|
2102
|
+
|
|
2030
2103
|
// src/core/primitives/aria-slider-writer.ts
|
|
2031
2104
|
var AriaSliderWriter = class {
|
|
2032
2105
|
constructor(handle, mode) {
|
|
@@ -2383,6 +2456,8 @@ function resolveEngineOptions(opts, extras) {
|
|
|
2383
2456
|
mode: opts.mode ?? "bottom",
|
|
2384
2457
|
flickVelocity: opts.flickVelocity ?? DEFAULT_FLICK_VELOCITY,
|
|
2385
2458
|
dragThreshold: opts.dragThreshold ?? DEFAULT_DRAG_THRESHOLD,
|
|
2459
|
+
dragFrom: opts.dragFrom ?? (opts.handle ? "handle" : "sheet"),
|
|
2460
|
+
dragFromContent: opts.dragFromContent ?? true,
|
|
2386
2461
|
rubberBandEnabled: opts.rubberBand ?? true,
|
|
2387
2462
|
closeOnBack: opts.closeOnBack ?? false,
|
|
2388
2463
|
persistent: opts.persistent ?? false,
|
|
@@ -2465,6 +2540,8 @@ var BottomSheetCore = class {
|
|
|
2465
2540
|
mode;
|
|
2466
2541
|
flickVelocity;
|
|
2467
2542
|
dragThreshold;
|
|
2543
|
+
dragFromMode;
|
|
2544
|
+
dragFromContentDefault;
|
|
2468
2545
|
rubberBandEnabled;
|
|
2469
2546
|
scrim;
|
|
2470
2547
|
aria;
|
|
@@ -2482,8 +2559,11 @@ var BottomSheetCore = class {
|
|
|
2482
2559
|
activeId;
|
|
2483
2560
|
size = 0;
|
|
2484
2561
|
gesture;
|
|
2562
|
+
contentGesture;
|
|
2563
|
+
detachSheetGesture = null;
|
|
2485
2564
|
rootEl = null;
|
|
2486
2565
|
destroyed = false;
|
|
2566
|
+
restClosed = false;
|
|
2487
2567
|
currentViewTransition = null;
|
|
2488
2568
|
currentAbort = new AbortController();
|
|
2489
2569
|
sizeWriteSentinel = new WriteSentinel();
|
|
@@ -2537,6 +2617,8 @@ var BottomSheetCore = class {
|
|
|
2537
2617
|
this.aria = new AriaSliderWriter(this.handle, this.mode);
|
|
2538
2618
|
this.flickVelocity = resolved.flickVelocity;
|
|
2539
2619
|
this.dragThreshold = resolved.dragThreshold;
|
|
2620
|
+
this.dragFromMode = resolved.dragFrom;
|
|
2621
|
+
this.dragFromContentDefault = resolved.dragFromContent;
|
|
2540
2622
|
this.rubberBandEnabled = resolved.rubberBandEnabled;
|
|
2541
2623
|
this.scrim = new ScrimController(
|
|
2542
2624
|
{
|
|
@@ -2563,7 +2645,7 @@ var BottomSheetCore = class {
|
|
|
2563
2645
|
getRootEl: () => this.rootEl,
|
|
2564
2646
|
applySize: (size) => this.applySize(size),
|
|
2565
2647
|
getSize: () => this.size,
|
|
2566
|
-
isDragging: () => this.
|
|
2648
|
+
isDragging: () => this.isDraggingAny(),
|
|
2567
2649
|
applyAux: (size) => this.applySize(size, true),
|
|
2568
2650
|
getTransformFor: (size) => this.transformTemplate(this.snaps.getMaxAxisSize() - size)
|
|
2569
2651
|
},
|
|
@@ -2624,6 +2706,7 @@ var BottomSheetCore = class {
|
|
|
2624
2706
|
const initial = this.snaps.findById(this.activeId);
|
|
2625
2707
|
if (initial) this.size = initial.size;
|
|
2626
2708
|
this.applySize(this.size);
|
|
2709
|
+
this.setRestClosed(this.size === 0);
|
|
2627
2710
|
this.updateAriaSlider();
|
|
2628
2711
|
this.scrollCache = createScrollCache({
|
|
2629
2712
|
scrollContainer: this.scrollContainer,
|
|
@@ -2654,7 +2737,7 @@ var BottomSheetCore = class {
|
|
|
2654
2737
|
(p) => p.size === "fit" || p.size === "content"
|
|
2655
2738
|
),
|
|
2656
2739
|
isDestroyed: () => this.destroyed,
|
|
2657
|
-
isDragging: () => this.
|
|
2740
|
+
isDragging: () => this.isDraggingAny(),
|
|
2658
2741
|
recompute: () => this.recompute()
|
|
2659
2742
|
})
|
|
2660
2743
|
);
|
|
@@ -2680,7 +2763,7 @@ var BottomSheetCore = class {
|
|
|
2680
2763
|
autoCollapseAfter
|
|
2681
2764
|
},
|
|
2682
2765
|
isDestroyed: () => this.destroyed,
|
|
2683
|
-
isDragging: () => this.
|
|
2766
|
+
isDragging: () => this.isDraggingAny(),
|
|
2684
2767
|
isAnimating: () => this.animation.isAnimating,
|
|
2685
2768
|
isTopSheet: () => this.isTopSheet,
|
|
2686
2769
|
isVerticalAxis: () => this.mode === "bottom" || this.mode === "top",
|
|
@@ -2710,6 +2793,7 @@ var BottomSheetCore = class {
|
|
|
2710
2793
|
void this.snapTo(id);
|
|
2711
2794
|
},
|
|
2712
2795
|
close: (reason) => this.close(reason),
|
|
2796
|
+
attachDragSurface: (surface, kind) => this.attachDragSurface(surface, kind),
|
|
2713
2797
|
on: (event, fn) => this.on(event, fn),
|
|
2714
2798
|
addTeardown: (fn) => this.teardowns.add(fn)
|
|
2715
2799
|
};
|
|
@@ -2738,7 +2822,7 @@ var BottomSheetCore = class {
|
|
|
2738
2822
|
return {
|
|
2739
2823
|
size: this.size,
|
|
2740
2824
|
activeId: this.activeId,
|
|
2741
|
-
isDragging: this.
|
|
2825
|
+
isDragging: this.isDraggingAny(),
|
|
2742
2826
|
isAnimating: this.animation.isAnimating,
|
|
2743
2827
|
progress: this.computeProgress(this.size)
|
|
2744
2828
|
};
|
|
@@ -2858,9 +2942,16 @@ var BottomSheetCore = class {
|
|
|
2858
2942
|
progress: this.computeProgress(this.size)
|
|
2859
2943
|
});
|
|
2860
2944
|
if (withHaptic) this.haptic();
|
|
2945
|
+
this.setRestClosed(targetSize === 0);
|
|
2861
2946
|
if (wasClosed && targetSize > 0) this.emitOpenSequence(id);
|
|
2862
2947
|
if (targetSize === 0) this.emitCloseSequence();
|
|
2863
2948
|
}
|
|
2949
|
+
setRestClosed(closed) {
|
|
2950
|
+
if (closed === this.restClosed) return;
|
|
2951
|
+
this.restClosed = closed;
|
|
2952
|
+
if (closed) this.element.setAttribute("data-bs-rest", "closed");
|
|
2953
|
+
else this.element.removeAttribute("data-bs-rest");
|
|
2954
|
+
}
|
|
2864
2955
|
emitOpenSequence(id) {
|
|
2865
2956
|
this.emit("open", { id });
|
|
2866
2957
|
this.handleOpen();
|
|
@@ -2916,6 +3007,20 @@ var BottomSheetCore = class {
|
|
|
2916
3007
|
if (this.destroyed) return;
|
|
2917
3008
|
this.disableDragFlag = value;
|
|
2918
3009
|
}
|
|
3010
|
+
setDragFromContent(value) {
|
|
3011
|
+
if (this.destroyed) return;
|
|
3012
|
+
this.dragFromContentDefault = value;
|
|
3013
|
+
}
|
|
3014
|
+
setDragFrom(mode) {
|
|
3015
|
+
if (this.destroyed || mode === this.dragFromMode) return;
|
|
3016
|
+
this.gesture?.forceClearDragState();
|
|
3017
|
+
this.detachSheetGesture?.();
|
|
3018
|
+
this.dragFromMode = mode;
|
|
3019
|
+
this.mountSheetGesture();
|
|
3020
|
+
}
|
|
3021
|
+
getDragFrom() {
|
|
3022
|
+
return this.dragFromMode;
|
|
3023
|
+
}
|
|
2919
3024
|
isTop() {
|
|
2920
3025
|
return this.isTopSheet;
|
|
2921
3026
|
}
|
|
@@ -3070,12 +3175,24 @@ var BottomSheetCore = class {
|
|
|
3070
3175
|
auditVhUsage(points);
|
|
3071
3176
|
this.auditDuplicateSnapIds(points);
|
|
3072
3177
|
this.snaps.setRaw(points);
|
|
3073
|
-
if (allowed)
|
|
3178
|
+
if (allowed) {
|
|
3179
|
+
this.snaps.setAllowedIds(allowed);
|
|
3180
|
+
} else {
|
|
3181
|
+
const present = this.snaps.getResolvedSnaps().map((s) => s.id);
|
|
3182
|
+
const kept = this.snaps.getAllowedIds().filter((id) => present.includes(id));
|
|
3183
|
+
this.snaps.setAllowedIds(kept.length ? kept : present);
|
|
3184
|
+
}
|
|
3074
3185
|
this.scrollCache.clear();
|
|
3075
3186
|
this.scrim.invalidateOpacityCache();
|
|
3076
3187
|
const current = this.snaps.findById(this.activeId);
|
|
3077
3188
|
if (current) {
|
|
3078
3189
|
this.applySize(current.size);
|
|
3190
|
+
} else {
|
|
3191
|
+
const fallback = this.snaps.getResolvedSnaps().find((s) => this.snaps.getAllowedIds().includes(s.id)) ?? this.snaps.getResolvedSnaps()[0];
|
|
3192
|
+
if (fallback) {
|
|
3193
|
+
this.activeId = fallback.id;
|
|
3194
|
+
this.applySize(fallback.size);
|
|
3195
|
+
}
|
|
3079
3196
|
}
|
|
3080
3197
|
this.updateAriaSlider();
|
|
3081
3198
|
}
|
|
@@ -3085,7 +3202,7 @@ var BottomSheetCore = class {
|
|
|
3085
3202
|
this.snaps.recompute();
|
|
3086
3203
|
this.maxHeight.clampTo();
|
|
3087
3204
|
this.scrim.invalidateOpacityCache();
|
|
3088
|
-
if (this.
|
|
3205
|
+
if (this.isDraggingAny()) return;
|
|
3089
3206
|
this.healActiveSnap();
|
|
3090
3207
|
}
|
|
3091
3208
|
healActiveSnap() {
|
|
@@ -3107,6 +3224,8 @@ var BottomSheetCore = class {
|
|
|
3107
3224
|
this.bus.clear();
|
|
3108
3225
|
this.animation.cancel();
|
|
3109
3226
|
this.gesture?.forceClearDragState();
|
|
3227
|
+
this.contentGesture?.forceClearDragState();
|
|
3228
|
+
this.setRestClosed(false);
|
|
3110
3229
|
this.teardowns.drain();
|
|
3111
3230
|
this.scrim.destroy();
|
|
3112
3231
|
this.animation.destroy();
|
|
@@ -3219,11 +3338,12 @@ var BottomSheetCore = class {
|
|
|
3219
3338
|
const scale = Math.max(1 - depth * 0.04, 0.86);
|
|
3220
3339
|
this.element.style.scale = scale === 1 ? "" : String(scale);
|
|
3221
3340
|
}
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
handle:
|
|
3341
|
+
buildGestureDeps(surface, gestureOptions) {
|
|
3342
|
+
return {
|
|
3343
|
+
handle: surface,
|
|
3225
3344
|
element: this.element,
|
|
3226
3345
|
mode: this.mode,
|
|
3346
|
+
gestureOptions,
|
|
3227
3347
|
getRoot: () => this.rootEl,
|
|
3228
3348
|
getDragContext: () => {
|
|
3229
3349
|
const buf = this.dragContextBuf;
|
|
@@ -3242,8 +3362,88 @@ var BottomSheetCore = class {
|
|
|
3242
3362
|
settleAfterDrag: (delta, velocity, kind) => this.settleAfterDrag(delta, velocity, kind),
|
|
3243
3363
|
emit: (event, payload) => this.emit(event, payload),
|
|
3244
3364
|
listenerCount: (event) => this.bus.listenerCount(event)
|
|
3365
|
+
};
|
|
3366
|
+
}
|
|
3367
|
+
isContentDragAllowed() {
|
|
3368
|
+
if (this.disableDragFlag) return false;
|
|
3369
|
+
const point = this.snapPointsRaw.find((p) => p.id === this.activeId);
|
|
3370
|
+
return point?.dragFromContent ?? this.dragFromContentDefault;
|
|
3371
|
+
}
|
|
3372
|
+
decideContentDrag(surface, e, delta) {
|
|
3373
|
+
if (this.destroyed) return false;
|
|
3374
|
+
if (e.pointerType === "mouse") return false;
|
|
3375
|
+
if (this.gesture?.isDragging) return false;
|
|
3376
|
+
if (!this.isContentDragAllowed()) return false;
|
|
3377
|
+
if (!isDragAllowedFrom(e.target, "sheet")) return false;
|
|
3378
|
+
const decision = decideContentGesture({
|
|
3379
|
+
delta,
|
|
3380
|
+
scrollTop: surface.scrollTop,
|
|
3381
|
+
atMaxSnap: this.size >= this.getAllowedRange().max - 0.5
|
|
3382
|
+
});
|
|
3383
|
+
if (decision === "pending") return null;
|
|
3384
|
+
return decision === "drag";
|
|
3385
|
+
}
|
|
3386
|
+
attachDragSurface(surface, kind) {
|
|
3387
|
+
if (this.destroyed || kind !== "content") return;
|
|
3388
|
+
if (this.contentGesture) return;
|
|
3389
|
+
const controller = new GestureController(
|
|
3390
|
+
this.buildGestureDeps(surface, {
|
|
3391
|
+
manageTouchAction: false,
|
|
3392
|
+
deferStart: (e, delta) => this.decideContentDrag(surface, e, delta)
|
|
3393
|
+
})
|
|
3394
|
+
);
|
|
3395
|
+
this.contentGesture = controller;
|
|
3396
|
+
const detachGestures = controller.install();
|
|
3397
|
+
const detachGuard = installTouchScrollGuard(
|
|
3398
|
+
surface,
|
|
3399
|
+
() => controller.isDragging
|
|
3400
|
+
);
|
|
3401
|
+
return () => {
|
|
3402
|
+
detachGuard();
|
|
3403
|
+
detachGestures();
|
|
3404
|
+
if (this.contentGesture === controller) this.contentGesture = void 0;
|
|
3405
|
+
};
|
|
3406
|
+
}
|
|
3407
|
+
sheetDragSurface() {
|
|
3408
|
+
return this.dragFromMode === "handle" ? this.handle : this.element;
|
|
3409
|
+
}
|
|
3410
|
+
canStartSheetDrag(e) {
|
|
3411
|
+
if (this.contentGesture?.isDragging) return false;
|
|
3412
|
+
const target = e.target;
|
|
3413
|
+
const scoped = typeof target?.closest === "function";
|
|
3414
|
+
if (scoped && target.closest(NO_DRAG_SELECTOR)) return false;
|
|
3415
|
+
if (this.handle !== this.element && scoped && this.handle.contains(target)) {
|
|
3416
|
+
return true;
|
|
3417
|
+
}
|
|
3418
|
+
if (!isDragAllowedFrom(e.target, this.dragFromMode)) return false;
|
|
3419
|
+
if (this.dragFromMode === "handle") return true;
|
|
3420
|
+
if (this.scrollContainer && scoped && this.scrollContainer.contains(target) && !target.closest(DRAG_ZONE_SELECTOR)) {
|
|
3421
|
+
return false;
|
|
3422
|
+
}
|
|
3423
|
+
return true;
|
|
3424
|
+
}
|
|
3425
|
+
mountSheetGesture() {
|
|
3426
|
+
const surface = this.sheetDragSurface();
|
|
3427
|
+
const controller = new GestureController(
|
|
3428
|
+
this.buildGestureDeps(surface, {
|
|
3429
|
+
shouldStart: (e) => this.canStartSheetDrag(e),
|
|
3430
|
+
manageTouchAction: this.dragFromMode === "handle"
|
|
3431
|
+
})
|
|
3432
|
+
);
|
|
3433
|
+
this.gesture = controller;
|
|
3434
|
+
const detachGestures = controller.install();
|
|
3435
|
+
const detachGuard = this.dragFromMode === "handle" ? null : installTouchScrollGuard(surface, () => controller.isDragging);
|
|
3436
|
+
this.detachSheetGesture = () => {
|
|
3437
|
+
detachGuard?.();
|
|
3438
|
+
detachGestures();
|
|
3439
|
+
};
|
|
3440
|
+
}
|
|
3441
|
+
attach() {
|
|
3442
|
+
this.mountSheetGesture();
|
|
3443
|
+
this.teardowns.add(() => {
|
|
3444
|
+
this.detachSheetGesture?.();
|
|
3445
|
+
this.detachSheetGesture = null;
|
|
3245
3446
|
});
|
|
3246
|
-
this.teardowns.add(this.gesture.install());
|
|
3247
3447
|
try {
|
|
3248
3448
|
this.attachFeatures();
|
|
3249
3449
|
} catch (err) {
|
|
@@ -3280,7 +3480,7 @@ var BottomSheetCore = class {
|
|
|
3280
3480
|
element: this.element,
|
|
3281
3481
|
getMode: () => this.mode,
|
|
3282
3482
|
isDestroyed: () => this.destroyed,
|
|
3283
|
-
isDragging: () => this.
|
|
3483
|
+
isDragging: () => this.isDraggingAny(),
|
|
3284
3484
|
resolveActiveSnap: () => this.snaps.findById(this.activeId),
|
|
3285
3485
|
getMaxAxisSize: () => this.snaps.getMaxAxisSize(),
|
|
3286
3486
|
getSize: () => this.size,
|
|
@@ -3378,8 +3578,11 @@ var BottomSheetCore = class {
|
|
|
3378
3578
|
);
|
|
3379
3579
|
});
|
|
3380
3580
|
}
|
|
3581
|
+
isDraggingAny() {
|
|
3582
|
+
return (this.gesture?.isDragging ?? false) || (this.contentGesture?.isDragging ?? false);
|
|
3583
|
+
}
|
|
3381
3584
|
clearWillChangeIfIdle() {
|
|
3382
|
-
if (this.animation.isAnimating || this.
|
|
3585
|
+
if (this.animation.isAnimating || this.isDraggingAny()) return;
|
|
3383
3586
|
this.element.style.willChange = "";
|
|
3384
3587
|
}
|
|
3385
3588
|
haptic() {
|
|
@@ -3392,8 +3595,9 @@ var BottomSheetCore = class {
|
|
|
3392
3595
|
}
|
|
3393
3596
|
applySize(size, skipTransform = false) {
|
|
3394
3597
|
const cap = this.snaps.getMaxAxisSize();
|
|
3395
|
-
const clamped = cap > 0 && size > cap && !this.
|
|
3598
|
+
const clamped = cap > 0 && size > cap && !this.isDraggingAny() && !this.allowOvershoot ? cap : size;
|
|
3396
3599
|
this.size = clamped;
|
|
3600
|
+
if (clamped > 0) this.setRestClosed(false);
|
|
3397
3601
|
const offset = cap - clamped;
|
|
3398
3602
|
const style = this.element.style;
|
|
3399
3603
|
if (!skipTransform) style.transform = this.transformTemplate(offset);
|
|
@@ -3773,50 +3977,10 @@ function installAutoCollapse(deps) {
|
|
|
3773
3977
|
};
|
|
3774
3978
|
}
|
|
3775
3979
|
|
|
3776
|
-
// src/core/features/content-
|
|
3777
|
-
|
|
3778
|
-
|
|
3779
|
-
|
|
3780
|
-
let startY = 0;
|
|
3781
|
-
let startScrollTop = 0;
|
|
3782
|
-
let moved = false;
|
|
3783
|
-
const onTouchStart = (e) => {
|
|
3784
|
-
const t = e.touches[0];
|
|
3785
|
-
if (!t) return;
|
|
3786
|
-
startY = t.clientY;
|
|
3787
|
-
startScrollTop = container.scrollTop;
|
|
3788
|
-
moved = false;
|
|
3789
|
-
};
|
|
3790
|
-
const onTouchMove = (e) => {
|
|
3791
|
-
const t = e.touches[0];
|
|
3792
|
-
if (!t) return;
|
|
3793
|
-
if (Math.abs(t.clientY - startY) > CONTENT_PULL_THRESHOLD) moved = true;
|
|
3794
|
-
};
|
|
3795
|
-
const onTouchEnd = (e) => {
|
|
3796
|
-
if (!moved) return;
|
|
3797
|
-
if (deps.isDragging() || deps.isAnimating()) return;
|
|
3798
|
-
if (container.scrollTop !== startScrollTop) return;
|
|
3799
|
-
const t = e.changedTouches[0];
|
|
3800
|
-
if (!t) return;
|
|
3801
|
-
const deltaY = t.clientY - startY;
|
|
3802
|
-
const atTop = container.scrollTop <= 0;
|
|
3803
|
-
const allowed = deps.getAllowedIds();
|
|
3804
|
-
const idx = allowed.indexOf(deps.getActiveId());
|
|
3805
|
-
if (idx === -1) return;
|
|
3806
|
-
if (atTop && deltaY > CONTENT_PULL_THRESHOLD && idx > 0) {
|
|
3807
|
-
deps.snapTo(allowed[idx - 1]);
|
|
3808
|
-
} else if (deltaY < -CONTENT_PULL_THRESHOLD && idx < allowed.length - 1) {
|
|
3809
|
-
deps.snapTo(allowed[idx + 1]);
|
|
3810
|
-
}
|
|
3811
|
-
};
|
|
3812
|
-
container.addEventListener("touchstart", onTouchStart, { passive: true });
|
|
3813
|
-
container.addEventListener("touchmove", onTouchMove, { passive: true });
|
|
3814
|
-
container.addEventListener("touchend", onTouchEnd, { passive: true });
|
|
3815
|
-
return () => {
|
|
3816
|
-
container.removeEventListener("touchstart", onTouchStart);
|
|
3817
|
-
container.removeEventListener("touchmove", onTouchMove);
|
|
3818
|
-
container.removeEventListener("touchend", onTouchEnd);
|
|
3819
|
-
};
|
|
3980
|
+
// src/core/features/content-drag.ts
|
|
3981
|
+
function installContentDrag(deps) {
|
|
3982
|
+
const detach = deps.attachDragSurface(deps.container, "content");
|
|
3983
|
+
return () => detach?.();
|
|
3820
3984
|
}
|
|
3821
3985
|
|
|
3822
3986
|
// src/core/features/visual-viewport.ts
|
|
@@ -3924,13 +4088,9 @@ function contentSwipeFeature() {
|
|
|
3924
4088
|
stage: "attach",
|
|
3925
4089
|
install: (ctx) => {
|
|
3926
4090
|
if (!ctx.scrollContainer) return;
|
|
3927
|
-
return
|
|
4091
|
+
return installContentDrag({
|
|
3928
4092
|
container: ctx.scrollContainer,
|
|
3929
|
-
|
|
3930
|
-
isAnimating: ctx.isAnimating,
|
|
3931
|
-
getAllowedIds: ctx.allowedIdsBySize,
|
|
3932
|
-
getActiveId: ctx.getActiveId,
|
|
3933
|
-
snapTo: ctx.snapTo
|
|
4093
|
+
attachDragSurface: ctx.attachDragSurface
|
|
3934
4094
|
});
|
|
3935
4095
|
}
|
|
3936
4096
|
};
|
|
@@ -4056,6 +4216,8 @@ var BottomSheet = (props) => {
|
|
|
4056
4216
|
persistent: props.persistent,
|
|
4057
4217
|
disableClose: props.disableClose,
|
|
4058
4218
|
disableDrag: props.disableDrag,
|
|
4219
|
+
dragFrom: props.dragFrom,
|
|
4220
|
+
dragFromContent: props.dragFromContent,
|
|
4059
4221
|
closeOnRouteChange: props.closeOnRouteChange,
|
|
4060
4222
|
stackEffect: props.stackEffect,
|
|
4061
4223
|
returnFocusTo: props.returnFocusTo
|
|
@@ -4168,6 +4330,26 @@ var BottomSheet = (props) => {
|
|
|
4168
4330
|
{ defer: true }
|
|
4169
4331
|
)
|
|
4170
4332
|
);
|
|
4333
|
+
createEffect(
|
|
4334
|
+
on(
|
|
4335
|
+
() => props.dragFromContent,
|
|
4336
|
+
(value, prev) => {
|
|
4337
|
+
if (!engine || prev === void 0 || value === void 0) return;
|
|
4338
|
+
engine.setDragFromContent(value);
|
|
4339
|
+
},
|
|
4340
|
+
{ defer: true }
|
|
4341
|
+
)
|
|
4342
|
+
);
|
|
4343
|
+
createEffect(
|
|
4344
|
+
on(
|
|
4345
|
+
() => props.dragFrom,
|
|
4346
|
+
(value, prev) => {
|
|
4347
|
+
if (!engine || prev === void 0 || value === void 0) return;
|
|
4348
|
+
engine.setDragFrom(value);
|
|
4349
|
+
},
|
|
4350
|
+
{ defer: true }
|
|
4351
|
+
)
|
|
4352
|
+
);
|
|
4171
4353
|
const showBackdrop = createMemo(() => props.backdrop !== false);
|
|
4172
4354
|
const mode = createMemo(() => props.mode ?? "bottom");
|
|
4173
4355
|
const ariaLabel = createMemo(() => props.ariaLabel ?? "Bottom sheet");
|
package/dist/styles.css
CHANGED
|
@@ -41,6 +41,8 @@
|
|
|
41
41
|
position: fixed;
|
|
42
42
|
background: var(--bs-surface, var(--bs-surface-d));
|
|
43
43
|
box-shadow: var(--bs-shadow, var(--bs-shadow-auto, none));
|
|
44
|
+
|
|
45
|
+
--bs-shadow-fade: clamp(0, calc(var(--bs-progress, 0) * 8), 1);
|
|
44
46
|
z-index: var(--bs-z-sheet);
|
|
45
47
|
pointer-events: auto;
|
|
46
48
|
overflow: hidden;
|
|
@@ -67,7 +69,12 @@
|
|
|
67
69
|
--bs-shadow-auto: 0
|
|
68
70
|
calc(var(--bs-progress, 0) * -2px - 3px)
|
|
69
71
|
calc(var(--bs-progress, 0) * 18px + 12px)
|
|
70
|
-
rgba(
|
|
72
|
+
rgba(
|
|
73
|
+
0,
|
|
74
|
+
0,
|
|
75
|
+
0,
|
|
76
|
+
calc(var(--bs-shadow-fade) * (var(--bs-progress, 0) * 0.15 + 0.12))
|
|
77
|
+
);
|
|
71
78
|
}
|
|
72
79
|
.bs-sheet[data-mode="top"] {
|
|
73
80
|
left: 0;
|
|
@@ -78,7 +85,7 @@
|
|
|
78
85
|
border-bottom-right-radius: var(--bs-radius, var(--bs-radius-d));
|
|
79
86
|
border-bottom: 1px solid var(--bs-surface-border, var(--bs-surface-border-d));
|
|
80
87
|
flex-direction: column-reverse;
|
|
81
|
-
--bs-shadow-auto: 0 3px 12px rgba(0, 0, 0, 0.12);
|
|
88
|
+
--bs-shadow-auto: 0 3px 12px rgba(0, 0, 0, calc(var(--bs-shadow-fade) * 0.12));
|
|
82
89
|
padding-top: env(safe-area-inset-top);
|
|
83
90
|
}
|
|
84
91
|
.bs-sheet[data-mode="left"] {
|
|
@@ -90,7 +97,7 @@
|
|
|
90
97
|
border-bottom-right-radius: var(--bs-radius, var(--bs-radius-d));
|
|
91
98
|
border-right: 1px solid var(--bs-surface-border, var(--bs-surface-border-d));
|
|
92
99
|
|
|
93
|
-
--bs-shadow-auto: 3px 0 12px rgba(0, 0, 0, 0.12);
|
|
100
|
+
--bs-shadow-auto: 3px 0 12px rgba(0, 0, 0, calc(var(--bs-shadow-fade) * 0.12));
|
|
94
101
|
}
|
|
95
102
|
.bs-sheet[data-mode="right"] {
|
|
96
103
|
top: 0;
|
|
@@ -100,7 +107,20 @@
|
|
|
100
107
|
border-top-left-radius: var(--bs-radius, var(--bs-radius-d));
|
|
101
108
|
border-bottom-left-radius: var(--bs-radius, var(--bs-radius-d));
|
|
102
109
|
border-left: 1px solid var(--bs-surface-border, var(--bs-surface-border-d));
|
|
103
|
-
--bs-shadow-auto: -3px 0 12px rgba(0, 0, 0, 0.12);
|
|
110
|
+
--bs-shadow-auto: -3px 0 12px rgba(0, 0, 0, calc(var(--bs-shadow-fade) * 0.12));
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.bs-sheet[data-bs-rest="closed"] {
|
|
114
|
+
box-shadow: none;
|
|
115
|
+
visibility: hidden;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.bs-sheet[data-bs-webgl="on"],
|
|
119
|
+
.bs-sheet[data-bs-webgl="on"] .bs-handle,
|
|
120
|
+
.bs-sheet[data-bs-webgl="on"] .bs-header,
|
|
121
|
+
.bs-sheet[data-bs-webgl="on"] .bs-footer {
|
|
122
|
+
background: transparent;
|
|
123
|
+
box-shadow: none;
|
|
104
124
|
}
|
|
105
125
|
|
|
106
126
|
.bs-sheet[data-mode="left"] .bs-content {
|