@surdeddd/bottom-sheet 0.14.0 → 0.20.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 (56) hide show
  1. package/README.md +13 -0
  2. package/dist/{BottomSheetCore-DJYwWOqt.d.ts → BottomSheetCore-Cgn8b_6A.d.ts} +11 -2
  3. package/dist/{BottomSheetCore-Cp7dWy91.d.cts → BottomSheetCore-VPJZcKcg.d.cts} +11 -2
  4. package/dist/{BottomSheetEngine-Lm7HIVHv.d.cts → BottomSheetEngine-B8C2CwF9.d.cts} +1 -1
  5. package/dist/{BottomSheetEngine-O5PbeKfe.d.ts → BottomSheetEngine-DwYR_ygJ.d.ts} +1 -1
  6. package/dist/core.cjs +100 -9
  7. package/dist/core.d.cts +2 -2
  8. package/dist/core.d.ts +2 -2
  9. package/dist/core.js +100 -9
  10. package/dist/debug.d.cts +1 -1
  11. package/dist/debug.d.ts +1 -1
  12. package/dist/element.cjs +107 -9
  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 +107 -9
  17. package/dist/features.d.cts +4 -4
  18. package/dist/features.d.ts +4 -4
  19. package/dist/{index-Bb5TRmyg.d.cts → index-CnfbOKx0.d.cts} +1 -1
  20. package/dist/{index-Cl9ebCP2.d.ts → index-DcMkhXAy.d.ts} +1 -1
  21. package/dist/index.cjs +100 -9
  22. package/dist/index.d.cts +8 -8
  23. package/dist/index.d.ts +8 -8
  24. package/dist/index.js +100 -9
  25. package/dist/integrations/formik.d.cts +1 -1
  26. package/dist/integrations/formik.d.ts +1 -1
  27. package/dist/integrations/react-hook-form.d.cts +1 -1
  28. package/dist/integrations/react-hook-form.d.ts +1 -1
  29. package/dist/preact.d.cts +2 -2
  30. package/dist/preact.d.ts +2 -2
  31. package/dist/qwik-lib/index.qwik.cjs +98 -9
  32. package/dist/qwik-lib/index.qwik.mjs +98 -9
  33. package/dist/qwik.cjs +100 -9
  34. package/dist/qwik.d.cts +2 -2
  35. package/dist/qwik.d.ts +2 -2
  36. package/dist/qwik.js +100 -9
  37. package/dist/react.cjs +100 -9
  38. package/dist/react.d.cts +3 -3
  39. package/dist/react.d.ts +3 -3
  40. package/dist/react.js +100 -9
  41. package/dist/solid.cjs +100 -9
  42. package/dist/solid.d.cts +10 -1
  43. package/dist/solid.d.ts +10 -1
  44. package/dist/solid.js +100 -9
  45. package/dist/solid.source.jsx +100 -9
  46. package/dist/svelte-core.cjs +100 -9
  47. package/dist/svelte-core.js +100 -9
  48. package/dist/svelte.cjs +100 -9
  49. package/dist/svelte.js +100 -9
  50. package/dist/vue.cjs +100 -9
  51. package/dist/vue.js +100 -9
  52. package/dist/webgl.cjs +104 -14
  53. package/dist/webgl.d.cts +1 -1
  54. package/dist/webgl.d.ts +1 -1
  55. package/dist/webgl.js +104 -14
  56. package/package.json +39 -39
package/dist/element.js CHANGED
@@ -365,6 +365,11 @@ var init_snap_resolver = __esm({
365
365
  this.raw = raw;
366
366
  this.recompute();
367
367
  }
368
+ setMode(mode) {
369
+ if (mode === this.mode) return;
370
+ this.mode = mode;
371
+ this.recompute();
372
+ }
368
373
  setAllowedIds(ids) {
369
374
  this.allowedIds = ids;
370
375
  this.rangeCache = null;
@@ -1007,6 +1012,11 @@ var init_scrim_controller = __esm({
1007
1012
  if (this.isDestroyed()) return;
1008
1013
  this.applyScrimStyles({ interactive });
1009
1014
  }
1015
+ setSheetMode(mode) {
1016
+ if (this.isDestroyed() || mode === this.mode) return;
1017
+ this.mode = mode;
1018
+ this.invalidateOpacityCache();
1019
+ }
1010
1020
  setScrimMode(mode, applySize) {
1011
1021
  if (this.isDestroyed()) return;
1012
1022
  if (mode === this.scrimMode) return;
@@ -1987,6 +1997,7 @@ var init_gestures = __esm({
1987
1997
  let activePointerId = null;
1988
1998
  let activePointerType = "touch";
1989
1999
  let startCoord = 0;
2000
+ let startCross = 0;
1990
2001
  let lastCoord = 0;
1991
2002
  let pendingStart = false;
1992
2003
  const VELOCITY_WINDOW_MS = (kind) => kind === "mouse" ? 160 : 120;
@@ -1995,6 +2006,7 @@ var init_gestures = __esm({
1995
2006
  const axis = isAxisVertical(mode) ? "Y" : "X";
1996
2007
  const sign = mode === "bottom" || mode === "right" ? -1 : 1;
1997
2008
  const coordOf = (e) => axis === "Y" ? e.clientY : e.clientX;
2009
+ const crossOf = (e) => axis === "Y" ? e.clientX : e.clientY;
1998
2010
  const capture = (pointerId) => {
1999
2011
  try {
2000
2012
  handle.setPointerCapture(pointerId);
@@ -2013,6 +2025,7 @@ var init_gestures = __esm({
2013
2025
  activePointerId = e.pointerId;
2014
2026
  activePointerType = e.pointerType || "touch";
2015
2027
  startCoord = coordOf(e);
2028
+ startCross = crossOf(e);
2016
2029
  lastCoord = startCoord;
2017
2030
  samples.reset();
2018
2031
  samples.push(e.timeStamp, startCoord);
@@ -2029,7 +2042,7 @@ var init_gestures = __esm({
2029
2042
  const rawDelta = coord - startCoord;
2030
2043
  const delta = rawDelta * sign;
2031
2044
  if (pendingStart) {
2032
- const verdict = options.deferStart(e, delta);
2045
+ const verdict = options.deferStart(e, delta, crossOf(e) - startCross);
2033
2046
  if (verdict === false) {
2034
2047
  releaseTracking();
2035
2048
  return;
@@ -2269,6 +2282,13 @@ var init_drag_zones = __esm({
2269
2282
  // src/core/primitives/content-gesture.ts
2270
2283
  function decideContentGesture(input) {
2271
2284
  const slop = input.slop ?? CONTENT_DRAG_SLOP;
2285
+ const cross = input.crossDelta ?? 0;
2286
+ const sharesScrollAxis = input.sharesScrollAxis ?? true;
2287
+ if (!sharesScrollAxis) {
2288
+ if (Math.abs(input.delta) < slop && Math.abs(cross) < slop) return "pending";
2289
+ if (Math.abs(input.delta) <= Math.abs(cross)) return "scroll";
2290
+ return "drag";
2291
+ }
2272
2292
  if (Math.abs(input.delta) < slop) return "pending";
2273
2293
  if (input.scrollTop > 0) return "scroll";
2274
2294
  if (input.delta > 0 && input.atMaxSnap) return "scroll";
@@ -2281,6 +2301,37 @@ var init_content_gesture = __esm({
2281
2301
  }
2282
2302
  });
2283
2303
 
2304
+ // src/core/primitives/logical-mode.ts
2305
+ var isLogicalMode, readDirection, resolveMode;
2306
+ var init_logical_mode = __esm({
2307
+ "src/core/primitives/logical-mode.ts"() {
2308
+ isLogicalMode = (mode) => mode === "start" || mode === "end";
2309
+ readDirection = (el) => {
2310
+ if (!el) return "ltr";
2311
+ if (typeof getComputedStyle === "function") {
2312
+ try {
2313
+ if (getComputedStyle(el).direction === "rtl") return "rtl";
2314
+ } catch {
2315
+ }
2316
+ }
2317
+ try {
2318
+ const marked = el.closest?.("[dir]");
2319
+ if (marked) {
2320
+ return marked.getAttribute("dir")?.toLowerCase() === "rtl" ? "rtl" : "ltr";
2321
+ }
2322
+ } catch {
2323
+ }
2324
+ return "ltr";
2325
+ };
2326
+ resolveMode = (mode, el) => {
2327
+ if (!isLogicalMode(mode)) return mode;
2328
+ const rtl = readDirection(el) === "rtl";
2329
+ if (mode === "start") return rtl ? "right" : "left";
2330
+ return rtl ? "left" : "right";
2331
+ };
2332
+ }
2333
+ });
2334
+
2284
2335
  // src/core/primitives/touch-scroll-guard.ts
2285
2336
  function installTouchScrollGuard(surface, isDragging) {
2286
2337
  const onTouchMove = (e) => {
@@ -2673,7 +2724,7 @@ function resolveEngineOptions(opts, extras) {
2673
2724
  }
2674
2725
  }
2675
2726
  return {
2676
- mode: opts.mode ?? "bottom",
2727
+ mode: resolveMode(opts.mode ?? "bottom", opts.element),
2677
2728
  flickVelocity: opts.flickVelocity ?? DEFAULT_FLICK_VELOCITY,
2678
2729
  dragThreshold: opts.dragThreshold ?? DEFAULT_DRAG_THRESHOLD,
2679
2730
  dragFrom: opts.dragFrom ?? (opts.handle ? "handle" : "sheet"),
@@ -2721,6 +2772,7 @@ function resolveEngineOptions(opts, extras) {
2721
2772
  var DEFAULT_FLICK_VELOCITY, DEFAULT_DRAG_THRESHOLD, readPersistedIdSafe;
2722
2773
  var init_engine_options = __esm({
2723
2774
  "src/core/primitives/engine-options.ts"() {
2775
+ init_logical_mode();
2724
2776
  DEFAULT_FLICK_VELOCITY = 0.65;
2725
2777
  DEFAULT_DRAG_THRESHOLD = 18;
2726
2778
  readPersistedIdSafe = (key) => {
@@ -2785,6 +2837,7 @@ var init_BottomSheetCore = __esm({
2785
2837
  init_gesture_controller();
2786
2838
  init_drag_zones();
2787
2839
  init_content_gesture();
2840
+ init_logical_mode();
2788
2841
  init_touch_scroll_guard();
2789
2842
  init_aria_slider_writer();
2790
2843
  init_hot_path_thresholds();
@@ -2821,6 +2874,7 @@ var init_BottomSheetCore = __esm({
2821
2874
  __publicField(this, "disableDragFlag");
2822
2875
  __publicField(this, "closeOnRouteChange");
2823
2876
  __publicField(this, "maxHeight");
2877
+ __publicField(this, "maxHeightDeps");
2824
2878
  __publicField(this, "snapPointsRaw");
2825
2879
  __publicField(this, "snaps");
2826
2880
  __publicField(this, "activeId");
@@ -2828,6 +2882,7 @@ var init_BottomSheetCore = __esm({
2828
2882
  __publicField(this, "gesture");
2829
2883
  __publicField(this, "contentGesture");
2830
2884
  __publicField(this, "detachSheetGesture", null);
2885
+ __publicField(this, "detachSliderKeyboard", null);
2831
2886
  __publicField(this, "rootEl", null);
2832
2887
  __publicField(this, "destroyed", false);
2833
2888
  __publicField(this, "restClosed", false);
@@ -2879,6 +2934,7 @@ var init_BottomSheetCore = __esm({
2879
2934
  this.screenComponent = opts.scrim ?? opts.screenComponent;
2880
2935
  this.scrimParent = this.screenComponent?.parentElement ?? null;
2881
2936
  this.mode = resolved.mode;
2937
+ this.element.dataset.mode = this.mode;
2882
2938
  this.transformTemplate = buildTransformTemplate(this.mode);
2883
2939
  this.aria = new AriaSliderWriter(this.handle, this.mode);
2884
2940
  this.flickVelocity = resolved.flickVelocity;
@@ -2945,7 +3001,7 @@ var init_BottomSheetCore = __esm({
2945
3001
  auditVhUsage(this.snapPointsRaw);
2946
3002
  this.auditDuplicateSnapIds(this.snapPointsRaw);
2947
3003
  this.rootEl = this.element.closest(".bs-root");
2948
- this.maxHeight = createMaxHeightController({
3004
+ this.maxHeightDeps = {
2949
3005
  element: this.element,
2950
3006
  mode: this.mode,
2951
3007
  getMaxAxisSize: () => this.snaps.getMaxAxisSize(),
@@ -2953,7 +3009,8 @@ var init_BottomSheetCore = __esm({
2953
3009
  this.snaps.setMaxAxisSize(size);
2954
3010
  },
2955
3011
  recompute: () => this.recompute()
2956
- });
3012
+ };
3013
+ this.maxHeight = createMaxHeightController(this.maxHeightDeps);
2957
3014
  this.fitDeps = {
2958
3015
  element: this.element,
2959
3016
  scrollContainer: this.scrollContainer,
@@ -3287,6 +3344,37 @@ var init_BottomSheetCore = __esm({
3287
3344
  getDragFrom() {
3288
3345
  return this.dragFromMode;
3289
3346
  }
3347
+ setMode(mode) {
3348
+ if (this.destroyed) return;
3349
+ const next = resolveMode(mode, this.element);
3350
+ if (next === this.mode) return;
3351
+ const wasVertical = this.mode === "bottom" || this.mode === "top";
3352
+ const nowVertical = next === "bottom" || next === "top";
3353
+ this.gesture?.forceClearDragState();
3354
+ this.detachSheetGesture?.();
3355
+ this.animation.cancel();
3356
+ this.element.style.removeProperty(layoutAxis(this.mode));
3357
+ this.mode = next;
3358
+ this.element.dataset.mode = next;
3359
+ this.transformTemplate = buildTransformTemplate(next);
3360
+ this.maxHeightDeps.mode = next;
3361
+ this.fitDeps.mode = next;
3362
+ this.snaps.setMode(next);
3363
+ this.scrim.setSheetMode(next);
3364
+ if (wasVertical !== nowVertical) {
3365
+ this.aria = new AriaSliderWriter(this.handle, next);
3366
+ }
3367
+ this.detachSliderKeyboard?.();
3368
+ this.mountSliderKeyboard();
3369
+ this.mountSheetGesture();
3370
+ this.recompute();
3371
+ const active = this.snaps.findById(this.activeId);
3372
+ if (active) this.applySize(active.size);
3373
+ this.updateAriaSlider();
3374
+ }
3375
+ getMode() {
3376
+ return this.mode;
3377
+ }
3290
3378
  isTop() {
3291
3379
  return this.isTopSheet;
3292
3380
  }
@@ -3635,7 +3723,7 @@ var init_BottomSheetCore = __esm({
3635
3723
  const point = this.snapPointsRaw.find((p) => p.id === this.activeId);
3636
3724
  return point?.dragFromContent ?? this.dragFromContentDefault;
3637
3725
  }
3638
- decideContentDrag(surface, e, delta) {
3726
+ decideContentDrag(surface, e, delta, crossDelta) {
3639
3727
  if (this.destroyed) return false;
3640
3728
  if (e.pointerType === "mouse") return false;
3641
3729
  if (this.gesture?.isDragging) return false;
@@ -3643,6 +3731,8 @@ var init_BottomSheetCore = __esm({
3643
3731
  if (!isDragAllowedFrom(e.target, "sheet")) return false;
3644
3732
  const decision = decideContentGesture({
3645
3733
  delta,
3734
+ crossDelta,
3735
+ sharesScrollAxis: this.mode === "bottom" || this.mode === "top",
3646
3736
  scrollTop: surface.scrollTop,
3647
3737
  atMaxSnap: this.size >= this.getAllowedRange().max - 0.5
3648
3738
  });
@@ -3655,7 +3745,7 @@ var init_BottomSheetCore = __esm({
3655
3745
  const controller = new GestureController(
3656
3746
  this.buildGestureDeps(surface, {
3657
3747
  manageTouchAction: false,
3658
- deferStart: (e, delta) => this.decideContentDrag(surface, e, delta)
3748
+ deferStart: (e, delta, crossDelta) => this.decideContentDrag(surface, e, delta, crossDelta)
3659
3749
  })
3660
3750
  );
3661
3751
  this.contentGesture = controller;
@@ -3781,7 +3871,11 @@ var init_BottomSheetCore = __esm({
3781
3871
  );
3782
3872
  }
3783
3873
  }
3784
- this.teardowns.add(installSliderKeyboard({
3874
+ this.mountSliderKeyboard();
3875
+ this.scrim.attach();
3876
+ }
3877
+ mountSliderKeyboard() {
3878
+ const detach = installSliderKeyboard({
3785
3879
  handle: this.handle,
3786
3880
  mode: this.mode,
3787
3881
  isDestroyed: () => this.destroyed,
@@ -3790,8 +3884,12 @@ var init_BottomSheetCore = __esm({
3790
3884
  snapTo: (id) => {
3791
3885
  void this.snapTo(id);
3792
3886
  }
3793
- }));
3794
- this.scrim.attach();
3887
+ });
3888
+ this.detachSliderKeyboard = detach;
3889
+ this.teardowns.add(() => {
3890
+ this.detachSliderKeyboard?.();
3891
+ this.detachSliderKeyboard = null;
3892
+ });
3795
3893
  }
3796
3894
  settleAfterDrag(delta, velocity, kind = "touch") {
3797
3895
  const signal = this.newCycle();
@@ -1,13 +1,13 @@
1
- import { f as EngineFeature } from './BottomSheetCore-Cp7dWy91.cjs';
2
- export { m as EngineFeatureContext, n as EngineFeatureOptions, o as EngineFeatureStage } from './BottomSheetCore-Cp7dWy91.cjs';
1
+ import { f as EngineFeature } from './BottomSheetCore-VPJZcKcg.cjs';
2
+ export { m as EngineFeatureContext, n as EngineFeatureOptions, o as EngineFeatureStage } from './BottomSheetCore-VPJZcKcg.cjs';
3
3
  import './transform-jVfAikE9.cjs';
4
4
 
5
- declare function defaultEngineFeatures(): EngineFeature[];
6
-
7
5
  declare function routeFeature(): EngineFeature;
8
6
  declare function persistFeature(): EngineFeature;
9
7
  declare function autoCollapseFeature(): EngineFeature;
10
8
  declare function contentSwipeFeature(): EngineFeature;
11
9
  declare function visualViewportFeature(): EngineFeature;
12
10
 
11
+ declare function defaultEngineFeatures(): EngineFeature[];
12
+
13
13
  export { EngineFeature, autoCollapseFeature, contentSwipeFeature, defaultEngineFeatures, persistFeature, routeFeature, visualViewportFeature };
@@ -1,13 +1,13 @@
1
- import { f as EngineFeature } from './BottomSheetCore-DJYwWOqt.js';
2
- export { m as EngineFeatureContext, n as EngineFeatureOptions, o as EngineFeatureStage } from './BottomSheetCore-DJYwWOqt.js';
1
+ import { f as EngineFeature } from './BottomSheetCore-Cgn8b_6A.js';
2
+ export { m as EngineFeatureContext, n as EngineFeatureOptions, o as EngineFeatureStage } from './BottomSheetCore-Cgn8b_6A.js';
3
3
  import './transform-jVfAikE9.js';
4
4
 
5
- declare function defaultEngineFeatures(): EngineFeature[];
6
-
7
5
  declare function routeFeature(): EngineFeature;
8
6
  declare function persistFeature(): EngineFeature;
9
7
  declare function autoCollapseFeature(): EngineFeature;
10
8
  declare function contentSwipeFeature(): EngineFeature;
11
9
  declare function visualViewportFeature(): EngineFeature;
12
10
 
11
+ declare function defaultEngineFeatures(): EngineFeature[];
12
+
13
13
  export { EngineFeature, autoCollapseFeature, contentSwipeFeature, defaultEngineFeatures, persistFeature, routeFeature, visualViewportFeature };
@@ -1,4 +1,4 @@
1
- import { b as SnapPointDef, c as SheetMode } from './BottomSheetCore-Cp7dWy91.cjs';
1
+ import { a as SnapPointDef, b as SheetMode } from './BottomSheetCore-VPJZcKcg.cjs';
2
2
 
3
3
  type ResolvedSnap = {
4
4
  id: string;
@@ -1,4 +1,4 @@
1
- import { b as SnapPointDef, c as SheetMode } from './BottomSheetCore-DJYwWOqt.js';
1
+ import { a as SnapPointDef, b as SheetMode } from './BottomSheetCore-Cgn8b_6A.js';
2
2
 
3
3
  type ResolvedSnap = {
4
4
  id: string;
package/dist/index.cjs CHANGED
@@ -315,6 +315,11 @@ var SnapResolver = class {
315
315
  this.raw = raw;
316
316
  this.recompute();
317
317
  }
318
+ setMode(mode) {
319
+ if (mode === this.mode) return;
320
+ this.mode = mode;
321
+ this.recompute();
322
+ }
318
323
  setAllowedIds(ids) {
319
324
  this.allowedIds = ids;
320
325
  this.rangeCache = null;
@@ -898,6 +903,11 @@ var ScrimController = class {
898
903
  if (this.isDestroyed()) return;
899
904
  this.applyScrimStyles({ interactive });
900
905
  }
906
+ setSheetMode(mode) {
907
+ if (this.isDestroyed() || mode === this.mode) return;
908
+ this.mode = mode;
909
+ this.invalidateOpacityCache();
910
+ }
901
911
  setScrimMode(mode, applySize) {
902
912
  if (this.isDestroyed()) return;
903
913
  if (mode === this.scrimMode) return;
@@ -1820,6 +1830,7 @@ var installGestures = (handle, mode, callbacks, options = {}) => {
1820
1830
  let activePointerId = null;
1821
1831
  let activePointerType = "touch";
1822
1832
  let startCoord = 0;
1833
+ let startCross = 0;
1823
1834
  let lastCoord = 0;
1824
1835
  let pendingStart = false;
1825
1836
  const VELOCITY_WINDOW_MS = (kind) => kind === "mouse" ? 160 : 120;
@@ -1828,6 +1839,7 @@ var installGestures = (handle, mode, callbacks, options = {}) => {
1828
1839
  const axis = isAxisVertical(mode) ? "Y" : "X";
1829
1840
  const sign = mode === "bottom" || mode === "right" ? -1 : 1;
1830
1841
  const coordOf = (e) => axis === "Y" ? e.clientY : e.clientX;
1842
+ const crossOf = (e) => axis === "Y" ? e.clientX : e.clientY;
1831
1843
  const capture = (pointerId) => {
1832
1844
  try {
1833
1845
  handle.setPointerCapture(pointerId);
@@ -1846,6 +1858,7 @@ var installGestures = (handle, mode, callbacks, options = {}) => {
1846
1858
  activePointerId = e.pointerId;
1847
1859
  activePointerType = e.pointerType || "touch";
1848
1860
  startCoord = coordOf(e);
1861
+ startCross = crossOf(e);
1849
1862
  lastCoord = startCoord;
1850
1863
  samples.reset();
1851
1864
  samples.push(e.timeStamp, startCoord);
@@ -1862,7 +1875,7 @@ var installGestures = (handle, mode, callbacks, options = {}) => {
1862
1875
  const rawDelta = coord - startCoord;
1863
1876
  const delta = rawDelta * sign;
1864
1877
  if (pendingStart) {
1865
- const verdict = options.deferStart(e, delta);
1878
+ const verdict = options.deferStart(e, delta, crossOf(e) - startCross);
1866
1879
  if (verdict === false) {
1867
1880
  releaseTracking();
1868
1881
  return;
@@ -2080,12 +2093,45 @@ function isDragAllowedFrom(target, mode) {
2080
2093
  var CONTENT_DRAG_SLOP = 6;
2081
2094
  function decideContentGesture(input) {
2082
2095
  const slop = input.slop ?? CONTENT_DRAG_SLOP;
2096
+ const cross = input.crossDelta ?? 0;
2097
+ const sharesScrollAxis = input.sharesScrollAxis ?? true;
2098
+ if (!sharesScrollAxis) {
2099
+ if (Math.abs(input.delta) < slop && Math.abs(cross) < slop) return "pending";
2100
+ if (Math.abs(input.delta) <= Math.abs(cross)) return "scroll";
2101
+ return "drag";
2102
+ }
2083
2103
  if (Math.abs(input.delta) < slop) return "pending";
2084
2104
  if (input.scrollTop > 0) return "scroll";
2085
2105
  if (input.delta > 0 && input.atMaxSnap) return "scroll";
2086
2106
  return "drag";
2087
2107
  }
2088
2108
 
2109
+ // src/core/primitives/logical-mode.ts
2110
+ var isLogicalMode = (mode) => mode === "start" || mode === "end";
2111
+ var readDirection = (el) => {
2112
+ if (!el) return "ltr";
2113
+ if (typeof getComputedStyle === "function") {
2114
+ try {
2115
+ if (getComputedStyle(el).direction === "rtl") return "rtl";
2116
+ } catch {
2117
+ }
2118
+ }
2119
+ try {
2120
+ const marked = el.closest?.("[dir]");
2121
+ if (marked) {
2122
+ return marked.getAttribute("dir")?.toLowerCase() === "rtl" ? "rtl" : "ltr";
2123
+ }
2124
+ } catch {
2125
+ }
2126
+ return "ltr";
2127
+ };
2128
+ var resolveMode = (mode, el) => {
2129
+ if (!isLogicalMode(mode)) return mode;
2130
+ const rtl = readDirection(el) === "rtl";
2131
+ if (mode === "start") return rtl ? "right" : "left";
2132
+ return rtl ? "left" : "right";
2133
+ };
2134
+
2089
2135
  // src/core/primitives/touch-scroll-guard.ts
2090
2136
  function installTouchScrollGuard(surface, isDragging) {
2091
2137
  const onTouchMove = (e) => {
@@ -2448,7 +2494,7 @@ function resolveEngineOptions(opts, extras) {
2448
2494
  }
2449
2495
  }
2450
2496
  return {
2451
- mode: opts.mode ?? "bottom",
2497
+ mode: resolveMode(opts.mode ?? "bottom", opts.element),
2452
2498
  flickVelocity: opts.flickVelocity ?? DEFAULT_FLICK_VELOCITY,
2453
2499
  dragThreshold: opts.dragThreshold ?? DEFAULT_DRAG_THRESHOLD,
2454
2500
  dragFrom: opts.dragFrom ?? (opts.handle ? "handle" : "sheet"),
@@ -2552,6 +2598,7 @@ var BottomSheetCore = class {
2552
2598
  __publicField(this, "disableDragFlag");
2553
2599
  __publicField(this, "closeOnRouteChange");
2554
2600
  __publicField(this, "maxHeight");
2601
+ __publicField(this, "maxHeightDeps");
2555
2602
  __publicField(this, "snapPointsRaw");
2556
2603
  __publicField(this, "snaps");
2557
2604
  __publicField(this, "activeId");
@@ -2559,6 +2606,7 @@ var BottomSheetCore = class {
2559
2606
  __publicField(this, "gesture");
2560
2607
  __publicField(this, "contentGesture");
2561
2608
  __publicField(this, "detachSheetGesture", null);
2609
+ __publicField(this, "detachSliderKeyboard", null);
2562
2610
  __publicField(this, "rootEl", null);
2563
2611
  __publicField(this, "destroyed", false);
2564
2612
  __publicField(this, "restClosed", false);
@@ -2610,6 +2658,7 @@ var BottomSheetCore = class {
2610
2658
  this.screenComponent = opts.scrim ?? opts.screenComponent;
2611
2659
  this.scrimParent = this.screenComponent?.parentElement ?? null;
2612
2660
  this.mode = resolved.mode;
2661
+ this.element.dataset.mode = this.mode;
2613
2662
  this.transformTemplate = buildTransformTemplate(this.mode);
2614
2663
  this.aria = new AriaSliderWriter(this.handle, this.mode);
2615
2664
  this.flickVelocity = resolved.flickVelocity;
@@ -2676,7 +2725,7 @@ var BottomSheetCore = class {
2676
2725
  auditVhUsage(this.snapPointsRaw);
2677
2726
  this.auditDuplicateSnapIds(this.snapPointsRaw);
2678
2727
  this.rootEl = this.element.closest(".bs-root");
2679
- this.maxHeight = createMaxHeightController({
2728
+ this.maxHeightDeps = {
2680
2729
  element: this.element,
2681
2730
  mode: this.mode,
2682
2731
  getMaxAxisSize: () => this.snaps.getMaxAxisSize(),
@@ -2684,7 +2733,8 @@ var BottomSheetCore = class {
2684
2733
  this.snaps.setMaxAxisSize(size);
2685
2734
  },
2686
2735
  recompute: () => this.recompute()
2687
- });
2736
+ };
2737
+ this.maxHeight = createMaxHeightController(this.maxHeightDeps);
2688
2738
  this.fitDeps = {
2689
2739
  element: this.element,
2690
2740
  scrollContainer: this.scrollContainer,
@@ -3018,6 +3068,37 @@ var BottomSheetCore = class {
3018
3068
  getDragFrom() {
3019
3069
  return this.dragFromMode;
3020
3070
  }
3071
+ setMode(mode) {
3072
+ if (this.destroyed) return;
3073
+ const next = resolveMode(mode, this.element);
3074
+ if (next === this.mode) return;
3075
+ const wasVertical = this.mode === "bottom" || this.mode === "top";
3076
+ const nowVertical = next === "bottom" || next === "top";
3077
+ this.gesture?.forceClearDragState();
3078
+ this.detachSheetGesture?.();
3079
+ this.animation.cancel();
3080
+ this.element.style.removeProperty(layoutAxis(this.mode));
3081
+ this.mode = next;
3082
+ this.element.dataset.mode = next;
3083
+ this.transformTemplate = buildTransformTemplate(next);
3084
+ this.maxHeightDeps.mode = next;
3085
+ this.fitDeps.mode = next;
3086
+ this.snaps.setMode(next);
3087
+ this.scrim.setSheetMode(next);
3088
+ if (wasVertical !== nowVertical) {
3089
+ this.aria = new AriaSliderWriter(this.handle, next);
3090
+ }
3091
+ this.detachSliderKeyboard?.();
3092
+ this.mountSliderKeyboard();
3093
+ this.mountSheetGesture();
3094
+ this.recompute();
3095
+ const active = this.snaps.findById(this.activeId);
3096
+ if (active) this.applySize(active.size);
3097
+ this.updateAriaSlider();
3098
+ }
3099
+ getMode() {
3100
+ return this.mode;
3101
+ }
3021
3102
  isTop() {
3022
3103
  return this.isTopSheet;
3023
3104
  }
@@ -3366,7 +3447,7 @@ var BottomSheetCore = class {
3366
3447
  const point = this.snapPointsRaw.find((p) => p.id === this.activeId);
3367
3448
  return point?.dragFromContent ?? this.dragFromContentDefault;
3368
3449
  }
3369
- decideContentDrag(surface, e, delta) {
3450
+ decideContentDrag(surface, e, delta, crossDelta) {
3370
3451
  if (this.destroyed) return false;
3371
3452
  if (e.pointerType === "mouse") return false;
3372
3453
  if (this.gesture?.isDragging) return false;
@@ -3374,6 +3455,8 @@ var BottomSheetCore = class {
3374
3455
  if (!isDragAllowedFrom(e.target, "sheet")) return false;
3375
3456
  const decision = decideContentGesture({
3376
3457
  delta,
3458
+ crossDelta,
3459
+ sharesScrollAxis: this.mode === "bottom" || this.mode === "top",
3377
3460
  scrollTop: surface.scrollTop,
3378
3461
  atMaxSnap: this.size >= this.getAllowedRange().max - 0.5
3379
3462
  });
@@ -3386,7 +3469,7 @@ var BottomSheetCore = class {
3386
3469
  const controller = new GestureController(
3387
3470
  this.buildGestureDeps(surface, {
3388
3471
  manageTouchAction: false,
3389
- deferStart: (e, delta) => this.decideContentDrag(surface, e, delta)
3472
+ deferStart: (e, delta, crossDelta) => this.decideContentDrag(surface, e, delta, crossDelta)
3390
3473
  })
3391
3474
  );
3392
3475
  this.contentGesture = controller;
@@ -3512,7 +3595,11 @@ var BottomSheetCore = class {
3512
3595
  );
3513
3596
  }
3514
3597
  }
3515
- this.teardowns.add(installSliderKeyboard({
3598
+ this.mountSliderKeyboard();
3599
+ this.scrim.attach();
3600
+ }
3601
+ mountSliderKeyboard() {
3602
+ const detach = installSliderKeyboard({
3516
3603
  handle: this.handle,
3517
3604
  mode: this.mode,
3518
3605
  isDestroyed: () => this.destroyed,
@@ -3521,8 +3608,12 @@ var BottomSheetCore = class {
3521
3608
  snapTo: (id) => {
3522
3609
  void this.snapTo(id);
3523
3610
  }
3524
- }));
3525
- this.scrim.attach();
3611
+ });
3612
+ this.detachSliderKeyboard = detach;
3613
+ this.teardowns.add(() => {
3614
+ this.detachSliderKeyboard?.();
3615
+ this.detachSliderKeyboard = null;
3616
+ });
3526
3617
  }
3527
3618
  settleAfterDrag(delta, velocity, kind = "touch") {
3528
3619
  const signal = this.newCycle();
package/dist/index.d.cts CHANGED
@@ -1,8 +1,8 @@
1
- export { B as BottomSheetEngine } from './BottomSheetEngine-Lm7HIVHv.cjs';
2
- import { e as SnapPoint, c as SheetMode, a as EngineOptions, g as ScrimOverlayPosition } from './BottomSheetCore-Cp7dWy91.cjs';
3
- export { h as AnchorAnimationPreset, i as AnchorAnimationSpec, j as AnchorHandle, A as AnchorOptions, k as AnchorPosition, l as AnchorState, B as BottomSheetCore, C as CloseReason, f as EngineFeature, m as EngineFeatureContext, n as EngineFeatureOptions, o as EngineFeatureStage, E as EngineState, P as Plugin, p as SCRIM_PRESETS, q as ScrimOverlayOptions, r as ScrimPreset, s as ScrimPresetConfig, t as ScrimStageDef, S as ScrimStagesOptions, u as ScrimUpdate, d as SheetEventMap, v as SnapId, b as SnapPointDef, T as TeardownScope, w as runAnchorTransition } from './BottomSheetCore-Cp7dWy91.cjs';
1
+ export { B as BottomSheetEngine } from './BottomSheetEngine-B8C2CwF9.cjs';
2
+ import { d as SnapPoint, b as SheetMode, c as EngineOptions, P as PhysicalSheetMode, g as ScrimOverlayPosition } from './BottomSheetCore-VPJZcKcg.cjs';
3
+ export { h as AnchorAnimationPreset, i as AnchorAnimationSpec, j as AnchorHandle, A as AnchorOptions, k as AnchorPosition, l as AnchorState, B as BottomSheetCore, C as CloseReason, f as EngineFeature, m as EngineFeatureContext, n as EngineFeatureOptions, o as EngineFeatureStage, E as EngineState, L as LogicalSheetMode, p as Plugin, q as SCRIM_PRESETS, r as ScrimOverlayOptions, s as ScrimPreset, t as ScrimPresetConfig, u as ScrimStageDef, e as ScrimStagesOptions, v as ScrimUpdate, S as SheetEventMap, w as SnapId, a as SnapPointDef, T as TeardownScope, x as runAnchorTransition } from './BottomSheetCore-VPJZcKcg.cjs';
4
4
  export { autoCollapseFeature, contentSwipeFeature, defaultEngineFeatures, persistFeature, routeFeature, visualViewportFeature } from './features.cjs';
5
- export { R as ResolvedSnap, r as resolveSnapList } from './index-Bb5TRmyg.cjs';
5
+ export { R as ResolvedSnap, r as resolveSnapList } from './index-CnfbOKx0.cjs';
6
6
  import './transform-jVfAikE9.cjs';
7
7
 
8
8
  declare const resolveSnap: (point: SnapPoint | string, mode: SheetMode, measureFit?: () => number) => number;
@@ -16,7 +16,7 @@ type GestureCallbacks = {
16
16
  };
17
17
  type GestureOptions = {
18
18
  shouldStart?: (e: PointerEvent) => boolean;
19
- deferStart?: (e: PointerEvent, delta: number) => boolean | null;
19
+ deferStart?: (e: PointerEvent, delta: number, crossDelta: number) => boolean | null;
20
20
  manageTouchAction?: boolean;
21
21
  };
22
22
  declare const installGestures: (handle: HTMLElement, mode: SheetMode, callbacks: GestureCallbacks, options?: GestureOptions) => (() => void);
@@ -100,7 +100,7 @@ type SheetAnchoredStyle = {
100
100
  right?: string;
101
101
  transform?: string;
102
102
  };
103
- declare function resolveSheetAnchoredStyle(mode: SheetMode, position: "sheet-top-left" | "sheet-top-center" | "sheet-top-right", inset: string): SheetAnchoredStyle;
104
- declare function applyOverlayPosition(ws: CSSStyleDeclaration, mode: SheetMode, position: ScrimOverlayPosition, inset: string): void;
103
+ declare function resolveSheetAnchoredStyle(mode: PhysicalSheetMode, position: "sheet-top-left" | "sheet-top-center" | "sheet-top-right", inset: string): SheetAnchoredStyle;
104
+ declare function applyOverlayPosition(ws: CSSStyleDeclaration, mode: PhysicalSheetMode, position: ScrimOverlayPosition, inset: string): void;
105
105
 
106
- export { EngineOptions, ScrimOverlayPosition, type SheetConfig, type SheetManager, SheetMode, SnapPoint, type SpringConfig, type SpringHandle, type SpringRunOptions, type StackEntry, type Tween, type TweenOptions, applyOverlayPosition, createSheetManager, installFocusTrap, installGestures, lockBodyScroll, resolveSheetAnchoredStyle, resolveSnap, sheetStack };
106
+ export { EngineOptions, PhysicalSheetMode, ScrimOverlayPosition, type SheetConfig, type SheetManager, SheetMode, SnapPoint, type SpringConfig, type SpringHandle, type SpringRunOptions, type StackEntry, type Tween, type TweenOptions, applyOverlayPosition, createSheetManager, installFocusTrap, installGestures, lockBodyScroll, resolveSheetAnchoredStyle, resolveSnap, sheetStack };
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- export { B as BottomSheetEngine } from './BottomSheetEngine-O5PbeKfe.js';
2
- import { e as SnapPoint, c as SheetMode, a as EngineOptions, g as ScrimOverlayPosition } from './BottomSheetCore-DJYwWOqt.js';
3
- export { h as AnchorAnimationPreset, i as AnchorAnimationSpec, j as AnchorHandle, A as AnchorOptions, k as AnchorPosition, l as AnchorState, B as BottomSheetCore, C as CloseReason, f as EngineFeature, m as EngineFeatureContext, n as EngineFeatureOptions, o as EngineFeatureStage, E as EngineState, P as Plugin, p as SCRIM_PRESETS, q as ScrimOverlayOptions, r as ScrimPreset, s as ScrimPresetConfig, t as ScrimStageDef, S as ScrimStagesOptions, u as ScrimUpdate, d as SheetEventMap, v as SnapId, b as SnapPointDef, T as TeardownScope, w as runAnchorTransition } from './BottomSheetCore-DJYwWOqt.js';
1
+ export { B as BottomSheetEngine } from './BottomSheetEngine-DwYR_ygJ.js';
2
+ import { d as SnapPoint, b as SheetMode, c as EngineOptions, P as PhysicalSheetMode, g as ScrimOverlayPosition } from './BottomSheetCore-Cgn8b_6A.js';
3
+ export { h as AnchorAnimationPreset, i as AnchorAnimationSpec, j as AnchorHandle, A as AnchorOptions, k as AnchorPosition, l as AnchorState, B as BottomSheetCore, C as CloseReason, f as EngineFeature, m as EngineFeatureContext, n as EngineFeatureOptions, o as EngineFeatureStage, E as EngineState, L as LogicalSheetMode, p as Plugin, q as SCRIM_PRESETS, r as ScrimOverlayOptions, s as ScrimPreset, t as ScrimPresetConfig, u as ScrimStageDef, e as ScrimStagesOptions, v as ScrimUpdate, S as SheetEventMap, w as SnapId, a as SnapPointDef, T as TeardownScope, x as runAnchorTransition } from './BottomSheetCore-Cgn8b_6A.js';
4
4
  export { autoCollapseFeature, contentSwipeFeature, defaultEngineFeatures, persistFeature, routeFeature, visualViewportFeature } from './features.js';
5
- export { R as ResolvedSnap, r as resolveSnapList } from './index-Cl9ebCP2.js';
5
+ export { R as ResolvedSnap, r as resolveSnapList } from './index-DcMkhXAy.js';
6
6
  import './transform-jVfAikE9.js';
7
7
 
8
8
  declare const resolveSnap: (point: SnapPoint | string, mode: SheetMode, measureFit?: () => number) => number;
@@ -16,7 +16,7 @@ type GestureCallbacks = {
16
16
  };
17
17
  type GestureOptions = {
18
18
  shouldStart?: (e: PointerEvent) => boolean;
19
- deferStart?: (e: PointerEvent, delta: number) => boolean | null;
19
+ deferStart?: (e: PointerEvent, delta: number, crossDelta: number) => boolean | null;
20
20
  manageTouchAction?: boolean;
21
21
  };
22
22
  declare const installGestures: (handle: HTMLElement, mode: SheetMode, callbacks: GestureCallbacks, options?: GestureOptions) => (() => void);
@@ -100,7 +100,7 @@ type SheetAnchoredStyle = {
100
100
  right?: string;
101
101
  transform?: string;
102
102
  };
103
- declare function resolveSheetAnchoredStyle(mode: SheetMode, position: "sheet-top-left" | "sheet-top-center" | "sheet-top-right", inset: string): SheetAnchoredStyle;
104
- declare function applyOverlayPosition(ws: CSSStyleDeclaration, mode: SheetMode, position: ScrimOverlayPosition, inset: string): void;
103
+ declare function resolveSheetAnchoredStyle(mode: PhysicalSheetMode, position: "sheet-top-left" | "sheet-top-center" | "sheet-top-right", inset: string): SheetAnchoredStyle;
104
+ declare function applyOverlayPosition(ws: CSSStyleDeclaration, mode: PhysicalSheetMode, position: ScrimOverlayPosition, inset: string): void;
105
105
 
106
- export { EngineOptions, ScrimOverlayPosition, type SheetConfig, type SheetManager, SheetMode, SnapPoint, type SpringConfig, type SpringHandle, type SpringRunOptions, type StackEntry, type Tween, type TweenOptions, applyOverlayPosition, createSheetManager, installFocusTrap, installGestures, lockBodyScroll, resolveSheetAnchoredStyle, resolveSnap, sheetStack };
106
+ export { EngineOptions, PhysicalSheetMode, ScrimOverlayPosition, type SheetConfig, type SheetManager, SheetMode, SnapPoint, type SpringConfig, type SpringHandle, type SpringRunOptions, type StackEntry, type Tween, type TweenOptions, applyOverlayPosition, createSheetManager, installFocusTrap, installGestures, lockBodyScroll, resolveSheetAnchoredStyle, resolveSnap, sheetStack };