@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/vue.cjs 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);
2918
+ if (!content) {
2919
+ return vertical ? el.offsetHeight : el.offsetWidth;
2942
2920
  }
2943
- return max - min + pad;
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 });
@@ -3937,11 +3942,6 @@ var _sfc_main = /* @__PURE__ */ vue.defineComponent({
3937
3942
  const mode = props.mode ?? "bottom";
3938
3943
  return mode === "bottom" || mode === "top";
3939
3944
  });
3940
- const allowedIds = vue.computed(() => props.allowed ?? props.snapPoints.map((p) => p.id));
3941
- const activeIdx = vue.computed(() => {
3942
- const idx = allowedIds.value.indexOf(state.activeId);
3943
- return idx === -1 ? 0 : idx;
3944
- });
3945
3945
  const ariaModal = vue.computed(() => props.focusTrap === true);
3946
3946
  __expose({
3947
3947
  snapTo,
@@ -4011,8 +4011,6 @@ var _sfc_main = /* @__PURE__ */ vue.defineComponent({
4011
4011
  anchorsKey,
4012
4012
  applyStages,
4013
4013
  isVerticalAxis,
4014
- allowedIds,
4015
- activeIdx,
4016
4014
  ariaModal
4017
4015
  };
4018
4016
  Object.defineProperty(__returned__, "__isScriptSetup", {
@@ -4034,12 +4032,7 @@ var _hoisted_3 = [
4034
4032
  "aria-modal",
4035
4033
  "aria-label"
4036
4034
  ];
4037
- var _hoisted_4 = [
4038
- "aria-orientation",
4039
- "aria-valuemax",
4040
- "aria-valuenow",
4041
- "aria-valuetext"
4042
- ];
4035
+ var _hoisted_4 = ["aria-orientation"];
4043
4036
  var _hoisted_5 = {
4044
4037
  key: 0,
4045
4038
  class: "bs-header"
@@ -4102,10 +4095,6 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
4102
4095
  role: "slider",
4103
4096
  tabindex: "0",
4104
4097
  "aria-orientation": $setup.isVerticalAxis ? "vertical" : "horizontal",
4105
- "aria-valuemin": "0",
4106
- "aria-valuemax": Math.max(0, $setup.allowedIds.length - 1),
4107
- "aria-valuenow": $setup.activeIdx,
4108
- "aria-valuetext": $setup.state.activeId,
4109
4098
  "aria-label": "Resize sheet"
4110
4099
  }, null, 8, _hoisted_4),
4111
4100
  _ctx.$slots.header ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_5, [vue.renderSlot(_ctx.$slots, "header", { state: $setup.state })])) : vue.createCommentVNode("v-if", true),
package/dist/vue.js CHANGED
@@ -2357,6 +2357,7 @@ var BottomSheetEngine = class {
2357
2357
  __publicField(this, "progressWriteSentinel", new WriteSentinel());
2358
2358
  __publicField(this, "isTopSheet", true);
2359
2359
  __publicField(this, "opening", false);
2360
+ __publicField(this, "allowOvershoot", false);
2360
2361
  __publicField(this, "progressPayload", {
2361
2362
  value: 0,
2362
2363
  size: 0
@@ -2647,8 +2648,8 @@ var BottomSheetEngine = class {
2647
2648
  this.updateAriaSlider();
2648
2649
  this.emit("snap", {
2649
2650
  id,
2650
- size: target.size,
2651
- progress: this.computeProgress(target.size)
2651
+ size: this.size,
2652
+ progress: this.computeProgress(this.size)
2652
2653
  });
2653
2654
  if (wasClosed && target.size > 0) {
2654
2655
  this.emit("open", { id });
@@ -2727,12 +2728,12 @@ var BottomSheetEngine = class {
2727
2728
  const value = typeof h === "number" ? `${h}px` : h;
2728
2729
  const axis = layoutAxis(this.mode);
2729
2730
  this.element.style.setProperty(
2730
- axis === "height" ? "maxHeight" : "maxWidth",
2731
+ axis === "height" ? "max-height" : "max-width",
2731
2732
  value
2732
2733
  );
2733
2734
  if (typeof h === "number") {
2734
2735
  this.maxHeightCap = h;
2735
- this.clampToMaxHeight();
2736
+ this.recompute();
2736
2737
  } else if (typeof window !== "undefined") {
2737
2738
  const probe2 = document.createElement("div");
2738
2739
  probe2.style.cssText = `position:absolute;visibility:hidden;pointer-events:none;${axis === "height" ? "height" : "width"}:${value};`;
@@ -2740,7 +2741,7 @@ var BottomSheetEngine = class {
2740
2741
  const measured = axis === "height" ? probe2.offsetHeight : probe2.offsetWidth;
2741
2742
  probe2.remove();
2742
2743
  this.maxHeightCap = measured > 0 ? measured : void 0;
2743
- this.clampToMaxHeight();
2744
+ this.recompute();
2744
2745
  }
2745
2746
  }
2746
2747
  clampToMaxHeight() {
@@ -2748,9 +2749,6 @@ var BottomSheetEngine = class {
2748
2749
  if (this.snaps.getMaxAxisSize() > this.maxHeightCap) {
2749
2750
  this.snaps.setMaxAxisSize(this.maxHeightCap);
2750
2751
  }
2751
- if (this.size > this.maxHeightCap && !this.gesture?.isDragging) {
2752
- this.applySize(this.maxHeightCap);
2753
- }
2754
2752
  }
2755
2753
  setAllowed(ids, snap) {
2756
2754
  if (this.destroyed) return;
@@ -2888,6 +2886,7 @@ var BottomSheetEngine = class {
2888
2886
  recompute() {
2889
2887
  if (this.destroyed) return;
2890
2888
  this.snaps.recompute();
2889
+ this.clampToMaxHeight();
2891
2890
  this.scrim.invalidateOpacityCache();
2892
2891
  if (this.gesture?.isDragging) return;
2893
2892
  const current = this.snaps.findById(this.activeId);
@@ -2911,43 +2910,36 @@ var BottomSheetEngine = class {
2911
2910
  }
2912
2911
  return out;
2913
2912
  }
2914
- measureContentExtent(vertical) {
2913
+ measureSheetNatural(vertical) {
2914
+ const el = this.element;
2915
2915
  const content = this.scrollContainer;
2916
- if (!content) return 0;
2917
- const targets = this.contentTargets();
2918
- if (targets.length === 0) {
2919
- return vertical ? content.scrollHeight : content.scrollWidth;
2920
- }
2921
- let min = Infinity;
2922
- let max = -Infinity;
2923
- for (const el of targets) {
2924
- const r = el.getBoundingClientRect();
2925
- if (vertical) {
2926
- if (r.top < min) min = r.top;
2927
- if (r.bottom > max) max = r.bottom;
2928
- } else {
2929
- if (r.left < min) min = r.left;
2930
- if (r.right > max) max = r.right;
2931
- }
2932
- }
2933
- if (!isFinite(min) || !isFinite(max) || max <= min) {
2934
- return vertical ? content.scrollHeight : content.scrollWidth;
2935
- }
2936
- let pad = 0;
2937
- if (typeof getComputedStyle !== "undefined") {
2938
- const cs = getComputedStyle(content);
2939
- pad = vertical ? (parseFloat(cs.paddingTop) || 0) + (parseFloat(cs.paddingBottom) || 0) : (parseFloat(cs.paddingLeft) || 0) + (parseFloat(cs.paddingRight) || 0);
2916
+ if (!content) {
2917
+ return vertical ? el.offsetHeight : el.offsetWidth;
2940
2918
  }
2941
- return max - min + pad;
2919
+ const axis = vertical ? "height" : "width";
2920
+ const sheetStyle = el.style;
2921
+ const cs = content.style;
2922
+ const prevSheet = sheetStyle[axis];
2923
+ const prevFlex = cs.flex;
2924
+ const prevContent = vertical ? cs.height : cs.width;
2925
+ sheetStyle[axis] = "auto";
2926
+ cs.flex = "none";
2927
+ if (vertical) cs.height = "auto";
2928
+ else cs.width = "auto";
2929
+ const natural = vertical ? el.offsetHeight : el.offsetWidth;
2930
+ sheetStyle[axis] = prevSheet;
2931
+ cs.flex = prevFlex;
2932
+ if (vertical) cs.height = prevContent;
2933
+ else cs.width = prevContent;
2934
+ return natural;
2942
2935
  }
2943
2936
  measureFitSize() {
2944
2937
  const vertical = layoutAxis(this.mode) === "height";
2945
- const handleSize = vertical ? this.handle.offsetHeight : this.handle.offsetWidth;
2946
- const content = this.scrollContainer;
2947
- const natural = content ? handleSize + this.measureContentExtent(vertical) : handleSize;
2948
- if (typeof window === "undefined") return natural;
2938
+ const natural = this.measureSheetNatural(vertical);
2939
+ const capped = this.maxHeightCap !== void 0 ? Math.min(natural, this.maxHeightCap) : natural;
2940
+ if (typeof window === "undefined") return capped;
2949
2941
  const viewport = vertical ? window.innerHeight : window.innerWidth;
2950
- return viewport > 0 ? Math.min(natural, viewport) : natural;
2942
+ return viewport > 0 ? Math.min(capped, viewport) : capped;
2951
2943
  }
2952
2944
  installFitObserver() {
2953
2945
  if (typeof ResizeObserver === "undefined") return;
@@ -3029,6 +3021,10 @@ var BottomSheetEngine = class {
3029
3021
  this.backdrop.style.opacity = "";
3030
3022
  this.backdrop.style.pointerEvents = "";
3031
3023
  }
3024
+ if (this.anchorHost) {
3025
+ this.anchorHost.style.removeProperty("--bs-size");
3026
+ this.anchorHost.style.removeProperty("--bs-progress");
3027
+ }
3032
3028
  if (this.screenComponent) {
3033
3029
  this.screenComponent.style.opacity = "";
3034
3030
  this.screenComponent.style.display = "";
@@ -3040,6 +3036,7 @@ var BottomSheetEngine = class {
3040
3036
  this.bus.emit(event, payload);
3041
3037
  }
3042
3038
  newCycle() {
3039
+ this.allowOvershoot = false;
3043
3040
  this.currentAbort.abort();
3044
3041
  this.currentAbort = new AbortController();
3045
3042
  return this.currentAbort.signal;
@@ -3105,6 +3102,7 @@ var BottomSheetEngine = class {
3105
3102
  seen.add(p.id);
3106
3103
  }
3107
3104
  this.snaps.setRaw(this.snapPointsRaw);
3105
+ this.clampToMaxHeight();
3108
3106
  this.scrim.invalidateOpacityCache();
3109
3107
  }
3110
3108
  getAllowedRange() {
@@ -3311,15 +3309,19 @@ var BottomSheetEngine = class {
3311
3309
  this.opening = true;
3312
3310
  sheetStack.promote(this.id);
3313
3311
  }
3314
- void this.animation.animateTo(target.size, velocity).then(() => {
3315
- this.opening = false;
3312
+ const settleCap = this.snaps.getMaxAxisSize();
3313
+ const settleSize = settleCap > 0 ? Math.min(target.size, settleCap) : target.size;
3314
+ this.allowOvershoot = true;
3315
+ void this.animation.animateTo(settleSize, velocity).then(() => {
3316
3316
  if (signal.aborted) return;
3317
+ this.allowOvershoot = false;
3318
+ this.opening = false;
3317
3319
  this.scrollCache.restore(target.id, previousSize, target.size);
3318
3320
  this.updateAriaSlider();
3319
3321
  this.emit("snap", {
3320
3322
  id: target.id,
3321
- size: target.size,
3322
- progress: this.computeProgress(target.size)
3323
+ size: this.size,
3324
+ progress: this.computeProgress(this.size)
3323
3325
  });
3324
3326
  this.haptic();
3325
3327
  if (previousSnapSize === 0 && target.size > 0) {
@@ -3344,23 +3346,25 @@ var BottomSheetEngine = class {
3344
3346
  }
3345
3347
  }
3346
3348
  applySize(size) {
3347
- this.size = size;
3348
- const offset = this.snaps.getMaxAxisSize() - size;
3349
+ const cap = this.snaps.getMaxAxisSize();
3350
+ const clamped = cap > 0 && size > cap && !this.gesture?.isDragging && !this.allowOvershoot ? cap : size;
3351
+ this.size = clamped;
3352
+ const offset = cap - clamped;
3349
3353
  const style = this.element.style;
3350
3354
  style.transform = this.transformTemplate(offset);
3351
- if (this.sizeWriteSentinel.shouldWrite(size, SIZE_WRITE_EPSILON)) {
3352
- style.setProperty("--bs-size", `${size}px`);
3355
+ if (this.sizeWriteSentinel.shouldWrite(clamped, SIZE_WRITE_EPSILON)) {
3356
+ style.setProperty("--bs-size", `${clamped}px`);
3353
3357
  if (this.scrimParent) {
3354
- this.scrimParent.style.setProperty("--bs-size", `${size}px`);
3358
+ this.scrimParent.style.setProperty("--bs-size", `${clamped}px`);
3355
3359
  }
3356
3360
  if (this.anchorHost && this.anchorHost !== this.scrimParent) {
3357
- this.anchorHost.style.setProperty("--bs-size", `${size}px`);
3361
+ this.anchorHost.style.setProperty("--bs-size", `${clamped}px`);
3358
3362
  }
3359
3363
  if (this.rootEl && this.rootEl !== this.scrimParent && this.rootEl !== this.anchorHost) {
3360
- this.rootEl.style.setProperty("--bs-size", `${size}px`);
3364
+ this.rootEl.style.setProperty("--bs-size", `${clamped}px`);
3361
3365
  }
3362
3366
  }
3363
- const progress = this.computeProgress(size);
3367
+ const progress = this.computeProgress(clamped);
3364
3368
  const progressChanged = this.progressWriteSentinel.shouldWrite(
3365
3369
  progress,
3366
3370
  OPACITY_WRITE_EPSILON
@@ -3377,14 +3381,15 @@ var BottomSheetEngine = class {
3377
3381
  this.scrim.applyOpacity(progress, progressChanged);
3378
3382
  if (progressChanged && this.bus.listenerCount("progress") > 0) {
3379
3383
  this.progressPayload.value = progress;
3380
- this.progressPayload.size = size;
3384
+ this.progressPayload.size = clamped;
3381
3385
  this.emit("progress", this.progressPayload);
3382
3386
  }
3383
3387
  }
3384
3388
  computeProgress(size) {
3385
3389
  const { min, max } = this.getAllowedRange();
3386
- if (max <= min) return 0;
3387
- 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);
3388
3393
  }
3389
3394
  handleOpen() {
3390
3395
  sheetStack.promote(this.id);
@@ -3408,8 +3413,8 @@ var BottomSheetEngine = class {
3408
3413
  this.updateAriaSlider();
3409
3414
  this.emit("snap", {
3410
3415
  id: target.id,
3411
- size: target.size,
3412
- progress: this.computeProgress(target.size)
3416
+ size: this.size,
3417
+ progress: this.computeProgress(this.size)
3413
3418
  });
3414
3419
  if (target.size > 0 && !this.lifecycle.isInstalled) {
3415
3420
  this.emit("open", { id: target.id });
@@ -3935,11 +3940,6 @@ var _sfc_main = /* @__PURE__ */ defineComponent({
3935
3940
  const mode = props.mode ?? "bottom";
3936
3941
  return mode === "bottom" || mode === "top";
3937
3942
  });
3938
- const allowedIds = computed(() => props.allowed ?? props.snapPoints.map((p) => p.id));
3939
- const activeIdx = computed(() => {
3940
- const idx = allowedIds.value.indexOf(state.activeId);
3941
- return idx === -1 ? 0 : idx;
3942
- });
3943
3943
  const ariaModal = computed(() => props.focusTrap === true);
3944
3944
  __expose({
3945
3945
  snapTo,
@@ -4009,8 +4009,6 @@ var _sfc_main = /* @__PURE__ */ defineComponent({
4009
4009
  anchorsKey,
4010
4010
  applyStages,
4011
4011
  isVerticalAxis,
4012
- allowedIds,
4013
- activeIdx,
4014
4012
  ariaModal
4015
4013
  };
4016
4014
  Object.defineProperty(__returned__, "__isScriptSetup", {
@@ -4032,12 +4030,7 @@ var _hoisted_3 = [
4032
4030
  "aria-modal",
4033
4031
  "aria-label"
4034
4032
  ];
4035
- var _hoisted_4 = [
4036
- "aria-orientation",
4037
- "aria-valuemax",
4038
- "aria-valuenow",
4039
- "aria-valuetext"
4040
- ];
4033
+ var _hoisted_4 = ["aria-orientation"];
4041
4034
  var _hoisted_5 = {
4042
4035
  key: 0,
4043
4036
  class: "bs-header"
@@ -4100,10 +4093,6 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
4100
4093
  role: "slider",
4101
4094
  tabindex: "0",
4102
4095
  "aria-orientation": $setup.isVerticalAxis ? "vertical" : "horizontal",
4103
- "aria-valuemin": "0",
4104
- "aria-valuemax": Math.max(0, $setup.allowedIds.length - 1),
4105
- "aria-valuenow": $setup.activeIdx,
4106
- "aria-valuetext": $setup.state.activeId,
4107
4096
  "aria-label": "Resize sheet"
4108
4097
  }, null, 8, _hoisted_4),
4109
4098
  _ctx.$slots.header ? (openBlock(), createElementBlock("div", _hoisted_5, [renderSlot(_ctx.$slots, "header", { state: $setup.state })])) : createCommentVNode("v-if", true),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@surdeddd/bottom-sheet",
3
- "version": "0.6.1",
3
+ "version": "0.8.0",
4
4
  "description": "Universal, headless bottom sheet — framework-agnostic core with React, Vue 3, Svelte, Solid, Qwik, Preact, Lit and Custom Element adapters. Pointer Events, snap points, momentum, a11y, SSR-safe.",
5
5
  "type": "module",
6
6
  "license": "MIT",