@surdeddd/bottom-sheet 0.6.0 → 0.7.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
@@ -2860,7 +2860,9 @@ var init_BottomSheetEngine = __esm({
2860
2860
  const previousSize = this.size;
2861
2861
  this.scrollCache.cache(previousId, previousSize, target.size);
2862
2862
  this.activeId = id;
2863
- if (wasClosed && target.size > 0) {
2863
+ const rawTargetSize = this.snapPointsRaw.find((p) => p.id === id)?.size;
2864
+ const opensToRest = id === "closed" || rawTargetSize === 0;
2865
+ if (wasClosed && !opensToRest) {
2864
2866
  this.opening = true;
2865
2867
  sheetStack.promote(this.id);
2866
2868
  }
@@ -2885,8 +2887,8 @@ var init_BottomSheetEngine = __esm({
2885
2887
  this.updateAriaSlider();
2886
2888
  this.emit("snap", {
2887
2889
  id,
2888
- size: target.size,
2889
- progress: this.computeProgress(target.size)
2890
+ size: this.size,
2891
+ progress: this.computeProgress(this.size)
2890
2892
  });
2891
2893
  if (wasClosed && target.size > 0) {
2892
2894
  this.emit("open", { id });
@@ -2965,12 +2967,12 @@ var init_BottomSheetEngine = __esm({
2965
2967
  const value = typeof h === "number" ? `${h}px` : h;
2966
2968
  const axis = layoutAxis(this.mode);
2967
2969
  this.element.style.setProperty(
2968
- axis === "height" ? "maxHeight" : "maxWidth",
2970
+ axis === "height" ? "max-height" : "max-width",
2969
2971
  value
2970
2972
  );
2971
2973
  if (typeof h === "number") {
2972
2974
  this.maxHeightCap = h;
2973
- this.clampToMaxHeight();
2975
+ this.recompute();
2974
2976
  } else if (typeof window !== "undefined") {
2975
2977
  const probe2 = document.createElement("div");
2976
2978
  probe2.style.cssText = `position:absolute;visibility:hidden;pointer-events:none;${axis === "height" ? "height" : "width"}:${value};`;
@@ -2978,7 +2980,7 @@ var init_BottomSheetEngine = __esm({
2978
2980
  const measured = axis === "height" ? probe2.offsetHeight : probe2.offsetWidth;
2979
2981
  probe2.remove();
2980
2982
  this.maxHeightCap = measured > 0 ? measured : void 0;
2981
- this.clampToMaxHeight();
2983
+ this.recompute();
2982
2984
  }
2983
2985
  }
2984
2986
  clampToMaxHeight() {
@@ -2986,9 +2988,6 @@ var init_BottomSheetEngine = __esm({
2986
2988
  if (this.snaps.getMaxAxisSize() > this.maxHeightCap) {
2987
2989
  this.snaps.setMaxAxisSize(this.maxHeightCap);
2988
2990
  }
2989
- if (this.size > this.maxHeightCap && !this.gesture?.isDragging) {
2990
- this.applySize(this.maxHeightCap);
2991
- }
2992
2991
  }
2993
2992
  setAllowed(ids, snap) {
2994
2993
  if (this.destroyed) return;
@@ -3126,6 +3125,7 @@ var init_BottomSheetEngine = __esm({
3126
3125
  recompute() {
3127
3126
  if (this.destroyed) return;
3128
3127
  this.snaps.recompute();
3128
+ this.clampToMaxHeight();
3129
3129
  this.scrim.invalidateOpacityCache();
3130
3130
  if (this.gesture?.isDragging) return;
3131
3131
  const current = this.snaps.findById(this.activeId);
@@ -3183,9 +3183,10 @@ var init_BottomSheetEngine = __esm({
3183
3183
  const handleSize = vertical ? this.handle.offsetHeight : this.handle.offsetWidth;
3184
3184
  const content = this.scrollContainer;
3185
3185
  const natural = content ? handleSize + this.measureContentExtent(vertical) : handleSize;
3186
- if (typeof window === "undefined") return natural;
3186
+ const capped = this.maxHeightCap !== void 0 ? Math.min(natural, this.maxHeightCap) : natural;
3187
+ if (typeof window === "undefined") return capped;
3187
3188
  const viewport = vertical ? window.innerHeight : window.innerWidth;
3188
- return viewport > 0 ? Math.min(natural, viewport) : natural;
3189
+ return viewport > 0 ? Math.min(capped, viewport) : capped;
3189
3190
  }
3190
3191
  installFitObserver() {
3191
3192
  if (typeof ResizeObserver === "undefined") return;
@@ -3556,8 +3557,8 @@ var init_BottomSheetEngine = __esm({
3556
3557
  this.updateAriaSlider();
3557
3558
  this.emit("snap", {
3558
3559
  id: target.id,
3559
- size: target.size,
3560
- progress: this.computeProgress(target.size)
3560
+ size: this.size,
3561
+ progress: this.computeProgress(this.size)
3561
3562
  });
3562
3563
  this.haptic();
3563
3564
  if (previousSnapSize === 0 && target.size > 0) {
@@ -3582,23 +3583,25 @@ var init_BottomSheetEngine = __esm({
3582
3583
  }
3583
3584
  }
3584
3585
  applySize(size) {
3585
- this.size = size;
3586
- const offset = this.snaps.getMaxAxisSize() - size;
3586
+ const cap = this.snaps.getMaxAxisSize();
3587
+ const clamped = cap > 0 && size > cap && !this.gesture?.isDragging ? cap : size;
3588
+ this.size = clamped;
3589
+ const offset = cap - clamped;
3587
3590
  const style = this.element.style;
3588
3591
  style.transform = this.transformTemplate(offset);
3589
- if (this.sizeWriteSentinel.shouldWrite(size, SIZE_WRITE_EPSILON)) {
3590
- style.setProperty("--bs-size", `${size}px`);
3592
+ if (this.sizeWriteSentinel.shouldWrite(clamped, SIZE_WRITE_EPSILON)) {
3593
+ style.setProperty("--bs-size", `${clamped}px`);
3591
3594
  if (this.scrimParent) {
3592
- this.scrimParent.style.setProperty("--bs-size", `${size}px`);
3595
+ this.scrimParent.style.setProperty("--bs-size", `${clamped}px`);
3593
3596
  }
3594
3597
  if (this.anchorHost && this.anchorHost !== this.scrimParent) {
3595
- this.anchorHost.style.setProperty("--bs-size", `${size}px`);
3598
+ this.anchorHost.style.setProperty("--bs-size", `${clamped}px`);
3596
3599
  }
3597
3600
  if (this.rootEl && this.rootEl !== this.scrimParent && this.rootEl !== this.anchorHost) {
3598
- this.rootEl.style.setProperty("--bs-size", `${size}px`);
3601
+ this.rootEl.style.setProperty("--bs-size", `${clamped}px`);
3599
3602
  }
3600
3603
  }
3601
- const progress = this.computeProgress(size);
3604
+ const progress = this.computeProgress(clamped);
3602
3605
  const progressChanged = this.progressWriteSentinel.shouldWrite(
3603
3606
  progress,
3604
3607
  OPACITY_WRITE_EPSILON
@@ -3615,14 +3618,15 @@ var init_BottomSheetEngine = __esm({
3615
3618
  this.scrim.applyOpacity(progress, progressChanged);
3616
3619
  if (progressChanged && this.bus.listenerCount("progress") > 0) {
3617
3620
  this.progressPayload.value = progress;
3618
- this.progressPayload.size = size;
3621
+ this.progressPayload.size = clamped;
3619
3622
  this.emit("progress", this.progressPayload);
3620
3623
  }
3621
3624
  }
3622
3625
  computeProgress(size) {
3623
3626
  const { min, max } = this.getAllowedRange();
3624
- if (max <= min) return 0;
3625
- return Math.min(Math.max((size - min) / (max - min), 0), 1);
3627
+ const reachableMax = Math.min(max, this.snaps.getMaxAxisSize());
3628
+ if (reachableMax <= min) return 0;
3629
+ return Math.min(Math.max((size - min) / (reachableMax - min), 0), 1);
3626
3630
  }
3627
3631
  handleOpen() {
3628
3632
  sheetStack.promote(this.id);
@@ -3646,8 +3650,8 @@ var init_BottomSheetEngine = __esm({
3646
3650
  this.updateAriaSlider();
3647
3651
  this.emit("snap", {
3648
3652
  id: target.id,
3649
- size: target.size,
3650
- progress: this.computeProgress(target.size)
3653
+ size: this.size,
3654
+ progress: this.computeProgress(this.size)
3651
3655
  });
3652
3656
  if (target.size > 0 && !this.lifecycle.isInstalled) {
3653
3657
  this.emit("open", { id: target.id });
@@ -3673,7 +3677,7 @@ var init_BottomSheetEngine = __esm({
3673
3677
  var baseStyles;
3674
3678
  var init_baseStyles = __esm({
3675
3679
  "src/web-component/baseStyles.ts"() {
3676
- 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-header-min-height:80px;--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));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-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,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,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,0.12)}.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: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;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:0 16px 16px}.bs-footer{flex:0 0 auto;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));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)}}.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}}`;
3680
+ 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-header-min-height:80px;--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));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-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,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,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,0.12)}.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;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));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)}}.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}}`;
3677
3681
  }
3678
3682
  });
3679
3683
 
package/dist/index.cjs CHANGED
@@ -2627,7 +2627,9 @@ var BottomSheetEngine = class {
2627
2627
  const previousSize = this.size;
2628
2628
  this.scrollCache.cache(previousId, previousSize, target.size);
2629
2629
  this.activeId = id;
2630
- if (wasClosed && target.size > 0) {
2630
+ const rawTargetSize = this.snapPointsRaw.find((p) => p.id === id)?.size;
2631
+ const opensToRest = id === "closed" || rawTargetSize === 0;
2632
+ if (wasClosed && !opensToRest) {
2631
2633
  this.opening = true;
2632
2634
  sheetStack.promote(this.id);
2633
2635
  }
@@ -2652,8 +2654,8 @@ var BottomSheetEngine = class {
2652
2654
  this.updateAriaSlider();
2653
2655
  this.emit("snap", {
2654
2656
  id,
2655
- size: target.size,
2656
- progress: this.computeProgress(target.size)
2657
+ size: this.size,
2658
+ progress: this.computeProgress(this.size)
2657
2659
  });
2658
2660
  if (wasClosed && target.size > 0) {
2659
2661
  this.emit("open", { id });
@@ -2732,12 +2734,12 @@ var BottomSheetEngine = class {
2732
2734
  const value = typeof h === "number" ? `${h}px` : h;
2733
2735
  const axis = layoutAxis(this.mode);
2734
2736
  this.element.style.setProperty(
2735
- axis === "height" ? "maxHeight" : "maxWidth",
2737
+ axis === "height" ? "max-height" : "max-width",
2736
2738
  value
2737
2739
  );
2738
2740
  if (typeof h === "number") {
2739
2741
  this.maxHeightCap = h;
2740
- this.clampToMaxHeight();
2742
+ this.recompute();
2741
2743
  } else if (typeof window !== "undefined") {
2742
2744
  const probe2 = document.createElement("div");
2743
2745
  probe2.style.cssText = `position:absolute;visibility:hidden;pointer-events:none;${axis === "height" ? "height" : "width"}:${value};`;
@@ -2745,7 +2747,7 @@ var BottomSheetEngine = class {
2745
2747
  const measured = axis === "height" ? probe2.offsetHeight : probe2.offsetWidth;
2746
2748
  probe2.remove();
2747
2749
  this.maxHeightCap = measured > 0 ? measured : void 0;
2748
- this.clampToMaxHeight();
2750
+ this.recompute();
2749
2751
  }
2750
2752
  }
2751
2753
  clampToMaxHeight() {
@@ -2753,9 +2755,6 @@ var BottomSheetEngine = class {
2753
2755
  if (this.snaps.getMaxAxisSize() > this.maxHeightCap) {
2754
2756
  this.snaps.setMaxAxisSize(this.maxHeightCap);
2755
2757
  }
2756
- if (this.size > this.maxHeightCap && !this.gesture?.isDragging) {
2757
- this.applySize(this.maxHeightCap);
2758
- }
2759
2758
  }
2760
2759
  setAllowed(ids, snap) {
2761
2760
  if (this.destroyed) return;
@@ -2893,6 +2892,7 @@ var BottomSheetEngine = class {
2893
2892
  recompute() {
2894
2893
  if (this.destroyed) return;
2895
2894
  this.snaps.recompute();
2895
+ this.clampToMaxHeight();
2896
2896
  this.scrim.invalidateOpacityCache();
2897
2897
  if (this.gesture?.isDragging) return;
2898
2898
  const current = this.snaps.findById(this.activeId);
@@ -2950,9 +2950,10 @@ var BottomSheetEngine = class {
2950
2950
  const handleSize = vertical ? this.handle.offsetHeight : this.handle.offsetWidth;
2951
2951
  const content = this.scrollContainer;
2952
2952
  const natural = content ? handleSize + this.measureContentExtent(vertical) : handleSize;
2953
- if (typeof window === "undefined") return natural;
2953
+ const capped = this.maxHeightCap !== void 0 ? Math.min(natural, this.maxHeightCap) : natural;
2954
+ if (typeof window === "undefined") return capped;
2954
2955
  const viewport = vertical ? window.innerHeight : window.innerWidth;
2955
- return viewport > 0 ? Math.min(natural, viewport) : natural;
2956
+ return viewport > 0 ? Math.min(capped, viewport) : capped;
2956
2957
  }
2957
2958
  installFitObserver() {
2958
2959
  if (typeof ResizeObserver === "undefined") return;
@@ -3323,8 +3324,8 @@ var BottomSheetEngine = class {
3323
3324
  this.updateAriaSlider();
3324
3325
  this.emit("snap", {
3325
3326
  id: target.id,
3326
- size: target.size,
3327
- progress: this.computeProgress(target.size)
3327
+ size: this.size,
3328
+ progress: this.computeProgress(this.size)
3328
3329
  });
3329
3330
  this.haptic();
3330
3331
  if (previousSnapSize === 0 && target.size > 0) {
@@ -3349,23 +3350,25 @@ var BottomSheetEngine = class {
3349
3350
  }
3350
3351
  }
3351
3352
  applySize(size) {
3352
- this.size = size;
3353
- const offset = this.snaps.getMaxAxisSize() - size;
3353
+ const cap = this.snaps.getMaxAxisSize();
3354
+ const clamped = cap > 0 && size > cap && !this.gesture?.isDragging ? cap : size;
3355
+ this.size = clamped;
3356
+ const offset = cap - clamped;
3354
3357
  const style = this.element.style;
3355
3358
  style.transform = this.transformTemplate(offset);
3356
- if (this.sizeWriteSentinel.shouldWrite(size, SIZE_WRITE_EPSILON)) {
3357
- style.setProperty("--bs-size", `${size}px`);
3359
+ if (this.sizeWriteSentinel.shouldWrite(clamped, SIZE_WRITE_EPSILON)) {
3360
+ style.setProperty("--bs-size", `${clamped}px`);
3358
3361
  if (this.scrimParent) {
3359
- this.scrimParent.style.setProperty("--bs-size", `${size}px`);
3362
+ this.scrimParent.style.setProperty("--bs-size", `${clamped}px`);
3360
3363
  }
3361
3364
  if (this.anchorHost && this.anchorHost !== this.scrimParent) {
3362
- this.anchorHost.style.setProperty("--bs-size", `${size}px`);
3365
+ this.anchorHost.style.setProperty("--bs-size", `${clamped}px`);
3363
3366
  }
3364
3367
  if (this.rootEl && this.rootEl !== this.scrimParent && this.rootEl !== this.anchorHost) {
3365
- this.rootEl.style.setProperty("--bs-size", `${size}px`);
3368
+ this.rootEl.style.setProperty("--bs-size", `${clamped}px`);
3366
3369
  }
3367
3370
  }
3368
- const progress = this.computeProgress(size);
3371
+ const progress = this.computeProgress(clamped);
3369
3372
  const progressChanged = this.progressWriteSentinel.shouldWrite(
3370
3373
  progress,
3371
3374
  OPACITY_WRITE_EPSILON
@@ -3382,14 +3385,15 @@ var BottomSheetEngine = class {
3382
3385
  this.scrim.applyOpacity(progress, progressChanged);
3383
3386
  if (progressChanged && this.bus.listenerCount("progress") > 0) {
3384
3387
  this.progressPayload.value = progress;
3385
- this.progressPayload.size = size;
3388
+ this.progressPayload.size = clamped;
3386
3389
  this.emit("progress", this.progressPayload);
3387
3390
  }
3388
3391
  }
3389
3392
  computeProgress(size) {
3390
3393
  const { min, max } = this.getAllowedRange();
3391
- if (max <= min) return 0;
3392
- return Math.min(Math.max((size - min) / (max - min), 0), 1);
3394
+ const reachableMax = Math.min(max, this.snaps.getMaxAxisSize());
3395
+ if (reachableMax <= min) return 0;
3396
+ return Math.min(Math.max((size - min) / (reachableMax - min), 0), 1);
3393
3397
  }
3394
3398
  handleOpen() {
3395
3399
  sheetStack.promote(this.id);
@@ -3413,8 +3417,8 @@ var BottomSheetEngine = class {
3413
3417
  this.updateAriaSlider();
3414
3418
  this.emit("snap", {
3415
3419
  id: target.id,
3416
- size: target.size,
3417
- progress: this.computeProgress(target.size)
3420
+ size: this.size,
3421
+ progress: this.computeProgress(this.size)
3418
3422
  });
3419
3423
  if (target.size > 0 && !this.lifecycle.isInstalled) {
3420
3424
  this.emit("open", { id: target.id });
package/dist/index.js CHANGED
@@ -2625,7 +2625,9 @@ var BottomSheetEngine = class {
2625
2625
  const previousSize = this.size;
2626
2626
  this.scrollCache.cache(previousId, previousSize, target.size);
2627
2627
  this.activeId = id;
2628
- if (wasClosed && target.size > 0) {
2628
+ const rawTargetSize = this.snapPointsRaw.find((p) => p.id === id)?.size;
2629
+ const opensToRest = id === "closed" || rawTargetSize === 0;
2630
+ if (wasClosed && !opensToRest) {
2629
2631
  this.opening = true;
2630
2632
  sheetStack.promote(this.id);
2631
2633
  }
@@ -2650,8 +2652,8 @@ var BottomSheetEngine = class {
2650
2652
  this.updateAriaSlider();
2651
2653
  this.emit("snap", {
2652
2654
  id,
2653
- size: target.size,
2654
- progress: this.computeProgress(target.size)
2655
+ size: this.size,
2656
+ progress: this.computeProgress(this.size)
2655
2657
  });
2656
2658
  if (wasClosed && target.size > 0) {
2657
2659
  this.emit("open", { id });
@@ -2730,12 +2732,12 @@ var BottomSheetEngine = class {
2730
2732
  const value = typeof h === "number" ? `${h}px` : h;
2731
2733
  const axis = layoutAxis(this.mode);
2732
2734
  this.element.style.setProperty(
2733
- axis === "height" ? "maxHeight" : "maxWidth",
2735
+ axis === "height" ? "max-height" : "max-width",
2734
2736
  value
2735
2737
  );
2736
2738
  if (typeof h === "number") {
2737
2739
  this.maxHeightCap = h;
2738
- this.clampToMaxHeight();
2740
+ this.recompute();
2739
2741
  } else if (typeof window !== "undefined") {
2740
2742
  const probe2 = document.createElement("div");
2741
2743
  probe2.style.cssText = `position:absolute;visibility:hidden;pointer-events:none;${axis === "height" ? "height" : "width"}:${value};`;
@@ -2743,7 +2745,7 @@ var BottomSheetEngine = class {
2743
2745
  const measured = axis === "height" ? probe2.offsetHeight : probe2.offsetWidth;
2744
2746
  probe2.remove();
2745
2747
  this.maxHeightCap = measured > 0 ? measured : void 0;
2746
- this.clampToMaxHeight();
2748
+ this.recompute();
2747
2749
  }
2748
2750
  }
2749
2751
  clampToMaxHeight() {
@@ -2751,9 +2753,6 @@ var BottomSheetEngine = class {
2751
2753
  if (this.snaps.getMaxAxisSize() > this.maxHeightCap) {
2752
2754
  this.snaps.setMaxAxisSize(this.maxHeightCap);
2753
2755
  }
2754
- if (this.size > this.maxHeightCap && !this.gesture?.isDragging) {
2755
- this.applySize(this.maxHeightCap);
2756
- }
2757
2756
  }
2758
2757
  setAllowed(ids, snap) {
2759
2758
  if (this.destroyed) return;
@@ -2891,6 +2890,7 @@ var BottomSheetEngine = class {
2891
2890
  recompute() {
2892
2891
  if (this.destroyed) return;
2893
2892
  this.snaps.recompute();
2893
+ this.clampToMaxHeight();
2894
2894
  this.scrim.invalidateOpacityCache();
2895
2895
  if (this.gesture?.isDragging) return;
2896
2896
  const current = this.snaps.findById(this.activeId);
@@ -2948,9 +2948,10 @@ var BottomSheetEngine = class {
2948
2948
  const handleSize = vertical ? this.handle.offsetHeight : this.handle.offsetWidth;
2949
2949
  const content = this.scrollContainer;
2950
2950
  const natural = content ? handleSize + this.measureContentExtent(vertical) : handleSize;
2951
- if (typeof window === "undefined") return natural;
2951
+ const capped = this.maxHeightCap !== void 0 ? Math.min(natural, this.maxHeightCap) : natural;
2952
+ if (typeof window === "undefined") return capped;
2952
2953
  const viewport = vertical ? window.innerHeight : window.innerWidth;
2953
- return viewport > 0 ? Math.min(natural, viewport) : natural;
2954
+ return viewport > 0 ? Math.min(capped, viewport) : capped;
2954
2955
  }
2955
2956
  installFitObserver() {
2956
2957
  if (typeof ResizeObserver === "undefined") return;
@@ -3321,8 +3322,8 @@ var BottomSheetEngine = class {
3321
3322
  this.updateAriaSlider();
3322
3323
  this.emit("snap", {
3323
3324
  id: target.id,
3324
- size: target.size,
3325
- progress: this.computeProgress(target.size)
3325
+ size: this.size,
3326
+ progress: this.computeProgress(this.size)
3326
3327
  });
3327
3328
  this.haptic();
3328
3329
  if (previousSnapSize === 0 && target.size > 0) {
@@ -3347,23 +3348,25 @@ var BottomSheetEngine = class {
3347
3348
  }
3348
3349
  }
3349
3350
  applySize(size) {
3350
- this.size = size;
3351
- const offset = this.snaps.getMaxAxisSize() - size;
3351
+ const cap = this.snaps.getMaxAxisSize();
3352
+ const clamped = cap > 0 && size > cap && !this.gesture?.isDragging ? cap : size;
3353
+ this.size = clamped;
3354
+ const offset = cap - clamped;
3352
3355
  const style = this.element.style;
3353
3356
  style.transform = this.transformTemplate(offset);
3354
- if (this.sizeWriteSentinel.shouldWrite(size, SIZE_WRITE_EPSILON)) {
3355
- style.setProperty("--bs-size", `${size}px`);
3357
+ if (this.sizeWriteSentinel.shouldWrite(clamped, SIZE_WRITE_EPSILON)) {
3358
+ style.setProperty("--bs-size", `${clamped}px`);
3356
3359
  if (this.scrimParent) {
3357
- this.scrimParent.style.setProperty("--bs-size", `${size}px`);
3360
+ this.scrimParent.style.setProperty("--bs-size", `${clamped}px`);
3358
3361
  }
3359
3362
  if (this.anchorHost && this.anchorHost !== this.scrimParent) {
3360
- this.anchorHost.style.setProperty("--bs-size", `${size}px`);
3363
+ this.anchorHost.style.setProperty("--bs-size", `${clamped}px`);
3361
3364
  }
3362
3365
  if (this.rootEl && this.rootEl !== this.scrimParent && this.rootEl !== this.anchorHost) {
3363
- this.rootEl.style.setProperty("--bs-size", `${size}px`);
3366
+ this.rootEl.style.setProperty("--bs-size", `${clamped}px`);
3364
3367
  }
3365
3368
  }
3366
- const progress = this.computeProgress(size);
3369
+ const progress = this.computeProgress(clamped);
3367
3370
  const progressChanged = this.progressWriteSentinel.shouldWrite(
3368
3371
  progress,
3369
3372
  OPACITY_WRITE_EPSILON
@@ -3380,14 +3383,15 @@ var BottomSheetEngine = class {
3380
3383
  this.scrim.applyOpacity(progress, progressChanged);
3381
3384
  if (progressChanged && this.bus.listenerCount("progress") > 0) {
3382
3385
  this.progressPayload.value = progress;
3383
- this.progressPayload.size = size;
3386
+ this.progressPayload.size = clamped;
3384
3387
  this.emit("progress", this.progressPayload);
3385
3388
  }
3386
3389
  }
3387
3390
  computeProgress(size) {
3388
3391
  const { min, max } = this.getAllowedRange();
3389
- if (max <= min) return 0;
3390
- return Math.min(Math.max((size - min) / (max - min), 0), 1);
3392
+ const reachableMax = Math.min(max, this.snaps.getMaxAxisSize());
3393
+ if (reachableMax <= min) return 0;
3394
+ return Math.min(Math.max((size - min) / (reachableMax - min), 0), 1);
3391
3395
  }
3392
3396
  handleOpen() {
3393
3397
  sheetStack.promote(this.id);
@@ -3411,8 +3415,8 @@ var BottomSheetEngine = class {
3411
3415
  this.updateAriaSlider();
3412
3416
  this.emit("snap", {
3413
3417
  id: target.id,
3414
- size: target.size,
3415
- progress: this.computeProgress(target.size)
3418
+ size: this.size,
3419
+ progress: this.computeProgress(this.size)
3416
3420
  });
3417
3421
  if (target.size > 0 && !this.lifecycle.isInstalled) {
3418
3422
  this.emit("open", { id: target.id });
package/dist/qwik.cjs CHANGED
@@ -2623,7 +2623,9 @@ var BottomSheetEngine = class {
2623
2623
  const previousSize = this.size;
2624
2624
  this.scrollCache.cache(previousId, previousSize, target.size);
2625
2625
  this.activeId = id;
2626
- if (wasClosed && target.size > 0) {
2626
+ const rawTargetSize = this.snapPointsRaw.find((p) => p.id === id)?.size;
2627
+ const opensToRest = id === "closed" || rawTargetSize === 0;
2628
+ if (wasClosed && !opensToRest) {
2627
2629
  this.opening = true;
2628
2630
  sheetStack.promote(this.id);
2629
2631
  }
@@ -2648,8 +2650,8 @@ var BottomSheetEngine = class {
2648
2650
  this.updateAriaSlider();
2649
2651
  this.emit("snap", {
2650
2652
  id,
2651
- size: target.size,
2652
- progress: this.computeProgress(target.size)
2653
+ size: this.size,
2654
+ progress: this.computeProgress(this.size)
2653
2655
  });
2654
2656
  if (wasClosed && target.size > 0) {
2655
2657
  this.emit("open", { id });
@@ -2728,12 +2730,12 @@ var BottomSheetEngine = class {
2728
2730
  const value = typeof h === "number" ? `${h}px` : h;
2729
2731
  const axis = layoutAxis(this.mode);
2730
2732
  this.element.style.setProperty(
2731
- axis === "height" ? "maxHeight" : "maxWidth",
2733
+ axis === "height" ? "max-height" : "max-width",
2732
2734
  value
2733
2735
  );
2734
2736
  if (typeof h === "number") {
2735
2737
  this.maxHeightCap = h;
2736
- this.clampToMaxHeight();
2738
+ this.recompute();
2737
2739
  } else if (typeof window !== "undefined") {
2738
2740
  const probe2 = document.createElement("div");
2739
2741
  probe2.style.cssText = `position:absolute;visibility:hidden;pointer-events:none;${axis === "height" ? "height" : "width"}:${value};`;
@@ -2741,7 +2743,7 @@ var BottomSheetEngine = class {
2741
2743
  const measured = axis === "height" ? probe2.offsetHeight : probe2.offsetWidth;
2742
2744
  probe2.remove();
2743
2745
  this.maxHeightCap = measured > 0 ? measured : void 0;
2744
- this.clampToMaxHeight();
2746
+ this.recompute();
2745
2747
  }
2746
2748
  }
2747
2749
  clampToMaxHeight() {
@@ -2749,9 +2751,6 @@ var BottomSheetEngine = class {
2749
2751
  if (this.snaps.getMaxAxisSize() > this.maxHeightCap) {
2750
2752
  this.snaps.setMaxAxisSize(this.maxHeightCap);
2751
2753
  }
2752
- if (this.size > this.maxHeightCap && !this.gesture?.isDragging) {
2753
- this.applySize(this.maxHeightCap);
2754
- }
2755
2754
  }
2756
2755
  setAllowed(ids, snap) {
2757
2756
  if (this.destroyed) return;
@@ -2889,6 +2888,7 @@ var BottomSheetEngine = class {
2889
2888
  recompute() {
2890
2889
  if (this.destroyed) return;
2891
2890
  this.snaps.recompute();
2891
+ this.clampToMaxHeight();
2892
2892
  this.scrim.invalidateOpacityCache();
2893
2893
  if (this.gesture?.isDragging) return;
2894
2894
  const current = this.snaps.findById(this.activeId);
@@ -2946,9 +2946,10 @@ var BottomSheetEngine = class {
2946
2946
  const handleSize = vertical ? this.handle.offsetHeight : this.handle.offsetWidth;
2947
2947
  const content = this.scrollContainer;
2948
2948
  const natural = content ? handleSize + this.measureContentExtent(vertical) : handleSize;
2949
- if (typeof window === "undefined") return natural;
2949
+ const capped = this.maxHeightCap !== void 0 ? Math.min(natural, this.maxHeightCap) : natural;
2950
+ if (typeof window === "undefined") return capped;
2950
2951
  const viewport = vertical ? window.innerHeight : window.innerWidth;
2951
- return viewport > 0 ? Math.min(natural, viewport) : natural;
2952
+ return viewport > 0 ? Math.min(capped, viewport) : capped;
2952
2953
  }
2953
2954
  installFitObserver() {
2954
2955
  if (typeof ResizeObserver === "undefined") return;
@@ -3319,8 +3320,8 @@ var BottomSheetEngine = class {
3319
3320
  this.updateAriaSlider();
3320
3321
  this.emit("snap", {
3321
3322
  id: target.id,
3322
- size: target.size,
3323
- progress: this.computeProgress(target.size)
3323
+ size: this.size,
3324
+ progress: this.computeProgress(this.size)
3324
3325
  });
3325
3326
  this.haptic();
3326
3327
  if (previousSnapSize === 0 && target.size > 0) {
@@ -3345,23 +3346,25 @@ var BottomSheetEngine = class {
3345
3346
  }
3346
3347
  }
3347
3348
  applySize(size) {
3348
- this.size = size;
3349
- const offset = this.snaps.getMaxAxisSize() - size;
3349
+ const cap = this.snaps.getMaxAxisSize();
3350
+ const clamped = cap > 0 && size > cap && !this.gesture?.isDragging ? cap : size;
3351
+ this.size = clamped;
3352
+ const offset = cap - clamped;
3350
3353
  const style = this.element.style;
3351
3354
  style.transform = this.transformTemplate(offset);
3352
- if (this.sizeWriteSentinel.shouldWrite(size, SIZE_WRITE_EPSILON)) {
3353
- style.setProperty("--bs-size", `${size}px`);
3355
+ if (this.sizeWriteSentinel.shouldWrite(clamped, SIZE_WRITE_EPSILON)) {
3356
+ style.setProperty("--bs-size", `${clamped}px`);
3354
3357
  if (this.scrimParent) {
3355
- this.scrimParent.style.setProperty("--bs-size", `${size}px`);
3358
+ this.scrimParent.style.setProperty("--bs-size", `${clamped}px`);
3356
3359
  }
3357
3360
  if (this.anchorHost && this.anchorHost !== this.scrimParent) {
3358
- this.anchorHost.style.setProperty("--bs-size", `${size}px`);
3361
+ this.anchorHost.style.setProperty("--bs-size", `${clamped}px`);
3359
3362
  }
3360
3363
  if (this.rootEl && this.rootEl !== this.scrimParent && this.rootEl !== this.anchorHost) {
3361
- this.rootEl.style.setProperty("--bs-size", `${size}px`);
3364
+ this.rootEl.style.setProperty("--bs-size", `${clamped}px`);
3362
3365
  }
3363
3366
  }
3364
- const progress = this.computeProgress(size);
3367
+ const progress = this.computeProgress(clamped);
3365
3368
  const progressChanged = this.progressWriteSentinel.shouldWrite(
3366
3369
  progress,
3367
3370
  OPACITY_WRITE_EPSILON
@@ -3378,14 +3381,15 @@ var BottomSheetEngine = class {
3378
3381
  this.scrim.applyOpacity(progress, progressChanged);
3379
3382
  if (progressChanged && this.bus.listenerCount("progress") > 0) {
3380
3383
  this.progressPayload.value = progress;
3381
- this.progressPayload.size = size;
3384
+ this.progressPayload.size = clamped;
3382
3385
  this.emit("progress", this.progressPayload);
3383
3386
  }
3384
3387
  }
3385
3388
  computeProgress(size) {
3386
3389
  const { min, max } = this.getAllowedRange();
3387
- if (max <= min) return 0;
3388
- return Math.min(Math.max((size - min) / (max - min), 0), 1);
3390
+ const reachableMax = Math.min(max, this.snaps.getMaxAxisSize());
3391
+ if (reachableMax <= min) return 0;
3392
+ return Math.min(Math.max((size - min) / (reachableMax - min), 0), 1);
3389
3393
  }
3390
3394
  handleOpen() {
3391
3395
  sheetStack.promote(this.id);
@@ -3409,8 +3413,8 @@ var BottomSheetEngine = class {
3409
3413
  this.updateAriaSlider();
3410
3414
  this.emit("snap", {
3411
3415
  id: target.id,
3412
- size: target.size,
3413
- progress: this.computeProgress(target.size)
3416
+ size: this.size,
3417
+ progress: this.computeProgress(this.size)
3414
3418
  });
3415
3419
  if (target.size > 0 && !this.lifecycle.isInstalled) {
3416
3420
  this.emit("open", { id: target.id });