@surdeddd/bottom-sheet 0.6.1 → 0.8.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/svelte.cjs CHANGED
@@ -2381,6 +2381,7 @@ var BottomSheetEngine = class {
2381
2381
  __publicField(this, "progressWriteSentinel", new WriteSentinel());
2382
2382
  __publicField(this, "isTopSheet", true);
2383
2383
  __publicField(this, "opening", false);
2384
+ __publicField(this, "allowOvershoot", false);
2384
2385
  __publicField(this, "progressPayload", {
2385
2386
  value: 0,
2386
2387
  size: 0
@@ -2671,8 +2672,8 @@ var BottomSheetEngine = class {
2671
2672
  this.updateAriaSlider();
2672
2673
  this.emit("snap", {
2673
2674
  id,
2674
- size: target.size,
2675
- progress: this.computeProgress(target.size)
2675
+ size: this.size,
2676
+ progress: this.computeProgress(this.size)
2676
2677
  });
2677
2678
  if (wasClosed && target.size > 0) {
2678
2679
  this.emit("open", { id });
@@ -2751,12 +2752,12 @@ var BottomSheetEngine = class {
2751
2752
  const value = typeof h === "number" ? `${h}px` : h;
2752
2753
  const axis = layoutAxis(this.mode);
2753
2754
  this.element.style.setProperty(
2754
- axis === "height" ? "maxHeight" : "maxWidth",
2755
+ axis === "height" ? "max-height" : "max-width",
2755
2756
  value
2756
2757
  );
2757
2758
  if (typeof h === "number") {
2758
2759
  this.maxHeightCap = h;
2759
- this.clampToMaxHeight();
2760
+ this.recompute();
2760
2761
  } else if (typeof window !== "undefined") {
2761
2762
  const probe2 = document.createElement("div");
2762
2763
  probe2.style.cssText = `position:absolute;visibility:hidden;pointer-events:none;${axis === "height" ? "height" : "width"}:${value};`;
@@ -2764,7 +2765,7 @@ var BottomSheetEngine = class {
2764
2765
  const measured = axis === "height" ? probe2.offsetHeight : probe2.offsetWidth;
2765
2766
  probe2.remove();
2766
2767
  this.maxHeightCap = measured > 0 ? measured : void 0;
2767
- this.clampToMaxHeight();
2768
+ this.recompute();
2768
2769
  }
2769
2770
  }
2770
2771
  clampToMaxHeight() {
@@ -2772,9 +2773,6 @@ var BottomSheetEngine = class {
2772
2773
  if (this.snaps.getMaxAxisSize() > this.maxHeightCap) {
2773
2774
  this.snaps.setMaxAxisSize(this.maxHeightCap);
2774
2775
  }
2775
- if (this.size > this.maxHeightCap && !this.gesture?.isDragging) {
2776
- this.applySize(this.maxHeightCap);
2777
- }
2778
2776
  }
2779
2777
  setAllowed(ids, snap) {
2780
2778
  if (this.destroyed) return;
@@ -2912,6 +2910,7 @@ var BottomSheetEngine = class {
2912
2910
  recompute() {
2913
2911
  if (this.destroyed) return;
2914
2912
  this.snaps.recompute();
2913
+ this.clampToMaxHeight();
2915
2914
  this.scrim.invalidateOpacityCache();
2916
2915
  if (this.gesture?.isDragging) return;
2917
2916
  const current = this.snaps.findById(this.activeId);
@@ -2935,43 +2934,36 @@ var BottomSheetEngine = class {
2935
2934
  }
2936
2935
  return out;
2937
2936
  }
2938
- measureContentExtent(vertical) {
2937
+ measureSheetNatural(vertical) {
2938
+ const el = this.element;
2939
2939
  const content = this.scrollContainer;
2940
- if (!content) return 0;
2941
- const targets = this.contentTargets();
2942
- if (targets.length === 0) {
2943
- return vertical ? content.scrollHeight : content.scrollWidth;
2944
- }
2945
- let min = Infinity;
2946
- let max = -Infinity;
2947
- for (const el of targets) {
2948
- const r = el.getBoundingClientRect();
2949
- if (vertical) {
2950
- if (r.top < min) min = r.top;
2951
- if (r.bottom > max) max = r.bottom;
2952
- } else {
2953
- if (r.left < min) min = r.left;
2954
- if (r.right > max) max = r.right;
2955
- }
2956
- }
2957
- if (!isFinite(min) || !isFinite(max) || max <= min) {
2958
- return vertical ? content.scrollHeight : content.scrollWidth;
2959
- }
2960
- let pad = 0;
2961
- if (typeof getComputedStyle !== "undefined") {
2962
- const cs = getComputedStyle(content);
2963
- pad = vertical ? (parseFloat(cs.paddingTop) || 0) + (parseFloat(cs.paddingBottom) || 0) : (parseFloat(cs.paddingLeft) || 0) + (parseFloat(cs.paddingRight) || 0);
2964
- }
2965
- return max - min + pad;
2940
+ if (!content) {
2941
+ return vertical ? el.offsetHeight : el.offsetWidth;
2942
+ }
2943
+ const axis = vertical ? "height" : "width";
2944
+ const sheetStyle = el.style;
2945
+ const cs = content.style;
2946
+ const prevSheet = sheetStyle[axis];
2947
+ const prevFlex = cs.flex;
2948
+ const prevContent = vertical ? cs.height : cs.width;
2949
+ sheetStyle[axis] = "auto";
2950
+ cs.flex = "none";
2951
+ if (vertical) cs.height = "auto";
2952
+ else cs.width = "auto";
2953
+ const natural = vertical ? el.offsetHeight : el.offsetWidth;
2954
+ sheetStyle[axis] = prevSheet;
2955
+ cs.flex = prevFlex;
2956
+ if (vertical) cs.height = prevContent;
2957
+ else cs.width = prevContent;
2958
+ return natural;
2966
2959
  }
2967
2960
  measureFitSize() {
2968
2961
  const vertical = layoutAxis(this.mode) === "height";
2969
- const handleSize = vertical ? this.handle.offsetHeight : this.handle.offsetWidth;
2970
- const content = this.scrollContainer;
2971
- const natural = content ? handleSize + this.measureContentExtent(vertical) : handleSize;
2972
- if (typeof window === "undefined") return natural;
2962
+ const natural = this.measureSheetNatural(vertical);
2963
+ const capped = this.maxHeightCap !== void 0 ? Math.min(natural, this.maxHeightCap) : natural;
2964
+ if (typeof window === "undefined") return capped;
2973
2965
  const viewport = vertical ? window.innerHeight : window.innerWidth;
2974
- return viewport > 0 ? Math.min(natural, viewport) : natural;
2966
+ return viewport > 0 ? Math.min(capped, viewport) : capped;
2975
2967
  }
2976
2968
  installFitObserver() {
2977
2969
  if (typeof ResizeObserver === "undefined") return;
@@ -3053,6 +3045,10 @@ var BottomSheetEngine = class {
3053
3045
  this.backdrop.style.opacity = "";
3054
3046
  this.backdrop.style.pointerEvents = "";
3055
3047
  }
3048
+ if (this.anchorHost) {
3049
+ this.anchorHost.style.removeProperty("--bs-size");
3050
+ this.anchorHost.style.removeProperty("--bs-progress");
3051
+ }
3056
3052
  if (this.screenComponent) {
3057
3053
  this.screenComponent.style.opacity = "";
3058
3054
  this.screenComponent.style.display = "";
@@ -3064,6 +3060,7 @@ var BottomSheetEngine = class {
3064
3060
  this.bus.emit(event, payload);
3065
3061
  }
3066
3062
  newCycle() {
3063
+ this.allowOvershoot = false;
3067
3064
  this.currentAbort.abort();
3068
3065
  this.currentAbort = new AbortController();
3069
3066
  return this.currentAbort.signal;
@@ -3129,6 +3126,7 @@ var BottomSheetEngine = class {
3129
3126
  seen.add(p.id);
3130
3127
  }
3131
3128
  this.snaps.setRaw(this.snapPointsRaw);
3129
+ this.clampToMaxHeight();
3132
3130
  this.scrim.invalidateOpacityCache();
3133
3131
  }
3134
3132
  getAllowedRange() {
@@ -3335,15 +3333,19 @@ var BottomSheetEngine = class {
3335
3333
  this.opening = true;
3336
3334
  sheetStack.promote(this.id);
3337
3335
  }
3338
- void this.animation.animateTo(target.size, velocity).then(() => {
3339
- this.opening = false;
3336
+ const settleCap = this.snaps.getMaxAxisSize();
3337
+ const settleSize = settleCap > 0 ? Math.min(target.size, settleCap) : target.size;
3338
+ this.allowOvershoot = true;
3339
+ void this.animation.animateTo(settleSize, velocity).then(() => {
3340
3340
  if (signal.aborted) return;
3341
+ this.allowOvershoot = false;
3342
+ this.opening = false;
3341
3343
  this.scrollCache.restore(target.id, previousSize, target.size);
3342
3344
  this.updateAriaSlider();
3343
3345
  this.emit("snap", {
3344
3346
  id: target.id,
3345
- size: target.size,
3346
- progress: this.computeProgress(target.size)
3347
+ size: this.size,
3348
+ progress: this.computeProgress(this.size)
3347
3349
  });
3348
3350
  this.haptic();
3349
3351
  if (previousSnapSize === 0 && target.size > 0) {
@@ -3368,23 +3370,25 @@ var BottomSheetEngine = class {
3368
3370
  }
3369
3371
  }
3370
3372
  applySize(size) {
3371
- this.size = size;
3372
- const offset = this.snaps.getMaxAxisSize() - size;
3373
+ const cap = this.snaps.getMaxAxisSize();
3374
+ const clamped = cap > 0 && size > cap && !this.gesture?.isDragging && !this.allowOvershoot ? cap : size;
3375
+ this.size = clamped;
3376
+ const offset = cap - clamped;
3373
3377
  const style = this.element.style;
3374
3378
  style.transform = this.transformTemplate(offset);
3375
- if (this.sizeWriteSentinel.shouldWrite(size, SIZE_WRITE_EPSILON)) {
3376
- style.setProperty("--bs-size", `${size}px`);
3379
+ if (this.sizeWriteSentinel.shouldWrite(clamped, SIZE_WRITE_EPSILON)) {
3380
+ style.setProperty("--bs-size", `${clamped}px`);
3377
3381
  if (this.scrimParent) {
3378
- this.scrimParent.style.setProperty("--bs-size", `${size}px`);
3382
+ this.scrimParent.style.setProperty("--bs-size", `${clamped}px`);
3379
3383
  }
3380
3384
  if (this.anchorHost && this.anchorHost !== this.scrimParent) {
3381
- this.anchorHost.style.setProperty("--bs-size", `${size}px`);
3385
+ this.anchorHost.style.setProperty("--bs-size", `${clamped}px`);
3382
3386
  }
3383
3387
  if (this.rootEl && this.rootEl !== this.scrimParent && this.rootEl !== this.anchorHost) {
3384
- this.rootEl.style.setProperty("--bs-size", `${size}px`);
3388
+ this.rootEl.style.setProperty("--bs-size", `${clamped}px`);
3385
3389
  }
3386
3390
  }
3387
- const progress = this.computeProgress(size);
3391
+ const progress = this.computeProgress(clamped);
3388
3392
  const progressChanged = this.progressWriteSentinel.shouldWrite(
3389
3393
  progress,
3390
3394
  OPACITY_WRITE_EPSILON
@@ -3401,14 +3405,15 @@ var BottomSheetEngine = class {
3401
3405
  this.scrim.applyOpacity(progress, progressChanged);
3402
3406
  if (progressChanged && this.bus.listenerCount("progress") > 0) {
3403
3407
  this.progressPayload.value = progress;
3404
- this.progressPayload.size = size;
3408
+ this.progressPayload.size = clamped;
3405
3409
  this.emit("progress", this.progressPayload);
3406
3410
  }
3407
3411
  }
3408
3412
  computeProgress(size) {
3409
3413
  const { min, max } = this.getAllowedRange();
3410
- if (max <= min) return 0;
3411
- return Math.min(Math.max((size - min) / (max - min), 0), 1);
3414
+ const reachableMax = Math.min(max, this.snaps.getMaxAxisSize());
3415
+ if (reachableMax <= min) return 0;
3416
+ return Math.min(Math.max((size - min) / (reachableMax - min), 0), 1);
3412
3417
  }
3413
3418
  handleOpen() {
3414
3419
  sheetStack.promote(this.id);
@@ -3432,8 +3437,8 @@ var BottomSheetEngine = class {
3432
3437
  this.updateAriaSlider();
3433
3438
  this.emit("snap", {
3434
3439
  id: target.id,
3435
- size: target.size,
3436
- progress: this.computeProgress(target.size)
3440
+ size: this.size,
3441
+ progress: this.computeProgress(this.size)
3437
3442
  });
3438
3443
  if (target.size > 0 && !this.lifecycle.isInstalled) {
3439
3444
  this.emit("open", { id: target.id });
@@ -3697,8 +3702,6 @@ function BottomSheet($$anchor, $$props) {
3697
3702
  if (next && !isOpen) void engine.open();
3698
3703
  else if (!next && isOpen) void engine.close();
3699
3704
  });
3700
- let allowedIds = $2__namespace.derived(() => $$props.allowed && $$props.allowed.length > 0 ? $$props.allowed : $$props.snapPoints.map((s) => s.id));
3701
- let activeIdx = $2__namespace.derived(() => $2__namespace.get(allowedIds).indexOf($2__namespace.get(viewState).activeId));
3702
3705
  let isVerticalAxis = $2__namespace.derived(() => mode() === "bottom" || mode() === "top");
3703
3706
  var $$exports = {
3704
3707
  snapTo,
@@ -3752,7 +3755,6 @@ function BottomSheet($$anchor, $$props) {
3752
3755
  $2__namespace.bind_this(div_2, ($$value) => $2__namespace.set(screenEl, $$value), () => $2__namespace.get(screenEl));
3753
3756
  var section = $2__namespace.sibling(div_2, 2);
3754
3757
  var div_3 = $2__namespace.child(section);
3755
- $2__namespace.set_attribute(div_3, "aria-valuemin", 0);
3756
3758
  $2__namespace.bind_this(div_3, ($$value) => $2__namespace.set(handleEl, $$value), () => $2__namespace.get(handleEl));
3757
3759
  var node_3 = $2__namespace.sibling(div_3, 2);
3758
3760
  {
@@ -3829,23 +3831,14 @@ function BottomSheet($$anchor, $$props) {
3829
3831
  });
3830
3832
  }
3831
3833
  $2__namespace.reset(div);
3832
- $2__namespace.template_effect(
3833
- ($0, $1) => {
3834
- $2__namespace.set_attribute(section, "data-mode", mode());
3835
- $2__namespace.set_attribute(section, "data-active", $2__namespace.get(viewState).activeId);
3836
- $2__namespace.set_attribute(section, "aria-modal", focusTrap() ? "true" : void 0);
3837
- $2__namespace.set_attribute(section, "aria-label", ariaLabel());
3838
- $2__namespace.set_attribute(div_3, "aria-orientation", $2__namespace.get(isVerticalAxis) ? "vertical" : "horizontal");
3839
- $2__namespace.set_attribute(div_3, "aria-valuemax", $0);
3840
- $2__namespace.set_attribute(div_3, "aria-valuenow", $1);
3841
- $2__namespace.set_attribute(div_3, "aria-valuetext", $2__namespace.get(viewState).activeId);
3842
- $2__namespace.set_text(text, $2__namespace.get(viewState).activeId);
3843
- },
3844
- [
3845
- () => Math.max(0, $2__namespace.get(allowedIds).length - 1),
3846
- () => Math.max(0, $2__namespace.get(activeIdx))
3847
- ]
3848
- );
3834
+ $2__namespace.template_effect(() => {
3835
+ $2__namespace.set_attribute(section, "data-mode", mode());
3836
+ $2__namespace.set_attribute(section, "data-active", $2__namespace.get(viewState).activeId);
3837
+ $2__namespace.set_attribute(section, "aria-modal", focusTrap() ? "true" : void 0);
3838
+ $2__namespace.set_attribute(section, "aria-label", ariaLabel());
3839
+ $2__namespace.set_attribute(div_3, "aria-orientation", $2__namespace.get(isVerticalAxis) ? "vertical" : "horizontal");
3840
+ $2__namespace.set_text(text, $2__namespace.get(viewState).activeId);
3841
+ });
3849
3842
  $2__namespace.append($$anchor, div);
3850
3843
  return $2__namespace.pop($$exports);
3851
3844
  }
package/dist/svelte.js CHANGED
@@ -2359,6 +2359,7 @@ var BottomSheetEngine = class {
2359
2359
  __publicField(this, "progressWriteSentinel", new WriteSentinel());
2360
2360
  __publicField(this, "isTopSheet", true);
2361
2361
  __publicField(this, "opening", false);
2362
+ __publicField(this, "allowOvershoot", false);
2362
2363
  __publicField(this, "progressPayload", {
2363
2364
  value: 0,
2364
2365
  size: 0
@@ -2649,8 +2650,8 @@ var BottomSheetEngine = class {
2649
2650
  this.updateAriaSlider();
2650
2651
  this.emit("snap", {
2651
2652
  id,
2652
- size: target.size,
2653
- progress: this.computeProgress(target.size)
2653
+ size: this.size,
2654
+ progress: this.computeProgress(this.size)
2654
2655
  });
2655
2656
  if (wasClosed && target.size > 0) {
2656
2657
  this.emit("open", { id });
@@ -2729,12 +2730,12 @@ var BottomSheetEngine = class {
2729
2730
  const value = typeof h === "number" ? `${h}px` : h;
2730
2731
  const axis = layoutAxis(this.mode);
2731
2732
  this.element.style.setProperty(
2732
- axis === "height" ? "maxHeight" : "maxWidth",
2733
+ axis === "height" ? "max-height" : "max-width",
2733
2734
  value
2734
2735
  );
2735
2736
  if (typeof h === "number") {
2736
2737
  this.maxHeightCap = h;
2737
- this.clampToMaxHeight();
2738
+ this.recompute();
2738
2739
  } else if (typeof window !== "undefined") {
2739
2740
  const probe2 = document.createElement("div");
2740
2741
  probe2.style.cssText = `position:absolute;visibility:hidden;pointer-events:none;${axis === "height" ? "height" : "width"}:${value};`;
@@ -2742,7 +2743,7 @@ var BottomSheetEngine = class {
2742
2743
  const measured = axis === "height" ? probe2.offsetHeight : probe2.offsetWidth;
2743
2744
  probe2.remove();
2744
2745
  this.maxHeightCap = measured > 0 ? measured : void 0;
2745
- this.clampToMaxHeight();
2746
+ this.recompute();
2746
2747
  }
2747
2748
  }
2748
2749
  clampToMaxHeight() {
@@ -2750,9 +2751,6 @@ var BottomSheetEngine = class {
2750
2751
  if (this.snaps.getMaxAxisSize() > this.maxHeightCap) {
2751
2752
  this.snaps.setMaxAxisSize(this.maxHeightCap);
2752
2753
  }
2753
- if (this.size > this.maxHeightCap && !this.gesture?.isDragging) {
2754
- this.applySize(this.maxHeightCap);
2755
- }
2756
2754
  }
2757
2755
  setAllowed(ids, snap) {
2758
2756
  if (this.destroyed) return;
@@ -2890,6 +2888,7 @@ var BottomSheetEngine = class {
2890
2888
  recompute() {
2891
2889
  if (this.destroyed) return;
2892
2890
  this.snaps.recompute();
2891
+ this.clampToMaxHeight();
2893
2892
  this.scrim.invalidateOpacityCache();
2894
2893
  if (this.gesture?.isDragging) return;
2895
2894
  const current = this.snaps.findById(this.activeId);
@@ -2913,43 +2912,36 @@ var BottomSheetEngine = class {
2913
2912
  }
2914
2913
  return out;
2915
2914
  }
2916
- measureContentExtent(vertical) {
2915
+ measureSheetNatural(vertical) {
2916
+ const el = this.element;
2917
2917
  const content = this.scrollContainer;
2918
- if (!content) return 0;
2919
- const targets = this.contentTargets();
2920
- if (targets.length === 0) {
2921
- return vertical ? content.scrollHeight : content.scrollWidth;
2922
- }
2923
- let min = Infinity;
2924
- let max = -Infinity;
2925
- for (const el of targets) {
2926
- const r = el.getBoundingClientRect();
2927
- if (vertical) {
2928
- if (r.top < min) min = r.top;
2929
- if (r.bottom > max) max = r.bottom;
2930
- } else {
2931
- if (r.left < min) min = r.left;
2932
- if (r.right > max) max = r.right;
2933
- }
2934
- }
2935
- if (!isFinite(min) || !isFinite(max) || max <= min) {
2936
- return vertical ? content.scrollHeight : content.scrollWidth;
2937
- }
2938
- let pad = 0;
2939
- if (typeof getComputedStyle !== "undefined") {
2940
- const cs = getComputedStyle(content);
2941
- pad = vertical ? (parseFloat(cs.paddingTop) || 0) + (parseFloat(cs.paddingBottom) || 0) : (parseFloat(cs.paddingLeft) || 0) + (parseFloat(cs.paddingRight) || 0);
2942
- }
2943
- return max - min + pad;
2918
+ if (!content) {
2919
+ return vertical ? el.offsetHeight : el.offsetWidth;
2920
+ }
2921
+ const axis = vertical ? "height" : "width";
2922
+ const sheetStyle = el.style;
2923
+ const cs = content.style;
2924
+ const prevSheet = sheetStyle[axis];
2925
+ const prevFlex = cs.flex;
2926
+ const prevContent = vertical ? cs.height : cs.width;
2927
+ sheetStyle[axis] = "auto";
2928
+ cs.flex = "none";
2929
+ if (vertical) cs.height = "auto";
2930
+ else cs.width = "auto";
2931
+ const natural = vertical ? el.offsetHeight : el.offsetWidth;
2932
+ sheetStyle[axis] = prevSheet;
2933
+ cs.flex = prevFlex;
2934
+ if (vertical) cs.height = prevContent;
2935
+ else cs.width = prevContent;
2936
+ return natural;
2944
2937
  }
2945
2938
  measureFitSize() {
2946
2939
  const vertical = layoutAxis(this.mode) === "height";
2947
- const handleSize = vertical ? this.handle.offsetHeight : this.handle.offsetWidth;
2948
- const content = this.scrollContainer;
2949
- const natural = content ? handleSize + this.measureContentExtent(vertical) : handleSize;
2950
- if (typeof window === "undefined") return natural;
2940
+ const natural = this.measureSheetNatural(vertical);
2941
+ const capped = this.maxHeightCap !== void 0 ? Math.min(natural, this.maxHeightCap) : natural;
2942
+ if (typeof window === "undefined") return capped;
2951
2943
  const viewport = vertical ? window.innerHeight : window.innerWidth;
2952
- return viewport > 0 ? Math.min(natural, viewport) : natural;
2944
+ return viewport > 0 ? Math.min(capped, viewport) : capped;
2953
2945
  }
2954
2946
  installFitObserver() {
2955
2947
  if (typeof ResizeObserver === "undefined") return;
@@ -3031,6 +3023,10 @@ var BottomSheetEngine = class {
3031
3023
  this.backdrop.style.opacity = "";
3032
3024
  this.backdrop.style.pointerEvents = "";
3033
3025
  }
3026
+ if (this.anchorHost) {
3027
+ this.anchorHost.style.removeProperty("--bs-size");
3028
+ this.anchorHost.style.removeProperty("--bs-progress");
3029
+ }
3034
3030
  if (this.screenComponent) {
3035
3031
  this.screenComponent.style.opacity = "";
3036
3032
  this.screenComponent.style.display = "";
@@ -3042,6 +3038,7 @@ var BottomSheetEngine = class {
3042
3038
  this.bus.emit(event, payload);
3043
3039
  }
3044
3040
  newCycle() {
3041
+ this.allowOvershoot = false;
3045
3042
  this.currentAbort.abort();
3046
3043
  this.currentAbort = new AbortController();
3047
3044
  return this.currentAbort.signal;
@@ -3107,6 +3104,7 @@ var BottomSheetEngine = class {
3107
3104
  seen.add(p.id);
3108
3105
  }
3109
3106
  this.snaps.setRaw(this.snapPointsRaw);
3107
+ this.clampToMaxHeight();
3110
3108
  this.scrim.invalidateOpacityCache();
3111
3109
  }
3112
3110
  getAllowedRange() {
@@ -3313,15 +3311,19 @@ var BottomSheetEngine = class {
3313
3311
  this.opening = true;
3314
3312
  sheetStack.promote(this.id);
3315
3313
  }
3316
- void this.animation.animateTo(target.size, velocity).then(() => {
3317
- this.opening = false;
3314
+ const settleCap = this.snaps.getMaxAxisSize();
3315
+ const settleSize = settleCap > 0 ? Math.min(target.size, settleCap) : target.size;
3316
+ this.allowOvershoot = true;
3317
+ void this.animation.animateTo(settleSize, velocity).then(() => {
3318
3318
  if (signal.aborted) return;
3319
+ this.allowOvershoot = false;
3320
+ this.opening = false;
3319
3321
  this.scrollCache.restore(target.id, previousSize, target.size);
3320
3322
  this.updateAriaSlider();
3321
3323
  this.emit("snap", {
3322
3324
  id: target.id,
3323
- size: target.size,
3324
- progress: this.computeProgress(target.size)
3325
+ size: this.size,
3326
+ progress: this.computeProgress(this.size)
3325
3327
  });
3326
3328
  this.haptic();
3327
3329
  if (previousSnapSize === 0 && target.size > 0) {
@@ -3346,23 +3348,25 @@ var BottomSheetEngine = class {
3346
3348
  }
3347
3349
  }
3348
3350
  applySize(size) {
3349
- this.size = size;
3350
- const offset = this.snaps.getMaxAxisSize() - size;
3351
+ const cap = this.snaps.getMaxAxisSize();
3352
+ const clamped = cap > 0 && size > cap && !this.gesture?.isDragging && !this.allowOvershoot ? cap : size;
3353
+ this.size = clamped;
3354
+ const offset = cap - clamped;
3351
3355
  const style = this.element.style;
3352
3356
  style.transform = this.transformTemplate(offset);
3353
- if (this.sizeWriteSentinel.shouldWrite(size, SIZE_WRITE_EPSILON)) {
3354
- style.setProperty("--bs-size", `${size}px`);
3357
+ if (this.sizeWriteSentinel.shouldWrite(clamped, SIZE_WRITE_EPSILON)) {
3358
+ style.setProperty("--bs-size", `${clamped}px`);
3355
3359
  if (this.scrimParent) {
3356
- this.scrimParent.style.setProperty("--bs-size", `${size}px`);
3360
+ this.scrimParent.style.setProperty("--bs-size", `${clamped}px`);
3357
3361
  }
3358
3362
  if (this.anchorHost && this.anchorHost !== this.scrimParent) {
3359
- this.anchorHost.style.setProperty("--bs-size", `${size}px`);
3363
+ this.anchorHost.style.setProperty("--bs-size", `${clamped}px`);
3360
3364
  }
3361
3365
  if (this.rootEl && this.rootEl !== this.scrimParent && this.rootEl !== this.anchorHost) {
3362
- this.rootEl.style.setProperty("--bs-size", `${size}px`);
3366
+ this.rootEl.style.setProperty("--bs-size", `${clamped}px`);
3363
3367
  }
3364
3368
  }
3365
- const progress = this.computeProgress(size);
3369
+ const progress = this.computeProgress(clamped);
3366
3370
  const progressChanged = this.progressWriteSentinel.shouldWrite(
3367
3371
  progress,
3368
3372
  OPACITY_WRITE_EPSILON
@@ -3379,14 +3383,15 @@ var BottomSheetEngine = class {
3379
3383
  this.scrim.applyOpacity(progress, progressChanged);
3380
3384
  if (progressChanged && this.bus.listenerCount("progress") > 0) {
3381
3385
  this.progressPayload.value = progress;
3382
- this.progressPayload.size = size;
3386
+ this.progressPayload.size = clamped;
3383
3387
  this.emit("progress", this.progressPayload);
3384
3388
  }
3385
3389
  }
3386
3390
  computeProgress(size) {
3387
3391
  const { min, max } = this.getAllowedRange();
3388
- if (max <= min) return 0;
3389
- 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);
3390
3395
  }
3391
3396
  handleOpen() {
3392
3397
  sheetStack.promote(this.id);
@@ -3410,8 +3415,8 @@ var BottomSheetEngine = class {
3410
3415
  this.updateAriaSlider();
3411
3416
  this.emit("snap", {
3412
3417
  id: target.id,
3413
- size: target.size,
3414
- progress: this.computeProgress(target.size)
3418
+ size: this.size,
3419
+ progress: this.computeProgress(this.size)
3415
3420
  });
3416
3421
  if (target.size > 0 && !this.lifecycle.isInstalled) {
3417
3422
  this.emit("open", { id: target.id });
@@ -3675,8 +3680,6 @@ function BottomSheet($$anchor, $$props) {
3675
3680
  if (next && !isOpen) void engine.open();
3676
3681
  else if (!next && isOpen) void engine.close();
3677
3682
  });
3678
- let allowedIds = $2.derived(() => $$props.allowed && $$props.allowed.length > 0 ? $$props.allowed : $$props.snapPoints.map((s) => s.id));
3679
- let activeIdx = $2.derived(() => $2.get(allowedIds).indexOf($2.get(viewState).activeId));
3680
3683
  let isVerticalAxis = $2.derived(() => mode() === "bottom" || mode() === "top");
3681
3684
  var $$exports = {
3682
3685
  snapTo,
@@ -3730,7 +3733,6 @@ function BottomSheet($$anchor, $$props) {
3730
3733
  $2.bind_this(div_2, ($$value) => $2.set(screenEl, $$value), () => $2.get(screenEl));
3731
3734
  var section = $2.sibling(div_2, 2);
3732
3735
  var div_3 = $2.child(section);
3733
- $2.set_attribute(div_3, "aria-valuemin", 0);
3734
3736
  $2.bind_this(div_3, ($$value) => $2.set(handleEl, $$value), () => $2.get(handleEl));
3735
3737
  var node_3 = $2.sibling(div_3, 2);
3736
3738
  {
@@ -3807,23 +3809,14 @@ function BottomSheet($$anchor, $$props) {
3807
3809
  });
3808
3810
  }
3809
3811
  $2.reset(div);
3810
- $2.template_effect(
3811
- ($0, $1) => {
3812
- $2.set_attribute(section, "data-mode", mode());
3813
- $2.set_attribute(section, "data-active", $2.get(viewState).activeId);
3814
- $2.set_attribute(section, "aria-modal", focusTrap() ? "true" : void 0);
3815
- $2.set_attribute(section, "aria-label", ariaLabel());
3816
- $2.set_attribute(div_3, "aria-orientation", $2.get(isVerticalAxis) ? "vertical" : "horizontal");
3817
- $2.set_attribute(div_3, "aria-valuemax", $0);
3818
- $2.set_attribute(div_3, "aria-valuenow", $1);
3819
- $2.set_attribute(div_3, "aria-valuetext", $2.get(viewState).activeId);
3820
- $2.set_text(text, $2.get(viewState).activeId);
3821
- },
3822
- [
3823
- () => Math.max(0, $2.get(allowedIds).length - 1),
3824
- () => Math.max(0, $2.get(activeIdx))
3825
- ]
3826
- );
3812
+ $2.template_effect(() => {
3813
+ $2.set_attribute(section, "data-mode", mode());
3814
+ $2.set_attribute(section, "data-active", $2.get(viewState).activeId);
3815
+ $2.set_attribute(section, "aria-modal", focusTrap() ? "true" : void 0);
3816
+ $2.set_attribute(section, "aria-label", ariaLabel());
3817
+ $2.set_attribute(div_3, "aria-orientation", $2.get(isVerticalAxis) ? "vertical" : "horizontal");
3818
+ $2.set_text(text, $2.get(viewState).activeId);
3819
+ });
3827
3820
  $2.append($$anchor, div);
3828
3821
  return $2.pop($$exports);
3829
3822
  }