@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/element.js CHANGED
@@ -431,14 +431,31 @@ var init_linked_sheets = __esm({
431
431
  }
432
432
  });
433
433
 
434
+ // src/core/primitives/hot-path-thresholds.ts
435
+ var SIZE_WRITE_EPSILON, OPACITY_WRITE_EPSILON, POINTER_EVENTS_OPACITY_THRESHOLD, RANGE_DIVISION_EPSILON;
436
+ var init_hot_path_thresholds = __esm({
437
+ "src/core/primitives/hot-path-thresholds.ts"() {
438
+ SIZE_WRITE_EPSILON = 0.5;
439
+ OPACITY_WRITE_EPSILON = 5e-3;
440
+ POINTER_EVENTS_OPACITY_THRESHOLD = 0.05;
441
+ RANGE_DIVISION_EPSILON = 1e-4;
442
+ }
443
+ });
444
+
434
445
  // src/core/features/resize-observer.ts
435
446
  function installResizeObserver(deps) {
436
447
  if (typeof window === "undefined") {
437
448
  return () => {
438
449
  };
439
450
  }
451
+ const seatFor = () => {
452
+ const snap = deps.resolveActiveSnap();
453
+ const max = deps.getMaxAxisSize();
454
+ return { target: snap ? Math.min(snap.size, max) : null, max };
455
+ };
440
456
  const onResize = () => {
441
457
  if (deps.isDestroyed()) return;
458
+ const before = seatFor();
442
459
  deps.recomputeSnaps();
443
460
  const mode = deps.getMode();
444
461
  const isVerticalAxis = mode === "bottom" || mode === "top";
@@ -447,6 +464,10 @@ function installResizeObserver(deps) {
447
464
  if (viewportSize2 > 0 && viewportSize2 < max) {
448
465
  deps.setMaxAxisSize(viewportSize2);
449
466
  }
467
+ const after = seatFor();
468
+ 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) {
469
+ return;
470
+ }
450
471
  const wasAnimating = deps.isAnimating?.() ?? false;
451
472
  deps.cancelInFlight();
452
473
  deps.newCycle();
@@ -481,6 +502,7 @@ function installResizeObserver(deps) {
481
502
  }
482
503
  var init_resize_observer = __esm({
483
504
  "src/core/features/resize-observer.ts"() {
505
+ init_hot_path_thresholds();
484
506
  }
485
507
  });
486
508
 
@@ -745,17 +767,6 @@ var init_types = __esm({
745
767
  }
746
768
  });
747
769
 
748
- // src/core/primitives/hot-path-thresholds.ts
749
- var SIZE_WRITE_EPSILON, OPACITY_WRITE_EPSILON, POINTER_EVENTS_OPACITY_THRESHOLD, RANGE_DIVISION_EPSILON;
750
- var init_hot_path_thresholds = __esm({
751
- "src/core/primitives/hot-path-thresholds.ts"() {
752
- SIZE_WRITE_EPSILON = 0.5;
753
- OPACITY_WRITE_EPSILON = 5e-3;
754
- POINTER_EVENTS_OPACITY_THRESHOLD = 0.05;
755
- RANGE_DIVISION_EPSILON = 1e-4;
756
- }
757
- });
758
-
759
770
  // src/core/primitives/opacity-dedup.ts
760
771
  var WriteSentinel;
761
772
  var init_opacity_dedup = __esm({
@@ -2870,6 +2881,7 @@ var init_BottomSheetCore = __esm({
2870
2881
  __publicField(this, "lifecycle");
2871
2882
  __publicField(this, "closeOnBack");
2872
2883
  __publicField(this, "routedTo");
2884
+ __publicField(this, "fitContentToSnap");
2873
2885
  __publicField(this, "persistent");
2874
2886
  __publicField(this, "disableCloseFlag");
2875
2887
  __publicField(this, "disableDragFlag");
@@ -2983,6 +2995,7 @@ var init_BottomSheetCore = __esm({
2983
2995
  );
2984
2996
  this.closeOnBack = resolved.closeOnBack;
2985
2997
  this.routedTo = opts.routedTo;
2998
+ this.fitContentToSnap = opts.fitContentToSnap === true;
2986
2999
  this.persistent = resolved.persistent;
2987
3000
  this.disableCloseFlag = resolved.disableClose;
2988
3001
  this.disableDragFlag = resolved.disableDrag;
@@ -3084,7 +3097,8 @@ var init_BottomSheetCore = __esm({
3084
3097
  closeOnBack: this.closeOnBack,
3085
3098
  closeOnRouteChange: this.closeOnRouteChange,
3086
3099
  persistKey: this.persistKey,
3087
- autoCollapseAfter
3100
+ autoCollapseAfter,
3101
+ fitContentToSnap: this.fitContentToSnap
3088
3102
  },
3089
3103
  isDestroyed: () => this.destroyed,
3090
3104
  isDragging: () => this.isDraggingAny(),
@@ -3136,6 +3150,11 @@ var init_BottomSheetCore = __esm({
3136
3150
  "[BottomSheet] closeOnBack/routedTo/closeOnRouteChange need routeFeature() \u2014 option ignored"
3137
3151
  );
3138
3152
  }
3153
+ if (this.fitContentToSnap && !names.has("content-fit")) {
3154
+ devWarn(
3155
+ "[BottomSheet] fitContentToSnap needs contentFitFeature() \u2014 option ignored"
3156
+ );
3157
+ }
3139
3158
  if (this.persistKey && !names.has("persist")) {
3140
3159
  devWarn(
3141
3160
  "[BottomSheet] persistKey needs persistFeature() \u2014 snaps will not be saved"
@@ -4532,6 +4551,73 @@ var init_engine_features = __esm({
4532
4551
  }
4533
4552
  });
4534
4553
 
4554
+ // src/core/features/content-fit.ts
4555
+ function contentFitFeature() {
4556
+ return {
4557
+ name: "content-fit",
4558
+ install: (ctx) => {
4559
+ const scroller = ctx.scrollContainer;
4560
+ if (!ctx.options.fitContentToSnap || !scroller || typeof window === "undefined") {
4561
+ return;
4562
+ }
4563
+ const sheet = ctx.element;
4564
+ let inset = 0;
4565
+ let unpaddedMax = -1;
4566
+ let top = 0;
4567
+ const hiddenAt = (size) => sheet.dataset.mode === "bottom" ? Math.max(0, ctx.getMaxAxisSize() - size) : 0;
4568
+ const follow = (size) => {
4569
+ if (unpaddedMax < 0) {
4570
+ unpaddedMax = scroller.scrollHeight - scroller.clientHeight - inset;
4571
+ top = scroller.scrollTop;
4572
+ }
4573
+ const limit = Math.max(0, unpaddedMax + hiddenAt(size));
4574
+ if (top > limit) {
4575
+ if (scroller.scrollTop > limit) scroller.scrollTop = limit;
4576
+ top = limit;
4577
+ }
4578
+ };
4579
+ const settle = () => {
4580
+ if (ctx.isDestroyed()) return;
4581
+ const size = ctx.getSize();
4582
+ unpaddedMax = -1;
4583
+ follow(size);
4584
+ inset = hiddenAt(size);
4585
+ sheet.style.setProperty(INSET_VAR, `${inset}px`);
4586
+ unpaddedMax = -1;
4587
+ };
4588
+ const moving = () => ctx.isAnimating() || ctx.isDragging();
4589
+ const whenIdle = () => {
4590
+ if (!moving()) settle();
4591
+ };
4592
+ sheet.setAttribute(FIT_ATTR, "");
4593
+ settle();
4594
+ const offProgress = ctx.on(
4595
+ "progress",
4596
+ (p) => moving() ? follow(p.size) : settle()
4597
+ );
4598
+ const offSnap = ctx.on("snap", settle);
4599
+ const observer = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(whenIdle);
4600
+ observer?.observe(document.documentElement);
4601
+ window.addEventListener("orientationchange", whenIdle);
4602
+ return () => {
4603
+ offProgress();
4604
+ offSnap();
4605
+ observer?.disconnect();
4606
+ window.removeEventListener("orientationchange", whenIdle);
4607
+ sheet.removeAttribute(FIT_ATTR);
4608
+ sheet.style.removeProperty(INSET_VAR);
4609
+ };
4610
+ }
4611
+ };
4612
+ }
4613
+ var INSET_VAR, FIT_ATTR;
4614
+ var init_content_fit = __esm({
4615
+ "src/core/features/content-fit.ts"() {
4616
+ INSET_VAR = "--bs-content-inset";
4617
+ FIT_ATTR = "data-bs-fit-content";
4618
+ }
4619
+ });
4620
+
4535
4621
  // src/core/default-features.ts
4536
4622
  function defaultEngineFeatures() {
4537
4623
  return [
@@ -4539,12 +4625,14 @@ function defaultEngineFeatures() {
4539
4625
  visualViewportFeature(),
4540
4626
  persistFeature(),
4541
4627
  autoCollapseFeature(),
4542
- routeFeature()
4628
+ routeFeature(),
4629
+ contentFitFeature()
4543
4630
  ];
4544
4631
  }
4545
4632
  var init_default_features = __esm({
4546
4633
  "src/core/default-features.ts"() {
4547
4634
  init_engine_features();
4635
+ init_content_fit();
4548
4636
  }
4549
4637
  });
4550
4638
 
@@ -4569,7 +4657,7 @@ var init_BottomSheetEngine = __esm({
4569
4657
  var baseStyles;
4570
4658
  var init_baseStyles = __esm({
4571
4659
  "src/web-component/baseStyles.ts"() {
4572
- baseStyles = `:where(.bs-root){--bs-surface-d:#ffffff;--bs-surface-border-d:rgba(225,227,237,1);--bs-radius-d:20px;--bs-handle-color-d:rgba(26,22,20,0.3);--bs-handle-width:40px;--bs-handle-height:5px;--bs-z-backdrop:90;--bs-z-sheet:100;--bs-backdrop-color-d:rgba(0,0,0,0.5);--bs-scrim-color-d:transparent;--bs-scrim-blur:0px;--bs-z-scrim:calc(var(--bs-z-sheet) - 1);--bs-size:0px;--bs-progress:0}.bs-backdrop{position:fixed;inset:0;background:var(--bs-backdrop-color,var(--bs-backdrop-color-d));opacity:0;pointer-events:none;z-index:var(--bs-z-backdrop);transition:opacity 0.24s cubic-bezier(0.22,1,0.36,1);will-change:opacity}.bs-root[data-dragging="true"] .bs-backdrop,.bs-root[data-animating="true"] .bs-backdrop{transition:none}.bs-sheet{position:fixed;background:var(--bs-surface,var(--bs-surface-d));box-shadow:var(--bs-shadow,var(--bs-shadow-auto,none));--bs-shadow-fade:clamp(0,calc(var(--bs-progress,0) * 8),1);z-index:var(--bs-z-sheet);pointer-events:auto;overflow:hidden;display:flex;flex-direction:column;-webkit-tap-highlight-color:transparent;user-select:none;overscroll-behavior:contain}.bs-sheet[data-mode="bottom"]{left:0;right:0;bottom:0;width:100%;border-top-left-radius:var(--bs-radius,var(--bs-radius-d));border-top-right-radius:var(--bs-radius,var(--bs-radius-d));border-top:1px solid var(--bs-surface-border,var(--bs-surface-border-d));padding-bottom:env(safe-area-inset-bottom);--bs-shadow-auto:0 calc(var(--bs-progress,0) * -2px - 3px) calc(var(--bs-progress,0) * 18px + 12px) rgba( 0,0,0,calc(var(--bs-shadow-fade) * (var(--bs-progress,0) * 0.15 + 0.12)) )}.bs-sheet[data-mode="top"]{left:0;right:0;top:0;width:100%;border-bottom-left-radius:var(--bs-radius,var(--bs-radius-d));border-bottom-right-radius:var(--bs-radius,var(--bs-radius-d));border-bottom:1px solid var(--bs-surface-border,var(--bs-surface-border-d));flex-direction:column-reverse;--bs-shadow-auto:0 3px 12px rgba(0,0,0,calc(var(--bs-shadow-fade) * 0.12));padding-top:env(safe-area-inset-top)}.bs-sheet[data-mode="left"]{top:0;bottom:0;left:0;height:100%;border-top-right-radius:var(--bs-radius,var(--bs-radius-d));border-bottom-right-radius:var(--bs-radius,var(--bs-radius-d));border-right:1px solid var(--bs-surface-border,var(--bs-surface-border-d));--bs-shadow-auto:3px 0 12px rgba(0,0,0,calc(var(--bs-shadow-fade) * 0.12))}.bs-sheet[data-mode="right"]{top:0;bottom:0;right:0;height:100%;border-top-left-radius:var(--bs-radius,var(--bs-radius-d));border-bottom-left-radius:var(--bs-radius,var(--bs-radius-d));border-left:1px solid var(--bs-surface-border,var(--bs-surface-border-d));--bs-shadow-auto:-3px 0 12px rgba(0,0,0,calc(var(--bs-shadow-fade) * 0.12))}.bs-sheet[data-bs-rest="closed"]{box-shadow:none;visibility:hidden}.bs-sheet[data-bs-webgl="on"],.bs-sheet[data-bs-webgl="on"] .bs-handle,.bs-sheet[data-bs-webgl="on"] .bs-header,.bs-sheet[data-bs-webgl="on"] .bs-footer{background:transparent;box-shadow:none}.bs-sheet[data-mode="left"] .bs-content{padding-right:36px}.bs-sheet[data-mode="right"] .bs-content{padding-left:36px}.bs-handle{flex-shrink:0;min-height:44px;display:flex;flex-direction:column;justify-content:center;padding:var(--bs-handle-padding,8px 16px 4px);cursor:grab;touch-action:none;user-select:none;background:var(--bs-surface,var(--bs-surface-d));-webkit-tap-highlight-color:transparent;outline:none;position:relative}.bs-handle:active{cursor:grabbing}.bs-handle:focus-visible{outline:2px solid currentColor;outline-offset:-2px;border-radius:var(--bs-radius,var(--bs-radius-d))}.bs-handle::before{content:"";display:block;width:var(--bs-handle-width);height:var(--bs-handle-height);background:var(--bs-handle-color,var(--bs-handle-color-d));border-radius:calc(var(--bs-handle-height) / 2);margin:0 auto 8px;transition:width 0.15s ease,background 0.15s ease,transform 0.15s ease;pointer-events:none}.bs-sheet[data-mode="left"] .bs-handle,.bs-sheet[data-mode="right"] .bs-handle{position:absolute;top:0;bottom:0;width:28px;min-width:0;min-height:0;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:0;background:var(--bs-surface,var(--bs-surface-d));z-index:1;overflow:hidden}.bs-sheet[data-mode="left"] .bs-handle>*,.bs-sheet[data-mode="right"] .bs-handle>*{display:none}.bs-sheet[data-mode="left"] .bs-handle{right:0;border-left:1px solid var(--bs-surface-border,var(--bs-surface-border-d))}.bs-sheet[data-mode="right"] .bs-handle{left:0;border-right:1px solid var(--bs-surface-border,var(--bs-surface-border-d))}.bs-sheet[data-mode="left"] .bs-handle::before,.bs-sheet[data-mode="right"] .bs-handle::before{width:var(--bs-handle-height);height:var(--bs-handle-width);margin:0}.bs-sheet:hover .bs-handle::before{background:color-mix(in oklab,var(--bs-handle-color,var(--bs-handle-color-d)),#000 15%)}.bs-handle:active::before{background:color-mix(in oklab,var(--bs-handle-color,var(--bs-handle-color-d)),#000 35%);transform:scaleX(1.15)}.bs-handle.bs-handle--ticks::after{content:"";display:block;position:absolute;left:50%;bottom:6px;transform:translateX(-50%);width:calc(var(--bs-handle-width) * 2);height:3px;background-image:radial-gradient( circle,var(--bs-handle-color,var(--bs-handle-color-d)) 0 1.5px,transparent 1.6px );background-size:8px 3px;background-repeat:repeat-x;background-position:center;opacity:0;transition:opacity 0.18s ease-out;pointer-events:none}.bs-root[data-dragging="true"] .bs-handle.bs-handle--ticks::after{opacity:0.4}.bs-sheet[data-mode="top"] .bs-handle.bs-handle--ticks::after{bottom:auto;top:6px}.bs-sheet[data-mode="left"] .bs-handle.bs-handle--ticks::after,.bs-sheet[data-mode="right"] .bs-handle.bs-handle--ticks::after{left:50%;top:50%;bottom:auto;transform:translate(-50%,-50%);width:3px;height:calc(var(--bs-handle-width) * 2);background-size:3px 8px;background-repeat:repeat-y;margin-left:calc(var(--bs-handle-height) + 6px)}.bs-sheet[data-mode="right"] .bs-handle.bs-handle--ticks::after{margin-left:calc(-1 * (var(--bs-handle-height) + 6px))}.bs-header{flex:0 0 auto;min-height:var(--bs-header-min-height,0px);padding:var(--bs-header-padding,0 16px 8px);background:var(--bs-surface,var(--bs-surface-d))}.bs-content{flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;overscroll-behavior:contain;user-select:text;padding:var(--bs-content-padding,0 16px 16px)}.bs-footer{flex:0 0 auto;padding:var(--bs-footer-padding,12px 16px calc(12px + env(safe-area-inset-bottom)));border-top:1px solid var(--bs-surface-border,var(--bs-surface-border-d));background:var(--bs-surface,var(--bs-surface-d))}.bs-sheet[data-mode="bottom"]:has(.bs-footer:not([hidden]):has(*)){padding-bottom:0}.bs-header:not(:has(*)),.bs-footer:not(:has(*)),.bs-header[hidden],.bs-footer[hidden]{display:none}.bs-screen{position:absolute;inset:0;pointer-events:none;z-index:var(--bs-z-scrim);background:var(--bs-scrim-color,var(--bs-scrim-color-d));backdrop-filter:blur(var(--bs-scrim-blur,0px));-webkit-backdrop-filter:blur(var(--bs-scrim-blur,0px));transition:opacity 0.24s cubic-bezier(0.22,1,0.36,1);will-change:opacity}.bs-root[data-dragging="true"] .bs-screen,.bs-root[data-animating="true"] .bs-screen{transition:none}.bs-scrim-overlay{z-index:calc(var(--bs-z-sheet) + 1);pointer-events:none}.bs-button-slot{position:fixed;z-index:calc(var(--bs-z-sheet) + 1);pointer-events:auto}.bs-button-slot[data-side="left"]{left:16px;bottom:calc(var(--bs-size,0px) + 12px)}.bs-button-slot[data-side="right"]{right:16px;bottom:calc(var(--bs-size,0px) + 12px)}.bs-button-slot[data-mode="top"]{bottom:auto;top:calc(var(--bs-size,0px) + 12px)}.bs-button-slot[data-mode="left"]{left:calc(var(--bs-size,0px) + 12px);right:auto;bottom:auto;top:16px}.bs-button-slot[data-mode="right"]{right:calc(var(--bs-size,0px) + 12px);left:auto;bottom:auto;top:16px}@media (prefers-reduced-motion:reduce){.bs-backdrop,.bs-handle::before,.bs-button-slot[data-side="left"],.bs-button-slot[data-side="right"]{transition:none !important}}@media (prefers-color-scheme:dark){:where(.bs-root){--bs-surface-d:#1a1a1d;--bs-surface-border-d:rgba(255,255,255,0.08);--bs-handle-color-d:rgba(255,255,255,0.45);--bs-shadow-auto:0 -3px 16px rgba(0,0,0,0.5)}}@media (forced-colors:active){.bs-sheet{border:1px solid CanvasText}.bs-handle::before{background:CanvasText;forced-color-adjust:none}.bs-backdrop,.bs-screen{forced-color-adjust:none}}.bs-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}:where(.ovl-root){--ovl-surface:var(--bs-surface,var(--bs-surface-d,#ffffff));--ovl-surface-border:var(--bs-surface-border,var(--bs-surface-border-d,rgba(0,0,0,0.08)));--ovl-shadow:0 -8px 40px rgba(0,0,0,0.35);--ovl-radius:var(--bs-radius,var(--bs-radius-d,20px));--ovl-backdrop-color:rgba(0,0,0,0.5);--ovl-z-backdrop:200;--ovl-z-panel:201}.ovl-backdrop{position:fixed;inset:0;background:var(--ovl-backdrop-color);opacity:0;pointer-events:none;z-index:var(--ovl-z-backdrop)}.ovl-panel{position:fixed;background:var(--ovl-surface);box-shadow:var(--ovl-shadow);z-index:var(--ovl-z-panel);-webkit-tap-highlight-color:transparent;outline:none;transition:transform 0.32s cubic-bezier(0.29,1.24,0.84,0.99),opacity 0.32s ease-out}.ovl-panel[data-state="open"]{transform:translate3d(0,0,0);opacity:1}@starting-style{.ovl-panel[data-edge="bottom"][data-state="open"]{transform:translate3d(0,100%,0);opacity:0}.ovl-panel[data-edge="top"][data-state="open"]{transform:translate3d(0,-100%,0);opacity:0}.ovl-panel[data-edge="left"][data-state="open"]{transform:translate3d(-100%,0,0);opacity:0}.ovl-panel[data-edge="right"][data-state="open"]{transform:translate3d(100%,0,0);opacity:0}}.ovl-panel[data-edge="bottom"]{left:0;right:0;bottom:0;width:100%;border-top-left-radius:var(--ovl-radius);border-top-right-radius:var(--ovl-radius);border-top:1px solid var(--ovl-surface-border);padding-bottom:env(safe-area-inset-bottom)}.ovl-panel[data-edge="top"]{left:0;right:0;top:0;width:100%;border-bottom-left-radius:var(--ovl-radius);border-bottom-right-radius:var(--ovl-radius);border-bottom:1px solid var(--ovl-surface-border);padding-top:env(safe-area-inset-top)}.ovl-panel[data-edge="left"]{top:0;bottom:0;left:0;height:100%;border-top-right-radius:var(--ovl-radius);border-bottom-right-radius:var(--ovl-radius);border-right:1px solid var(--ovl-surface-border)}.ovl-panel[data-edge="right"]{top:0;bottom:0;right:0;height:100%;border-top-left-radius:var(--ovl-radius);border-bottom-left-radius:var(--ovl-radius);border-left:1px solid var(--ovl-surface-border)}@media (prefers-reduced-motion:reduce){.ovl-panel,.ovl-backdrop{transition:none !important}}`;
4660
+ baseStyles = `:where(.bs-root){--bs-surface-d:#ffffff;--bs-surface-border-d:rgba(225,227,237,1);--bs-radius-d:20px;--bs-handle-color-d:rgba(26,22,20,0.3);--bs-handle-width:40px;--bs-handle-height:5px;--bs-z-backdrop:90;--bs-z-sheet:100;--bs-backdrop-color-d:rgba(0,0,0,0.5);--bs-scrim-color-d:transparent;--bs-scrim-blur:0px;--bs-z-scrim:calc(var(--bs-z-sheet) - 1);--bs-size:0px;--bs-progress:0}.bs-backdrop{position:fixed;inset:0;background:var(--bs-backdrop-color,var(--bs-backdrop-color-d));opacity:0;pointer-events:none;z-index:var(--bs-z-backdrop);transition:opacity 0.24s cubic-bezier(0.22,1,0.36,1);will-change:opacity}.bs-root[data-dragging="true"] .bs-backdrop,.bs-root[data-animating="true"] .bs-backdrop{transition:none}.bs-sheet{position:fixed;background:var(--bs-surface,var(--bs-surface-d));box-shadow:var(--bs-shadow,var(--bs-shadow-auto,none));--bs-shadow-fade:clamp(0,calc(var(--bs-progress,0) * 8),1);z-index:var(--bs-z-sheet);pointer-events:auto;overflow:hidden;display:flex;flex-direction:column;-webkit-tap-highlight-color:transparent;user-select:none;overscroll-behavior:contain}.bs-sheet[data-mode="bottom"]{left:0;right:0;bottom:0;width:100%;border-top-left-radius:var(--bs-radius,var(--bs-radius-d));border-top-right-radius:var(--bs-radius,var(--bs-radius-d));border-top:1px solid var(--bs-surface-border,var(--bs-surface-border-d));padding-bottom:env(safe-area-inset-bottom);--bs-shadow-auto:0 calc(var(--bs-progress,0) * -2px - 3px) calc(var(--bs-progress,0) * 18px + 12px) rgba( 0,0,0,calc(var(--bs-shadow-fade) * (var(--bs-progress,0) * 0.15 + 0.12)) )}.bs-sheet[data-mode="top"]{left:0;right:0;top:0;width:100%;border-bottom-left-radius:var(--bs-radius,var(--bs-radius-d));border-bottom-right-radius:var(--bs-radius,var(--bs-radius-d));border-bottom:1px solid var(--bs-surface-border,var(--bs-surface-border-d));flex-direction:column-reverse;--bs-shadow-auto:0 3px 12px rgba(0,0,0,calc(var(--bs-shadow-fade) * 0.12));padding-top:env(safe-area-inset-top)}.bs-sheet[data-mode="left"]{top:0;bottom:0;left:0;height:100%;border-top-right-radius:var(--bs-radius,var(--bs-radius-d));border-bottom-right-radius:var(--bs-radius,var(--bs-radius-d));border-right:1px solid var(--bs-surface-border,var(--bs-surface-border-d));--bs-shadow-auto:3px 0 12px rgba(0,0,0,calc(var(--bs-shadow-fade) * 0.12))}.bs-sheet[data-mode="right"]{top:0;bottom:0;right:0;height:100%;border-top-left-radius:var(--bs-radius,var(--bs-radius-d));border-bottom-left-radius:var(--bs-radius,var(--bs-radius-d));border-left:1px solid var(--bs-surface-border,var(--bs-surface-border-d));--bs-shadow-auto:-3px 0 12px rgba(0,0,0,calc(var(--bs-shadow-fade) * 0.12))}.bs-sheet[data-bs-rest="closed"]{box-shadow:none;visibility:hidden}.bs-sheet[data-bs-webgl="on"],.bs-sheet[data-bs-webgl="on"] .bs-handle,.bs-sheet[data-bs-webgl="on"] .bs-header,.bs-sheet[data-bs-webgl="on"] .bs-footer{background:transparent;box-shadow:none}.bs-sheet[data-mode="left"] .bs-content{padding-right:36px}.bs-sheet[data-mode="right"] .bs-content{padding-left:36px}.bs-handle{flex-shrink:0;min-height:44px;display:flex;flex-direction:column;justify-content:center;padding:var(--bs-handle-padding,8px 16px 4px);cursor:grab;touch-action:none;user-select:none;background:var(--bs-surface,var(--bs-surface-d));-webkit-tap-highlight-color:transparent;outline:none;position:relative}.bs-handle:active{cursor:grabbing}.bs-handle:focus-visible{outline:2px solid currentColor;outline-offset:-2px;border-radius:var(--bs-radius,var(--bs-radius-d))}.bs-handle::before{content:"";display:block;width:var(--bs-handle-width);height:var(--bs-handle-height);background:var(--bs-handle-color,var(--bs-handle-color-d));border-radius:calc(var(--bs-handle-height) / 2);margin:0 auto 8px;transition:width 0.15s ease,background 0.15s ease,transform 0.15s ease;pointer-events:none}.bs-sheet[data-mode="left"] .bs-handle,.bs-sheet[data-mode="right"] .bs-handle{position:absolute;top:0;bottom:0;width:28px;min-width:0;min-height:0;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:0;background:var(--bs-surface,var(--bs-surface-d));z-index:1;overflow:hidden}.bs-sheet[data-mode="left"] .bs-handle>*,.bs-sheet[data-mode="right"] .bs-handle>*{display:none}.bs-sheet[data-mode="left"] .bs-handle{right:0;border-left:1px solid var(--bs-surface-border,var(--bs-surface-border-d))}.bs-sheet[data-mode="right"] .bs-handle{left:0;border-right:1px solid var(--bs-surface-border,var(--bs-surface-border-d))}.bs-sheet[data-mode="left"] .bs-handle::before,.bs-sheet[data-mode="right"] .bs-handle::before{width:var(--bs-handle-height);height:var(--bs-handle-width);margin:0}.bs-sheet:hover .bs-handle::before{background:color-mix(in oklab,var(--bs-handle-color,var(--bs-handle-color-d)),#000 15%)}.bs-handle:active::before{background:color-mix(in oklab,var(--bs-handle-color,var(--bs-handle-color-d)),#000 35%);transform:scaleX(1.15)}.bs-handle.bs-handle--ticks::after{content:"";display:block;position:absolute;left:50%;bottom:6px;transform:translateX(-50%);width:calc(var(--bs-handle-width) * 2);height:3px;background-image:radial-gradient( circle,var(--bs-handle-color,var(--bs-handle-color-d)) 0 1.5px,transparent 1.6px );background-size:8px 3px;background-repeat:repeat-x;background-position:center;opacity:0;transition:opacity 0.18s ease-out;pointer-events:none}.bs-root[data-dragging="true"] .bs-handle.bs-handle--ticks::after{opacity:0.4}.bs-sheet[data-mode="top"] .bs-handle.bs-handle--ticks::after{bottom:auto;top:6px}.bs-sheet[data-mode="left"] .bs-handle.bs-handle--ticks::after,.bs-sheet[data-mode="right"] .bs-handle.bs-handle--ticks::after{left:50%;top:50%;bottom:auto;transform:translate(-50%,-50%);width:3px;height:calc(var(--bs-handle-width) * 2);background-size:3px 8px;background-repeat:repeat-y;margin-left:calc(var(--bs-handle-height) + 6px)}.bs-sheet[data-mode="right"] .bs-handle.bs-handle--ticks::after{margin-left:calc(-1 * (var(--bs-handle-height) + 6px))}.bs-header{flex:0 0 auto;min-height:var(--bs-header-min-height,0px);padding:var(--bs-header-padding,0 16px 8px);background:var(--bs-surface,var(--bs-surface-d))}.bs-content{flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;overscroll-behavior:contain;user-select:text;padding:var(--bs-content-padding,0 16px 16px)}.bs-sheet[data-bs-fit-content] .bs-content{scroll-padding-bottom:var(--bs-content-inset,0px)}.bs-sheet[data-bs-fit-content] .bs-content::after{content:"";display:block;flex:none;height:var(--bs-content-inset,0px)}.bs-footer{flex:0 0 auto;padding:var(--bs-footer-padding,12px 16px calc(12px + env(safe-area-inset-bottom)));border-top:1px solid var(--bs-surface-border,var(--bs-surface-border-d));background:var(--bs-surface,var(--bs-surface-d))}.bs-sheet[data-mode="bottom"]:has(.bs-footer:not([hidden]):has(*)){padding-bottom:0}.bs-header:not(:has(*)),.bs-footer:not(:has(*)),.bs-header[hidden],.bs-footer[hidden]{display:none}.bs-screen{position:absolute;inset:0;pointer-events:none;z-index:var(--bs-z-scrim);background:var(--bs-scrim-color,var(--bs-scrim-color-d));backdrop-filter:blur(var(--bs-scrim-blur,0px));-webkit-backdrop-filter:blur(var(--bs-scrim-blur,0px));transition:opacity 0.24s cubic-bezier(0.22,1,0.36,1);will-change:opacity}.bs-root[data-dragging="true"] .bs-screen,.bs-root[data-animating="true"] .bs-screen{transition:none}.bs-scrim-overlay{z-index:calc(var(--bs-z-sheet) + 1);pointer-events:none}.bs-button-slot{position:fixed;z-index:calc(var(--bs-z-sheet) + 1);pointer-events:auto}.bs-button-slot[data-side="left"]{left:16px;bottom:calc(var(--bs-size,0px) + 12px)}.bs-button-slot[data-side="right"]{right:16px;bottom:calc(var(--bs-size,0px) + 12px)}.bs-button-slot[data-mode="top"]{bottom:auto;top:calc(var(--bs-size,0px) + 12px)}.bs-button-slot[data-mode="left"]{left:calc(var(--bs-size,0px) + 12px);right:auto;bottom:auto;top:16px}.bs-button-slot[data-mode="right"]{right:calc(var(--bs-size,0px) + 12px);left:auto;bottom:auto;top:16px}@media (prefers-reduced-motion:reduce){.bs-backdrop,.bs-handle::before,.bs-button-slot[data-side="left"],.bs-button-slot[data-side="right"]{transition:none !important}}@media (prefers-color-scheme:dark){:where(.bs-root){--bs-surface-d:#1a1a1d;--bs-surface-border-d:rgba(255,255,255,0.08);--bs-handle-color-d:rgba(255,255,255,0.45);--bs-shadow-auto:0 -3px 16px rgba(0,0,0,0.5)}}@media (forced-colors:active){.bs-sheet{border:1px solid CanvasText}.bs-handle::before{background:CanvasText;forced-color-adjust:none}.bs-backdrop,.bs-screen{forced-color-adjust:none}}.bs-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}:where(.ovl-root){--ovl-surface:var(--bs-surface,var(--bs-surface-d,#ffffff));--ovl-surface-border:var(--bs-surface-border,var(--bs-surface-border-d,rgba(0,0,0,0.08)));--ovl-shadow:0 -8px 40px rgba(0,0,0,0.35);--ovl-radius:var(--bs-radius,var(--bs-radius-d,20px));--ovl-backdrop-color:rgba(0,0,0,0.5);--ovl-z-backdrop:200;--ovl-z-panel:201}.ovl-backdrop{position:fixed;inset:0;background:var(--ovl-backdrop-color);opacity:0;pointer-events:none;z-index:var(--ovl-z-backdrop)}.ovl-panel{position:fixed;background:var(--ovl-surface);box-shadow:var(--ovl-shadow);z-index:var(--ovl-z-panel);-webkit-tap-highlight-color:transparent;outline:none;transition:transform 0.32s cubic-bezier(0.29,1.24,0.84,0.99),opacity 0.32s ease-out}.ovl-panel[data-state="open"]{transform:translate3d(0,0,0);opacity:1}@starting-style{.ovl-panel[data-edge="bottom"][data-state="open"]{transform:translate3d(0,100%,0);opacity:0}.ovl-panel[data-edge="top"][data-state="open"]{transform:translate3d(0,-100%,0);opacity:0}.ovl-panel[data-edge="left"][data-state="open"]{transform:translate3d(-100%,0,0);opacity:0}.ovl-panel[data-edge="right"][data-state="open"]{transform:translate3d(100%,0,0);opacity:0}}.ovl-panel[data-edge="bottom"]{left:0;right:0;bottom:0;width:100%;border-top-left-radius:var(--ovl-radius);border-top-right-radius:var(--ovl-radius);border-top:1px solid var(--ovl-surface-border);padding-bottom:env(safe-area-inset-bottom)}.ovl-panel[data-edge="top"]{left:0;right:0;top:0;width:100%;border-bottom-left-radius:var(--ovl-radius);border-bottom-right-radius:var(--ovl-radius);border-bottom:1px solid var(--ovl-surface-border);padding-top:env(safe-area-inset-top)}.ovl-panel[data-edge="left"]{top:0;bottom:0;left:0;height:100%;border-top-right-radius:var(--ovl-radius);border-bottom-right-radius:var(--ovl-radius);border-right:1px solid var(--ovl-surface-border)}.ovl-panel[data-edge="right"]{top:0;bottom:0;right:0;height:100%;border-top-left-radius:var(--ovl-radius);border-bottom-left-radius:var(--ovl-radius);border-left:1px solid var(--ovl-surface-border)}@media (prefers-reduced-motion:reduce){.ovl-panel,.ovl-backdrop{transition:none !important}}`;
4573
4661
  }
4574
4662
  });
4575
4663
 
@@ -4666,7 +4754,7 @@ var init_shadow_tree = __esm({
4666
4754
  });
4667
4755
 
4668
4756
  // src/web-component/attributes.ts
4669
- var ATTR_SNAP_POINTS, ATTR_ALLOWED, ATTR_INITIAL, ATTR_MODE, ATTR_BACKDROP, ATTR_STYLESHEET, ATTR_ANIMATION, ATTR_FOCUS_TRAP, ATTR_CLOSE_ON_ESCAPE, ATTR_LOCK_BODY_SCROLL, ATTR_SHEET_LABEL, ATTR_STACK_EFFECT, ATTR_PERSISTENT, ATTR_DISABLE_CLOSE, ATTR_DISABLE_DRAG, ATTR_DRAG_FROM, ATTR_DRAG_FROM_CONTENT, ATTR_CLOSE_ON_ROUTE_CHANGE, ATTR_RADIUS, ATTR_MAX_HEIGHT, ATTR_RETURN_FOCUS_TO, ATTR_BACKDROP_COLOR, ATTR_SCRIM_COLOR, ATTR_SNAP, LIVE_ATTRS, OBSERVED_ATTRS, isValidSnapPoint, DEFAULT_SNAP_POINTS, parseSnapPoints, VALID_MODES, VALID_ANIMATIONS, parseMode, parseAnimation, VALID_DRAG_FROM, parseDragFrom, parseList, parseDimension, ANCHOR_POSITIONS, ANCHOR_ANIMATIONS, parseAnchorOptions;
4757
+ var ATTR_SNAP_POINTS, ATTR_ALLOWED, ATTR_INITIAL, ATTR_MODE, ATTR_BACKDROP, ATTR_STYLESHEET, ATTR_ANIMATION, ATTR_FOCUS_TRAP, ATTR_CLOSE_ON_ESCAPE, ATTR_LOCK_BODY_SCROLL, ATTR_SHEET_LABEL, ATTR_STACK_EFFECT, ATTR_PERSISTENT, ATTR_DISABLE_CLOSE, ATTR_DISABLE_DRAG, ATTR_DRAG_FROM, ATTR_DRAG_FROM_CONTENT, ATTR_FIT_CONTENT_TO_SNAP, ATTR_CLOSE_ON_ROUTE_CHANGE, ATTR_RADIUS, ATTR_MAX_HEIGHT, ATTR_RETURN_FOCUS_TO, ATTR_BACKDROP_COLOR, ATTR_SCRIM_COLOR, ATTR_SNAP, LIVE_ATTRS, OBSERVED_ATTRS, isValidSnapPoint, DEFAULT_SNAP_POINTS, parseSnapPoints, VALID_MODES, VALID_ANIMATIONS, parseMode, parseAnimation, VALID_DRAG_FROM, parseDragFrom, parseList, parseDimension, ANCHOR_POSITIONS, ANCHOR_ANIMATIONS, parseAnchorOptions;
4670
4758
  var init_attributes = __esm({
4671
4759
  "src/web-component/attributes.ts"() {
4672
4760
  ATTR_SNAP_POINTS = "snap-points";
@@ -4686,6 +4774,7 @@ var init_attributes = __esm({
4686
4774
  ATTR_DISABLE_DRAG = "disable-drag";
4687
4775
  ATTR_DRAG_FROM = "drag-from";
4688
4776
  ATTR_DRAG_FROM_CONTENT = "drag-from-content";
4777
+ ATTR_FIT_CONTENT_TO_SNAP = "fit-content-to-snap";
4689
4778
  ATTR_CLOSE_ON_ROUTE_CHANGE = "close-on-route-change";
4690
4779
  ATTR_RADIUS = "radius";
4691
4780
  ATTR_MAX_HEIGHT = "max-height";
@@ -4723,6 +4812,7 @@ var init_attributes = __esm({
4723
4812
  ATTR_DISABLE_DRAG,
4724
4813
  ATTR_DRAG_FROM,
4725
4814
  ATTR_DRAG_FROM_CONTENT,
4815
+ ATTR_FIT_CONTENT_TO_SNAP,
4726
4816
  ATTR_CLOSE_ON_ROUTE_CHANGE,
4727
4817
  ATTR_RADIUS,
4728
4818
  ATTR_MAX_HEIGHT,
@@ -4996,6 +5086,7 @@ var init_BottomSheetElement = __esm({
4996
5086
  disableDrag: this.getAttribute(ATTR_DISABLE_DRAG) === "true",
4997
5087
  dragFrom: parseDragFrom(this.getAttribute(ATTR_DRAG_FROM)),
4998
5088
  dragFromContent: this.getAttribute(ATTR_DRAG_FROM_CONTENT) === null ? void 0 : this.getAttribute(ATTR_DRAG_FROM_CONTENT) !== "false",
5089
+ fitContentToSnap: this.hasAttribute(ATTR_FIT_CONTENT_TO_SNAP) && this.getAttribute(ATTR_FIT_CONTENT_TO_SNAP) !== "false",
4999
5090
  closeOnRouteChange: this.getAttribute(ATTR_CLOSE_ON_ROUTE_CHANGE) === "true",
5000
5091
  radius: parseDimension(this.getAttribute(ATTR_RADIUS)),
5001
5092
  maxHeight: parseDimension(this.getAttribute(ATTR_MAX_HEIGHT)),
package/dist/features.cjs CHANGED
@@ -468,6 +468,68 @@ function visualViewportFeature() {
468
468
  };
469
469
  }
470
470
 
471
+ // src/core/features/content-fit.ts
472
+ var INSET_VAR = "--bs-content-inset";
473
+ var FIT_ATTR = "data-bs-fit-content";
474
+ function contentFitFeature() {
475
+ return {
476
+ name: "content-fit",
477
+ install: (ctx) => {
478
+ const scroller = ctx.scrollContainer;
479
+ if (!ctx.options.fitContentToSnap || !scroller || typeof window === "undefined") {
480
+ return;
481
+ }
482
+ const sheet = ctx.element;
483
+ let inset = 0;
484
+ let unpaddedMax = -1;
485
+ let top = 0;
486
+ const hiddenAt = (size) => sheet.dataset.mode === "bottom" ? Math.max(0, ctx.getMaxAxisSize() - size) : 0;
487
+ const follow = (size) => {
488
+ if (unpaddedMax < 0) {
489
+ unpaddedMax = scroller.scrollHeight - scroller.clientHeight - inset;
490
+ top = scroller.scrollTop;
491
+ }
492
+ const limit = Math.max(0, unpaddedMax + hiddenAt(size));
493
+ if (top > limit) {
494
+ if (scroller.scrollTop > limit) scroller.scrollTop = limit;
495
+ top = limit;
496
+ }
497
+ };
498
+ const settle = () => {
499
+ if (ctx.isDestroyed()) return;
500
+ const size = ctx.getSize();
501
+ unpaddedMax = -1;
502
+ follow(size);
503
+ inset = hiddenAt(size);
504
+ sheet.style.setProperty(INSET_VAR, `${inset}px`);
505
+ unpaddedMax = -1;
506
+ };
507
+ const moving = () => ctx.isAnimating() || ctx.isDragging();
508
+ const whenIdle = () => {
509
+ if (!moving()) settle();
510
+ };
511
+ sheet.setAttribute(FIT_ATTR, "");
512
+ settle();
513
+ const offProgress = ctx.on(
514
+ "progress",
515
+ (p) => moving() ? follow(p.size) : settle()
516
+ );
517
+ const offSnap = ctx.on("snap", settle);
518
+ const observer = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(whenIdle);
519
+ observer?.observe(document.documentElement);
520
+ window.addEventListener("orientationchange", whenIdle);
521
+ return () => {
522
+ offProgress();
523
+ offSnap();
524
+ observer?.disconnect();
525
+ window.removeEventListener("orientationchange", whenIdle);
526
+ sheet.removeAttribute(FIT_ATTR);
527
+ sheet.style.removeProperty(INSET_VAR);
528
+ };
529
+ }
530
+ };
531
+ }
532
+
471
533
  // src/core/default-features.ts
472
534
  function defaultEngineFeatures() {
473
535
  return [
@@ -475,11 +537,13 @@ function defaultEngineFeatures() {
475
537
  visualViewportFeature(),
476
538
  persistFeature(),
477
539
  autoCollapseFeature(),
478
- routeFeature()
540
+ routeFeature(),
541
+ contentFitFeature()
479
542
  ];
480
543
  }
481
544
 
482
545
  exports.autoCollapseFeature = autoCollapseFeature;
546
+ exports.contentFitFeature = contentFitFeature;
483
547
  exports.contentSwipeFeature = contentSwipeFeature;
484
548
  exports.defaultEngineFeatures = defaultEngineFeatures;
485
549
  exports.persistFeature = persistFeature;
@@ -1,13 +1,8 @@
1
- import { f as EngineFeature } from './BottomSheetCore-BHv6LPmS.cjs';
2
- export { m as EngineFeatureContext, n as EngineFeatureOptions, o as EngineFeatureStage } from './BottomSheetCore-BHv6LPmS.cjs';
1
+ export { a as autoCollapseFeature, c as contentSwipeFeature, d as defaultEngineFeatures, p as persistFeature, r as routeFeature, v as visualViewportFeature } from './default-features-DkG9aho0.cjs';
2
+ import { E as EngineFeature } from './BottomSheetCore-CQStdVy2.cjs';
3
+ export { a as EngineFeatureContext, b as EngineFeatureOptions, c as EngineFeatureStage } from './BottomSheetCore-CQStdVy2.cjs';
3
4
  import './transform-jVfAikE9.cjs';
4
5
 
5
- declare function routeFeature(): EngineFeature;
6
- declare function persistFeature(): EngineFeature;
7
- declare function autoCollapseFeature(): EngineFeature;
8
- declare function contentSwipeFeature(): EngineFeature;
9
- declare function visualViewportFeature(): EngineFeature;
6
+ declare function contentFitFeature(): EngineFeature;
10
7
 
11
- declare function defaultEngineFeatures(): EngineFeature[];
12
-
13
- export { EngineFeature, autoCollapseFeature, contentSwipeFeature, defaultEngineFeatures, persistFeature, routeFeature, visualViewportFeature };
8
+ export { EngineFeature, contentFitFeature };
@@ -1,13 +1,8 @@
1
- import { f as EngineFeature } from './BottomSheetCore-CK_mq14p.js';
2
- export { m as EngineFeatureContext, n as EngineFeatureOptions, o as EngineFeatureStage } from './BottomSheetCore-CK_mq14p.js';
1
+ export { a as autoCollapseFeature, c as contentSwipeFeature, d as defaultEngineFeatures, p as persistFeature, r as routeFeature, v as visualViewportFeature } from './default-features-C3cilcW9.js';
2
+ import { E as EngineFeature } from './BottomSheetCore-9i-Uh6T3.js';
3
+ export { a as EngineFeatureContext, b as EngineFeatureOptions, c as EngineFeatureStage } from './BottomSheetCore-9i-Uh6T3.js';
3
4
  import './transform-jVfAikE9.js';
4
5
 
5
- declare function routeFeature(): EngineFeature;
6
- declare function persistFeature(): EngineFeature;
7
- declare function autoCollapseFeature(): EngineFeature;
8
- declare function contentSwipeFeature(): EngineFeature;
9
- declare function visualViewportFeature(): EngineFeature;
6
+ declare function contentFitFeature(): EngineFeature;
10
7
 
11
- declare function defaultEngineFeatures(): EngineFeature[];
12
-
13
- export { EngineFeature, autoCollapseFeature, contentSwipeFeature, defaultEngineFeatures, persistFeature, routeFeature, visualViewportFeature };
8
+ export { EngineFeature, contentFitFeature };
package/dist/features.js CHANGED
@@ -466,6 +466,68 @@ function visualViewportFeature() {
466
466
  };
467
467
  }
468
468
 
469
+ // src/core/features/content-fit.ts
470
+ var INSET_VAR = "--bs-content-inset";
471
+ var FIT_ATTR = "data-bs-fit-content";
472
+ function contentFitFeature() {
473
+ return {
474
+ name: "content-fit",
475
+ install: (ctx) => {
476
+ const scroller = ctx.scrollContainer;
477
+ if (!ctx.options.fitContentToSnap || !scroller || typeof window === "undefined") {
478
+ return;
479
+ }
480
+ const sheet = ctx.element;
481
+ let inset = 0;
482
+ let unpaddedMax = -1;
483
+ let top = 0;
484
+ const hiddenAt = (size) => sheet.dataset.mode === "bottom" ? Math.max(0, ctx.getMaxAxisSize() - size) : 0;
485
+ const follow = (size) => {
486
+ if (unpaddedMax < 0) {
487
+ unpaddedMax = scroller.scrollHeight - scroller.clientHeight - inset;
488
+ top = scroller.scrollTop;
489
+ }
490
+ const limit = Math.max(0, unpaddedMax + hiddenAt(size));
491
+ if (top > limit) {
492
+ if (scroller.scrollTop > limit) scroller.scrollTop = limit;
493
+ top = limit;
494
+ }
495
+ };
496
+ const settle = () => {
497
+ if (ctx.isDestroyed()) return;
498
+ const size = ctx.getSize();
499
+ unpaddedMax = -1;
500
+ follow(size);
501
+ inset = hiddenAt(size);
502
+ sheet.style.setProperty(INSET_VAR, `${inset}px`);
503
+ unpaddedMax = -1;
504
+ };
505
+ const moving = () => ctx.isAnimating() || ctx.isDragging();
506
+ const whenIdle = () => {
507
+ if (!moving()) settle();
508
+ };
509
+ sheet.setAttribute(FIT_ATTR, "");
510
+ settle();
511
+ const offProgress = ctx.on(
512
+ "progress",
513
+ (p) => moving() ? follow(p.size) : settle()
514
+ );
515
+ const offSnap = ctx.on("snap", settle);
516
+ const observer = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(whenIdle);
517
+ observer?.observe(document.documentElement);
518
+ window.addEventListener("orientationchange", whenIdle);
519
+ return () => {
520
+ offProgress();
521
+ offSnap();
522
+ observer?.disconnect();
523
+ window.removeEventListener("orientationchange", whenIdle);
524
+ sheet.removeAttribute(FIT_ATTR);
525
+ sheet.style.removeProperty(INSET_VAR);
526
+ };
527
+ }
528
+ };
529
+ }
530
+
469
531
  // src/core/default-features.ts
470
532
  function defaultEngineFeatures() {
471
533
  return [
@@ -473,10 +535,11 @@ function defaultEngineFeatures() {
473
535
  visualViewportFeature(),
474
536
  persistFeature(),
475
537
  autoCollapseFeature(),
476
- routeFeature()
538
+ routeFeature(),
539
+ contentFitFeature()
477
540
  ];
478
541
  }
479
542
 
480
- export { autoCollapseFeature, contentSwipeFeature, defaultEngineFeatures, persistFeature, routeFeature, visualViewportFeature };
543
+ export { autoCollapseFeature, contentFitFeature, contentSwipeFeature, defaultEngineFeatures, persistFeature, routeFeature, visualViewportFeature };
481
544
  //# sourceMappingURL=features.js.map
482
545
  //# sourceMappingURL=features.js.map
@@ -1,4 +1,4 @@
1
- import { a as SnapPointDef, b as SheetMode } from './BottomSheetCore-BHv6LPmS.cjs';
1
+ import { e as SnapPointDef, f as SheetMode } from './BottomSheetCore-CQStdVy2.cjs';
2
2
 
3
3
  type ResolvedSnap = {
4
4
  id: string;
@@ -1,4 +1,4 @@
1
- import { a as SnapPointDef, b as SheetMode } from './BottomSheetCore-CK_mq14p.js';
1
+ import { e as SnapPointDef, f as SheetMode } from './BottomSheetCore-9i-Uh6T3.js';
2
2
 
3
3
  type ResolvedSnap = {
4
4
  id: string;
package/dist/index.cjs CHANGED
@@ -375,14 +375,26 @@ function notifyLinkedSheets(sheets, self) {
375
375
  }
376
376
  }
377
377
 
378
+ // src/core/primitives/hot-path-thresholds.ts
379
+ var SIZE_WRITE_EPSILON = 0.5;
380
+ var OPACITY_WRITE_EPSILON = 5e-3;
381
+ var POINTER_EVENTS_OPACITY_THRESHOLD = 0.05;
382
+ var RANGE_DIVISION_EPSILON = 1e-4;
383
+
378
384
  // src/core/features/resize-observer.ts
379
385
  function installResizeObserver(deps) {
380
386
  if (typeof window === "undefined") {
381
387
  return () => {
382
388
  };
383
389
  }
390
+ const seatFor = () => {
391
+ const snap = deps.resolveActiveSnap();
392
+ const max = deps.getMaxAxisSize();
393
+ return { target: snap ? Math.min(snap.size, max) : null, max };
394
+ };
384
395
  const onResize = () => {
385
396
  if (deps.isDestroyed()) return;
397
+ const before = seatFor();
386
398
  deps.recomputeSnaps();
387
399
  const mode = deps.getMode();
388
400
  const isVerticalAxis = mode === "bottom" || mode === "top";
@@ -391,6 +403,10 @@ function installResizeObserver(deps) {
391
403
  if (viewportSize2 > 0 && viewportSize2 < max) {
392
404
  deps.setMaxAxisSize(viewportSize2);
393
405
  }
406
+ const after = seatFor();
407
+ 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) {
408
+ return;
409
+ }
394
410
  const wasAnimating = deps.isAnimating?.() ?? false;
395
411
  deps.cancelInFlight();
396
412
  deps.newCycle();
@@ -659,12 +675,6 @@ var SCRIM_PRESETS = Object.freeze({
659
675
  }
660
676
  });
661
677
 
662
- // src/core/primitives/hot-path-thresholds.ts
663
- var SIZE_WRITE_EPSILON = 0.5;
664
- var OPACITY_WRITE_EPSILON = 5e-3;
665
- var POINTER_EVENTS_OPACITY_THRESHOLD = 0.05;
666
- var RANGE_DIVISION_EPSILON = 1e-4;
667
-
668
678
  // src/core/primitives/opacity-dedup.ts
669
679
  var WriteSentinel = class {
670
680
  constructor() {
@@ -2594,6 +2604,7 @@ var BottomSheetCore = class {
2594
2604
  __publicField(this, "lifecycle");
2595
2605
  __publicField(this, "closeOnBack");
2596
2606
  __publicField(this, "routedTo");
2607
+ __publicField(this, "fitContentToSnap");
2597
2608
  __publicField(this, "persistent");
2598
2609
  __publicField(this, "disableCloseFlag");
2599
2610
  __publicField(this, "disableDragFlag");
@@ -2707,6 +2718,7 @@ var BottomSheetCore = class {
2707
2718
  );
2708
2719
  this.closeOnBack = resolved.closeOnBack;
2709
2720
  this.routedTo = opts.routedTo;
2721
+ this.fitContentToSnap = opts.fitContentToSnap === true;
2710
2722
  this.persistent = resolved.persistent;
2711
2723
  this.disableCloseFlag = resolved.disableClose;
2712
2724
  this.disableDragFlag = resolved.disableDrag;
@@ -2808,7 +2820,8 @@ var BottomSheetCore = class {
2808
2820
  closeOnBack: this.closeOnBack,
2809
2821
  closeOnRouteChange: this.closeOnRouteChange,
2810
2822
  persistKey: this.persistKey,
2811
- autoCollapseAfter
2823
+ autoCollapseAfter,
2824
+ fitContentToSnap: this.fitContentToSnap
2812
2825
  },
2813
2826
  isDestroyed: () => this.destroyed,
2814
2827
  isDragging: () => this.isDraggingAny(),
@@ -2860,6 +2873,11 @@ var BottomSheetCore = class {
2860
2873
  "[BottomSheet] closeOnBack/routedTo/closeOnRouteChange need routeFeature() \u2014 option ignored"
2861
2874
  );
2862
2875
  }
2876
+ if (this.fitContentToSnap && !names.has("content-fit")) {
2877
+ devWarn(
2878
+ "[BottomSheet] fitContentToSnap needs contentFitFeature() \u2014 option ignored"
2879
+ );
2880
+ }
2863
2881
  if (this.persistKey && !names.has("persist")) {
2864
2882
  devWarn(
2865
2883
  "[BottomSheet] persistKey needs persistFeature() \u2014 snaps will not be saved"
@@ -4217,6 +4235,68 @@ function visualViewportFeature() {
4217
4235
  };
4218
4236
  }
4219
4237
 
4238
+ // src/core/features/content-fit.ts
4239
+ var INSET_VAR = "--bs-content-inset";
4240
+ var FIT_ATTR = "data-bs-fit-content";
4241
+ function contentFitFeature() {
4242
+ return {
4243
+ name: "content-fit",
4244
+ install: (ctx) => {
4245
+ const scroller = ctx.scrollContainer;
4246
+ if (!ctx.options.fitContentToSnap || !scroller || typeof window === "undefined") {
4247
+ return;
4248
+ }
4249
+ const sheet = ctx.element;
4250
+ let inset = 0;
4251
+ let unpaddedMax = -1;
4252
+ let top = 0;
4253
+ const hiddenAt = (size) => sheet.dataset.mode === "bottom" ? Math.max(0, ctx.getMaxAxisSize() - size) : 0;
4254
+ const follow = (size) => {
4255
+ if (unpaddedMax < 0) {
4256
+ unpaddedMax = scroller.scrollHeight - scroller.clientHeight - inset;
4257
+ top = scroller.scrollTop;
4258
+ }
4259
+ const limit = Math.max(0, unpaddedMax + hiddenAt(size));
4260
+ if (top > limit) {
4261
+ if (scroller.scrollTop > limit) scroller.scrollTop = limit;
4262
+ top = limit;
4263
+ }
4264
+ };
4265
+ const settle = () => {
4266
+ if (ctx.isDestroyed()) return;
4267
+ const size = ctx.getSize();
4268
+ unpaddedMax = -1;
4269
+ follow(size);
4270
+ inset = hiddenAt(size);
4271
+ sheet.style.setProperty(INSET_VAR, `${inset}px`);
4272
+ unpaddedMax = -1;
4273
+ };
4274
+ const moving = () => ctx.isAnimating() || ctx.isDragging();
4275
+ const whenIdle = () => {
4276
+ if (!moving()) settle();
4277
+ };
4278
+ sheet.setAttribute(FIT_ATTR, "");
4279
+ settle();
4280
+ const offProgress = ctx.on(
4281
+ "progress",
4282
+ (p) => moving() ? follow(p.size) : settle()
4283
+ );
4284
+ const offSnap = ctx.on("snap", settle);
4285
+ const observer = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(whenIdle);
4286
+ observer?.observe(document.documentElement);
4287
+ window.addEventListener("orientationchange", whenIdle);
4288
+ return () => {
4289
+ offProgress();
4290
+ offSnap();
4291
+ observer?.disconnect();
4292
+ window.removeEventListener("orientationchange", whenIdle);
4293
+ sheet.removeAttribute(FIT_ATTR);
4294
+ sheet.style.removeProperty(INSET_VAR);
4295
+ };
4296
+ }
4297
+ };
4298
+ }
4299
+
4220
4300
  // src/core/default-features.ts
4221
4301
  function defaultEngineFeatures() {
4222
4302
  return [
@@ -4224,7 +4304,8 @@ function defaultEngineFeatures() {
4224
4304
  visualViewportFeature(),
4225
4305
  persistFeature(),
4226
4306
  autoCollapseFeature(),
4227
- routeFeature()
4307
+ routeFeature(),
4308
+ contentFitFeature()
4228
4309
  ];
4229
4310
  }
4230
4311