@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.
Files changed (66) hide show
  1. package/README.md +33 -0
  2. package/dist/{BottomSheetCore-CsIjyq7C.d.cts → BottomSheetCore-Cp7dWy91.d.cts} +26 -1
  3. package/dist/{BottomSheetCore-D16lsa6g.d.ts → BottomSheetCore-DJYwWOqt.d.ts} +26 -1
  4. package/dist/{BottomSheetEngine-BYjAVrmd.d.cts → BottomSheetEngine-Lm7HIVHv.d.cts} +1 -1
  5. package/dist/{BottomSheetEngine-YuCNugZn.d.ts → BottomSheetEngine-O5PbeKfe.d.ts} +1 -1
  6. package/dist/core.cjs +231 -27
  7. package/dist/core.d.cts +2 -2
  8. package/dist/core.d.ts +2 -2
  9. package/dist/core.js +231 -27
  10. package/dist/debug.d.cts +1 -1
  11. package/dist/debug.d.ts +1 -1
  12. package/dist/element.cjs +300 -102
  13. package/dist/element.d.cts +2 -2
  14. package/dist/element.d.ts +2 -2
  15. package/dist/element.iife.global.js +2 -2
  16. package/dist/element.js +300 -102
  17. package/dist/features.cjs +6 -50
  18. package/dist/features.d.cts +2 -2
  19. package/dist/features.d.ts +2 -2
  20. package/dist/features.js +6 -50
  21. package/dist/index-Bb5TRmyg.d.cts +9 -0
  22. package/dist/index-Cl9ebCP2.d.ts +9 -0
  23. package/dist/index.cjs +238 -823
  24. package/dist/index.d.cts +42 -45
  25. package/dist/index.d.ts +42 -45
  26. package/dist/index.js +239 -810
  27. package/dist/integrations/formik.d.cts +1 -1
  28. package/dist/integrations/formik.d.ts +1 -1
  29. package/dist/integrations/react-hook-form.d.cts +1 -1
  30. package/dist/integrations/react-hook-form.d.ts +1 -1
  31. package/dist/overlay.cjs +5 -5
  32. package/dist/overlay.js +5 -5
  33. package/dist/preact.d.cts +2 -2
  34. package/dist/preact.d.ts +2 -2
  35. package/dist/qwik-lib/index.qwik.cjs +228 -77
  36. package/dist/qwik-lib/index.qwik.mjs +228 -77
  37. package/dist/qwik.cjs +245 -77
  38. package/dist/qwik.d.cts +4 -2
  39. package/dist/qwik.d.ts +4 -2
  40. package/dist/qwik.js +245 -77
  41. package/dist/react.cjs +250 -79
  42. package/dist/react.d.cts +3 -4
  43. package/dist/react.d.ts +3 -4
  44. package/dist/react.js +250 -79
  45. package/dist/solid.cjs +251 -77
  46. package/dist/solid.d.cts +27 -0
  47. package/dist/solid.d.ts +27 -0
  48. package/dist/solid.js +251 -77
  49. package/dist/solid.source.jsx +259 -77
  50. package/dist/styles.css +24 -4
  51. package/dist/svelte-core.cjs +237 -77
  52. package/dist/svelte-core.js +237 -77
  53. package/dist/svelte-src/BottomSheet.svelte +14 -0
  54. package/dist/svelte.cjs +247 -77
  55. package/dist/svelte.d.cts +2 -0
  56. package/dist/svelte.d.ts +2 -0
  57. package/dist/svelte.js +247 -77
  58. package/dist/vue.cjs +253 -77
  59. package/dist/vue.js +253 -77
  60. package/dist/webgl.cjs +583 -0
  61. package/dist/webgl.d.cts +17 -0
  62. package/dist/webgl.d.ts +17 -0
  63. package/dist/webgl.js +581 -0
  64. package/package.json +36 -12
  65. package/dist/index-DdYLOIIT.d.ts +0 -15
  66. package/dist/index-dfrzw-lI.d.cts +0 -15
package/dist/core.js CHANGED
@@ -2,7 +2,7 @@ var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
4
 
5
- // src/core/lifecycle/sheetStack.ts
5
+ // src/core/lifecycle/sheet-stack.ts
6
6
  var BASE_Z = 100;
7
7
  var STEP = 10;
8
8
  var SheetStack = class {
@@ -127,7 +127,7 @@ function createEventBus() {
127
127
  };
128
128
  }
129
129
 
130
- // src/core/primitives/cssLength.ts
130
+ // src/core/primitives/css-length.ts
131
131
  var probe = null;
132
132
  var PROBE_ATTR = "data-bs-probe";
133
133
  var ensureProbe = (axis) => {
@@ -181,7 +181,7 @@ var resolveSnap = (point, mode, measureFit) => {
181
181
  return Math.max(0, el.getBoundingClientRect().width);
182
182
  };
183
183
 
184
- // src/core/primitives/devWarn.ts
184
+ // src/core/primitives/dev-warn.ts
185
185
  function devWarn(...args) {
186
186
  if (typeof process !== "undefined" && process.env && process.env.NODE_ENV !== "production" && typeof console !== "undefined") {
187
187
  console.warn(...args);
@@ -1514,7 +1514,7 @@ var AnimationRunner = class {
1514
1514
  }
1515
1515
  };
1516
1516
 
1517
- // src/core/lifecycle/focusTrap.ts
1517
+ // src/core/lifecycle/focus-trap.ts
1518
1518
  var FOCUSABLE = [
1519
1519
  "a[href]",
1520
1520
  "area[href]",
@@ -1632,7 +1632,7 @@ var installFocusTrap = (container, options = {}) => {
1632
1632
  };
1633
1633
  };
1634
1634
 
1635
- // src/core/lifecycle/scrollLock.ts
1635
+ // src/core/lifecycle/scroll-lock.ts
1636
1636
  var lockCount = 0;
1637
1637
  var savedStyles = null;
1638
1638
  var lockBodyScroll = () => {
@@ -1814,30 +1814,44 @@ var SampleRing = class {
1814
1814
  this.size = 0;
1815
1815
  }
1816
1816
  };
1817
- var installGestures = (handle, mode, callbacks) => {
1817
+ var installGestures = (handle, mode, callbacks, options = {}) => {
1818
1818
  let activePointerId = null;
1819
1819
  let activePointerType = "touch";
1820
1820
  let startCoord = 0;
1821
1821
  let lastCoord = 0;
1822
+ let pendingStart = false;
1822
1823
  const VELOCITY_WINDOW_MS = (kind) => kind === "mouse" ? 160 : 120;
1823
1824
  const MAX_SAMPLES = 32;
1824
1825
  const samples = new SampleRing(MAX_SAMPLES);
1825
1826
  const axis = isAxisVertical(mode) ? "Y" : "X";
1826
1827
  const sign = mode === "bottom" || mode === "right" ? -1 : 1;
1827
1828
  const coordOf = (e) => axis === "Y" ? e.clientY : e.clientX;
1829
+ const capture = (pointerId) => {
1830
+ try {
1831
+ handle.setPointerCapture(pointerId);
1832
+ } catch {
1833
+ }
1834
+ };
1835
+ const releaseTracking = () => {
1836
+ activePointerId = null;
1837
+ pendingStart = false;
1838
+ samples.reset();
1839
+ };
1828
1840
  const onPointerDown = (e) => {
1829
1841
  if (activePointerId !== null) return;
1830
1842
  if (e.button !== void 0 && e.button !== 0) return;
1843
+ if (options.shouldStart && !options.shouldStart(e)) return;
1831
1844
  activePointerId = e.pointerId;
1832
1845
  activePointerType = e.pointerType || "touch";
1833
1846
  startCoord = coordOf(e);
1834
1847
  lastCoord = startCoord;
1835
1848
  samples.reset();
1836
1849
  samples.push(e.timeStamp, startCoord);
1837
- try {
1838
- handle.setPointerCapture(e.pointerId);
1839
- } catch {
1850
+ if (options.deferStart) {
1851
+ pendingStart = true;
1852
+ return;
1840
1853
  }
1854
+ capture(e.pointerId);
1841
1855
  callbacks.onStart(startCoord, activePointerType);
1842
1856
  };
1843
1857
  const onPointerMove = (e) => {
@@ -1845,6 +1859,22 @@ var installGestures = (handle, mode, callbacks) => {
1845
1859
  const coord = coordOf(e);
1846
1860
  const rawDelta = coord - startCoord;
1847
1861
  const delta = rawDelta * sign;
1862
+ if (pendingStart) {
1863
+ const verdict = options.deferStart(e, delta);
1864
+ if (verdict === false) {
1865
+ releaseTracking();
1866
+ return;
1867
+ }
1868
+ if (verdict !== true) return;
1869
+ pendingStart = false;
1870
+ startCoord = coord;
1871
+ lastCoord = coord;
1872
+ samples.reset();
1873
+ samples.push(e.timeStamp, coord);
1874
+ capture(e.pointerId);
1875
+ callbacks.onStart(startCoord, activePointerType);
1876
+ return;
1877
+ }
1848
1878
  lastCoord = coord;
1849
1879
  samples.push(e.timeStamp, coord);
1850
1880
  const cutoff = e.timeStamp - VELOCITY_WINDOW_MS(activePointerType);
@@ -1853,6 +1883,10 @@ var installGestures = (handle, mode, callbacks) => {
1853
1883
  };
1854
1884
  const finishGesture = (e) => {
1855
1885
  if (e.pointerId !== activePointerId) return;
1886
+ if (pendingStart) {
1887
+ releaseTracking();
1888
+ return;
1889
+ }
1856
1890
  const rawDelta = lastCoord - startCoord;
1857
1891
  const delta = rawDelta * sign;
1858
1892
  let velocity = 0;
@@ -1875,22 +1909,26 @@ var installGestures = (handle, mode, callbacks) => {
1875
1909
  };
1876
1910
  const onPointerCancel = (e) => {
1877
1911
  if (e.pointerId !== activePointerId) return;
1878
- activePointerId = null;
1879
- samples.reset();
1912
+ const wasPending = pendingStart;
1913
+ releaseTracking();
1914
+ if (wasPending) return;
1880
1915
  callbacks.onCancel?.();
1881
1916
  };
1882
1917
  handle.addEventListener("pointerdown", onPointerDown);
1883
1918
  handle.addEventListener("pointermove", onPointerMove);
1884
1919
  handle.addEventListener("pointerup", finishGesture);
1885
1920
  handle.addEventListener("pointercancel", onPointerCancel);
1921
+ const managesTouchAction = options.manageTouchAction !== false;
1886
1922
  const prevTouchAction = handle.style.touchAction;
1887
- handle.style.touchAction = isAxisVertical(mode) ? "pan-x" : "pan-y";
1923
+ if (managesTouchAction) {
1924
+ handle.style.touchAction = isAxisVertical(mode) ? "pan-x" : "pan-y";
1925
+ }
1888
1926
  return () => {
1889
1927
  handle.removeEventListener("pointerdown", onPointerDown);
1890
1928
  handle.removeEventListener("pointermove", onPointerMove);
1891
1929
  handle.removeEventListener("pointerup", finishGesture);
1892
1930
  handle.removeEventListener("pointercancel", onPointerCancel);
1893
- handle.style.touchAction = prevTouchAction;
1931
+ if (managesTouchAction) handle.style.touchAction = prevTouchAction;
1894
1932
  if (activePointerId !== null && handle.hasPointerCapture(activePointerId)) {
1895
1933
  handle.releasePointerCapture(activePointerId);
1896
1934
  }
@@ -2009,7 +2047,7 @@ var GestureController = class {
2009
2047
  const restoreTo = this.dragStartSize;
2010
2048
  void this.deps.animateTo(restoreTo, 0);
2011
2049
  }
2012
- });
2050
+ }, this.deps.gestureOptions);
2013
2051
  return this.detach;
2014
2052
  }
2015
2053
  forceClearDragState() {
@@ -2021,6 +2059,41 @@ var GestureController = class {
2021
2059
  }
2022
2060
  };
2023
2061
 
2062
+ // src/core/primitives/drag-zones.ts
2063
+ var DRAG_ZONE_SELECTOR = "[data-bs-drag]";
2064
+ var NO_DRAG_SELECTOR = "[data-bs-no-drag]";
2065
+ var asElement = (target) => {
2066
+ const candidate = target;
2067
+ return candidate && typeof candidate.closest === "function" ? candidate : null;
2068
+ };
2069
+ function isDragAllowedFrom(target, mode) {
2070
+ const el = asElement(target);
2071
+ if (!el) return mode !== "zones";
2072
+ if (el.closest(NO_DRAG_SELECTOR)) return false;
2073
+ if (mode === "zones") return el.closest(DRAG_ZONE_SELECTOR) !== null;
2074
+ return true;
2075
+ }
2076
+
2077
+ // src/core/primitives/content-gesture.ts
2078
+ var CONTENT_DRAG_SLOP = 6;
2079
+ function decideContentGesture(input) {
2080
+ const slop = input.slop ?? CONTENT_DRAG_SLOP;
2081
+ if (Math.abs(input.delta) < slop) return "pending";
2082
+ if (input.scrollTop > 0) return "scroll";
2083
+ if (input.delta > 0 && input.atMaxSnap) return "scroll";
2084
+ return "drag";
2085
+ }
2086
+
2087
+ // src/core/primitives/touch-scroll-guard.ts
2088
+ function installTouchScrollGuard(surface, isDragging) {
2089
+ const onTouchMove = (e) => {
2090
+ if (!isDragging()) return;
2091
+ if (e.cancelable) e.preventDefault();
2092
+ };
2093
+ surface.addEventListener("touchmove", onTouchMove, { passive: false });
2094
+ return () => surface.removeEventListener("touchmove", onTouchMove);
2095
+ }
2096
+
2024
2097
  // src/core/primitives/aria-slider-writer.ts
2025
2098
  var AriaSliderWriter = class {
2026
2099
  constructor(handle, mode) {
@@ -2376,6 +2449,8 @@ function resolveEngineOptions(opts, extras) {
2376
2449
  mode: opts.mode ?? "bottom",
2377
2450
  flickVelocity: opts.flickVelocity ?? DEFAULT_FLICK_VELOCITY,
2378
2451
  dragThreshold: opts.dragThreshold ?? DEFAULT_DRAG_THRESHOLD,
2452
+ dragFrom: opts.dragFrom ?? (opts.handle ? "handle" : "sheet"),
2453
+ dragFromContent: opts.dragFromContent ?? true,
2379
2454
  rubberBandEnabled: opts.rubberBand ?? true,
2380
2455
  closeOnBack: opts.closeOnBack ?? false,
2381
2456
  persistent: opts.persistent ?? false,
@@ -2461,6 +2536,8 @@ var BottomSheetCore = class {
2461
2536
  __publicField(this, "mode");
2462
2537
  __publicField(this, "flickVelocity");
2463
2538
  __publicField(this, "dragThreshold");
2539
+ __publicField(this, "dragFromMode");
2540
+ __publicField(this, "dragFromContentDefault");
2464
2541
  __publicField(this, "rubberBandEnabled");
2465
2542
  __publicField(this, "scrim");
2466
2543
  __publicField(this, "aria");
@@ -2478,8 +2555,11 @@ var BottomSheetCore = class {
2478
2555
  __publicField(this, "activeId");
2479
2556
  __publicField(this, "size", 0);
2480
2557
  __publicField(this, "gesture");
2558
+ __publicField(this, "contentGesture");
2559
+ __publicField(this, "detachSheetGesture", null);
2481
2560
  __publicField(this, "rootEl", null);
2482
2561
  __publicField(this, "destroyed", false);
2562
+ __publicField(this, "restClosed", false);
2483
2563
  __publicField(this, "currentViewTransition", null);
2484
2564
  __publicField(this, "currentAbort", new AbortController());
2485
2565
  __publicField(this, "sizeWriteSentinel", new WriteSentinel());
@@ -2532,6 +2612,8 @@ var BottomSheetCore = class {
2532
2612
  this.aria = new AriaSliderWriter(this.handle, this.mode);
2533
2613
  this.flickVelocity = resolved.flickVelocity;
2534
2614
  this.dragThreshold = resolved.dragThreshold;
2615
+ this.dragFromMode = resolved.dragFrom;
2616
+ this.dragFromContentDefault = resolved.dragFromContent;
2535
2617
  this.rubberBandEnabled = resolved.rubberBandEnabled;
2536
2618
  this.scrim = new ScrimController(
2537
2619
  {
@@ -2558,7 +2640,7 @@ var BottomSheetCore = class {
2558
2640
  getRootEl: () => this.rootEl,
2559
2641
  applySize: (size) => this.applySize(size),
2560
2642
  getSize: () => this.size,
2561
- isDragging: () => this.gesture?.isDragging ?? false,
2643
+ isDragging: () => this.isDraggingAny(),
2562
2644
  applyAux: (size) => this.applySize(size, true),
2563
2645
  getTransformFor: (size) => this.transformTemplate(this.snaps.getMaxAxisSize() - size)
2564
2646
  },
@@ -2619,6 +2701,7 @@ var BottomSheetCore = class {
2619
2701
  const initial = this.snaps.findById(this.activeId);
2620
2702
  if (initial) this.size = initial.size;
2621
2703
  this.applySize(this.size);
2704
+ this.setRestClosed(this.size === 0);
2622
2705
  this.updateAriaSlider();
2623
2706
  this.scrollCache = createScrollCache({
2624
2707
  scrollContainer: this.scrollContainer,
@@ -2649,7 +2732,7 @@ var BottomSheetCore = class {
2649
2732
  (p) => p.size === "fit" || p.size === "content"
2650
2733
  ),
2651
2734
  isDestroyed: () => this.destroyed,
2652
- isDragging: () => this.gesture?.isDragging ?? false,
2735
+ isDragging: () => this.isDraggingAny(),
2653
2736
  recompute: () => this.recompute()
2654
2737
  })
2655
2738
  );
@@ -2675,7 +2758,7 @@ var BottomSheetCore = class {
2675
2758
  autoCollapseAfter
2676
2759
  },
2677
2760
  isDestroyed: () => this.destroyed,
2678
- isDragging: () => this.gesture?.isDragging ?? false,
2761
+ isDragging: () => this.isDraggingAny(),
2679
2762
  isAnimating: () => this.animation.isAnimating,
2680
2763
  isTopSheet: () => this.isTopSheet,
2681
2764
  isVerticalAxis: () => this.mode === "bottom" || this.mode === "top",
@@ -2705,6 +2788,7 @@ var BottomSheetCore = class {
2705
2788
  void this.snapTo(id);
2706
2789
  },
2707
2790
  close: (reason) => this.close(reason),
2791
+ attachDragSurface: (surface, kind) => this.attachDragSurface(surface, kind),
2708
2792
  on: (event, fn) => this.on(event, fn),
2709
2793
  addTeardown: (fn) => this.teardowns.add(fn)
2710
2794
  };
@@ -2733,7 +2817,7 @@ var BottomSheetCore = class {
2733
2817
  return {
2734
2818
  size: this.size,
2735
2819
  activeId: this.activeId,
2736
- isDragging: this.gesture?.isDragging ?? false,
2820
+ isDragging: this.isDraggingAny(),
2737
2821
  isAnimating: this.animation.isAnimating,
2738
2822
  progress: this.computeProgress(this.size)
2739
2823
  };
@@ -2853,9 +2937,16 @@ var BottomSheetCore = class {
2853
2937
  progress: this.computeProgress(this.size)
2854
2938
  });
2855
2939
  if (withHaptic) this.haptic();
2940
+ this.setRestClosed(targetSize === 0);
2856
2941
  if (wasClosed && targetSize > 0) this.emitOpenSequence(id);
2857
2942
  if (targetSize === 0) this.emitCloseSequence();
2858
2943
  }
2944
+ setRestClosed(closed) {
2945
+ if (closed === this.restClosed) return;
2946
+ this.restClosed = closed;
2947
+ if (closed) this.element.setAttribute("data-bs-rest", "closed");
2948
+ else this.element.removeAttribute("data-bs-rest");
2949
+ }
2859
2950
  emitOpenSequence(id) {
2860
2951
  this.emit("open", { id });
2861
2952
  this.handleOpen();
@@ -2911,6 +3002,20 @@ var BottomSheetCore = class {
2911
3002
  if (this.destroyed) return;
2912
3003
  this.disableDragFlag = value;
2913
3004
  }
3005
+ setDragFromContent(value) {
3006
+ if (this.destroyed) return;
3007
+ this.dragFromContentDefault = value;
3008
+ }
3009
+ setDragFrom(mode) {
3010
+ if (this.destroyed || mode === this.dragFromMode) return;
3011
+ this.gesture?.forceClearDragState();
3012
+ this.detachSheetGesture?.();
3013
+ this.dragFromMode = mode;
3014
+ this.mountSheetGesture();
3015
+ }
3016
+ getDragFrom() {
3017
+ return this.dragFromMode;
3018
+ }
2914
3019
  isTop() {
2915
3020
  return this.isTopSheet;
2916
3021
  }
@@ -3065,12 +3170,24 @@ var BottomSheetCore = class {
3065
3170
  auditVhUsage(points);
3066
3171
  this.auditDuplicateSnapIds(points);
3067
3172
  this.snaps.setRaw(points);
3068
- if (allowed) this.snaps.setAllowedIds(allowed);
3173
+ if (allowed) {
3174
+ this.snaps.setAllowedIds(allowed);
3175
+ } else {
3176
+ const present = this.snaps.getResolvedSnaps().map((s) => s.id);
3177
+ const kept = this.snaps.getAllowedIds().filter((id) => present.includes(id));
3178
+ this.snaps.setAllowedIds(kept.length ? kept : present);
3179
+ }
3069
3180
  this.scrollCache.clear();
3070
3181
  this.scrim.invalidateOpacityCache();
3071
3182
  const current = this.snaps.findById(this.activeId);
3072
3183
  if (current) {
3073
3184
  this.applySize(current.size);
3185
+ } else {
3186
+ const fallback = this.snaps.getResolvedSnaps().find((s) => this.snaps.getAllowedIds().includes(s.id)) ?? this.snaps.getResolvedSnaps()[0];
3187
+ if (fallback) {
3188
+ this.activeId = fallback.id;
3189
+ this.applySize(fallback.size);
3190
+ }
3074
3191
  }
3075
3192
  this.updateAriaSlider();
3076
3193
  }
@@ -3080,7 +3197,7 @@ var BottomSheetCore = class {
3080
3197
  this.snaps.recompute();
3081
3198
  this.maxHeight.clampTo();
3082
3199
  this.scrim.invalidateOpacityCache();
3083
- if (this.gesture?.isDragging) return;
3200
+ if (this.isDraggingAny()) return;
3084
3201
  this.healActiveSnap();
3085
3202
  }
3086
3203
  healActiveSnap() {
@@ -3102,6 +3219,8 @@ var BottomSheetCore = class {
3102
3219
  this.bus.clear();
3103
3220
  this.animation.cancel();
3104
3221
  this.gesture?.forceClearDragState();
3222
+ this.contentGesture?.forceClearDragState();
3223
+ this.setRestClosed(false);
3105
3224
  this.teardowns.drain();
3106
3225
  this.scrim.destroy();
3107
3226
  this.animation.destroy();
@@ -3214,11 +3333,12 @@ var BottomSheetCore = class {
3214
3333
  const scale = Math.max(1 - depth * 0.04, 0.86);
3215
3334
  this.element.style.scale = scale === 1 ? "" : String(scale);
3216
3335
  }
3217
- attach() {
3218
- this.gesture = new GestureController({
3219
- handle: this.handle,
3336
+ buildGestureDeps(surface, gestureOptions) {
3337
+ return {
3338
+ handle: surface,
3220
3339
  element: this.element,
3221
3340
  mode: this.mode,
3341
+ gestureOptions,
3222
3342
  getRoot: () => this.rootEl,
3223
3343
  getDragContext: () => {
3224
3344
  const buf = this.dragContextBuf;
@@ -3237,8 +3357,88 @@ var BottomSheetCore = class {
3237
3357
  settleAfterDrag: (delta, velocity, kind) => this.settleAfterDrag(delta, velocity, kind),
3238
3358
  emit: (event, payload) => this.emit(event, payload),
3239
3359
  listenerCount: (event) => this.bus.listenerCount(event)
3360
+ };
3361
+ }
3362
+ isContentDragAllowed() {
3363
+ if (this.disableDragFlag) return false;
3364
+ const point = this.snapPointsRaw.find((p) => p.id === this.activeId);
3365
+ return point?.dragFromContent ?? this.dragFromContentDefault;
3366
+ }
3367
+ decideContentDrag(surface, e, delta) {
3368
+ if (this.destroyed) return false;
3369
+ if (e.pointerType === "mouse") return false;
3370
+ if (this.gesture?.isDragging) return false;
3371
+ if (!this.isContentDragAllowed()) return false;
3372
+ if (!isDragAllowedFrom(e.target, "sheet")) return false;
3373
+ const decision = decideContentGesture({
3374
+ delta,
3375
+ scrollTop: surface.scrollTop,
3376
+ atMaxSnap: this.size >= this.getAllowedRange().max - 0.5
3377
+ });
3378
+ if (decision === "pending") return null;
3379
+ return decision === "drag";
3380
+ }
3381
+ attachDragSurface(surface, kind) {
3382
+ if (this.destroyed || kind !== "content") return;
3383
+ if (this.contentGesture) return;
3384
+ const controller = new GestureController(
3385
+ this.buildGestureDeps(surface, {
3386
+ manageTouchAction: false,
3387
+ deferStart: (e, delta) => this.decideContentDrag(surface, e, delta)
3388
+ })
3389
+ );
3390
+ this.contentGesture = controller;
3391
+ const detachGestures = controller.install();
3392
+ const detachGuard = installTouchScrollGuard(
3393
+ surface,
3394
+ () => controller.isDragging
3395
+ );
3396
+ return () => {
3397
+ detachGuard();
3398
+ detachGestures();
3399
+ if (this.contentGesture === controller) this.contentGesture = void 0;
3400
+ };
3401
+ }
3402
+ sheetDragSurface() {
3403
+ return this.dragFromMode === "handle" ? this.handle : this.element;
3404
+ }
3405
+ canStartSheetDrag(e) {
3406
+ if (this.contentGesture?.isDragging) return false;
3407
+ const target = e.target;
3408
+ const scoped = typeof target?.closest === "function";
3409
+ if (scoped && target.closest(NO_DRAG_SELECTOR)) return false;
3410
+ if (this.handle !== this.element && scoped && this.handle.contains(target)) {
3411
+ return true;
3412
+ }
3413
+ if (!isDragAllowedFrom(e.target, this.dragFromMode)) return false;
3414
+ if (this.dragFromMode === "handle") return true;
3415
+ if (this.scrollContainer && scoped && this.scrollContainer.contains(target) && !target.closest(DRAG_ZONE_SELECTOR)) {
3416
+ return false;
3417
+ }
3418
+ return true;
3419
+ }
3420
+ mountSheetGesture() {
3421
+ const surface = this.sheetDragSurface();
3422
+ const controller = new GestureController(
3423
+ this.buildGestureDeps(surface, {
3424
+ shouldStart: (e) => this.canStartSheetDrag(e),
3425
+ manageTouchAction: this.dragFromMode === "handle"
3426
+ })
3427
+ );
3428
+ this.gesture = controller;
3429
+ const detachGestures = controller.install();
3430
+ const detachGuard = this.dragFromMode === "handle" ? null : installTouchScrollGuard(surface, () => controller.isDragging);
3431
+ this.detachSheetGesture = () => {
3432
+ detachGuard?.();
3433
+ detachGestures();
3434
+ };
3435
+ }
3436
+ attach() {
3437
+ this.mountSheetGesture();
3438
+ this.teardowns.add(() => {
3439
+ this.detachSheetGesture?.();
3440
+ this.detachSheetGesture = null;
3240
3441
  });
3241
- this.teardowns.add(this.gesture.install());
3242
3442
  try {
3243
3443
  this.attachFeatures();
3244
3444
  } catch (err) {
@@ -3275,7 +3475,7 @@ var BottomSheetCore = class {
3275
3475
  element: this.element,
3276
3476
  getMode: () => this.mode,
3277
3477
  isDestroyed: () => this.destroyed,
3278
- isDragging: () => this.gesture?.isDragging ?? false,
3478
+ isDragging: () => this.isDraggingAny(),
3279
3479
  resolveActiveSnap: () => this.snaps.findById(this.activeId),
3280
3480
  getMaxAxisSize: () => this.snaps.getMaxAxisSize(),
3281
3481
  getSize: () => this.size,
@@ -3373,8 +3573,11 @@ var BottomSheetCore = class {
3373
3573
  );
3374
3574
  });
3375
3575
  }
3576
+ isDraggingAny() {
3577
+ return (this.gesture?.isDragging ?? false) || (this.contentGesture?.isDragging ?? false);
3578
+ }
3376
3579
  clearWillChangeIfIdle() {
3377
- if (this.animation.isAnimating || this.gesture?.isDragging) return;
3580
+ if (this.animation.isAnimating || this.isDraggingAny()) return;
3378
3581
  this.element.style.willChange = "";
3379
3582
  }
3380
3583
  haptic() {
@@ -3387,8 +3590,9 @@ var BottomSheetCore = class {
3387
3590
  }
3388
3591
  applySize(size, skipTransform = false) {
3389
3592
  const cap = this.snaps.getMaxAxisSize();
3390
- const clamped = cap > 0 && size > cap && !this.gesture?.isDragging && !this.allowOvershoot ? cap : size;
3593
+ const clamped = cap > 0 && size > cap && !this.isDraggingAny() && !this.allowOvershoot ? cap : size;
3391
3594
  this.size = clamped;
3595
+ if (clamped > 0) this.setRestClosed(false);
3392
3596
  const offset = cap - clamped;
3393
3597
  const style = this.element.style;
3394
3598
  if (!skipTransform) style.transform = this.transformTemplate(offset);
package/dist/debug.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { E as EngineState, d as SheetEventMap } from './BottomSheetCore-CsIjyq7C.cjs';
1
+ import { E as EngineState, d as SheetEventMap } from './BottomSheetCore-Cp7dWy91.cjs';
2
2
  import './transform-jVfAikE9.cjs';
3
3
 
4
4
  type DebugOverlayPosition = "top-left" | "top-right" | "bottom-left" | "bottom-right";
package/dist/debug.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { E as EngineState, d as SheetEventMap } from './BottomSheetCore-D16lsa6g.js';
1
+ import { E as EngineState, d as SheetEventMap } from './BottomSheetCore-DJYwWOqt.js';
2
2
  import './transform-jVfAikE9.js';
3
3
 
4
4
  type DebugOverlayPosition = "top-left" | "top-right" | "bottom-left" | "bottom-right";