@surdeddd/bottom-sheet 0.21.1 → 0.22.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 (62) hide show
  1. package/README.md +32 -0
  2. package/dist/{BottomSheetCore-CK_mq14p.d.ts → BottomSheetCore-9i-Uh6T3.d.ts} +4 -1
  3. package/dist/{BottomSheetCore-BHv6LPmS.d.cts → BottomSheetCore-CQStdVy2.d.cts} +4 -1
  4. package/dist/{BottomSheetEngine-mmFzIK1Z.d.cts → BottomSheetEngine-CsQWHLNb.d.cts} +1 -1
  5. package/dist/{BottomSheetEngine-wLn6Q2kA.d.ts → BottomSheetEngine-Dn6h-7gF.d.ts} +1 -1
  6. package/dist/core.cjs +25 -7
  7. package/dist/core.d.cts +2 -2
  8. package/dist/core.d.ts +2 -2
  9. package/dist/core.js +25 -7
  10. package/dist/debug.d.cts +1 -1
  11. package/dist/debug.d.ts +1 -1
  12. package/dist/default-features-C3cilcW9.d.ts +11 -0
  13. package/dist/default-features-DkG9aho0.d.cts +11 -0
  14. package/dist/element.cjs +106 -15
  15. package/dist/element.d.cts +2 -2
  16. package/dist/element.d.ts +2 -2
  17. package/dist/element.iife.global.js +2 -2
  18. package/dist/element.js +106 -15
  19. package/dist/features.cjs +65 -1
  20. package/dist/features.d.cts +5 -10
  21. package/dist/features.d.ts +5 -10
  22. package/dist/features.js +65 -2
  23. package/dist/{index-juAyT76E.d.cts → index-CVGC5B5D.d.cts} +1 -1
  24. package/dist/{index-CWKv1Xy4.d.ts → index-CnsJQZp2.d.ts} +1 -1
  25. package/dist/index.cjs +89 -8
  26. package/dist/index.d.cts +5 -5
  27. package/dist/index.d.ts +5 -5
  28. package/dist/index.js +89 -8
  29. package/dist/integrations/formik.d.cts +1 -1
  30. package/dist/integrations/formik.d.ts +1 -1
  31. package/dist/integrations/react-hook-form.d.cts +1 -1
  32. package/dist/integrations/react-hook-form.d.ts +1 -1
  33. package/dist/preact.d.cts +2 -2
  34. package/dist/preact.d.ts +2 -2
  35. package/dist/qwik-lib/index.qwik.cjs +84 -6
  36. package/dist/qwik-lib/index.qwik.mjs +84 -6
  37. package/dist/qwik.cjs +90 -8
  38. package/dist/qwik.d.cts +3 -2
  39. package/dist/qwik.d.ts +3 -2
  40. package/dist/qwik.js +90 -8
  41. package/dist/react.cjs +89 -8
  42. package/dist/react.d.cts +3 -3
  43. package/dist/react.d.ts +3 -3
  44. package/dist/react.js +89 -8
  45. package/dist/solid.cjs +90 -8
  46. package/dist/solid.d.cts +4 -0
  47. package/dist/solid.d.ts +4 -0
  48. package/dist/solid.js +90 -8
  49. package/dist/solid.source.jsx +90 -8
  50. package/dist/styles.css +11 -0
  51. package/dist/svelte-core.cjs +89 -8
  52. package/dist/svelte-core.js +89 -8
  53. package/dist/svelte-src/BottomSheet.svelte +3 -0
  54. package/dist/svelte.cjs +90 -8
  55. package/dist/svelte.d.cts +1 -0
  56. package/dist/svelte.d.ts +1 -0
  57. package/dist/svelte.js +90 -8
  58. package/dist/vue.cjs +93 -8
  59. package/dist/vue.js +93 -8
  60. package/dist/webgl.d.cts +1 -1
  61. package/dist/webgl.d.ts +1 -1
  62. package/package.json +9 -9
package/dist/qwik.cjs CHANGED
@@ -378,14 +378,26 @@ function notifyLinkedSheets(sheets, self) {
378
378
  }
379
379
  }
380
380
 
381
+ // src/core/primitives/hot-path-thresholds.ts
382
+ var SIZE_WRITE_EPSILON = 0.5;
383
+ var OPACITY_WRITE_EPSILON = 5e-3;
384
+ var POINTER_EVENTS_OPACITY_THRESHOLD = 0.05;
385
+ var RANGE_DIVISION_EPSILON = 1e-4;
386
+
381
387
  // src/core/features/resize-observer.ts
382
388
  function installResizeObserver(deps) {
383
389
  if (typeof window === "undefined") {
384
390
  return () => {
385
391
  };
386
392
  }
393
+ const seatFor = () => {
394
+ const snap = deps.resolveActiveSnap();
395
+ const max = deps.getMaxAxisSize();
396
+ return { target: snap ? Math.min(snap.size, max) : null, max };
397
+ };
387
398
  const onResize = () => {
388
399
  if (deps.isDestroyed()) return;
400
+ const before = seatFor();
389
401
  deps.recomputeSnaps();
390
402
  const mode = deps.getMode();
391
403
  const isVerticalAxis = mode === "bottom" || mode === "top";
@@ -394,6 +406,10 @@ function installResizeObserver(deps) {
394
406
  if (viewportSize2 > 0 && viewportSize2 < max) {
395
407
  deps.setMaxAxisSize(viewportSize2);
396
408
  }
409
+ const after = seatFor();
410
+ if (before.target !== null && after.target !== null && Math.abs(after.target - before.target) < SIZE_WRITE_EPSILON && Math.abs(after.max - before.max) < SIZE_WRITE_EPSILON) {
411
+ return;
412
+ }
397
413
  const wasAnimating = deps.isAnimating?.() ?? false;
398
414
  deps.cancelInFlight();
399
415
  deps.newCycle();
@@ -662,12 +678,6 @@ var SCRIM_PRESETS = Object.freeze({
662
678
  }
663
679
  });
664
680
 
665
- // src/core/primitives/hot-path-thresholds.ts
666
- var SIZE_WRITE_EPSILON = 0.5;
667
- var OPACITY_WRITE_EPSILON = 5e-3;
668
- var POINTER_EVENTS_OPACITY_THRESHOLD = 0.05;
669
- var RANGE_DIVISION_EPSILON = 1e-4;
670
-
671
681
  // src/core/primitives/opacity-dedup.ts
672
682
  var WriteSentinel = class {
673
683
  constructor() {
@@ -2597,6 +2607,7 @@ var BottomSheetCore = class {
2597
2607
  __publicField(this, "lifecycle");
2598
2608
  __publicField(this, "closeOnBack");
2599
2609
  __publicField(this, "routedTo");
2610
+ __publicField(this, "fitContentToSnap");
2600
2611
  __publicField(this, "persistent");
2601
2612
  __publicField(this, "disableCloseFlag");
2602
2613
  __publicField(this, "disableDragFlag");
@@ -2710,6 +2721,7 @@ var BottomSheetCore = class {
2710
2721
  );
2711
2722
  this.closeOnBack = resolved.closeOnBack;
2712
2723
  this.routedTo = opts.routedTo;
2724
+ this.fitContentToSnap = opts.fitContentToSnap === true;
2713
2725
  this.persistent = resolved.persistent;
2714
2726
  this.disableCloseFlag = resolved.disableClose;
2715
2727
  this.disableDragFlag = resolved.disableDrag;
@@ -2811,7 +2823,8 @@ var BottomSheetCore = class {
2811
2823
  closeOnBack: this.closeOnBack,
2812
2824
  closeOnRouteChange: this.closeOnRouteChange,
2813
2825
  persistKey: this.persistKey,
2814
- autoCollapseAfter
2826
+ autoCollapseAfter,
2827
+ fitContentToSnap: this.fitContentToSnap
2815
2828
  },
2816
2829
  isDestroyed: () => this.destroyed,
2817
2830
  isDragging: () => this.isDraggingAny(),
@@ -2863,6 +2876,11 @@ var BottomSheetCore = class {
2863
2876
  "[BottomSheet] closeOnBack/routedTo/closeOnRouteChange need routeFeature() \u2014 option ignored"
2864
2877
  );
2865
2878
  }
2879
+ if (this.fitContentToSnap && !names.has("content-fit")) {
2880
+ devWarn(
2881
+ "[BottomSheet] fitContentToSnap needs contentFitFeature() \u2014 option ignored"
2882
+ );
2883
+ }
2866
2884
  if (this.persistKey && !names.has("persist")) {
2867
2885
  devWarn(
2868
2886
  "[BottomSheet] persistKey needs persistFeature() \u2014 snaps will not be saved"
@@ -4220,6 +4238,68 @@ function visualViewportFeature() {
4220
4238
  };
4221
4239
  }
4222
4240
 
4241
+ // src/core/features/content-fit.ts
4242
+ var INSET_VAR = "--bs-content-inset";
4243
+ var FIT_ATTR = "data-bs-fit-content";
4244
+ function contentFitFeature() {
4245
+ return {
4246
+ name: "content-fit",
4247
+ install: (ctx) => {
4248
+ const scroller = ctx.scrollContainer;
4249
+ if (!ctx.options.fitContentToSnap || !scroller || typeof window === "undefined") {
4250
+ return;
4251
+ }
4252
+ const sheet = ctx.element;
4253
+ let inset = 0;
4254
+ let unpaddedMax = -1;
4255
+ let top = 0;
4256
+ const hiddenAt = (size) => sheet.dataset.mode === "bottom" ? Math.max(0, ctx.getMaxAxisSize() - size) : 0;
4257
+ const follow = (size) => {
4258
+ if (unpaddedMax < 0) {
4259
+ unpaddedMax = scroller.scrollHeight - scroller.clientHeight - inset;
4260
+ top = scroller.scrollTop;
4261
+ }
4262
+ const limit = Math.max(0, unpaddedMax + hiddenAt(size));
4263
+ if (top > limit) {
4264
+ if (scroller.scrollTop > limit) scroller.scrollTop = limit;
4265
+ top = limit;
4266
+ }
4267
+ };
4268
+ const settle = () => {
4269
+ if (ctx.isDestroyed()) return;
4270
+ const size = ctx.getSize();
4271
+ unpaddedMax = -1;
4272
+ follow(size);
4273
+ inset = hiddenAt(size);
4274
+ sheet.style.setProperty(INSET_VAR, `${inset}px`);
4275
+ unpaddedMax = -1;
4276
+ };
4277
+ const moving = () => ctx.isAnimating() || ctx.isDragging();
4278
+ const whenIdle = () => {
4279
+ if (!moving()) settle();
4280
+ };
4281
+ sheet.setAttribute(FIT_ATTR, "");
4282
+ settle();
4283
+ const offProgress = ctx.on(
4284
+ "progress",
4285
+ (p) => moving() ? follow(p.size) : settle()
4286
+ );
4287
+ const offSnap = ctx.on("snap", settle);
4288
+ const observer = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(whenIdle);
4289
+ observer?.observe(document.documentElement);
4290
+ window.addEventListener("orientationchange", whenIdle);
4291
+ return () => {
4292
+ offProgress();
4293
+ offSnap();
4294
+ observer?.disconnect();
4295
+ window.removeEventListener("orientationchange", whenIdle);
4296
+ sheet.removeAttribute(FIT_ATTR);
4297
+ sheet.style.removeProperty(INSET_VAR);
4298
+ };
4299
+ }
4300
+ };
4301
+ }
4302
+
4223
4303
  // src/core/default-features.ts
4224
4304
  function defaultEngineFeatures() {
4225
4305
  return [
@@ -4227,7 +4307,8 @@ function defaultEngineFeatures() {
4227
4307
  visualViewportFeature(),
4228
4308
  persistFeature(),
4229
4309
  autoCollapseFeature(),
4230
- routeFeature()
4310
+ routeFeature(),
4311
+ contentFitFeature()
4231
4312
  ];
4232
4313
  }
4233
4314
 
@@ -4321,6 +4402,7 @@ var BottomSheet = qwik.component$((props) => {
4321
4402
  disableDrag: props.disableDrag,
4322
4403
  dragFrom: props.dragFrom,
4323
4404
  dragFromContent: props.dragFromContent,
4405
+ fitContentToSnap: props.fitContentToSnap,
4324
4406
  closeOnRouteChange: props.closeOnRouteChange,
4325
4407
  stackEffect: props.stackEffect,
4326
4408
  returnFocusTo: props.returnFocusTo,
package/dist/qwik.d.cts CHANGED
@@ -1,8 +1,8 @@
1
1
  import * as _builder_io_qwik from '@builder.io/qwik';
2
2
  import { QRL } from '@builder.io/qwik';
3
3
  import { T as TeleportTarget } from './teleport-7uYNiEAT.cjs';
4
- import { a as SnapPointDef, b as SheetMode, c as EngineOptions, S as SheetEventMap, E as EngineState } from './BottomSheetCore-BHv6LPmS.cjs';
5
- export { d as SnapPoint } from './BottomSheetCore-BHv6LPmS.cjs';
4
+ import { e as SnapPointDef, f as SheetMode, g as EngineOptions, S as SheetEventMap, d as EngineState } from './BottomSheetCore-CQStdVy2.cjs';
5
+ export { h as SnapPoint } from './BottomSheetCore-CQStdVy2.cjs';
6
6
  import './transform-jVfAikE9.cjs';
7
7
 
8
8
  type BottomSheetProps<TId extends string = string> = {
@@ -29,6 +29,7 @@ type BottomSheetProps<TId extends string = string> = {
29
29
  disableDrag?: boolean;
30
30
  dragFrom?: EngineOptions["dragFrom"];
31
31
  dragFromContent?: boolean;
32
+ fitContentToSnap?: boolean;
32
33
  closeOnRouteChange?: boolean;
33
34
  stackEffect?: boolean;
34
35
  teleport?: boolean;
package/dist/qwik.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import * as _builder_io_qwik from '@builder.io/qwik';
2
2
  import { QRL } from '@builder.io/qwik';
3
3
  import { T as TeleportTarget } from './teleport-7uYNiEAT.js';
4
- import { a as SnapPointDef, b as SheetMode, c as EngineOptions, S as SheetEventMap, E as EngineState } from './BottomSheetCore-CK_mq14p.js';
5
- export { d as SnapPoint } from './BottomSheetCore-CK_mq14p.js';
4
+ import { e as SnapPointDef, f as SheetMode, g as EngineOptions, S as SheetEventMap, d as EngineState } from './BottomSheetCore-9i-Uh6T3.js';
5
+ export { h as SnapPoint } from './BottomSheetCore-9i-Uh6T3.js';
6
6
  import './transform-jVfAikE9.js';
7
7
 
8
8
  type BottomSheetProps<TId extends string = string> = {
@@ -29,6 +29,7 @@ type BottomSheetProps<TId extends string = string> = {
29
29
  disableDrag?: boolean;
30
30
  dragFrom?: EngineOptions["dragFrom"];
31
31
  dragFromContent?: boolean;
32
+ fitContentToSnap?: boolean;
32
33
  closeOnRouteChange?: boolean;
33
34
  stackEffect?: boolean;
34
35
  teleport?: boolean;
package/dist/qwik.js CHANGED
@@ -376,14 +376,26 @@ function notifyLinkedSheets(sheets, self) {
376
376
  }
377
377
  }
378
378
 
379
+ // src/core/primitives/hot-path-thresholds.ts
380
+ var SIZE_WRITE_EPSILON = 0.5;
381
+ var OPACITY_WRITE_EPSILON = 5e-3;
382
+ var POINTER_EVENTS_OPACITY_THRESHOLD = 0.05;
383
+ var RANGE_DIVISION_EPSILON = 1e-4;
384
+
379
385
  // src/core/features/resize-observer.ts
380
386
  function installResizeObserver(deps) {
381
387
  if (typeof window === "undefined") {
382
388
  return () => {
383
389
  };
384
390
  }
391
+ const seatFor = () => {
392
+ const snap = deps.resolveActiveSnap();
393
+ const max = deps.getMaxAxisSize();
394
+ return { target: snap ? Math.min(snap.size, max) : null, max };
395
+ };
385
396
  const onResize = () => {
386
397
  if (deps.isDestroyed()) return;
398
+ const before = seatFor();
387
399
  deps.recomputeSnaps();
388
400
  const mode = deps.getMode();
389
401
  const isVerticalAxis = mode === "bottom" || mode === "top";
@@ -392,6 +404,10 @@ function installResizeObserver(deps) {
392
404
  if (viewportSize2 > 0 && viewportSize2 < max) {
393
405
  deps.setMaxAxisSize(viewportSize2);
394
406
  }
407
+ const after = seatFor();
408
+ if (before.target !== null && after.target !== null && Math.abs(after.target - before.target) < SIZE_WRITE_EPSILON && Math.abs(after.max - before.max) < SIZE_WRITE_EPSILON) {
409
+ return;
410
+ }
395
411
  const wasAnimating = deps.isAnimating?.() ?? false;
396
412
  deps.cancelInFlight();
397
413
  deps.newCycle();
@@ -660,12 +676,6 @@ var SCRIM_PRESETS = Object.freeze({
660
676
  }
661
677
  });
662
678
 
663
- // src/core/primitives/hot-path-thresholds.ts
664
- var SIZE_WRITE_EPSILON = 0.5;
665
- var OPACITY_WRITE_EPSILON = 5e-3;
666
- var POINTER_EVENTS_OPACITY_THRESHOLD = 0.05;
667
- var RANGE_DIVISION_EPSILON = 1e-4;
668
-
669
679
  // src/core/primitives/opacity-dedup.ts
670
680
  var WriteSentinel = class {
671
681
  constructor() {
@@ -2595,6 +2605,7 @@ var BottomSheetCore = class {
2595
2605
  __publicField(this, "lifecycle");
2596
2606
  __publicField(this, "closeOnBack");
2597
2607
  __publicField(this, "routedTo");
2608
+ __publicField(this, "fitContentToSnap");
2598
2609
  __publicField(this, "persistent");
2599
2610
  __publicField(this, "disableCloseFlag");
2600
2611
  __publicField(this, "disableDragFlag");
@@ -2708,6 +2719,7 @@ var BottomSheetCore = class {
2708
2719
  );
2709
2720
  this.closeOnBack = resolved.closeOnBack;
2710
2721
  this.routedTo = opts.routedTo;
2722
+ this.fitContentToSnap = opts.fitContentToSnap === true;
2711
2723
  this.persistent = resolved.persistent;
2712
2724
  this.disableCloseFlag = resolved.disableClose;
2713
2725
  this.disableDragFlag = resolved.disableDrag;
@@ -2809,7 +2821,8 @@ var BottomSheetCore = class {
2809
2821
  closeOnBack: this.closeOnBack,
2810
2822
  closeOnRouteChange: this.closeOnRouteChange,
2811
2823
  persistKey: this.persistKey,
2812
- autoCollapseAfter
2824
+ autoCollapseAfter,
2825
+ fitContentToSnap: this.fitContentToSnap
2813
2826
  },
2814
2827
  isDestroyed: () => this.destroyed,
2815
2828
  isDragging: () => this.isDraggingAny(),
@@ -2861,6 +2874,11 @@ var BottomSheetCore = class {
2861
2874
  "[BottomSheet] closeOnBack/routedTo/closeOnRouteChange need routeFeature() \u2014 option ignored"
2862
2875
  );
2863
2876
  }
2877
+ if (this.fitContentToSnap && !names.has("content-fit")) {
2878
+ devWarn(
2879
+ "[BottomSheet] fitContentToSnap needs contentFitFeature() \u2014 option ignored"
2880
+ );
2881
+ }
2864
2882
  if (this.persistKey && !names.has("persist")) {
2865
2883
  devWarn(
2866
2884
  "[BottomSheet] persistKey needs persistFeature() \u2014 snaps will not be saved"
@@ -4218,6 +4236,68 @@ function visualViewportFeature() {
4218
4236
  };
4219
4237
  }
4220
4238
 
4239
+ // src/core/features/content-fit.ts
4240
+ var INSET_VAR = "--bs-content-inset";
4241
+ var FIT_ATTR = "data-bs-fit-content";
4242
+ function contentFitFeature() {
4243
+ return {
4244
+ name: "content-fit",
4245
+ install: (ctx) => {
4246
+ const scroller = ctx.scrollContainer;
4247
+ if (!ctx.options.fitContentToSnap || !scroller || typeof window === "undefined") {
4248
+ return;
4249
+ }
4250
+ const sheet = ctx.element;
4251
+ let inset = 0;
4252
+ let unpaddedMax = -1;
4253
+ let top = 0;
4254
+ const hiddenAt = (size) => sheet.dataset.mode === "bottom" ? Math.max(0, ctx.getMaxAxisSize() - size) : 0;
4255
+ const follow = (size) => {
4256
+ if (unpaddedMax < 0) {
4257
+ unpaddedMax = scroller.scrollHeight - scroller.clientHeight - inset;
4258
+ top = scroller.scrollTop;
4259
+ }
4260
+ const limit = Math.max(0, unpaddedMax + hiddenAt(size));
4261
+ if (top > limit) {
4262
+ if (scroller.scrollTop > limit) scroller.scrollTop = limit;
4263
+ top = limit;
4264
+ }
4265
+ };
4266
+ const settle = () => {
4267
+ if (ctx.isDestroyed()) return;
4268
+ const size = ctx.getSize();
4269
+ unpaddedMax = -1;
4270
+ follow(size);
4271
+ inset = hiddenAt(size);
4272
+ sheet.style.setProperty(INSET_VAR, `${inset}px`);
4273
+ unpaddedMax = -1;
4274
+ };
4275
+ const moving = () => ctx.isAnimating() || ctx.isDragging();
4276
+ const whenIdle = () => {
4277
+ if (!moving()) settle();
4278
+ };
4279
+ sheet.setAttribute(FIT_ATTR, "");
4280
+ settle();
4281
+ const offProgress = ctx.on(
4282
+ "progress",
4283
+ (p) => moving() ? follow(p.size) : settle()
4284
+ );
4285
+ const offSnap = ctx.on("snap", settle);
4286
+ const observer = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(whenIdle);
4287
+ observer?.observe(document.documentElement);
4288
+ window.addEventListener("orientationchange", whenIdle);
4289
+ return () => {
4290
+ offProgress();
4291
+ offSnap();
4292
+ observer?.disconnect();
4293
+ window.removeEventListener("orientationchange", whenIdle);
4294
+ sheet.removeAttribute(FIT_ATTR);
4295
+ sheet.style.removeProperty(INSET_VAR);
4296
+ };
4297
+ }
4298
+ };
4299
+ }
4300
+
4221
4301
  // src/core/default-features.ts
4222
4302
  function defaultEngineFeatures() {
4223
4303
  return [
@@ -4225,7 +4305,8 @@ function defaultEngineFeatures() {
4225
4305
  visualViewportFeature(),
4226
4306
  persistFeature(),
4227
4307
  autoCollapseFeature(),
4228
- routeFeature()
4308
+ routeFeature(),
4309
+ contentFitFeature()
4229
4310
  ];
4230
4311
  }
4231
4312
 
@@ -4319,6 +4400,7 @@ var BottomSheet = component$((props) => {
4319
4400
  disableDrag: props.disableDrag,
4320
4401
  dragFrom: props.dragFrom,
4321
4402
  dragFromContent: props.dragFromContent,
4403
+ fitContentToSnap: props.fitContentToSnap,
4322
4404
  closeOnRouteChange: props.closeOnRouteChange,
4323
4405
  stackEffect: props.stackEffect,
4324
4406
  returnFocusTo: props.returnFocusTo,
package/dist/react.cjs CHANGED
@@ -385,14 +385,26 @@ function notifyLinkedSheets(sheets, self) {
385
385
  }
386
386
  }
387
387
 
388
+ // src/core/primitives/hot-path-thresholds.ts
389
+ var SIZE_WRITE_EPSILON = 0.5;
390
+ var OPACITY_WRITE_EPSILON = 5e-3;
391
+ var POINTER_EVENTS_OPACITY_THRESHOLD = 0.05;
392
+ var RANGE_DIVISION_EPSILON = 1e-4;
393
+
388
394
  // src/core/features/resize-observer.ts
389
395
  function installResizeObserver(deps) {
390
396
  if (typeof window === "undefined") {
391
397
  return () => {
392
398
  };
393
399
  }
400
+ const seatFor = () => {
401
+ const snap = deps.resolveActiveSnap();
402
+ const max = deps.getMaxAxisSize();
403
+ return { target: snap ? Math.min(snap.size, max) : null, max };
404
+ };
394
405
  const onResize = () => {
395
406
  if (deps.isDestroyed()) return;
407
+ const before = seatFor();
396
408
  deps.recomputeSnaps();
397
409
  const mode = deps.getMode();
398
410
  const isVerticalAxis = mode === "bottom" || mode === "top";
@@ -401,6 +413,10 @@ function installResizeObserver(deps) {
401
413
  if (viewportSize2 > 0 && viewportSize2 < max) {
402
414
  deps.setMaxAxisSize(viewportSize2);
403
415
  }
416
+ const after = seatFor();
417
+ if (before.target !== null && after.target !== null && Math.abs(after.target - before.target) < SIZE_WRITE_EPSILON && Math.abs(after.max - before.max) < SIZE_WRITE_EPSILON) {
418
+ return;
419
+ }
404
420
  const wasAnimating = deps.isAnimating?.() ?? false;
405
421
  deps.cancelInFlight();
406
422
  deps.newCycle();
@@ -669,12 +685,6 @@ var SCRIM_PRESETS = Object.freeze({
669
685
  }
670
686
  });
671
687
 
672
- // src/core/primitives/hot-path-thresholds.ts
673
- var SIZE_WRITE_EPSILON = 0.5;
674
- var OPACITY_WRITE_EPSILON = 5e-3;
675
- var POINTER_EVENTS_OPACITY_THRESHOLD = 0.05;
676
- var RANGE_DIVISION_EPSILON = 1e-4;
677
-
678
688
  // src/core/primitives/opacity-dedup.ts
679
689
  var WriteSentinel = class {
680
690
  constructor() {
@@ -2604,6 +2614,7 @@ var BottomSheetCore = class {
2604
2614
  __publicField(this, "lifecycle");
2605
2615
  __publicField(this, "closeOnBack");
2606
2616
  __publicField(this, "routedTo");
2617
+ __publicField(this, "fitContentToSnap");
2607
2618
  __publicField(this, "persistent");
2608
2619
  __publicField(this, "disableCloseFlag");
2609
2620
  __publicField(this, "disableDragFlag");
@@ -2717,6 +2728,7 @@ var BottomSheetCore = class {
2717
2728
  );
2718
2729
  this.closeOnBack = resolved.closeOnBack;
2719
2730
  this.routedTo = opts.routedTo;
2731
+ this.fitContentToSnap = opts.fitContentToSnap === true;
2720
2732
  this.persistent = resolved.persistent;
2721
2733
  this.disableCloseFlag = resolved.disableClose;
2722
2734
  this.disableDragFlag = resolved.disableDrag;
@@ -2818,7 +2830,8 @@ var BottomSheetCore = class {
2818
2830
  closeOnBack: this.closeOnBack,
2819
2831
  closeOnRouteChange: this.closeOnRouteChange,
2820
2832
  persistKey: this.persistKey,
2821
- autoCollapseAfter
2833
+ autoCollapseAfter,
2834
+ fitContentToSnap: this.fitContentToSnap
2822
2835
  },
2823
2836
  isDestroyed: () => this.destroyed,
2824
2837
  isDragging: () => this.isDraggingAny(),
@@ -2870,6 +2883,11 @@ var BottomSheetCore = class {
2870
2883
  "[BottomSheet] closeOnBack/routedTo/closeOnRouteChange need routeFeature() \u2014 option ignored"
2871
2884
  );
2872
2885
  }
2886
+ if (this.fitContentToSnap && !names.has("content-fit")) {
2887
+ devWarn(
2888
+ "[BottomSheet] fitContentToSnap needs contentFitFeature() \u2014 option ignored"
2889
+ );
2890
+ }
2873
2891
  if (this.persistKey && !names.has("persist")) {
2874
2892
  devWarn(
2875
2893
  "[BottomSheet] persistKey needs persistFeature() \u2014 snaps will not be saved"
@@ -4227,6 +4245,68 @@ function visualViewportFeature() {
4227
4245
  };
4228
4246
  }
4229
4247
 
4248
+ // src/core/features/content-fit.ts
4249
+ var INSET_VAR = "--bs-content-inset";
4250
+ var FIT_ATTR = "data-bs-fit-content";
4251
+ function contentFitFeature() {
4252
+ return {
4253
+ name: "content-fit",
4254
+ install: (ctx) => {
4255
+ const scroller = ctx.scrollContainer;
4256
+ if (!ctx.options.fitContentToSnap || !scroller || typeof window === "undefined") {
4257
+ return;
4258
+ }
4259
+ const sheet = ctx.element;
4260
+ let inset = 0;
4261
+ let unpaddedMax = -1;
4262
+ let top = 0;
4263
+ const hiddenAt = (size) => sheet.dataset.mode === "bottom" ? Math.max(0, ctx.getMaxAxisSize() - size) : 0;
4264
+ const follow = (size) => {
4265
+ if (unpaddedMax < 0) {
4266
+ unpaddedMax = scroller.scrollHeight - scroller.clientHeight - inset;
4267
+ top = scroller.scrollTop;
4268
+ }
4269
+ const limit = Math.max(0, unpaddedMax + hiddenAt(size));
4270
+ if (top > limit) {
4271
+ if (scroller.scrollTop > limit) scroller.scrollTop = limit;
4272
+ top = limit;
4273
+ }
4274
+ };
4275
+ const settle = () => {
4276
+ if (ctx.isDestroyed()) return;
4277
+ const size = ctx.getSize();
4278
+ unpaddedMax = -1;
4279
+ follow(size);
4280
+ inset = hiddenAt(size);
4281
+ sheet.style.setProperty(INSET_VAR, `${inset}px`);
4282
+ unpaddedMax = -1;
4283
+ };
4284
+ const moving = () => ctx.isAnimating() || ctx.isDragging();
4285
+ const whenIdle = () => {
4286
+ if (!moving()) settle();
4287
+ };
4288
+ sheet.setAttribute(FIT_ATTR, "");
4289
+ settle();
4290
+ const offProgress = ctx.on(
4291
+ "progress",
4292
+ (p) => moving() ? follow(p.size) : settle()
4293
+ );
4294
+ const offSnap = ctx.on("snap", settle);
4295
+ const observer = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(whenIdle);
4296
+ observer?.observe(document.documentElement);
4297
+ window.addEventListener("orientationchange", whenIdle);
4298
+ return () => {
4299
+ offProgress();
4300
+ offSnap();
4301
+ observer?.disconnect();
4302
+ window.removeEventListener("orientationchange", whenIdle);
4303
+ sheet.removeAttribute(FIT_ATTR);
4304
+ sheet.style.removeProperty(INSET_VAR);
4305
+ };
4306
+ }
4307
+ };
4308
+ }
4309
+
4230
4310
  // src/core/default-features.ts
4231
4311
  function defaultEngineFeatures() {
4232
4312
  return [
@@ -4234,7 +4314,8 @@ function defaultEngineFeatures() {
4234
4314
  visualViewportFeature(),
4235
4315
  persistFeature(),
4236
4316
  autoCollapseFeature(),
4237
- routeFeature()
4317
+ routeFeature(),
4318
+ contentFitFeature()
4238
4319
  ];
4239
4320
  }
4240
4321
 
package/dist/react.d.cts CHANGED
@@ -1,10 +1,10 @@
1
- import { c as EngineOptions, E as EngineState, A as AnchorOptions, e as ScrimStagesOptions, u as ScrimStageDef, S as SheetEventMap, C as CloseReason, v as ScrimUpdate, r as ScrimOverlayOptions, a as SnapPointDef, b as SheetMode } from './BottomSheetCore-BHv6LPmS.cjs';
2
- export { d as SnapPoint } from './BottomSheetCore-BHv6LPmS.cjs';
1
+ import { g as EngineOptions, d as EngineState, A as AnchorOptions, i as ScrimStagesOptions, u as ScrimStageDef, S as SheetEventMap, C as CloseReason, v as ScrimUpdate, r as ScrimOverlayOptions, e as SnapPointDef, f as SheetMode } from './BottomSheetCore-CQStdVy2.cjs';
2
+ export { h as SnapPoint } from './BottomSheetCore-CQStdVy2.cjs';
3
3
  import { OverlayOptions, OverlayState, Overlay as OverlayEngine } from './overlay.cjs';
4
4
  export { OverlayEdge } from './overlay.cjs';
5
5
  import * as react from 'react';
6
6
  import { CSSProperties, ReactNode } from 'react';
7
- import { B as BottomSheetEngine } from './BottomSheetEngine-mmFzIK1Z.cjs';
7
+ import { B as BottomSheetEngine } from './BottomSheetEngine-CsQWHLNb.cjs';
8
8
  import { T as TeleportTarget } from './teleport-7uYNiEAT.cjs';
9
9
  import './transform-jVfAikE9.cjs';
10
10
 
package/dist/react.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- import { c as EngineOptions, E as EngineState, A as AnchorOptions, e as ScrimStagesOptions, u as ScrimStageDef, S as SheetEventMap, C as CloseReason, v as ScrimUpdate, r as ScrimOverlayOptions, a as SnapPointDef, b as SheetMode } from './BottomSheetCore-CK_mq14p.js';
2
- export { d as SnapPoint } from './BottomSheetCore-CK_mq14p.js';
1
+ import { g as EngineOptions, d as EngineState, A as AnchorOptions, i as ScrimStagesOptions, u as ScrimStageDef, S as SheetEventMap, C as CloseReason, v as ScrimUpdate, r as ScrimOverlayOptions, e as SnapPointDef, f as SheetMode } from './BottomSheetCore-9i-Uh6T3.js';
2
+ export { h as SnapPoint } from './BottomSheetCore-9i-Uh6T3.js';
3
3
  import { OverlayOptions, OverlayState, Overlay as OverlayEngine } from './overlay.js';
4
4
  export { OverlayEdge } from './overlay.js';
5
5
  import * as react from 'react';
6
6
  import { CSSProperties, ReactNode } from 'react';
7
- import { B as BottomSheetEngine } from './BottomSheetEngine-wLn6Q2kA.js';
7
+ import { B as BottomSheetEngine } from './BottomSheetEngine-Dn6h-7gF.js';
8
8
  import { T as TeleportTarget } from './teleport-7uYNiEAT.js';
9
9
  import './transform-jVfAikE9.js';
10
10