@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.cjs
CHANGED
|
@@ -7,7 +7,7 @@ var __defProp = Object.defineProperty;
|
|
|
7
7
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
8
8
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
9
9
|
|
|
10
|
-
// src/core/lifecycle/
|
|
10
|
+
// src/core/lifecycle/sheet-stack.ts
|
|
11
11
|
var BASE_Z = 100;
|
|
12
12
|
var STEP = 10;
|
|
13
13
|
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);
|
|
@@ -1519,7 +1519,7 @@ var AnimationRunner = class {
|
|
|
1519
1519
|
}
|
|
1520
1520
|
};
|
|
1521
1521
|
|
|
1522
|
-
// src/core/lifecycle/
|
|
1522
|
+
// src/core/lifecycle/focus-trap.ts
|
|
1523
1523
|
var FOCUSABLE = [
|
|
1524
1524
|
"a[href]",
|
|
1525
1525
|
"area[href]",
|
|
@@ -1637,7 +1637,7 @@ var installFocusTrap = (container, options = {}) => {
|
|
|
1637
1637
|
};
|
|
1638
1638
|
};
|
|
1639
1639
|
|
|
1640
|
-
// src/core/lifecycle/
|
|
1640
|
+
// src/core/lifecycle/scroll-lock.ts
|
|
1641
1641
|
var lockCount = 0;
|
|
1642
1642
|
var savedStyles = null;
|
|
1643
1643
|
var lockBodyScroll = () => {
|
|
@@ -1819,30 +1819,44 @@ var SampleRing = class {
|
|
|
1819
1819
|
this.size = 0;
|
|
1820
1820
|
}
|
|
1821
1821
|
};
|
|
1822
|
-
var installGestures = (handle, mode, callbacks) => {
|
|
1822
|
+
var installGestures = (handle, mode, callbacks, options = {}) => {
|
|
1823
1823
|
let activePointerId = null;
|
|
1824
1824
|
let activePointerType = "touch";
|
|
1825
1825
|
let startCoord = 0;
|
|
1826
1826
|
let lastCoord = 0;
|
|
1827
|
+
let pendingStart = false;
|
|
1827
1828
|
const VELOCITY_WINDOW_MS = (kind) => kind === "mouse" ? 160 : 120;
|
|
1828
1829
|
const MAX_SAMPLES = 32;
|
|
1829
1830
|
const samples = new SampleRing(MAX_SAMPLES);
|
|
1830
1831
|
const axis = isAxisVertical(mode) ? "Y" : "X";
|
|
1831
1832
|
const sign = mode === "bottom" || mode === "right" ? -1 : 1;
|
|
1832
1833
|
const coordOf = (e) => axis === "Y" ? e.clientY : e.clientX;
|
|
1834
|
+
const capture = (pointerId) => {
|
|
1835
|
+
try {
|
|
1836
|
+
handle.setPointerCapture(pointerId);
|
|
1837
|
+
} catch {
|
|
1838
|
+
}
|
|
1839
|
+
};
|
|
1840
|
+
const releaseTracking = () => {
|
|
1841
|
+
activePointerId = null;
|
|
1842
|
+
pendingStart = false;
|
|
1843
|
+
samples.reset();
|
|
1844
|
+
};
|
|
1833
1845
|
const onPointerDown = (e) => {
|
|
1834
1846
|
if (activePointerId !== null) return;
|
|
1835
1847
|
if (e.button !== void 0 && e.button !== 0) return;
|
|
1848
|
+
if (options.shouldStart && !options.shouldStart(e)) return;
|
|
1836
1849
|
activePointerId = e.pointerId;
|
|
1837
1850
|
activePointerType = e.pointerType || "touch";
|
|
1838
1851
|
startCoord = coordOf(e);
|
|
1839
1852
|
lastCoord = startCoord;
|
|
1840
1853
|
samples.reset();
|
|
1841
1854
|
samples.push(e.timeStamp, startCoord);
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1855
|
+
if (options.deferStart) {
|
|
1856
|
+
pendingStart = true;
|
|
1857
|
+
return;
|
|
1845
1858
|
}
|
|
1859
|
+
capture(e.pointerId);
|
|
1846
1860
|
callbacks.onStart(startCoord, activePointerType);
|
|
1847
1861
|
};
|
|
1848
1862
|
const onPointerMove = (e) => {
|
|
@@ -1850,6 +1864,22 @@ var installGestures = (handle, mode, callbacks) => {
|
|
|
1850
1864
|
const coord = coordOf(e);
|
|
1851
1865
|
const rawDelta = coord - startCoord;
|
|
1852
1866
|
const delta = rawDelta * sign;
|
|
1867
|
+
if (pendingStart) {
|
|
1868
|
+
const verdict = options.deferStart(e, delta);
|
|
1869
|
+
if (verdict === false) {
|
|
1870
|
+
releaseTracking();
|
|
1871
|
+
return;
|
|
1872
|
+
}
|
|
1873
|
+
if (verdict !== true) return;
|
|
1874
|
+
pendingStart = false;
|
|
1875
|
+
startCoord = coord;
|
|
1876
|
+
lastCoord = coord;
|
|
1877
|
+
samples.reset();
|
|
1878
|
+
samples.push(e.timeStamp, coord);
|
|
1879
|
+
capture(e.pointerId);
|
|
1880
|
+
callbacks.onStart(startCoord, activePointerType);
|
|
1881
|
+
return;
|
|
1882
|
+
}
|
|
1853
1883
|
lastCoord = coord;
|
|
1854
1884
|
samples.push(e.timeStamp, coord);
|
|
1855
1885
|
const cutoff = e.timeStamp - VELOCITY_WINDOW_MS(activePointerType);
|
|
@@ -1858,6 +1888,10 @@ var installGestures = (handle, mode, callbacks) => {
|
|
|
1858
1888
|
};
|
|
1859
1889
|
const finishGesture = (e) => {
|
|
1860
1890
|
if (e.pointerId !== activePointerId) return;
|
|
1891
|
+
if (pendingStart) {
|
|
1892
|
+
releaseTracking();
|
|
1893
|
+
return;
|
|
1894
|
+
}
|
|
1861
1895
|
const rawDelta = lastCoord - startCoord;
|
|
1862
1896
|
const delta = rawDelta * sign;
|
|
1863
1897
|
let velocity = 0;
|
|
@@ -1880,22 +1914,26 @@ var installGestures = (handle, mode, callbacks) => {
|
|
|
1880
1914
|
};
|
|
1881
1915
|
const onPointerCancel = (e) => {
|
|
1882
1916
|
if (e.pointerId !== activePointerId) return;
|
|
1883
|
-
|
|
1884
|
-
|
|
1917
|
+
const wasPending = pendingStart;
|
|
1918
|
+
releaseTracking();
|
|
1919
|
+
if (wasPending) return;
|
|
1885
1920
|
callbacks.onCancel?.();
|
|
1886
1921
|
};
|
|
1887
1922
|
handle.addEventListener("pointerdown", onPointerDown);
|
|
1888
1923
|
handle.addEventListener("pointermove", onPointerMove);
|
|
1889
1924
|
handle.addEventListener("pointerup", finishGesture);
|
|
1890
1925
|
handle.addEventListener("pointercancel", onPointerCancel);
|
|
1926
|
+
const managesTouchAction = options.manageTouchAction !== false;
|
|
1891
1927
|
const prevTouchAction = handle.style.touchAction;
|
|
1892
|
-
|
|
1928
|
+
if (managesTouchAction) {
|
|
1929
|
+
handle.style.touchAction = isAxisVertical(mode) ? "pan-x" : "pan-y";
|
|
1930
|
+
}
|
|
1893
1931
|
return () => {
|
|
1894
1932
|
handle.removeEventListener("pointerdown", onPointerDown);
|
|
1895
1933
|
handle.removeEventListener("pointermove", onPointerMove);
|
|
1896
1934
|
handle.removeEventListener("pointerup", finishGesture);
|
|
1897
1935
|
handle.removeEventListener("pointercancel", onPointerCancel);
|
|
1898
|
-
handle.style.touchAction = prevTouchAction;
|
|
1936
|
+
if (managesTouchAction) handle.style.touchAction = prevTouchAction;
|
|
1899
1937
|
if (activePointerId !== null && handle.hasPointerCapture(activePointerId)) {
|
|
1900
1938
|
handle.releasePointerCapture(activePointerId);
|
|
1901
1939
|
}
|
|
@@ -2014,7 +2052,7 @@ var GestureController = class {
|
|
|
2014
2052
|
const restoreTo = this.dragStartSize;
|
|
2015
2053
|
void this.deps.animateTo(restoreTo, 0);
|
|
2016
2054
|
}
|
|
2017
|
-
});
|
|
2055
|
+
}, this.deps.gestureOptions);
|
|
2018
2056
|
return this.detach;
|
|
2019
2057
|
}
|
|
2020
2058
|
forceClearDragState() {
|
|
@@ -2026,6 +2064,41 @@ var GestureController = class {
|
|
|
2026
2064
|
}
|
|
2027
2065
|
};
|
|
2028
2066
|
|
|
2067
|
+
// src/core/primitives/drag-zones.ts
|
|
2068
|
+
var DRAG_ZONE_SELECTOR = "[data-bs-drag]";
|
|
2069
|
+
var NO_DRAG_SELECTOR = "[data-bs-no-drag]";
|
|
2070
|
+
var asElement = (target) => {
|
|
2071
|
+
const candidate = target;
|
|
2072
|
+
return candidate && typeof candidate.closest === "function" ? candidate : null;
|
|
2073
|
+
};
|
|
2074
|
+
function isDragAllowedFrom(target, mode) {
|
|
2075
|
+
const el = asElement(target);
|
|
2076
|
+
if (!el) return mode !== "zones";
|
|
2077
|
+
if (el.closest(NO_DRAG_SELECTOR)) return false;
|
|
2078
|
+
if (mode === "zones") return el.closest(DRAG_ZONE_SELECTOR) !== null;
|
|
2079
|
+
return true;
|
|
2080
|
+
}
|
|
2081
|
+
|
|
2082
|
+
// src/core/primitives/content-gesture.ts
|
|
2083
|
+
var CONTENT_DRAG_SLOP = 6;
|
|
2084
|
+
function decideContentGesture(input) {
|
|
2085
|
+
const slop = input.slop ?? CONTENT_DRAG_SLOP;
|
|
2086
|
+
if (Math.abs(input.delta) < slop) return "pending";
|
|
2087
|
+
if (input.scrollTop > 0) return "scroll";
|
|
2088
|
+
if (input.delta > 0 && input.atMaxSnap) return "scroll";
|
|
2089
|
+
return "drag";
|
|
2090
|
+
}
|
|
2091
|
+
|
|
2092
|
+
// src/core/primitives/touch-scroll-guard.ts
|
|
2093
|
+
function installTouchScrollGuard(surface, isDragging) {
|
|
2094
|
+
const onTouchMove = (e) => {
|
|
2095
|
+
if (!isDragging()) return;
|
|
2096
|
+
if (e.cancelable) e.preventDefault();
|
|
2097
|
+
};
|
|
2098
|
+
surface.addEventListener("touchmove", onTouchMove, { passive: false });
|
|
2099
|
+
return () => surface.removeEventListener("touchmove", onTouchMove);
|
|
2100
|
+
}
|
|
2101
|
+
|
|
2029
2102
|
// src/core/primitives/aria-slider-writer.ts
|
|
2030
2103
|
var AriaSliderWriter = class {
|
|
2031
2104
|
constructor(handle, mode) {
|
|
@@ -2381,6 +2454,8 @@ function resolveEngineOptions(opts, extras) {
|
|
|
2381
2454
|
mode: opts.mode ?? "bottom",
|
|
2382
2455
|
flickVelocity: opts.flickVelocity ?? DEFAULT_FLICK_VELOCITY,
|
|
2383
2456
|
dragThreshold: opts.dragThreshold ?? DEFAULT_DRAG_THRESHOLD,
|
|
2457
|
+
dragFrom: opts.dragFrom ?? (opts.handle ? "handle" : "sheet"),
|
|
2458
|
+
dragFromContent: opts.dragFromContent ?? true,
|
|
2384
2459
|
rubberBandEnabled: opts.rubberBand ?? true,
|
|
2385
2460
|
closeOnBack: opts.closeOnBack ?? false,
|
|
2386
2461
|
persistent: opts.persistent ?? false,
|
|
@@ -2466,6 +2541,8 @@ var BottomSheetCore = class {
|
|
|
2466
2541
|
__publicField(this, "mode");
|
|
2467
2542
|
__publicField(this, "flickVelocity");
|
|
2468
2543
|
__publicField(this, "dragThreshold");
|
|
2544
|
+
__publicField(this, "dragFromMode");
|
|
2545
|
+
__publicField(this, "dragFromContentDefault");
|
|
2469
2546
|
__publicField(this, "rubberBandEnabled");
|
|
2470
2547
|
__publicField(this, "scrim");
|
|
2471
2548
|
__publicField(this, "aria");
|
|
@@ -2483,8 +2560,11 @@ var BottomSheetCore = class {
|
|
|
2483
2560
|
__publicField(this, "activeId");
|
|
2484
2561
|
__publicField(this, "size", 0);
|
|
2485
2562
|
__publicField(this, "gesture");
|
|
2563
|
+
__publicField(this, "contentGesture");
|
|
2564
|
+
__publicField(this, "detachSheetGesture", null);
|
|
2486
2565
|
__publicField(this, "rootEl", null);
|
|
2487
2566
|
__publicField(this, "destroyed", false);
|
|
2567
|
+
__publicField(this, "restClosed", false);
|
|
2488
2568
|
__publicField(this, "currentViewTransition", null);
|
|
2489
2569
|
__publicField(this, "currentAbort", new AbortController());
|
|
2490
2570
|
__publicField(this, "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
|
};
|
|
@@ -4062,6 +4222,8 @@ var BottomSheet = (props) => {
|
|
|
4062
4222
|
persistent: props.persistent,
|
|
4063
4223
|
disableClose: props.disableClose,
|
|
4064
4224
|
disableDrag: props.disableDrag,
|
|
4225
|
+
dragFrom: props.dragFrom,
|
|
4226
|
+
dragFromContent: props.dragFromContent,
|
|
4065
4227
|
closeOnRouteChange: props.closeOnRouteChange,
|
|
4066
4228
|
stackEffect: props.stackEffect,
|
|
4067
4229
|
returnFocusTo: props.returnFocusTo
|
|
@@ -4150,6 +4312,18 @@ var BottomSheet = (props) => {
|
|
|
4150
4312
|
}, {
|
|
4151
4313
|
defer: true
|
|
4152
4314
|
}));
|
|
4315
|
+
solidJs.createEffect(solidJs.on(() => props.dragFromContent, (value, prev) => {
|
|
4316
|
+
if (!engine || prev === void 0 || value === void 0) return;
|
|
4317
|
+
engine.setDragFromContent(value);
|
|
4318
|
+
}, {
|
|
4319
|
+
defer: true
|
|
4320
|
+
}));
|
|
4321
|
+
solidJs.createEffect(solidJs.on(() => props.dragFrom, (value, prev) => {
|
|
4322
|
+
if (!engine || prev === void 0 || value === void 0) return;
|
|
4323
|
+
engine.setDragFrom(value);
|
|
4324
|
+
}, {
|
|
4325
|
+
defer: true
|
|
4326
|
+
}));
|
|
4153
4327
|
const showBackdrop = solidJs.createMemo(() => props.backdrop !== false);
|
|
4154
4328
|
const mode = solidJs.createMemo(() => props.mode ?? "bottom");
|
|
4155
4329
|
const ariaLabel = solidJs.createMemo(() => props.ariaLabel ?? "Bottom sheet");
|