@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.js
CHANGED
|
@@ -5,7 +5,7 @@ var __defProp = Object.defineProperty;
|
|
|
5
5
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
6
6
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
7
7
|
|
|
8
|
-
// src/core/lifecycle/
|
|
8
|
+
// src/core/lifecycle/sheet-stack.ts
|
|
9
9
|
var BASE_Z = 100;
|
|
10
10
|
var STEP = 10;
|
|
11
11
|
var SheetStack = class {
|
|
@@ -130,7 +130,7 @@ function createEventBus() {
|
|
|
130
130
|
};
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
-
// src/core/primitives/
|
|
133
|
+
// src/core/primitives/css-length.ts
|
|
134
134
|
var probe = null;
|
|
135
135
|
var PROBE_ATTR = "data-bs-probe";
|
|
136
136
|
var ensureProbe = (axis) => {
|
|
@@ -184,7 +184,7 @@ var resolveSnap = (point, mode, measureFit) => {
|
|
|
184
184
|
return Math.max(0, el.getBoundingClientRect().width);
|
|
185
185
|
};
|
|
186
186
|
|
|
187
|
-
// src/core/primitives/
|
|
187
|
+
// src/core/primitives/dev-warn.ts
|
|
188
188
|
function devWarn(...args) {
|
|
189
189
|
if (typeof process !== "undefined" && process.env && process.env.NODE_ENV !== "production" && typeof console !== "undefined") {
|
|
190
190
|
console.warn(...args);
|
|
@@ -1517,7 +1517,7 @@ var AnimationRunner = class {
|
|
|
1517
1517
|
}
|
|
1518
1518
|
};
|
|
1519
1519
|
|
|
1520
|
-
// src/core/lifecycle/
|
|
1520
|
+
// src/core/lifecycle/focus-trap.ts
|
|
1521
1521
|
var FOCUSABLE = [
|
|
1522
1522
|
"a[href]",
|
|
1523
1523
|
"area[href]",
|
|
@@ -1635,7 +1635,7 @@ var installFocusTrap = (container, options = {}) => {
|
|
|
1635
1635
|
};
|
|
1636
1636
|
};
|
|
1637
1637
|
|
|
1638
|
-
// src/core/lifecycle/
|
|
1638
|
+
// src/core/lifecycle/scroll-lock.ts
|
|
1639
1639
|
var lockCount = 0;
|
|
1640
1640
|
var savedStyles = null;
|
|
1641
1641
|
var lockBodyScroll = () => {
|
|
@@ -1817,30 +1817,44 @@ var SampleRing = class {
|
|
|
1817
1817
|
this.size = 0;
|
|
1818
1818
|
}
|
|
1819
1819
|
};
|
|
1820
|
-
var installGestures = (handle, mode, callbacks) => {
|
|
1820
|
+
var installGestures = (handle, mode, callbacks, options = {}) => {
|
|
1821
1821
|
let activePointerId = null;
|
|
1822
1822
|
let activePointerType = "touch";
|
|
1823
1823
|
let startCoord = 0;
|
|
1824
1824
|
let lastCoord = 0;
|
|
1825
|
+
let pendingStart = false;
|
|
1825
1826
|
const VELOCITY_WINDOW_MS = (kind) => kind === "mouse" ? 160 : 120;
|
|
1826
1827
|
const MAX_SAMPLES = 32;
|
|
1827
1828
|
const samples = new SampleRing(MAX_SAMPLES);
|
|
1828
1829
|
const axis = isAxisVertical(mode) ? "Y" : "X";
|
|
1829
1830
|
const sign = mode === "bottom" || mode === "right" ? -1 : 1;
|
|
1830
1831
|
const coordOf = (e) => axis === "Y" ? e.clientY : e.clientX;
|
|
1832
|
+
const capture = (pointerId) => {
|
|
1833
|
+
try {
|
|
1834
|
+
handle.setPointerCapture(pointerId);
|
|
1835
|
+
} catch {
|
|
1836
|
+
}
|
|
1837
|
+
};
|
|
1838
|
+
const releaseTracking = () => {
|
|
1839
|
+
activePointerId = null;
|
|
1840
|
+
pendingStart = false;
|
|
1841
|
+
samples.reset();
|
|
1842
|
+
};
|
|
1831
1843
|
const onPointerDown = (e) => {
|
|
1832
1844
|
if (activePointerId !== null) return;
|
|
1833
1845
|
if (e.button !== void 0 && e.button !== 0) return;
|
|
1846
|
+
if (options.shouldStart && !options.shouldStart(e)) return;
|
|
1834
1847
|
activePointerId = e.pointerId;
|
|
1835
1848
|
activePointerType = e.pointerType || "touch";
|
|
1836
1849
|
startCoord = coordOf(e);
|
|
1837
1850
|
lastCoord = startCoord;
|
|
1838
1851
|
samples.reset();
|
|
1839
1852
|
samples.push(e.timeStamp, startCoord);
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1853
|
+
if (options.deferStart) {
|
|
1854
|
+
pendingStart = true;
|
|
1855
|
+
return;
|
|
1843
1856
|
}
|
|
1857
|
+
capture(e.pointerId);
|
|
1844
1858
|
callbacks.onStart(startCoord, activePointerType);
|
|
1845
1859
|
};
|
|
1846
1860
|
const onPointerMove = (e) => {
|
|
@@ -1848,6 +1862,22 @@ var installGestures = (handle, mode, callbacks) => {
|
|
|
1848
1862
|
const coord = coordOf(e);
|
|
1849
1863
|
const rawDelta = coord - startCoord;
|
|
1850
1864
|
const delta = rawDelta * sign;
|
|
1865
|
+
if (pendingStart) {
|
|
1866
|
+
const verdict = options.deferStart(e, delta);
|
|
1867
|
+
if (verdict === false) {
|
|
1868
|
+
releaseTracking();
|
|
1869
|
+
return;
|
|
1870
|
+
}
|
|
1871
|
+
if (verdict !== true) return;
|
|
1872
|
+
pendingStart = false;
|
|
1873
|
+
startCoord = coord;
|
|
1874
|
+
lastCoord = coord;
|
|
1875
|
+
samples.reset();
|
|
1876
|
+
samples.push(e.timeStamp, coord);
|
|
1877
|
+
capture(e.pointerId);
|
|
1878
|
+
callbacks.onStart(startCoord, activePointerType);
|
|
1879
|
+
return;
|
|
1880
|
+
}
|
|
1851
1881
|
lastCoord = coord;
|
|
1852
1882
|
samples.push(e.timeStamp, coord);
|
|
1853
1883
|
const cutoff = e.timeStamp - VELOCITY_WINDOW_MS(activePointerType);
|
|
@@ -1856,6 +1886,10 @@ var installGestures = (handle, mode, callbacks) => {
|
|
|
1856
1886
|
};
|
|
1857
1887
|
const finishGesture = (e) => {
|
|
1858
1888
|
if (e.pointerId !== activePointerId) return;
|
|
1889
|
+
if (pendingStart) {
|
|
1890
|
+
releaseTracking();
|
|
1891
|
+
return;
|
|
1892
|
+
}
|
|
1859
1893
|
const rawDelta = lastCoord - startCoord;
|
|
1860
1894
|
const delta = rawDelta * sign;
|
|
1861
1895
|
let velocity = 0;
|
|
@@ -1878,22 +1912,26 @@ var installGestures = (handle, mode, callbacks) => {
|
|
|
1878
1912
|
};
|
|
1879
1913
|
const onPointerCancel = (e) => {
|
|
1880
1914
|
if (e.pointerId !== activePointerId) return;
|
|
1881
|
-
|
|
1882
|
-
|
|
1915
|
+
const wasPending = pendingStart;
|
|
1916
|
+
releaseTracking();
|
|
1917
|
+
if (wasPending) return;
|
|
1883
1918
|
callbacks.onCancel?.();
|
|
1884
1919
|
};
|
|
1885
1920
|
handle.addEventListener("pointerdown", onPointerDown);
|
|
1886
1921
|
handle.addEventListener("pointermove", onPointerMove);
|
|
1887
1922
|
handle.addEventListener("pointerup", finishGesture);
|
|
1888
1923
|
handle.addEventListener("pointercancel", onPointerCancel);
|
|
1924
|
+
const managesTouchAction = options.manageTouchAction !== false;
|
|
1889
1925
|
const prevTouchAction = handle.style.touchAction;
|
|
1890
|
-
|
|
1926
|
+
if (managesTouchAction) {
|
|
1927
|
+
handle.style.touchAction = isAxisVertical(mode) ? "pan-x" : "pan-y";
|
|
1928
|
+
}
|
|
1891
1929
|
return () => {
|
|
1892
1930
|
handle.removeEventListener("pointerdown", onPointerDown);
|
|
1893
1931
|
handle.removeEventListener("pointermove", onPointerMove);
|
|
1894
1932
|
handle.removeEventListener("pointerup", finishGesture);
|
|
1895
1933
|
handle.removeEventListener("pointercancel", onPointerCancel);
|
|
1896
|
-
handle.style.touchAction = prevTouchAction;
|
|
1934
|
+
if (managesTouchAction) handle.style.touchAction = prevTouchAction;
|
|
1897
1935
|
if (activePointerId !== null && handle.hasPointerCapture(activePointerId)) {
|
|
1898
1936
|
handle.releasePointerCapture(activePointerId);
|
|
1899
1937
|
}
|
|
@@ -2012,7 +2050,7 @@ var GestureController = class {
|
|
|
2012
2050
|
const restoreTo = this.dragStartSize;
|
|
2013
2051
|
void this.deps.animateTo(restoreTo, 0);
|
|
2014
2052
|
}
|
|
2015
|
-
});
|
|
2053
|
+
}, this.deps.gestureOptions);
|
|
2016
2054
|
return this.detach;
|
|
2017
2055
|
}
|
|
2018
2056
|
forceClearDragState() {
|
|
@@ -2024,6 +2062,41 @@ var GestureController = class {
|
|
|
2024
2062
|
}
|
|
2025
2063
|
};
|
|
2026
2064
|
|
|
2065
|
+
// src/core/primitives/drag-zones.ts
|
|
2066
|
+
var DRAG_ZONE_SELECTOR = "[data-bs-drag]";
|
|
2067
|
+
var NO_DRAG_SELECTOR = "[data-bs-no-drag]";
|
|
2068
|
+
var asElement = (target) => {
|
|
2069
|
+
const candidate = target;
|
|
2070
|
+
return candidate && typeof candidate.closest === "function" ? candidate : null;
|
|
2071
|
+
};
|
|
2072
|
+
function isDragAllowedFrom(target, mode) {
|
|
2073
|
+
const el = asElement(target);
|
|
2074
|
+
if (!el) return mode !== "zones";
|
|
2075
|
+
if (el.closest(NO_DRAG_SELECTOR)) return false;
|
|
2076
|
+
if (mode === "zones") return el.closest(DRAG_ZONE_SELECTOR) !== null;
|
|
2077
|
+
return true;
|
|
2078
|
+
}
|
|
2079
|
+
|
|
2080
|
+
// src/core/primitives/content-gesture.ts
|
|
2081
|
+
var CONTENT_DRAG_SLOP = 6;
|
|
2082
|
+
function decideContentGesture(input) {
|
|
2083
|
+
const slop = input.slop ?? CONTENT_DRAG_SLOP;
|
|
2084
|
+
if (Math.abs(input.delta) < slop) return "pending";
|
|
2085
|
+
if (input.scrollTop > 0) return "scroll";
|
|
2086
|
+
if (input.delta > 0 && input.atMaxSnap) return "scroll";
|
|
2087
|
+
return "drag";
|
|
2088
|
+
}
|
|
2089
|
+
|
|
2090
|
+
// src/core/primitives/touch-scroll-guard.ts
|
|
2091
|
+
function installTouchScrollGuard(surface, isDragging) {
|
|
2092
|
+
const onTouchMove = (e) => {
|
|
2093
|
+
if (!isDragging()) return;
|
|
2094
|
+
if (e.cancelable) e.preventDefault();
|
|
2095
|
+
};
|
|
2096
|
+
surface.addEventListener("touchmove", onTouchMove, { passive: false });
|
|
2097
|
+
return () => surface.removeEventListener("touchmove", onTouchMove);
|
|
2098
|
+
}
|
|
2099
|
+
|
|
2027
2100
|
// src/core/primitives/aria-slider-writer.ts
|
|
2028
2101
|
var AriaSliderWriter = class {
|
|
2029
2102
|
constructor(handle, mode) {
|
|
@@ -2379,6 +2452,8 @@ function resolveEngineOptions(opts, extras) {
|
|
|
2379
2452
|
mode: opts.mode ?? "bottom",
|
|
2380
2453
|
flickVelocity: opts.flickVelocity ?? DEFAULT_FLICK_VELOCITY,
|
|
2381
2454
|
dragThreshold: opts.dragThreshold ?? DEFAULT_DRAG_THRESHOLD,
|
|
2455
|
+
dragFrom: opts.dragFrom ?? (opts.handle ? "handle" : "sheet"),
|
|
2456
|
+
dragFromContent: opts.dragFromContent ?? true,
|
|
2382
2457
|
rubberBandEnabled: opts.rubberBand ?? true,
|
|
2383
2458
|
closeOnBack: opts.closeOnBack ?? false,
|
|
2384
2459
|
persistent: opts.persistent ?? false,
|
|
@@ -2464,6 +2539,8 @@ var BottomSheetCore = class {
|
|
|
2464
2539
|
__publicField(this, "mode");
|
|
2465
2540
|
__publicField(this, "flickVelocity");
|
|
2466
2541
|
__publicField(this, "dragThreshold");
|
|
2542
|
+
__publicField(this, "dragFromMode");
|
|
2543
|
+
__publicField(this, "dragFromContentDefault");
|
|
2467
2544
|
__publicField(this, "rubberBandEnabled");
|
|
2468
2545
|
__publicField(this, "scrim");
|
|
2469
2546
|
__publicField(this, "aria");
|
|
@@ -2481,8 +2558,11 @@ var BottomSheetCore = class {
|
|
|
2481
2558
|
__publicField(this, "activeId");
|
|
2482
2559
|
__publicField(this, "size", 0);
|
|
2483
2560
|
__publicField(this, "gesture");
|
|
2561
|
+
__publicField(this, "contentGesture");
|
|
2562
|
+
__publicField(this, "detachSheetGesture", null);
|
|
2484
2563
|
__publicField(this, "rootEl", null);
|
|
2485
2564
|
__publicField(this, "destroyed", false);
|
|
2565
|
+
__publicField(this, "restClosed", false);
|
|
2486
2566
|
__publicField(this, "currentViewTransition", null);
|
|
2487
2567
|
__publicField(this, "currentAbort", new AbortController());
|
|
2488
2568
|
__publicField(this, "sizeWriteSentinel", new WriteSentinel());
|
|
@@ -2535,6 +2615,8 @@ var BottomSheetCore = class {
|
|
|
2535
2615
|
this.aria = new AriaSliderWriter(this.handle, this.mode);
|
|
2536
2616
|
this.flickVelocity = resolved.flickVelocity;
|
|
2537
2617
|
this.dragThreshold = resolved.dragThreshold;
|
|
2618
|
+
this.dragFromMode = resolved.dragFrom;
|
|
2619
|
+
this.dragFromContentDefault = resolved.dragFromContent;
|
|
2538
2620
|
this.rubberBandEnabled = resolved.rubberBandEnabled;
|
|
2539
2621
|
this.scrim = new ScrimController(
|
|
2540
2622
|
{
|
|
@@ -2561,7 +2643,7 @@ var BottomSheetCore = class {
|
|
|
2561
2643
|
getRootEl: () => this.rootEl,
|
|
2562
2644
|
applySize: (size) => this.applySize(size),
|
|
2563
2645
|
getSize: () => this.size,
|
|
2564
|
-
isDragging: () => this.
|
|
2646
|
+
isDragging: () => this.isDraggingAny(),
|
|
2565
2647
|
applyAux: (size) => this.applySize(size, true),
|
|
2566
2648
|
getTransformFor: (size) => this.transformTemplate(this.snaps.getMaxAxisSize() - size)
|
|
2567
2649
|
},
|
|
@@ -2622,6 +2704,7 @@ var BottomSheetCore = class {
|
|
|
2622
2704
|
const initial = this.snaps.findById(this.activeId);
|
|
2623
2705
|
if (initial) this.size = initial.size;
|
|
2624
2706
|
this.applySize(this.size);
|
|
2707
|
+
this.setRestClosed(this.size === 0);
|
|
2625
2708
|
this.updateAriaSlider();
|
|
2626
2709
|
this.scrollCache = createScrollCache({
|
|
2627
2710
|
scrollContainer: this.scrollContainer,
|
|
@@ -2652,7 +2735,7 @@ var BottomSheetCore = class {
|
|
|
2652
2735
|
(p) => p.size === "fit" || p.size === "content"
|
|
2653
2736
|
),
|
|
2654
2737
|
isDestroyed: () => this.destroyed,
|
|
2655
|
-
isDragging: () => this.
|
|
2738
|
+
isDragging: () => this.isDraggingAny(),
|
|
2656
2739
|
recompute: () => this.recompute()
|
|
2657
2740
|
})
|
|
2658
2741
|
);
|
|
@@ -2678,7 +2761,7 @@ var BottomSheetCore = class {
|
|
|
2678
2761
|
autoCollapseAfter
|
|
2679
2762
|
},
|
|
2680
2763
|
isDestroyed: () => this.destroyed,
|
|
2681
|
-
isDragging: () => this.
|
|
2764
|
+
isDragging: () => this.isDraggingAny(),
|
|
2682
2765
|
isAnimating: () => this.animation.isAnimating,
|
|
2683
2766
|
isTopSheet: () => this.isTopSheet,
|
|
2684
2767
|
isVerticalAxis: () => this.mode === "bottom" || this.mode === "top",
|
|
@@ -2708,6 +2791,7 @@ var BottomSheetCore = class {
|
|
|
2708
2791
|
void this.snapTo(id);
|
|
2709
2792
|
},
|
|
2710
2793
|
close: (reason) => this.close(reason),
|
|
2794
|
+
attachDragSurface: (surface, kind) => this.attachDragSurface(surface, kind),
|
|
2711
2795
|
on: (event, fn) => this.on(event, fn),
|
|
2712
2796
|
addTeardown: (fn) => this.teardowns.add(fn)
|
|
2713
2797
|
};
|
|
@@ -2736,7 +2820,7 @@ var BottomSheetCore = class {
|
|
|
2736
2820
|
return {
|
|
2737
2821
|
size: this.size,
|
|
2738
2822
|
activeId: this.activeId,
|
|
2739
|
-
isDragging: this.
|
|
2823
|
+
isDragging: this.isDraggingAny(),
|
|
2740
2824
|
isAnimating: this.animation.isAnimating,
|
|
2741
2825
|
progress: this.computeProgress(this.size)
|
|
2742
2826
|
};
|
|
@@ -2856,9 +2940,16 @@ var BottomSheetCore = class {
|
|
|
2856
2940
|
progress: this.computeProgress(this.size)
|
|
2857
2941
|
});
|
|
2858
2942
|
if (withHaptic) this.haptic();
|
|
2943
|
+
this.setRestClosed(targetSize === 0);
|
|
2859
2944
|
if (wasClosed && targetSize > 0) this.emitOpenSequence(id);
|
|
2860
2945
|
if (targetSize === 0) this.emitCloseSequence();
|
|
2861
2946
|
}
|
|
2947
|
+
setRestClosed(closed) {
|
|
2948
|
+
if (closed === this.restClosed) return;
|
|
2949
|
+
this.restClosed = closed;
|
|
2950
|
+
if (closed) this.element.setAttribute("data-bs-rest", "closed");
|
|
2951
|
+
else this.element.removeAttribute("data-bs-rest");
|
|
2952
|
+
}
|
|
2862
2953
|
emitOpenSequence(id) {
|
|
2863
2954
|
this.emit("open", { id });
|
|
2864
2955
|
this.handleOpen();
|
|
@@ -2914,6 +3005,20 @@ var BottomSheetCore = class {
|
|
|
2914
3005
|
if (this.destroyed) return;
|
|
2915
3006
|
this.disableDragFlag = value;
|
|
2916
3007
|
}
|
|
3008
|
+
setDragFromContent(value) {
|
|
3009
|
+
if (this.destroyed) return;
|
|
3010
|
+
this.dragFromContentDefault = value;
|
|
3011
|
+
}
|
|
3012
|
+
setDragFrom(mode) {
|
|
3013
|
+
if (this.destroyed || mode === this.dragFromMode) return;
|
|
3014
|
+
this.gesture?.forceClearDragState();
|
|
3015
|
+
this.detachSheetGesture?.();
|
|
3016
|
+
this.dragFromMode = mode;
|
|
3017
|
+
this.mountSheetGesture();
|
|
3018
|
+
}
|
|
3019
|
+
getDragFrom() {
|
|
3020
|
+
return this.dragFromMode;
|
|
3021
|
+
}
|
|
2917
3022
|
isTop() {
|
|
2918
3023
|
return this.isTopSheet;
|
|
2919
3024
|
}
|
|
@@ -3068,12 +3173,24 @@ var BottomSheetCore = class {
|
|
|
3068
3173
|
auditVhUsage(points);
|
|
3069
3174
|
this.auditDuplicateSnapIds(points);
|
|
3070
3175
|
this.snaps.setRaw(points);
|
|
3071
|
-
if (allowed)
|
|
3176
|
+
if (allowed) {
|
|
3177
|
+
this.snaps.setAllowedIds(allowed);
|
|
3178
|
+
} else {
|
|
3179
|
+
const present = this.snaps.getResolvedSnaps().map((s) => s.id);
|
|
3180
|
+
const kept = this.snaps.getAllowedIds().filter((id) => present.includes(id));
|
|
3181
|
+
this.snaps.setAllowedIds(kept.length ? kept : present);
|
|
3182
|
+
}
|
|
3072
3183
|
this.scrollCache.clear();
|
|
3073
3184
|
this.scrim.invalidateOpacityCache();
|
|
3074
3185
|
const current = this.snaps.findById(this.activeId);
|
|
3075
3186
|
if (current) {
|
|
3076
3187
|
this.applySize(current.size);
|
|
3188
|
+
} else {
|
|
3189
|
+
const fallback = this.snaps.getResolvedSnaps().find((s) => this.snaps.getAllowedIds().includes(s.id)) ?? this.snaps.getResolvedSnaps()[0];
|
|
3190
|
+
if (fallback) {
|
|
3191
|
+
this.activeId = fallback.id;
|
|
3192
|
+
this.applySize(fallback.size);
|
|
3193
|
+
}
|
|
3077
3194
|
}
|
|
3078
3195
|
this.updateAriaSlider();
|
|
3079
3196
|
}
|
|
@@ -3083,7 +3200,7 @@ var BottomSheetCore = class {
|
|
|
3083
3200
|
this.snaps.recompute();
|
|
3084
3201
|
this.maxHeight.clampTo();
|
|
3085
3202
|
this.scrim.invalidateOpacityCache();
|
|
3086
|
-
if (this.
|
|
3203
|
+
if (this.isDraggingAny()) return;
|
|
3087
3204
|
this.healActiveSnap();
|
|
3088
3205
|
}
|
|
3089
3206
|
healActiveSnap() {
|
|
@@ -3105,6 +3222,8 @@ var BottomSheetCore = class {
|
|
|
3105
3222
|
this.bus.clear();
|
|
3106
3223
|
this.animation.cancel();
|
|
3107
3224
|
this.gesture?.forceClearDragState();
|
|
3225
|
+
this.contentGesture?.forceClearDragState();
|
|
3226
|
+
this.setRestClosed(false);
|
|
3108
3227
|
this.teardowns.drain();
|
|
3109
3228
|
this.scrim.destroy();
|
|
3110
3229
|
this.animation.destroy();
|
|
@@ -3217,11 +3336,12 @@ var BottomSheetCore = class {
|
|
|
3217
3336
|
const scale = Math.max(1 - depth * 0.04, 0.86);
|
|
3218
3337
|
this.element.style.scale = scale === 1 ? "" : String(scale);
|
|
3219
3338
|
}
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
handle:
|
|
3339
|
+
buildGestureDeps(surface, gestureOptions) {
|
|
3340
|
+
return {
|
|
3341
|
+
handle: surface,
|
|
3223
3342
|
element: this.element,
|
|
3224
3343
|
mode: this.mode,
|
|
3344
|
+
gestureOptions,
|
|
3225
3345
|
getRoot: () => this.rootEl,
|
|
3226
3346
|
getDragContext: () => {
|
|
3227
3347
|
const buf = this.dragContextBuf;
|
|
@@ -3240,8 +3360,88 @@ var BottomSheetCore = class {
|
|
|
3240
3360
|
settleAfterDrag: (delta, velocity, kind) => this.settleAfterDrag(delta, velocity, kind),
|
|
3241
3361
|
emit: (event, payload) => this.emit(event, payload),
|
|
3242
3362
|
listenerCount: (event) => this.bus.listenerCount(event)
|
|
3363
|
+
};
|
|
3364
|
+
}
|
|
3365
|
+
isContentDragAllowed() {
|
|
3366
|
+
if (this.disableDragFlag) return false;
|
|
3367
|
+
const point = this.snapPointsRaw.find((p) => p.id === this.activeId);
|
|
3368
|
+
return point?.dragFromContent ?? this.dragFromContentDefault;
|
|
3369
|
+
}
|
|
3370
|
+
decideContentDrag(surface, e, delta) {
|
|
3371
|
+
if (this.destroyed) return false;
|
|
3372
|
+
if (e.pointerType === "mouse") return false;
|
|
3373
|
+
if (this.gesture?.isDragging) return false;
|
|
3374
|
+
if (!this.isContentDragAllowed()) return false;
|
|
3375
|
+
if (!isDragAllowedFrom(e.target, "sheet")) return false;
|
|
3376
|
+
const decision = decideContentGesture({
|
|
3377
|
+
delta,
|
|
3378
|
+
scrollTop: surface.scrollTop,
|
|
3379
|
+
atMaxSnap: this.size >= this.getAllowedRange().max - 0.5
|
|
3380
|
+
});
|
|
3381
|
+
if (decision === "pending") return null;
|
|
3382
|
+
return decision === "drag";
|
|
3383
|
+
}
|
|
3384
|
+
attachDragSurface(surface, kind) {
|
|
3385
|
+
if (this.destroyed || kind !== "content") return;
|
|
3386
|
+
if (this.contentGesture) return;
|
|
3387
|
+
const controller = new GestureController(
|
|
3388
|
+
this.buildGestureDeps(surface, {
|
|
3389
|
+
manageTouchAction: false,
|
|
3390
|
+
deferStart: (e, delta) => this.decideContentDrag(surface, e, delta)
|
|
3391
|
+
})
|
|
3392
|
+
);
|
|
3393
|
+
this.contentGesture = controller;
|
|
3394
|
+
const detachGestures = controller.install();
|
|
3395
|
+
const detachGuard = installTouchScrollGuard(
|
|
3396
|
+
surface,
|
|
3397
|
+
() => controller.isDragging
|
|
3398
|
+
);
|
|
3399
|
+
return () => {
|
|
3400
|
+
detachGuard();
|
|
3401
|
+
detachGestures();
|
|
3402
|
+
if (this.contentGesture === controller) this.contentGesture = void 0;
|
|
3403
|
+
};
|
|
3404
|
+
}
|
|
3405
|
+
sheetDragSurface() {
|
|
3406
|
+
return this.dragFromMode === "handle" ? this.handle : this.element;
|
|
3407
|
+
}
|
|
3408
|
+
canStartSheetDrag(e) {
|
|
3409
|
+
if (this.contentGesture?.isDragging) return false;
|
|
3410
|
+
const target = e.target;
|
|
3411
|
+
const scoped = typeof target?.closest === "function";
|
|
3412
|
+
if (scoped && target.closest(NO_DRAG_SELECTOR)) return false;
|
|
3413
|
+
if (this.handle !== this.element && scoped && this.handle.contains(target)) {
|
|
3414
|
+
return true;
|
|
3415
|
+
}
|
|
3416
|
+
if (!isDragAllowedFrom(e.target, this.dragFromMode)) return false;
|
|
3417
|
+
if (this.dragFromMode === "handle") return true;
|
|
3418
|
+
if (this.scrollContainer && scoped && this.scrollContainer.contains(target) && !target.closest(DRAG_ZONE_SELECTOR)) {
|
|
3419
|
+
return false;
|
|
3420
|
+
}
|
|
3421
|
+
return true;
|
|
3422
|
+
}
|
|
3423
|
+
mountSheetGesture() {
|
|
3424
|
+
const surface = this.sheetDragSurface();
|
|
3425
|
+
const controller = new GestureController(
|
|
3426
|
+
this.buildGestureDeps(surface, {
|
|
3427
|
+
shouldStart: (e) => this.canStartSheetDrag(e),
|
|
3428
|
+
manageTouchAction: this.dragFromMode === "handle"
|
|
3429
|
+
})
|
|
3430
|
+
);
|
|
3431
|
+
this.gesture = controller;
|
|
3432
|
+
const detachGestures = controller.install();
|
|
3433
|
+
const detachGuard = this.dragFromMode === "handle" ? null : installTouchScrollGuard(surface, () => controller.isDragging);
|
|
3434
|
+
this.detachSheetGesture = () => {
|
|
3435
|
+
detachGuard?.();
|
|
3436
|
+
detachGestures();
|
|
3437
|
+
};
|
|
3438
|
+
}
|
|
3439
|
+
attach() {
|
|
3440
|
+
this.mountSheetGesture();
|
|
3441
|
+
this.teardowns.add(() => {
|
|
3442
|
+
this.detachSheetGesture?.();
|
|
3443
|
+
this.detachSheetGesture = null;
|
|
3243
3444
|
});
|
|
3244
|
-
this.teardowns.add(this.gesture.install());
|
|
3245
3445
|
try {
|
|
3246
3446
|
this.attachFeatures();
|
|
3247
3447
|
} catch (err) {
|
|
@@ -3278,7 +3478,7 @@ var BottomSheetCore = class {
|
|
|
3278
3478
|
element: this.element,
|
|
3279
3479
|
getMode: () => this.mode,
|
|
3280
3480
|
isDestroyed: () => this.destroyed,
|
|
3281
|
-
isDragging: () => this.
|
|
3481
|
+
isDragging: () => this.isDraggingAny(),
|
|
3282
3482
|
resolveActiveSnap: () => this.snaps.findById(this.activeId),
|
|
3283
3483
|
getMaxAxisSize: () => this.snaps.getMaxAxisSize(),
|
|
3284
3484
|
getSize: () => this.size,
|
|
@@ -3376,8 +3576,11 @@ var BottomSheetCore = class {
|
|
|
3376
3576
|
);
|
|
3377
3577
|
});
|
|
3378
3578
|
}
|
|
3579
|
+
isDraggingAny() {
|
|
3580
|
+
return (this.gesture?.isDragging ?? false) || (this.contentGesture?.isDragging ?? false);
|
|
3581
|
+
}
|
|
3379
3582
|
clearWillChangeIfIdle() {
|
|
3380
|
-
if (this.animation.isAnimating || this.
|
|
3583
|
+
if (this.animation.isAnimating || this.isDraggingAny()) return;
|
|
3381
3584
|
this.element.style.willChange = "";
|
|
3382
3585
|
}
|
|
3383
3586
|
haptic() {
|
|
@@ -3390,8 +3593,9 @@ var BottomSheetCore = class {
|
|
|
3390
3593
|
}
|
|
3391
3594
|
applySize(size, skipTransform = false) {
|
|
3392
3595
|
const cap = this.snaps.getMaxAxisSize();
|
|
3393
|
-
const clamped = cap > 0 && size > cap && !this.
|
|
3596
|
+
const clamped = cap > 0 && size > cap && !this.isDraggingAny() && !this.allowOvershoot ? cap : size;
|
|
3394
3597
|
this.size = clamped;
|
|
3598
|
+
if (clamped > 0) this.setRestClosed(false);
|
|
3395
3599
|
const offset = cap - clamped;
|
|
3396
3600
|
const style = this.element.style;
|
|
3397
3601
|
if (!skipTransform) style.transform = this.transformTemplate(offset);
|
|
@@ -3771,50 +3975,10 @@ function installAutoCollapse(deps) {
|
|
|
3771
3975
|
};
|
|
3772
3976
|
}
|
|
3773
3977
|
|
|
3774
|
-
// src/core/features/content-
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
|
|
3778
|
-
let startY = 0;
|
|
3779
|
-
let startScrollTop = 0;
|
|
3780
|
-
let moved = false;
|
|
3781
|
-
const onTouchStart = (e) => {
|
|
3782
|
-
const t = e.touches[0];
|
|
3783
|
-
if (!t) return;
|
|
3784
|
-
startY = t.clientY;
|
|
3785
|
-
startScrollTop = container.scrollTop;
|
|
3786
|
-
moved = false;
|
|
3787
|
-
};
|
|
3788
|
-
const onTouchMove = (e) => {
|
|
3789
|
-
const t = e.touches[0];
|
|
3790
|
-
if (!t) return;
|
|
3791
|
-
if (Math.abs(t.clientY - startY) > CONTENT_PULL_THRESHOLD) moved = true;
|
|
3792
|
-
};
|
|
3793
|
-
const onTouchEnd = (e) => {
|
|
3794
|
-
if (!moved) return;
|
|
3795
|
-
if (deps.isDragging() || deps.isAnimating()) return;
|
|
3796
|
-
if (container.scrollTop !== startScrollTop) return;
|
|
3797
|
-
const t = e.changedTouches[0];
|
|
3798
|
-
if (!t) return;
|
|
3799
|
-
const deltaY = t.clientY - startY;
|
|
3800
|
-
const atTop = container.scrollTop <= 0;
|
|
3801
|
-
const allowed = deps.getAllowedIds();
|
|
3802
|
-
const idx = allowed.indexOf(deps.getActiveId());
|
|
3803
|
-
if (idx === -1) return;
|
|
3804
|
-
if (atTop && deltaY > CONTENT_PULL_THRESHOLD && idx > 0) {
|
|
3805
|
-
deps.snapTo(allowed[idx - 1]);
|
|
3806
|
-
} else if (deltaY < -CONTENT_PULL_THRESHOLD && idx < allowed.length - 1) {
|
|
3807
|
-
deps.snapTo(allowed[idx + 1]);
|
|
3808
|
-
}
|
|
3809
|
-
};
|
|
3810
|
-
container.addEventListener("touchstart", onTouchStart, { passive: true });
|
|
3811
|
-
container.addEventListener("touchmove", onTouchMove, { passive: true });
|
|
3812
|
-
container.addEventListener("touchend", onTouchEnd, { passive: true });
|
|
3813
|
-
return () => {
|
|
3814
|
-
container.removeEventListener("touchstart", onTouchStart);
|
|
3815
|
-
container.removeEventListener("touchmove", onTouchMove);
|
|
3816
|
-
container.removeEventListener("touchend", onTouchEnd);
|
|
3817
|
-
};
|
|
3978
|
+
// src/core/features/content-drag.ts
|
|
3979
|
+
function installContentDrag(deps) {
|
|
3980
|
+
const detach = deps.attachDragSurface(deps.container, "content");
|
|
3981
|
+
return () => detach?.();
|
|
3818
3982
|
}
|
|
3819
3983
|
|
|
3820
3984
|
// src/core/features/visual-viewport.ts
|
|
@@ -3922,13 +4086,9 @@ function contentSwipeFeature() {
|
|
|
3922
4086
|
stage: "attach",
|
|
3923
4087
|
install: (ctx) => {
|
|
3924
4088
|
if (!ctx.scrollContainer) return;
|
|
3925
|
-
return
|
|
4089
|
+
return installContentDrag({
|
|
3926
4090
|
container: ctx.scrollContainer,
|
|
3927
|
-
|
|
3928
|
-
isAnimating: ctx.isAnimating,
|
|
3929
|
-
getAllowedIds: ctx.allowedIdsBySize,
|
|
3930
|
-
getActiveId: ctx.getActiveId,
|
|
3931
|
-
snapTo: ctx.snapTo
|
|
4091
|
+
attachDragSurface: ctx.attachDragSurface
|
|
3932
4092
|
});
|
|
3933
4093
|
}
|
|
3934
4094
|
};
|
|
@@ -4060,6 +4220,8 @@ var BottomSheet = (props) => {
|
|
|
4060
4220
|
persistent: props.persistent,
|
|
4061
4221
|
disableClose: props.disableClose,
|
|
4062
4222
|
disableDrag: props.disableDrag,
|
|
4223
|
+
dragFrom: props.dragFrom,
|
|
4224
|
+
dragFromContent: props.dragFromContent,
|
|
4063
4225
|
closeOnRouteChange: props.closeOnRouteChange,
|
|
4064
4226
|
stackEffect: props.stackEffect,
|
|
4065
4227
|
returnFocusTo: props.returnFocusTo
|
|
@@ -4148,6 +4310,18 @@ var BottomSheet = (props) => {
|
|
|
4148
4310
|
}, {
|
|
4149
4311
|
defer: true
|
|
4150
4312
|
}));
|
|
4313
|
+
createEffect(on(() => props.dragFromContent, (value, prev) => {
|
|
4314
|
+
if (!engine || prev === void 0 || value === void 0) return;
|
|
4315
|
+
engine.setDragFromContent(value);
|
|
4316
|
+
}, {
|
|
4317
|
+
defer: true
|
|
4318
|
+
}));
|
|
4319
|
+
createEffect(on(() => props.dragFrom, (value, prev) => {
|
|
4320
|
+
if (!engine || prev === void 0 || value === void 0) return;
|
|
4321
|
+
engine.setDragFrom(value);
|
|
4322
|
+
}, {
|
|
4323
|
+
defer: true
|
|
4324
|
+
}));
|
|
4151
4325
|
const showBackdrop = createMemo(() => props.backdrop !== false);
|
|
4152
4326
|
const mode = createMemo(() => props.mode ?? "bottom");
|
|
4153
4327
|
const ariaLabel = createMemo(() => props.ariaLabel ?? "Bottom sheet");
|