@surdeddd/bottom-sheet 0.22.0 → 0.23.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.
package/dist/element.js CHANGED
@@ -1628,13 +1628,17 @@ var init_animation_runner = __esm({
1628
1628
  });
1629
1629
  let stopped = false;
1630
1630
  let auxRaf = 0;
1631
- const start = performance.now();
1632
1631
  const lastIdx = samples.values.length - 1;
1633
1632
  const auxTick = () => {
1634
1633
  if (stopped) return;
1635
- const elapsed = performance.now() - start;
1636
- const idx = Math.min(Math.floor(elapsed / samples.stepMs), lastIdx);
1637
- applyAux(samples.values[idx]);
1634
+ const at = Math.min(
1635
+ (Number(anim.currentTime) || 0) / samples.stepMs,
1636
+ lastIdx
1637
+ );
1638
+ const idx = Math.floor(at);
1639
+ const from = samples.values[idx];
1640
+ const to = samples.values[Math.min(idx + 1, lastIdx)];
1641
+ applyAux(from + (to - from) * (at - idx));
1638
1642
  auxRaf = requestAnimationFrame(auxTick);
1639
1643
  };
1640
1644
  auxRaf = requestAnimationFrame(auxTick);
@@ -2982,7 +2986,11 @@ var init_BottomSheetCore = __esm({
2982
2986
  getSize: () => this.size,
2983
2987
  isDragging: () => this.isDraggingAny(),
2984
2988
  applyAux: (size) => this.applySize(size, true),
2985
- getTransformFor: (size) => this.transformTemplate(this.snaps.getMaxAxisSize() - size)
2989
+ getTransformFor: (size) => {
2990
+ const cap = this.snaps.getMaxAxisSize();
2991
+ const shown = cap > 0 && !this.allowOvershoot ? Math.min(size, cap) : size;
2992
+ return this.transformTemplate(cap - shown);
2993
+ }
2986
2994
  },
2987
2995
  resolved.animation
2988
2996
  );
@@ -4564,6 +4572,7 @@ function contentFitFeature() {
4564
4572
  let inset = 0;
4565
4573
  let unpaddedMax = -1;
4566
4574
  let top = 0;
4575
+ const put = (name, px) => sheet.style.setProperty(name, `${px}px`);
4567
4576
  const hiddenAt = (size) => sheet.dataset.mode === "bottom" ? Math.max(0, ctx.getMaxAxisSize() - size) : 0;
4568
4577
  const follow = (size) => {
4569
4578
  if (unpaddedMax < 0) {
@@ -4582,7 +4591,10 @@ function contentFitFeature() {
4582
4591
  unpaddedMax = -1;
4583
4592
  follow(size);
4584
4593
  inset = hiddenAt(size);
4585
- sheet.style.setProperty(INSET_VAR, `${inset}px`);
4594
+ put(LIFT_VAR, scroller.offsetHeight);
4595
+ put(INSET_VAR, inset);
4596
+ put(SIZE_VAR, size);
4597
+ put(CAP_VAR, ctx.getMaxAxisSize());
4586
4598
  unpaddedMax = -1;
4587
4599
  };
4588
4600
  const moving = () => ctx.isAnimating() || ctx.isDragging();
@@ -4605,15 +4617,20 @@ function contentFitFeature() {
4605
4617
  observer?.disconnect();
4606
4618
  window.removeEventListener("orientationchange", whenIdle);
4607
4619
  sheet.removeAttribute(FIT_ATTR);
4608
- sheet.style.removeProperty(INSET_VAR);
4620
+ for (const name of [INSET_VAR, CAP_VAR, LIFT_VAR]) {
4621
+ sheet.style.removeProperty(name);
4622
+ }
4609
4623
  };
4610
4624
  }
4611
4625
  };
4612
4626
  }
4613
- var INSET_VAR, FIT_ATTR;
4627
+ var INSET_VAR, SIZE_VAR, CAP_VAR, LIFT_VAR, FIT_ATTR;
4614
4628
  var init_content_fit = __esm({
4615
4629
  "src/core/features/content-fit.ts"() {
4616
4630
  INSET_VAR = "--bs-content-inset";
4631
+ SIZE_VAR = "--bs-size";
4632
+ CAP_VAR = "--bs-max-size";
4633
+ LIFT_VAR = "--bs-footer-lift-max";
4617
4634
  FIT_ATTR = "data-bs-fit-content";
4618
4635
  }
4619
4636
  });
@@ -4657,7 +4674,7 @@ var init_BottomSheetEngine = __esm({
4657
4674
  var baseStyles;
4658
4675
  var init_baseStyles = __esm({
4659
4676
  "src/web-component/baseStyles.ts"() {
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}}`;
4677
+ 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-bs-fit-content][data-mode="bottom"]:not([data-bs-webgl="on"]) .bs-footer{transform:translateY( clamp( calc(-1 * var(--bs-footer-lift-max,0px)),calc(var(--bs-size,0px) - var(--bs-max-size,0px)),0px ) )}.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}}`;
4661
4678
  }
4662
4679
  });
4663
4680
 
package/dist/features.cjs CHANGED
@@ -470,6 +470,9 @@ function visualViewportFeature() {
470
470
 
471
471
  // src/core/features/content-fit.ts
472
472
  var INSET_VAR = "--bs-content-inset";
473
+ var SIZE_VAR = "--bs-size";
474
+ var CAP_VAR = "--bs-max-size";
475
+ var LIFT_VAR = "--bs-footer-lift-max";
473
476
  var FIT_ATTR = "data-bs-fit-content";
474
477
  function contentFitFeature() {
475
478
  return {
@@ -483,6 +486,7 @@ function contentFitFeature() {
483
486
  let inset = 0;
484
487
  let unpaddedMax = -1;
485
488
  let top = 0;
489
+ const put = (name, px) => sheet.style.setProperty(name, `${px}px`);
486
490
  const hiddenAt = (size) => sheet.dataset.mode === "bottom" ? Math.max(0, ctx.getMaxAxisSize() - size) : 0;
487
491
  const follow = (size) => {
488
492
  if (unpaddedMax < 0) {
@@ -501,7 +505,10 @@ function contentFitFeature() {
501
505
  unpaddedMax = -1;
502
506
  follow(size);
503
507
  inset = hiddenAt(size);
504
- sheet.style.setProperty(INSET_VAR, `${inset}px`);
508
+ put(LIFT_VAR, scroller.offsetHeight);
509
+ put(INSET_VAR, inset);
510
+ put(SIZE_VAR, size);
511
+ put(CAP_VAR, ctx.getMaxAxisSize());
505
512
  unpaddedMax = -1;
506
513
  };
507
514
  const moving = () => ctx.isAnimating() || ctx.isDragging();
@@ -524,7 +531,9 @@ function contentFitFeature() {
524
531
  observer?.disconnect();
525
532
  window.removeEventListener("orientationchange", whenIdle);
526
533
  sheet.removeAttribute(FIT_ATTR);
527
- sheet.style.removeProperty(INSET_VAR);
534
+ for (const name of [INSET_VAR, CAP_VAR, LIFT_VAR]) {
535
+ sheet.style.removeProperty(name);
536
+ }
528
537
  };
529
538
  }
530
539
  };
package/dist/features.js CHANGED
@@ -468,6 +468,9 @@ function visualViewportFeature() {
468
468
 
469
469
  // src/core/features/content-fit.ts
470
470
  var INSET_VAR = "--bs-content-inset";
471
+ var SIZE_VAR = "--bs-size";
472
+ var CAP_VAR = "--bs-max-size";
473
+ var LIFT_VAR = "--bs-footer-lift-max";
471
474
  var FIT_ATTR = "data-bs-fit-content";
472
475
  function contentFitFeature() {
473
476
  return {
@@ -481,6 +484,7 @@ function contentFitFeature() {
481
484
  let inset = 0;
482
485
  let unpaddedMax = -1;
483
486
  let top = 0;
487
+ const put = (name, px) => sheet.style.setProperty(name, `${px}px`);
484
488
  const hiddenAt = (size) => sheet.dataset.mode === "bottom" ? Math.max(0, ctx.getMaxAxisSize() - size) : 0;
485
489
  const follow = (size) => {
486
490
  if (unpaddedMax < 0) {
@@ -499,7 +503,10 @@ function contentFitFeature() {
499
503
  unpaddedMax = -1;
500
504
  follow(size);
501
505
  inset = hiddenAt(size);
502
- sheet.style.setProperty(INSET_VAR, `${inset}px`);
506
+ put(LIFT_VAR, scroller.offsetHeight);
507
+ put(INSET_VAR, inset);
508
+ put(SIZE_VAR, size);
509
+ put(CAP_VAR, ctx.getMaxAxisSize());
503
510
  unpaddedMax = -1;
504
511
  };
505
512
  const moving = () => ctx.isAnimating() || ctx.isDragging();
@@ -522,7 +529,9 @@ function contentFitFeature() {
522
529
  observer?.disconnect();
523
530
  window.removeEventListener("orientationchange", whenIdle);
524
531
  sheet.removeAttribute(FIT_ATTR);
525
- sheet.style.removeProperty(INSET_VAR);
532
+ for (const name of [INSET_VAR, CAP_VAR, LIFT_VAR]) {
533
+ sheet.style.removeProperty(name);
534
+ }
526
535
  };
527
536
  }
528
537
  };
package/dist/index.cjs CHANGED
@@ -1487,13 +1487,17 @@ var AnimationRunner = class {
1487
1487
  });
1488
1488
  let stopped = false;
1489
1489
  let auxRaf = 0;
1490
- const start = performance.now();
1491
1490
  const lastIdx = samples.values.length - 1;
1492
1491
  const auxTick = () => {
1493
1492
  if (stopped) return;
1494
- const elapsed = performance.now() - start;
1495
- const idx = Math.min(Math.floor(elapsed / samples.stepMs), lastIdx);
1496
- applyAux(samples.values[idx]);
1493
+ const at = Math.min(
1494
+ (Number(anim.currentTime) || 0) / samples.stepMs,
1495
+ lastIdx
1496
+ );
1497
+ const idx = Math.floor(at);
1498
+ const from = samples.values[idx];
1499
+ const to = samples.values[Math.min(idx + 1, lastIdx)];
1500
+ applyAux(from + (to - from) * (at - idx));
1497
1501
  auxRaf = requestAnimationFrame(auxTick);
1498
1502
  };
1499
1503
  auxRaf = requestAnimationFrame(auxTick);
@@ -2705,7 +2709,11 @@ var BottomSheetCore = class {
2705
2709
  getSize: () => this.size,
2706
2710
  isDragging: () => this.isDraggingAny(),
2707
2711
  applyAux: (size) => this.applySize(size, true),
2708
- getTransformFor: (size) => this.transformTemplate(this.snaps.getMaxAxisSize() - size)
2712
+ getTransformFor: (size) => {
2713
+ const cap = this.snaps.getMaxAxisSize();
2714
+ const shown = cap > 0 && !this.allowOvershoot ? Math.min(size, cap) : size;
2715
+ return this.transformTemplate(cap - shown);
2716
+ }
2709
2717
  },
2710
2718
  resolved.animation
2711
2719
  );
@@ -4237,6 +4245,9 @@ function visualViewportFeature() {
4237
4245
 
4238
4246
  // src/core/features/content-fit.ts
4239
4247
  var INSET_VAR = "--bs-content-inset";
4248
+ var SIZE_VAR = "--bs-size";
4249
+ var CAP_VAR = "--bs-max-size";
4250
+ var LIFT_VAR = "--bs-footer-lift-max";
4240
4251
  var FIT_ATTR = "data-bs-fit-content";
4241
4252
  function contentFitFeature() {
4242
4253
  return {
@@ -4250,6 +4261,7 @@ function contentFitFeature() {
4250
4261
  let inset = 0;
4251
4262
  let unpaddedMax = -1;
4252
4263
  let top = 0;
4264
+ const put = (name, px) => sheet.style.setProperty(name, `${px}px`);
4253
4265
  const hiddenAt = (size) => sheet.dataset.mode === "bottom" ? Math.max(0, ctx.getMaxAxisSize() - size) : 0;
4254
4266
  const follow = (size) => {
4255
4267
  if (unpaddedMax < 0) {
@@ -4268,7 +4280,10 @@ function contentFitFeature() {
4268
4280
  unpaddedMax = -1;
4269
4281
  follow(size);
4270
4282
  inset = hiddenAt(size);
4271
- sheet.style.setProperty(INSET_VAR, `${inset}px`);
4283
+ put(LIFT_VAR, scroller.offsetHeight);
4284
+ put(INSET_VAR, inset);
4285
+ put(SIZE_VAR, size);
4286
+ put(CAP_VAR, ctx.getMaxAxisSize());
4272
4287
  unpaddedMax = -1;
4273
4288
  };
4274
4289
  const moving = () => ctx.isAnimating() || ctx.isDragging();
@@ -4291,7 +4306,9 @@ function contentFitFeature() {
4291
4306
  observer?.disconnect();
4292
4307
  window.removeEventListener("orientationchange", whenIdle);
4293
4308
  sheet.removeAttribute(FIT_ATTR);
4294
- sheet.style.removeProperty(INSET_VAR);
4309
+ for (const name of [INSET_VAR, CAP_VAR, LIFT_VAR]) {
4310
+ sheet.style.removeProperty(name);
4311
+ }
4295
4312
  };
4296
4313
  }
4297
4314
  };
package/dist/index.js CHANGED
@@ -1485,13 +1485,17 @@ var AnimationRunner = class {
1485
1485
  });
1486
1486
  let stopped = false;
1487
1487
  let auxRaf = 0;
1488
- const start = performance.now();
1489
1488
  const lastIdx = samples.values.length - 1;
1490
1489
  const auxTick = () => {
1491
1490
  if (stopped) return;
1492
- const elapsed = performance.now() - start;
1493
- const idx = Math.min(Math.floor(elapsed / samples.stepMs), lastIdx);
1494
- applyAux(samples.values[idx]);
1491
+ const at = Math.min(
1492
+ (Number(anim.currentTime) || 0) / samples.stepMs,
1493
+ lastIdx
1494
+ );
1495
+ const idx = Math.floor(at);
1496
+ const from = samples.values[idx];
1497
+ const to = samples.values[Math.min(idx + 1, lastIdx)];
1498
+ applyAux(from + (to - from) * (at - idx));
1495
1499
  auxRaf = requestAnimationFrame(auxTick);
1496
1500
  };
1497
1501
  auxRaf = requestAnimationFrame(auxTick);
@@ -2703,7 +2707,11 @@ var BottomSheetCore = class {
2703
2707
  getSize: () => this.size,
2704
2708
  isDragging: () => this.isDraggingAny(),
2705
2709
  applyAux: (size) => this.applySize(size, true),
2706
- getTransformFor: (size) => this.transformTemplate(this.snaps.getMaxAxisSize() - size)
2710
+ getTransformFor: (size) => {
2711
+ const cap = this.snaps.getMaxAxisSize();
2712
+ const shown = cap > 0 && !this.allowOvershoot ? Math.min(size, cap) : size;
2713
+ return this.transformTemplate(cap - shown);
2714
+ }
2707
2715
  },
2708
2716
  resolved.animation
2709
2717
  );
@@ -4235,6 +4243,9 @@ function visualViewportFeature() {
4235
4243
 
4236
4244
  // src/core/features/content-fit.ts
4237
4245
  var INSET_VAR = "--bs-content-inset";
4246
+ var SIZE_VAR = "--bs-size";
4247
+ var CAP_VAR = "--bs-max-size";
4248
+ var LIFT_VAR = "--bs-footer-lift-max";
4238
4249
  var FIT_ATTR = "data-bs-fit-content";
4239
4250
  function contentFitFeature() {
4240
4251
  return {
@@ -4248,6 +4259,7 @@ function contentFitFeature() {
4248
4259
  let inset = 0;
4249
4260
  let unpaddedMax = -1;
4250
4261
  let top = 0;
4262
+ const put = (name, px) => sheet.style.setProperty(name, `${px}px`);
4251
4263
  const hiddenAt = (size) => sheet.dataset.mode === "bottom" ? Math.max(0, ctx.getMaxAxisSize() - size) : 0;
4252
4264
  const follow = (size) => {
4253
4265
  if (unpaddedMax < 0) {
@@ -4266,7 +4278,10 @@ function contentFitFeature() {
4266
4278
  unpaddedMax = -1;
4267
4279
  follow(size);
4268
4280
  inset = hiddenAt(size);
4269
- sheet.style.setProperty(INSET_VAR, `${inset}px`);
4281
+ put(LIFT_VAR, scroller.offsetHeight);
4282
+ put(INSET_VAR, inset);
4283
+ put(SIZE_VAR, size);
4284
+ put(CAP_VAR, ctx.getMaxAxisSize());
4270
4285
  unpaddedMax = -1;
4271
4286
  };
4272
4287
  const moving = () => ctx.isAnimating() || ctx.isDragging();
@@ -4289,7 +4304,9 @@ function contentFitFeature() {
4289
4304
  observer?.disconnect();
4290
4305
  window.removeEventListener("orientationchange", whenIdle);
4291
4306
  sheet.removeAttribute(FIT_ATTR);
4292
- sheet.style.removeProperty(INSET_VAR);
4307
+ for (const name of [INSET_VAR, CAP_VAR, LIFT_VAR]) {
4308
+ sheet.style.removeProperty(name);
4309
+ }
4293
4310
  };
4294
4311
  }
4295
4312
  };
@@ -1504,13 +1504,14 @@ class AnimationRunner {
1504
1504
  });
1505
1505
  let stopped = false;
1506
1506
  let auxRaf = 0;
1507
- const start = performance.now();
1508
1507
  const lastIdx = samples.values.length - 1;
1509
1508
  const auxTick = () => {
1510
1509
  if (stopped) return;
1511
- const elapsed = performance.now() - start;
1512
- const idx = Math.min(Math.floor(elapsed / samples.stepMs), lastIdx);
1513
- applyAux(samples.values[idx]);
1510
+ const at = Math.min((Number(anim.currentTime) || 0) / samples.stepMs, lastIdx);
1511
+ const idx = Math.floor(at);
1512
+ const from = samples.values[idx];
1513
+ const to = samples.values[Math.min(idx + 1, lastIdx)];
1514
+ applyAux(from + (to - from) * (at - idx));
1514
1515
  auxRaf = requestAnimationFrame(auxTick);
1515
1516
  };
1516
1517
  auxRaf = requestAnimationFrame(auxTick);
@@ -2749,7 +2750,11 @@ class BottomSheetCore {
2749
2750
  getSize: () => this.size,
2750
2751
  isDragging: () => this.isDraggingAny(),
2751
2752
  applyAux: (size) => this.applySize(size, true),
2752
- getTransformFor: (size) => this.transformTemplate(this.snaps.getMaxAxisSize() - size)
2753
+ getTransformFor: (size) => {
2754
+ const cap = this.snaps.getMaxAxisSize();
2755
+ const shown = cap > 0 && !this.allowOvershoot ? Math.min(size, cap) : size;
2756
+ return this.transformTemplate(cap - shown);
2757
+ }
2753
2758
  }, resolved.animation);
2754
2759
  this.lifecycle = new LifecycleController({
2755
2760
  element: this.element,
@@ -4228,6 +4233,9 @@ function visualViewportFeature() {
4228
4233
  };
4229
4234
  }
4230
4235
  const INSET_VAR = "--bs-content-inset";
4236
+ const SIZE_VAR = "--bs-size";
4237
+ const CAP_VAR = "--bs-max-size";
4238
+ const LIFT_VAR = "--bs-footer-lift-max";
4231
4239
  const FIT_ATTR = "data-bs-fit-content";
4232
4240
  function contentFitFeature() {
4233
4241
  return {
@@ -4241,6 +4249,7 @@ function contentFitFeature() {
4241
4249
  let inset = 0;
4242
4250
  let unpaddedMax = -1;
4243
4251
  let top = 0;
4252
+ const put = (name, px) => sheet.style.setProperty(name, `${px}px`);
4244
4253
  const hiddenAt = (size) => sheet.dataset.mode === "bottom" ? Math.max(0, ctx.getMaxAxisSize() - size) : 0;
4245
4254
  const follow = (size) => {
4246
4255
  if (unpaddedMax < 0) {
@@ -4259,7 +4268,10 @@ function contentFitFeature() {
4259
4268
  unpaddedMax = -1;
4260
4269
  follow(size);
4261
4270
  inset = hiddenAt(size);
4262
- sheet.style.setProperty(INSET_VAR, `${inset}px`);
4271
+ put(LIFT_VAR, scroller.offsetHeight);
4272
+ put(INSET_VAR, inset);
4273
+ put(SIZE_VAR, size);
4274
+ put(CAP_VAR, ctx.getMaxAxisSize());
4263
4275
  unpaddedMax = -1;
4264
4276
  };
4265
4277
  const moving = () => ctx.isAnimating() || ctx.isDragging();
@@ -4279,7 +4291,13 @@ function contentFitFeature() {
4279
4291
  observer?.disconnect();
4280
4292
  window.removeEventListener("orientationchange", whenIdle);
4281
4293
  sheet.removeAttribute(FIT_ATTR);
4282
- sheet.style.removeProperty(INSET_VAR);
4294
+ for (const name of [
4295
+ INSET_VAR,
4296
+ CAP_VAR,
4297
+ LIFT_VAR
4298
+ ]) {
4299
+ sheet.style.removeProperty(name);
4300
+ }
4283
4301
  };
4284
4302
  }
4285
4303
  };
@@ -1502,13 +1502,14 @@ class AnimationRunner {
1502
1502
  });
1503
1503
  let stopped = false;
1504
1504
  let auxRaf = 0;
1505
- const start = performance.now();
1506
1505
  const lastIdx = samples.values.length - 1;
1507
1506
  const auxTick = () => {
1508
1507
  if (stopped) return;
1509
- const elapsed = performance.now() - start;
1510
- const idx = Math.min(Math.floor(elapsed / samples.stepMs), lastIdx);
1511
- applyAux(samples.values[idx]);
1508
+ const at = Math.min((Number(anim.currentTime) || 0) / samples.stepMs, lastIdx);
1509
+ const idx = Math.floor(at);
1510
+ const from = samples.values[idx];
1511
+ const to = samples.values[Math.min(idx + 1, lastIdx)];
1512
+ applyAux(from + (to - from) * (at - idx));
1512
1513
  auxRaf = requestAnimationFrame(auxTick);
1513
1514
  };
1514
1515
  auxRaf = requestAnimationFrame(auxTick);
@@ -2747,7 +2748,11 @@ class BottomSheetCore {
2747
2748
  getSize: () => this.size,
2748
2749
  isDragging: () => this.isDraggingAny(),
2749
2750
  applyAux: (size) => this.applySize(size, true),
2750
- getTransformFor: (size) => this.transformTemplate(this.snaps.getMaxAxisSize() - size)
2751
+ getTransformFor: (size) => {
2752
+ const cap = this.snaps.getMaxAxisSize();
2753
+ const shown = cap > 0 && !this.allowOvershoot ? Math.min(size, cap) : size;
2754
+ return this.transformTemplate(cap - shown);
2755
+ }
2751
2756
  }, resolved.animation);
2752
2757
  this.lifecycle = new LifecycleController({
2753
2758
  element: this.element,
@@ -4226,6 +4231,9 @@ function visualViewportFeature() {
4226
4231
  };
4227
4232
  }
4228
4233
  const INSET_VAR = "--bs-content-inset";
4234
+ const SIZE_VAR = "--bs-size";
4235
+ const CAP_VAR = "--bs-max-size";
4236
+ const LIFT_VAR = "--bs-footer-lift-max";
4229
4237
  const FIT_ATTR = "data-bs-fit-content";
4230
4238
  function contentFitFeature() {
4231
4239
  return {
@@ -4239,6 +4247,7 @@ function contentFitFeature() {
4239
4247
  let inset = 0;
4240
4248
  let unpaddedMax = -1;
4241
4249
  let top = 0;
4250
+ const put = (name, px) => sheet.style.setProperty(name, `${px}px`);
4242
4251
  const hiddenAt = (size) => sheet.dataset.mode === "bottom" ? Math.max(0, ctx.getMaxAxisSize() - size) : 0;
4243
4252
  const follow = (size) => {
4244
4253
  if (unpaddedMax < 0) {
@@ -4257,7 +4266,10 @@ function contentFitFeature() {
4257
4266
  unpaddedMax = -1;
4258
4267
  follow(size);
4259
4268
  inset = hiddenAt(size);
4260
- sheet.style.setProperty(INSET_VAR, `${inset}px`);
4269
+ put(LIFT_VAR, scroller.offsetHeight);
4270
+ put(INSET_VAR, inset);
4271
+ put(SIZE_VAR, size);
4272
+ put(CAP_VAR, ctx.getMaxAxisSize());
4261
4273
  unpaddedMax = -1;
4262
4274
  };
4263
4275
  const moving = () => ctx.isAnimating() || ctx.isDragging();
@@ -4277,7 +4289,13 @@ function contentFitFeature() {
4277
4289
  observer?.disconnect();
4278
4290
  window.removeEventListener("orientationchange", whenIdle);
4279
4291
  sheet.removeAttribute(FIT_ATTR);
4280
- sheet.style.removeProperty(INSET_VAR);
4292
+ for (const name of [
4293
+ INSET_VAR,
4294
+ CAP_VAR,
4295
+ LIFT_VAR
4296
+ ]) {
4297
+ sheet.style.removeProperty(name);
4298
+ }
4281
4299
  };
4282
4300
  }
4283
4301
  };
package/dist/qwik.cjs CHANGED
@@ -1490,13 +1490,17 @@ var AnimationRunner = class {
1490
1490
  });
1491
1491
  let stopped = false;
1492
1492
  let auxRaf = 0;
1493
- const start = performance.now();
1494
1493
  const lastIdx = samples.values.length - 1;
1495
1494
  const auxTick = () => {
1496
1495
  if (stopped) return;
1497
- const elapsed = performance.now() - start;
1498
- const idx = Math.min(Math.floor(elapsed / samples.stepMs), lastIdx);
1499
- applyAux(samples.values[idx]);
1496
+ const at = Math.min(
1497
+ (Number(anim.currentTime) || 0) / samples.stepMs,
1498
+ lastIdx
1499
+ );
1500
+ const idx = Math.floor(at);
1501
+ const from = samples.values[idx];
1502
+ const to = samples.values[Math.min(idx + 1, lastIdx)];
1503
+ applyAux(from + (to - from) * (at - idx));
1500
1504
  auxRaf = requestAnimationFrame(auxTick);
1501
1505
  };
1502
1506
  auxRaf = requestAnimationFrame(auxTick);
@@ -2708,7 +2712,11 @@ var BottomSheetCore = class {
2708
2712
  getSize: () => this.size,
2709
2713
  isDragging: () => this.isDraggingAny(),
2710
2714
  applyAux: (size) => this.applySize(size, true),
2711
- getTransformFor: (size) => this.transformTemplate(this.snaps.getMaxAxisSize() - size)
2715
+ getTransformFor: (size) => {
2716
+ const cap = this.snaps.getMaxAxisSize();
2717
+ const shown = cap > 0 && !this.allowOvershoot ? Math.min(size, cap) : size;
2718
+ return this.transformTemplate(cap - shown);
2719
+ }
2712
2720
  },
2713
2721
  resolved.animation
2714
2722
  );
@@ -4240,6 +4248,9 @@ function visualViewportFeature() {
4240
4248
 
4241
4249
  // src/core/features/content-fit.ts
4242
4250
  var INSET_VAR = "--bs-content-inset";
4251
+ var SIZE_VAR = "--bs-size";
4252
+ var CAP_VAR = "--bs-max-size";
4253
+ var LIFT_VAR = "--bs-footer-lift-max";
4243
4254
  var FIT_ATTR = "data-bs-fit-content";
4244
4255
  function contentFitFeature() {
4245
4256
  return {
@@ -4253,6 +4264,7 @@ function contentFitFeature() {
4253
4264
  let inset = 0;
4254
4265
  let unpaddedMax = -1;
4255
4266
  let top = 0;
4267
+ const put = (name, px) => sheet.style.setProperty(name, `${px}px`);
4256
4268
  const hiddenAt = (size) => sheet.dataset.mode === "bottom" ? Math.max(0, ctx.getMaxAxisSize() - size) : 0;
4257
4269
  const follow = (size) => {
4258
4270
  if (unpaddedMax < 0) {
@@ -4271,7 +4283,10 @@ function contentFitFeature() {
4271
4283
  unpaddedMax = -1;
4272
4284
  follow(size);
4273
4285
  inset = hiddenAt(size);
4274
- sheet.style.setProperty(INSET_VAR, `${inset}px`);
4286
+ put(LIFT_VAR, scroller.offsetHeight);
4287
+ put(INSET_VAR, inset);
4288
+ put(SIZE_VAR, size);
4289
+ put(CAP_VAR, ctx.getMaxAxisSize());
4275
4290
  unpaddedMax = -1;
4276
4291
  };
4277
4292
  const moving = () => ctx.isAnimating() || ctx.isDragging();
@@ -4294,7 +4309,9 @@ function contentFitFeature() {
4294
4309
  observer?.disconnect();
4295
4310
  window.removeEventListener("orientationchange", whenIdle);
4296
4311
  sheet.removeAttribute(FIT_ATTR);
4297
- sheet.style.removeProperty(INSET_VAR);
4312
+ for (const name of [INSET_VAR, CAP_VAR, LIFT_VAR]) {
4313
+ sheet.style.removeProperty(name);
4314
+ }
4298
4315
  };
4299
4316
  }
4300
4317
  };
package/dist/qwik.js CHANGED
@@ -1488,13 +1488,17 @@ var AnimationRunner = class {
1488
1488
  });
1489
1489
  let stopped = false;
1490
1490
  let auxRaf = 0;
1491
- const start = performance.now();
1492
1491
  const lastIdx = samples.values.length - 1;
1493
1492
  const auxTick = () => {
1494
1493
  if (stopped) return;
1495
- const elapsed = performance.now() - start;
1496
- const idx = Math.min(Math.floor(elapsed / samples.stepMs), lastIdx);
1497
- applyAux(samples.values[idx]);
1494
+ const at = Math.min(
1495
+ (Number(anim.currentTime) || 0) / samples.stepMs,
1496
+ lastIdx
1497
+ );
1498
+ const idx = Math.floor(at);
1499
+ const from = samples.values[idx];
1500
+ const to = samples.values[Math.min(idx + 1, lastIdx)];
1501
+ applyAux(from + (to - from) * (at - idx));
1498
1502
  auxRaf = requestAnimationFrame(auxTick);
1499
1503
  };
1500
1504
  auxRaf = requestAnimationFrame(auxTick);
@@ -2706,7 +2710,11 @@ var BottomSheetCore = class {
2706
2710
  getSize: () => this.size,
2707
2711
  isDragging: () => this.isDraggingAny(),
2708
2712
  applyAux: (size) => this.applySize(size, true),
2709
- getTransformFor: (size) => this.transformTemplate(this.snaps.getMaxAxisSize() - size)
2713
+ getTransformFor: (size) => {
2714
+ const cap = this.snaps.getMaxAxisSize();
2715
+ const shown = cap > 0 && !this.allowOvershoot ? Math.min(size, cap) : size;
2716
+ return this.transformTemplate(cap - shown);
2717
+ }
2710
2718
  },
2711
2719
  resolved.animation
2712
2720
  );
@@ -4238,6 +4246,9 @@ function visualViewportFeature() {
4238
4246
 
4239
4247
  // src/core/features/content-fit.ts
4240
4248
  var INSET_VAR = "--bs-content-inset";
4249
+ var SIZE_VAR = "--bs-size";
4250
+ var CAP_VAR = "--bs-max-size";
4251
+ var LIFT_VAR = "--bs-footer-lift-max";
4241
4252
  var FIT_ATTR = "data-bs-fit-content";
4242
4253
  function contentFitFeature() {
4243
4254
  return {
@@ -4251,6 +4262,7 @@ function contentFitFeature() {
4251
4262
  let inset = 0;
4252
4263
  let unpaddedMax = -1;
4253
4264
  let top = 0;
4265
+ const put = (name, px) => sheet.style.setProperty(name, `${px}px`);
4254
4266
  const hiddenAt = (size) => sheet.dataset.mode === "bottom" ? Math.max(0, ctx.getMaxAxisSize() - size) : 0;
4255
4267
  const follow = (size) => {
4256
4268
  if (unpaddedMax < 0) {
@@ -4269,7 +4281,10 @@ function contentFitFeature() {
4269
4281
  unpaddedMax = -1;
4270
4282
  follow(size);
4271
4283
  inset = hiddenAt(size);
4272
- sheet.style.setProperty(INSET_VAR, `${inset}px`);
4284
+ put(LIFT_VAR, scroller.offsetHeight);
4285
+ put(INSET_VAR, inset);
4286
+ put(SIZE_VAR, size);
4287
+ put(CAP_VAR, ctx.getMaxAxisSize());
4273
4288
  unpaddedMax = -1;
4274
4289
  };
4275
4290
  const moving = () => ctx.isAnimating() || ctx.isDragging();
@@ -4292,7 +4307,9 @@ function contentFitFeature() {
4292
4307
  observer?.disconnect();
4293
4308
  window.removeEventListener("orientationchange", whenIdle);
4294
4309
  sheet.removeAttribute(FIT_ATTR);
4295
- sheet.style.removeProperty(INSET_VAR);
4310
+ for (const name of [INSET_VAR, CAP_VAR, LIFT_VAR]) {
4311
+ sheet.style.removeProperty(name);
4312
+ }
4296
4313
  };
4297
4314
  }
4298
4315
  };