@surdeddd/bottom-sheet 0.21.2 → 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 +9 -1
  7. package/dist/core.d.cts +2 -2
  8. package/dist/core.d.ts +2 -2
  9. package/dist/core.js +9 -1
  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 +84 -4
  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 +84 -4
  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 +73 -2
  26. package/dist/index.d.cts +5 -5
  27. package/dist/index.d.ts +5 -5
  28. package/dist/index.js +73 -2
  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 +67 -2
  36. package/dist/qwik-lib/index.qwik.mjs +67 -2
  37. package/dist/qwik.cjs +74 -2
  38. package/dist/qwik.d.cts +3 -2
  39. package/dist/qwik.d.ts +3 -2
  40. package/dist/qwik.js +74 -2
  41. package/dist/react.cjs +73 -2
  42. package/dist/react.d.cts +3 -3
  43. package/dist/react.d.ts +3 -3
  44. package/dist/react.js +73 -2
  45. package/dist/solid.cjs +74 -2
  46. package/dist/solid.d.cts +4 -0
  47. package/dist/solid.d.ts +4 -0
  48. package/dist/solid.js +74 -2
  49. package/dist/solid.source.jsx +74 -2
  50. package/dist/styles.css +11 -0
  51. package/dist/svelte-core.cjs +73 -2
  52. package/dist/svelte-core.js +73 -2
  53. package/dist/svelte-src/BottomSheet.svelte +3 -0
  54. package/dist/svelte.cjs +74 -2
  55. package/dist/svelte.d.cts +1 -0
  56. package/dist/svelte.d.ts +1 -0
  57. package/dist/svelte.js +74 -2
  58. package/dist/vue.cjs +77 -2
  59. package/dist/vue.js +77 -2
  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
@@ -2881,6 +2881,7 @@ var init_BottomSheetCore = __esm({
2881
2881
  __publicField(this, "lifecycle");
2882
2882
  __publicField(this, "closeOnBack");
2883
2883
  __publicField(this, "routedTo");
2884
+ __publicField(this, "fitContentToSnap");
2884
2885
  __publicField(this, "persistent");
2885
2886
  __publicField(this, "disableCloseFlag");
2886
2887
  __publicField(this, "disableDragFlag");
@@ -2994,6 +2995,7 @@ var init_BottomSheetCore = __esm({
2994
2995
  );
2995
2996
  this.closeOnBack = resolved.closeOnBack;
2996
2997
  this.routedTo = opts.routedTo;
2998
+ this.fitContentToSnap = opts.fitContentToSnap === true;
2997
2999
  this.persistent = resolved.persistent;
2998
3000
  this.disableCloseFlag = resolved.disableClose;
2999
3001
  this.disableDragFlag = resolved.disableDrag;
@@ -3095,7 +3097,8 @@ var init_BottomSheetCore = __esm({
3095
3097
  closeOnBack: this.closeOnBack,
3096
3098
  closeOnRouteChange: this.closeOnRouteChange,
3097
3099
  persistKey: this.persistKey,
3098
- autoCollapseAfter
3100
+ autoCollapseAfter,
3101
+ fitContentToSnap: this.fitContentToSnap
3099
3102
  },
3100
3103
  isDestroyed: () => this.destroyed,
3101
3104
  isDragging: () => this.isDraggingAny(),
@@ -3147,6 +3150,11 @@ var init_BottomSheetCore = __esm({
3147
3150
  "[BottomSheet] closeOnBack/routedTo/closeOnRouteChange need routeFeature() \u2014 option ignored"
3148
3151
  );
3149
3152
  }
3153
+ if (this.fitContentToSnap && !names.has("content-fit")) {
3154
+ devWarn(
3155
+ "[BottomSheet] fitContentToSnap needs contentFitFeature() \u2014 option ignored"
3156
+ );
3157
+ }
3150
3158
  if (this.persistKey && !names.has("persist")) {
3151
3159
  devWarn(
3152
3160
  "[BottomSheet] persistKey needs persistFeature() \u2014 snaps will not be saved"
@@ -4543,6 +4551,73 @@ var init_engine_features = __esm({
4543
4551
  }
4544
4552
  });
4545
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
+
4546
4621
  // src/core/default-features.ts
4547
4622
  function defaultEngineFeatures() {
4548
4623
  return [
@@ -4550,12 +4625,14 @@ function defaultEngineFeatures() {
4550
4625
  visualViewportFeature(),
4551
4626
  persistFeature(),
4552
4627
  autoCollapseFeature(),
4553
- routeFeature()
4628
+ routeFeature(),
4629
+ contentFitFeature()
4554
4630
  ];
4555
4631
  }
4556
4632
  var init_default_features = __esm({
4557
4633
  "src/core/default-features.ts"() {
4558
4634
  init_engine_features();
4635
+ init_content_fit();
4559
4636
  }
4560
4637
  });
4561
4638
 
@@ -4580,7 +4657,7 @@ var init_BottomSheetEngine = __esm({
4580
4657
  var baseStyles;
4581
4658
  var init_baseStyles = __esm({
4582
4659
  "src/web-component/baseStyles.ts"() {
4583
- 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}}`;
4584
4661
  }
4585
4662
  });
4586
4663
 
@@ -4677,7 +4754,7 @@ var init_shadow_tree = __esm({
4677
4754
  });
4678
4755
 
4679
4756
  // src/web-component/attributes.ts
4680
- 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;
4681
4758
  var init_attributes = __esm({
4682
4759
  "src/web-component/attributes.ts"() {
4683
4760
  ATTR_SNAP_POINTS = "snap-points";
@@ -4697,6 +4774,7 @@ var init_attributes = __esm({
4697
4774
  ATTR_DISABLE_DRAG = "disable-drag";
4698
4775
  ATTR_DRAG_FROM = "drag-from";
4699
4776
  ATTR_DRAG_FROM_CONTENT = "drag-from-content";
4777
+ ATTR_FIT_CONTENT_TO_SNAP = "fit-content-to-snap";
4700
4778
  ATTR_CLOSE_ON_ROUTE_CHANGE = "close-on-route-change";
4701
4779
  ATTR_RADIUS = "radius";
4702
4780
  ATTR_MAX_HEIGHT = "max-height";
@@ -4734,6 +4812,7 @@ var init_attributes = __esm({
4734
4812
  ATTR_DISABLE_DRAG,
4735
4813
  ATTR_DRAG_FROM,
4736
4814
  ATTR_DRAG_FROM_CONTENT,
4815
+ ATTR_FIT_CONTENT_TO_SNAP,
4737
4816
  ATTR_CLOSE_ON_ROUTE_CHANGE,
4738
4817
  ATTR_RADIUS,
4739
4818
  ATTR_MAX_HEIGHT,
@@ -5007,6 +5086,7 @@ var init_BottomSheetElement = __esm({
5007
5086
  disableDrag: this.getAttribute(ATTR_DISABLE_DRAG) === "true",
5008
5087
  dragFrom: parseDragFrom(this.getAttribute(ATTR_DRAG_FROM)),
5009
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",
5010
5090
  closeOnRouteChange: this.getAttribute(ATTR_CLOSE_ON_ROUTE_CHANGE) === "true",
5011
5091
  radius: parseDimension(this.getAttribute(ATTR_RADIUS)),
5012
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
@@ -2604,6 +2604,7 @@ var BottomSheetCore = class {
2604
2604
  __publicField(this, "lifecycle");
2605
2605
  __publicField(this, "closeOnBack");
2606
2606
  __publicField(this, "routedTo");
2607
+ __publicField(this, "fitContentToSnap");
2607
2608
  __publicField(this, "persistent");
2608
2609
  __publicField(this, "disableCloseFlag");
2609
2610
  __publicField(this, "disableDragFlag");
@@ -2717,6 +2718,7 @@ var BottomSheetCore = class {
2717
2718
  );
2718
2719
  this.closeOnBack = resolved.closeOnBack;
2719
2720
  this.routedTo = opts.routedTo;
2721
+ this.fitContentToSnap = opts.fitContentToSnap === true;
2720
2722
  this.persistent = resolved.persistent;
2721
2723
  this.disableCloseFlag = resolved.disableClose;
2722
2724
  this.disableDragFlag = resolved.disableDrag;
@@ -2818,7 +2820,8 @@ var BottomSheetCore = class {
2818
2820
  closeOnBack: this.closeOnBack,
2819
2821
  closeOnRouteChange: this.closeOnRouteChange,
2820
2822
  persistKey: this.persistKey,
2821
- autoCollapseAfter
2823
+ autoCollapseAfter,
2824
+ fitContentToSnap: this.fitContentToSnap
2822
2825
  },
2823
2826
  isDestroyed: () => this.destroyed,
2824
2827
  isDragging: () => this.isDraggingAny(),
@@ -2870,6 +2873,11 @@ var BottomSheetCore = class {
2870
2873
  "[BottomSheet] closeOnBack/routedTo/closeOnRouteChange need routeFeature() \u2014 option ignored"
2871
2874
  );
2872
2875
  }
2876
+ if (this.fitContentToSnap && !names.has("content-fit")) {
2877
+ devWarn(
2878
+ "[BottomSheet] fitContentToSnap needs contentFitFeature() \u2014 option ignored"
2879
+ );
2880
+ }
2873
2881
  if (this.persistKey && !names.has("persist")) {
2874
2882
  devWarn(
2875
2883
  "[BottomSheet] persistKey needs persistFeature() \u2014 snaps will not be saved"
@@ -4227,6 +4235,68 @@ function visualViewportFeature() {
4227
4235
  };
4228
4236
  }
4229
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
+
4230
4300
  // src/core/default-features.ts
4231
4301
  function defaultEngineFeatures() {
4232
4302
  return [
@@ -4234,7 +4304,8 @@ function defaultEngineFeatures() {
4234
4304
  visualViewportFeature(),
4235
4305
  persistFeature(),
4236
4306
  autoCollapseFeature(),
4237
- routeFeature()
4307
+ routeFeature(),
4308
+ contentFitFeature()
4238
4309
  ];
4239
4310
  }
4240
4311
 
package/dist/index.d.cts CHANGED
@@ -1,8 +1,8 @@
1
- export { B as BottomSheetEngine } from './BottomSheetEngine-mmFzIK1Z.cjs';
2
- import { d as SnapPoint, b as SheetMode, c as EngineOptions, P as PhysicalSheetMode, g as ScrimOverlayPosition } from './BottomSheetCore-BHv6LPmS.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-BHv6LPmS.cjs';
4
- export { autoCollapseFeature, contentSwipeFeature, defaultEngineFeatures, persistFeature, routeFeature, visualViewportFeature } from './features.cjs';
5
- export { R as ResolvedSnap, r as resolveSnapList } from './index-juAyT76E.cjs';
1
+ export { B as BottomSheetEngine } from './BottomSheetEngine-CsQWHLNb.cjs';
2
+ import { h as SnapPoint, f as SheetMode, g as EngineOptions, P as PhysicalSheetMode, j as ScrimOverlayPosition } from './BottomSheetCore-CQStdVy2.cjs';
3
+ export { k as AnchorAnimationPreset, l as AnchorAnimationSpec, m as AnchorHandle, A as AnchorOptions, n as AnchorPosition, o as AnchorState, B as BottomSheetCore, C as CloseReason, E as EngineFeature, a as EngineFeatureContext, b as EngineFeatureOptions, c as EngineFeatureStage, d as EngineState, L as LogicalSheetMode, p as Plugin, q as SCRIM_PRESETS, r as ScrimOverlayOptions, s as ScrimPreset, t as ScrimPresetConfig, u as ScrimStageDef, i as ScrimStagesOptions, v as ScrimUpdate, S as SheetEventMap, w as SnapId, e as SnapPointDef, T as TeardownScope, x as runAnchorTransition } from './BottomSheetCore-CQStdVy2.cjs';
4
+ export { a as autoCollapseFeature, c as contentSwipeFeature, d as defaultEngineFeatures, p as persistFeature, r as routeFeature, v as visualViewportFeature } from './default-features-DkG9aho0.cjs';
5
+ export { R as ResolvedSnap, r as resolveSnapList } from './index-CVGC5B5D.cjs';
6
6
  import './transform-jVfAikE9.cjs';
7
7
 
8
8
  declare const resolveSnap: (point: SnapPoint | string, mode: SheetMode, measureFit?: () => number) => number;
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- export { B as BottomSheetEngine } from './BottomSheetEngine-wLn6Q2kA.js';
2
- import { d as SnapPoint, b as SheetMode, c as EngineOptions, P as PhysicalSheetMode, g as ScrimOverlayPosition } from './BottomSheetCore-CK_mq14p.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-CK_mq14p.js';
4
- export { autoCollapseFeature, contentSwipeFeature, defaultEngineFeatures, persistFeature, routeFeature, visualViewportFeature } from './features.js';
5
- export { R as ResolvedSnap, r as resolveSnapList } from './index-CWKv1Xy4.js';
1
+ export { B as BottomSheetEngine } from './BottomSheetEngine-Dn6h-7gF.js';
2
+ import { h as SnapPoint, f as SheetMode, g as EngineOptions, P as PhysicalSheetMode, j as ScrimOverlayPosition } from './BottomSheetCore-9i-Uh6T3.js';
3
+ export { k as AnchorAnimationPreset, l as AnchorAnimationSpec, m as AnchorHandle, A as AnchorOptions, n as AnchorPosition, o as AnchorState, B as BottomSheetCore, C as CloseReason, E as EngineFeature, a as EngineFeatureContext, b as EngineFeatureOptions, c as EngineFeatureStage, d as EngineState, L as LogicalSheetMode, p as Plugin, q as SCRIM_PRESETS, r as ScrimOverlayOptions, s as ScrimPreset, t as ScrimPresetConfig, u as ScrimStageDef, i as ScrimStagesOptions, v as ScrimUpdate, S as SheetEventMap, w as SnapId, e as SnapPointDef, T as TeardownScope, x as runAnchorTransition } from './BottomSheetCore-9i-Uh6T3.js';
4
+ export { a as autoCollapseFeature, c as contentSwipeFeature, d as defaultEngineFeatures, p as persistFeature, r as routeFeature, v as visualViewportFeature } from './default-features-C3cilcW9.js';
5
+ export { R as ResolvedSnap, r as resolveSnapList } from './index-CnsJQZp2.js';
6
6
  import './transform-jVfAikE9.js';
7
7
 
8
8
  declare const resolveSnap: (point: SnapPoint | string, mode: SheetMode, measureFit?: () => number) => number;