@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/solid.js CHANGED
@@ -2621,7 +2621,9 @@ var BottomSheetEngine = class {
2621
2621
  const previousSize = this.size;
2622
2622
  this.scrollCache.cache(previousId, previousSize, target.size);
2623
2623
  this.activeId = id;
2624
- if (wasClosed && target.size > 0) {
2624
+ const rawTargetSize = this.snapPointsRaw.find((p) => p.id === id)?.size;
2625
+ const opensToRest = id === "closed" || rawTargetSize === 0;
2626
+ if (wasClosed && !opensToRest) {
2625
2627
  this.opening = true;
2626
2628
  sheetStack.promote(this.id);
2627
2629
  }
@@ -2646,8 +2648,8 @@ var BottomSheetEngine = class {
2646
2648
  this.updateAriaSlider();
2647
2649
  this.emit("snap", {
2648
2650
  id,
2649
- size: target.size,
2650
- progress: this.computeProgress(target.size)
2651
+ size: this.size,
2652
+ progress: this.computeProgress(this.size)
2651
2653
  });
2652
2654
  if (wasClosed && target.size > 0) {
2653
2655
  this.emit("open", { id });
@@ -2726,12 +2728,12 @@ var BottomSheetEngine = class {
2726
2728
  const value = typeof h === "number" ? `${h}px` : h;
2727
2729
  const axis = layoutAxis(this.mode);
2728
2730
  this.element.style.setProperty(
2729
- axis === "height" ? "maxHeight" : "maxWidth",
2731
+ axis === "height" ? "max-height" : "max-width",
2730
2732
  value
2731
2733
  );
2732
2734
  if (typeof h === "number") {
2733
2735
  this.maxHeightCap = h;
2734
- this.clampToMaxHeight();
2736
+ this.recompute();
2735
2737
  } else if (typeof window !== "undefined") {
2736
2738
  const probe2 = document.createElement("div");
2737
2739
  probe2.style.cssText = `position:absolute;visibility:hidden;pointer-events:none;${axis === "height" ? "height" : "width"}:${value};`;
@@ -2739,7 +2741,7 @@ var BottomSheetEngine = class {
2739
2741
  const measured = axis === "height" ? probe2.offsetHeight : probe2.offsetWidth;
2740
2742
  probe2.remove();
2741
2743
  this.maxHeightCap = measured > 0 ? measured : void 0;
2742
- this.clampToMaxHeight();
2744
+ this.recompute();
2743
2745
  }
2744
2746
  }
2745
2747
  clampToMaxHeight() {
@@ -2747,9 +2749,6 @@ var BottomSheetEngine = class {
2747
2749
  if (this.snaps.getMaxAxisSize() > this.maxHeightCap) {
2748
2750
  this.snaps.setMaxAxisSize(this.maxHeightCap);
2749
2751
  }
2750
- if (this.size > this.maxHeightCap && !this.gesture?.isDragging) {
2751
- this.applySize(this.maxHeightCap);
2752
- }
2753
2752
  }
2754
2753
  setAllowed(ids, snap) {
2755
2754
  if (this.destroyed) return;
@@ -2887,6 +2886,7 @@ var BottomSheetEngine = class {
2887
2886
  recompute() {
2888
2887
  if (this.destroyed) return;
2889
2888
  this.snaps.recompute();
2889
+ this.clampToMaxHeight();
2890
2890
  this.scrim.invalidateOpacityCache();
2891
2891
  if (this.gesture?.isDragging) return;
2892
2892
  const current = this.snaps.findById(this.activeId);
@@ -2944,9 +2944,10 @@ var BottomSheetEngine = class {
2944
2944
  const handleSize = vertical ? this.handle.offsetHeight : this.handle.offsetWidth;
2945
2945
  const content = this.scrollContainer;
2946
2946
  const natural = content ? handleSize + this.measureContentExtent(vertical) : handleSize;
2947
- if (typeof window === "undefined") return natural;
2947
+ const capped = this.maxHeightCap !== void 0 ? Math.min(natural, this.maxHeightCap) : natural;
2948
+ if (typeof window === "undefined") return capped;
2948
2949
  const viewport = vertical ? window.innerHeight : window.innerWidth;
2949
- return viewport > 0 ? Math.min(natural, viewport) : natural;
2950
+ return viewport > 0 ? Math.min(capped, viewport) : capped;
2950
2951
  }
2951
2952
  installFitObserver() {
2952
2953
  if (typeof ResizeObserver === "undefined") return;
@@ -3317,8 +3318,8 @@ var BottomSheetEngine = class {
3317
3318
  this.updateAriaSlider();
3318
3319
  this.emit("snap", {
3319
3320
  id: target.id,
3320
- size: target.size,
3321
- progress: this.computeProgress(target.size)
3321
+ size: this.size,
3322
+ progress: this.computeProgress(this.size)
3322
3323
  });
3323
3324
  this.haptic();
3324
3325
  if (previousSnapSize === 0 && target.size > 0) {
@@ -3343,23 +3344,25 @@ var BottomSheetEngine = class {
3343
3344
  }
3344
3345
  }
3345
3346
  applySize(size) {
3346
- this.size = size;
3347
- const offset = this.snaps.getMaxAxisSize() - size;
3347
+ const cap = this.snaps.getMaxAxisSize();
3348
+ const clamped = cap > 0 && size > cap && !this.gesture?.isDragging ? cap : size;
3349
+ this.size = clamped;
3350
+ const offset = cap - clamped;
3348
3351
  const style = this.element.style;
3349
3352
  style.transform = this.transformTemplate(offset);
3350
- if (this.sizeWriteSentinel.shouldWrite(size, SIZE_WRITE_EPSILON)) {
3351
- style.setProperty("--bs-size", `${size}px`);
3353
+ if (this.sizeWriteSentinel.shouldWrite(clamped, SIZE_WRITE_EPSILON)) {
3354
+ style.setProperty("--bs-size", `${clamped}px`);
3352
3355
  if (this.scrimParent) {
3353
- this.scrimParent.style.setProperty("--bs-size", `${size}px`);
3356
+ this.scrimParent.style.setProperty("--bs-size", `${clamped}px`);
3354
3357
  }
3355
3358
  if (this.anchorHost && this.anchorHost !== this.scrimParent) {
3356
- this.anchorHost.style.setProperty("--bs-size", `${size}px`);
3359
+ this.anchorHost.style.setProperty("--bs-size", `${clamped}px`);
3357
3360
  }
3358
3361
  if (this.rootEl && this.rootEl !== this.scrimParent && this.rootEl !== this.anchorHost) {
3359
- this.rootEl.style.setProperty("--bs-size", `${size}px`);
3362
+ this.rootEl.style.setProperty("--bs-size", `${clamped}px`);
3360
3363
  }
3361
3364
  }
3362
- const progress = this.computeProgress(size);
3365
+ const progress = this.computeProgress(clamped);
3363
3366
  const progressChanged = this.progressWriteSentinel.shouldWrite(
3364
3367
  progress,
3365
3368
  OPACITY_WRITE_EPSILON
@@ -3376,14 +3379,15 @@ var BottomSheetEngine = class {
3376
3379
  this.scrim.applyOpacity(progress, progressChanged);
3377
3380
  if (progressChanged && this.bus.listenerCount("progress") > 0) {
3378
3381
  this.progressPayload.value = progress;
3379
- this.progressPayload.size = size;
3382
+ this.progressPayload.size = clamped;
3380
3383
  this.emit("progress", this.progressPayload);
3381
3384
  }
3382
3385
  }
3383
3386
  computeProgress(size) {
3384
3387
  const { min, max } = this.getAllowedRange();
3385
- if (max <= min) return 0;
3386
- return Math.min(Math.max((size - min) / (max - min), 0), 1);
3388
+ const reachableMax = Math.min(max, this.snaps.getMaxAxisSize());
3389
+ if (reachableMax <= min) return 0;
3390
+ return Math.min(Math.max((size - min) / (reachableMax - min), 0), 1);
3387
3391
  }
3388
3392
  handleOpen() {
3389
3393
  sheetStack.promote(this.id);
@@ -3407,8 +3411,8 @@ var BottomSheetEngine = class {
3407
3411
  this.updateAriaSlider();
3408
3412
  this.emit("snap", {
3409
3413
  id: target.id,
3410
- size: target.size,
3411
- progress: this.computeProgress(target.size)
3414
+ size: this.size,
3415
+ progress: this.computeProgress(this.size)
3412
3416
  });
3413
3417
  if (target.size > 0 && !this.lifecycle.isInstalled) {
3414
3418
  this.emit("open", { id: target.id });
@@ -3467,7 +3471,9 @@ var BottomSheet = (props) => {
3467
3471
  closeOnBack: props.closeOnBack,
3468
3472
  lockBodyScroll: props.lockBodyScroll,
3469
3473
  rubberBand: props.rubberBand,
3470
- backdropRange: props.backdropRange
3474
+ backdropRange: props.backdropRange,
3475
+ radius: props.radius,
3476
+ maxHeight: props.maxHeight
3471
3477
  };
3472
3478
  engine = new BottomSheetEngine(engineOpts);
3473
3479
  props.engineRef?.(engine);
@@ -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 });
@@ -3465,7 +3469,9 @@ var BottomSheet = (props) => {
3465
3469
  closeOnBack: props.closeOnBack,
3466
3470
  lockBodyScroll: props.lockBodyScroll,
3467
3471
  rubberBand: props.rubberBand,
3468
- backdropRange: props.backdropRange
3472
+ backdropRange: props.backdropRange,
3473
+ radius: props.radius,
3474
+ maxHeight: props.maxHeight
3469
3475
  };
3470
3476
  engine = new BottomSheetEngine(engineOpts);
3471
3477
  props.engineRef?.(engine);
package/dist/styles.css CHANGED
@@ -118,7 +118,7 @@
118
118
  display: flex;
119
119
  flex-direction: column;
120
120
  justify-content: center;
121
- padding: 8px 16px 4px;
121
+ padding: var(--bs-handle-padding, 8px 16px 4px);
122
122
  cursor: grab;
123
123
  touch-action: none;
124
124
  user-select: none;
@@ -246,7 +246,7 @@
246
246
 
247
247
  .bs-header {
248
248
  flex: 0 0 auto;
249
- padding: 0 16px 8px;
249
+ padding: var(--bs-header-padding, 0 16px 8px);
250
250
  background: var(--bs-surface, var(--bs-surface-d));
251
251
  }
252
252
 
@@ -257,12 +257,12 @@
257
257
  -webkit-overflow-scrolling: touch;
258
258
  overscroll-behavior: contain;
259
259
  user-select: text;
260
- padding: 0 16px 16px;
260
+ padding: var(--bs-content-padding, 0 16px 16px);
261
261
  }
262
262
 
263
263
  .bs-footer {
264
264
  flex: 0 0 auto;
265
- padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
265
+ padding: var(--bs-footer-padding, 12px 16px calc(12px + env(safe-area-inset-bottom)));
266
266
  border-top: 1px solid var(--bs-surface-border, var(--bs-surface-border-d));
267
267
  background: var(--bs-surface, var(--bs-surface-d));
268
268
  }
@@ -2622,7 +2622,9 @@ var BottomSheetEngine = class {
2622
2622
  const previousSize = this.size;
2623
2623
  this.scrollCache.cache(previousId, previousSize, target.size);
2624
2624
  this.activeId = id;
2625
- if (wasClosed && target.size > 0) {
2625
+ const rawTargetSize = this.snapPointsRaw.find((p) => p.id === id)?.size;
2626
+ const opensToRest = id === "closed" || rawTargetSize === 0;
2627
+ if (wasClosed && !opensToRest) {
2626
2628
  this.opening = true;
2627
2629
  sheetStack.promote(this.id);
2628
2630
  }
@@ -2647,8 +2649,8 @@ var BottomSheetEngine = class {
2647
2649
  this.updateAriaSlider();
2648
2650
  this.emit("snap", {
2649
2651
  id,
2650
- size: target.size,
2651
- progress: this.computeProgress(target.size)
2652
+ size: this.size,
2653
+ progress: this.computeProgress(this.size)
2652
2654
  });
2653
2655
  if (wasClosed && target.size > 0) {
2654
2656
  this.emit("open", { id });
@@ -2727,12 +2729,12 @@ var BottomSheetEngine = class {
2727
2729
  const value = typeof h === "number" ? `${h}px` : h;
2728
2730
  const axis = layoutAxis(this.mode);
2729
2731
  this.element.style.setProperty(
2730
- axis === "height" ? "maxHeight" : "maxWidth",
2732
+ axis === "height" ? "max-height" : "max-width",
2731
2733
  value
2732
2734
  );
2733
2735
  if (typeof h === "number") {
2734
2736
  this.maxHeightCap = h;
2735
- this.clampToMaxHeight();
2737
+ this.recompute();
2736
2738
  } else if (typeof window !== "undefined") {
2737
2739
  const probe2 = document.createElement("div");
2738
2740
  probe2.style.cssText = `position:absolute;visibility:hidden;pointer-events:none;${axis === "height" ? "height" : "width"}:${value};`;
@@ -2740,7 +2742,7 @@ var BottomSheetEngine = class {
2740
2742
  const measured = axis === "height" ? probe2.offsetHeight : probe2.offsetWidth;
2741
2743
  probe2.remove();
2742
2744
  this.maxHeightCap = measured > 0 ? measured : void 0;
2743
- this.clampToMaxHeight();
2745
+ this.recompute();
2744
2746
  }
2745
2747
  }
2746
2748
  clampToMaxHeight() {
@@ -2748,9 +2750,6 @@ var BottomSheetEngine = class {
2748
2750
  if (this.snaps.getMaxAxisSize() > this.maxHeightCap) {
2749
2751
  this.snaps.setMaxAxisSize(this.maxHeightCap);
2750
2752
  }
2751
- if (this.size > this.maxHeightCap && !this.gesture?.isDragging) {
2752
- this.applySize(this.maxHeightCap);
2753
- }
2754
2753
  }
2755
2754
  setAllowed(ids, snap) {
2756
2755
  if (this.destroyed) return;
@@ -2888,6 +2887,7 @@ var BottomSheetEngine = class {
2888
2887
  recompute() {
2889
2888
  if (this.destroyed) return;
2890
2889
  this.snaps.recompute();
2890
+ this.clampToMaxHeight();
2891
2891
  this.scrim.invalidateOpacityCache();
2892
2892
  if (this.gesture?.isDragging) return;
2893
2893
  const current = this.snaps.findById(this.activeId);
@@ -2945,9 +2945,10 @@ var BottomSheetEngine = class {
2945
2945
  const handleSize = vertical ? this.handle.offsetHeight : this.handle.offsetWidth;
2946
2946
  const content = this.scrollContainer;
2947
2947
  const natural = content ? handleSize + this.measureContentExtent(vertical) : handleSize;
2948
- if (typeof window === "undefined") return natural;
2948
+ const capped = this.maxHeightCap !== void 0 ? Math.min(natural, this.maxHeightCap) : natural;
2949
+ if (typeof window === "undefined") return capped;
2949
2950
  const viewport = vertical ? window.innerHeight : window.innerWidth;
2950
- return viewport > 0 ? Math.min(natural, viewport) : natural;
2951
+ return viewport > 0 ? Math.min(capped, viewport) : capped;
2951
2952
  }
2952
2953
  installFitObserver() {
2953
2954
  if (typeof ResizeObserver === "undefined") return;
@@ -3318,8 +3319,8 @@ var BottomSheetEngine = class {
3318
3319
  this.updateAriaSlider();
3319
3320
  this.emit("snap", {
3320
3321
  id: target.id,
3321
- size: target.size,
3322
- progress: this.computeProgress(target.size)
3322
+ size: this.size,
3323
+ progress: this.computeProgress(this.size)
3323
3324
  });
3324
3325
  this.haptic();
3325
3326
  if (previousSnapSize === 0 && target.size > 0) {
@@ -3344,23 +3345,25 @@ var BottomSheetEngine = class {
3344
3345
  }
3345
3346
  }
3346
3347
  applySize(size) {
3347
- this.size = size;
3348
- const offset = this.snaps.getMaxAxisSize() - size;
3348
+ const cap = this.snaps.getMaxAxisSize();
3349
+ const clamped = cap > 0 && size > cap && !this.gesture?.isDragging ? cap : size;
3350
+ this.size = clamped;
3351
+ const offset = cap - clamped;
3349
3352
  const style = this.element.style;
3350
3353
  style.transform = this.transformTemplate(offset);
3351
- if (this.sizeWriteSentinel.shouldWrite(size, SIZE_WRITE_EPSILON)) {
3352
- style.setProperty("--bs-size", `${size}px`);
3354
+ if (this.sizeWriteSentinel.shouldWrite(clamped, SIZE_WRITE_EPSILON)) {
3355
+ style.setProperty("--bs-size", `${clamped}px`);
3353
3356
  if (this.scrimParent) {
3354
- this.scrimParent.style.setProperty("--bs-size", `${size}px`);
3357
+ this.scrimParent.style.setProperty("--bs-size", `${clamped}px`);
3355
3358
  }
3356
3359
  if (this.anchorHost && this.anchorHost !== this.scrimParent) {
3357
- this.anchorHost.style.setProperty("--bs-size", `${size}px`);
3360
+ this.anchorHost.style.setProperty("--bs-size", `${clamped}px`);
3358
3361
  }
3359
3362
  if (this.rootEl && this.rootEl !== this.scrimParent && this.rootEl !== this.anchorHost) {
3360
- this.rootEl.style.setProperty("--bs-size", `${size}px`);
3363
+ this.rootEl.style.setProperty("--bs-size", `${clamped}px`);
3361
3364
  }
3362
3365
  }
3363
- const progress = this.computeProgress(size);
3366
+ const progress = this.computeProgress(clamped);
3364
3367
  const progressChanged = this.progressWriteSentinel.shouldWrite(
3365
3368
  progress,
3366
3369
  OPACITY_WRITE_EPSILON
@@ -3377,14 +3380,15 @@ var BottomSheetEngine = class {
3377
3380
  this.scrim.applyOpacity(progress, progressChanged);
3378
3381
  if (progressChanged && this.bus.listenerCount("progress") > 0) {
3379
3382
  this.progressPayload.value = progress;
3380
- this.progressPayload.size = size;
3383
+ this.progressPayload.size = clamped;
3381
3384
  this.emit("progress", this.progressPayload);
3382
3385
  }
3383
3386
  }
3384
3387
  computeProgress(size) {
3385
3388
  const { min, max } = this.getAllowedRange();
3386
- if (max <= min) return 0;
3387
- return Math.min(Math.max((size - min) / (max - min), 0), 1);
3389
+ const reachableMax = Math.min(max, this.snaps.getMaxAxisSize());
3390
+ if (reachableMax <= min) return 0;
3391
+ return Math.min(Math.max((size - min) / (reachableMax - min), 0), 1);
3388
3392
  }
3389
3393
  handleOpen() {
3390
3394
  sheetStack.promote(this.id);
@@ -3408,8 +3412,8 @@ var BottomSheetEngine = class {
3408
3412
  this.updateAriaSlider();
3409
3413
  this.emit("snap", {
3410
3414
  id: target.id,
3411
- size: target.size,
3412
- progress: this.computeProgress(target.size)
3415
+ size: this.size,
3416
+ progress: this.computeProgress(this.size)
3413
3417
  });
3414
3418
  if (target.size > 0 && !this.lifecycle.isInstalled) {
3415
3419
  this.emit("open", { id: target.id });
@@ -2620,7 +2620,9 @@ var BottomSheetEngine = class {
2620
2620
  const previousSize = this.size;
2621
2621
  this.scrollCache.cache(previousId, previousSize, target.size);
2622
2622
  this.activeId = id;
2623
- if (wasClosed && target.size > 0) {
2623
+ const rawTargetSize = this.snapPointsRaw.find((p) => p.id === id)?.size;
2624
+ const opensToRest = id === "closed" || rawTargetSize === 0;
2625
+ if (wasClosed && !opensToRest) {
2624
2626
  this.opening = true;
2625
2627
  sheetStack.promote(this.id);
2626
2628
  }
@@ -2645,8 +2647,8 @@ var BottomSheetEngine = class {
2645
2647
  this.updateAriaSlider();
2646
2648
  this.emit("snap", {
2647
2649
  id,
2648
- size: target.size,
2649
- progress: this.computeProgress(target.size)
2650
+ size: this.size,
2651
+ progress: this.computeProgress(this.size)
2650
2652
  });
2651
2653
  if (wasClosed && target.size > 0) {
2652
2654
  this.emit("open", { id });
@@ -2725,12 +2727,12 @@ var BottomSheetEngine = class {
2725
2727
  const value = typeof h === "number" ? `${h}px` : h;
2726
2728
  const axis = layoutAxis(this.mode);
2727
2729
  this.element.style.setProperty(
2728
- axis === "height" ? "maxHeight" : "maxWidth",
2730
+ axis === "height" ? "max-height" : "max-width",
2729
2731
  value
2730
2732
  );
2731
2733
  if (typeof h === "number") {
2732
2734
  this.maxHeightCap = h;
2733
- this.clampToMaxHeight();
2735
+ this.recompute();
2734
2736
  } else if (typeof window !== "undefined") {
2735
2737
  const probe2 = document.createElement("div");
2736
2738
  probe2.style.cssText = `position:absolute;visibility:hidden;pointer-events:none;${axis === "height" ? "height" : "width"}:${value};`;
@@ -2738,7 +2740,7 @@ var BottomSheetEngine = class {
2738
2740
  const measured = axis === "height" ? probe2.offsetHeight : probe2.offsetWidth;
2739
2741
  probe2.remove();
2740
2742
  this.maxHeightCap = measured > 0 ? measured : void 0;
2741
- this.clampToMaxHeight();
2743
+ this.recompute();
2742
2744
  }
2743
2745
  }
2744
2746
  clampToMaxHeight() {
@@ -2746,9 +2748,6 @@ var BottomSheetEngine = class {
2746
2748
  if (this.snaps.getMaxAxisSize() > this.maxHeightCap) {
2747
2749
  this.snaps.setMaxAxisSize(this.maxHeightCap);
2748
2750
  }
2749
- if (this.size > this.maxHeightCap && !this.gesture?.isDragging) {
2750
- this.applySize(this.maxHeightCap);
2751
- }
2752
2751
  }
2753
2752
  setAllowed(ids, snap) {
2754
2753
  if (this.destroyed) return;
@@ -2886,6 +2885,7 @@ var BottomSheetEngine = class {
2886
2885
  recompute() {
2887
2886
  if (this.destroyed) return;
2888
2887
  this.snaps.recompute();
2888
+ this.clampToMaxHeight();
2889
2889
  this.scrim.invalidateOpacityCache();
2890
2890
  if (this.gesture?.isDragging) return;
2891
2891
  const current = this.snaps.findById(this.activeId);
@@ -2943,9 +2943,10 @@ var BottomSheetEngine = class {
2943
2943
  const handleSize = vertical ? this.handle.offsetHeight : this.handle.offsetWidth;
2944
2944
  const content = this.scrollContainer;
2945
2945
  const natural = content ? handleSize + this.measureContentExtent(vertical) : handleSize;
2946
- if (typeof window === "undefined") return natural;
2946
+ const capped = this.maxHeightCap !== void 0 ? Math.min(natural, this.maxHeightCap) : natural;
2947
+ if (typeof window === "undefined") return capped;
2947
2948
  const viewport = vertical ? window.innerHeight : window.innerWidth;
2948
- return viewport > 0 ? Math.min(natural, viewport) : natural;
2949
+ return viewport > 0 ? Math.min(capped, viewport) : capped;
2949
2950
  }
2950
2951
  installFitObserver() {
2951
2952
  if (typeof ResizeObserver === "undefined") return;
@@ -3316,8 +3317,8 @@ var BottomSheetEngine = class {
3316
3317
  this.updateAriaSlider();
3317
3318
  this.emit("snap", {
3318
3319
  id: target.id,
3319
- size: target.size,
3320
- progress: this.computeProgress(target.size)
3320
+ size: this.size,
3321
+ progress: this.computeProgress(this.size)
3321
3322
  });
3322
3323
  this.haptic();
3323
3324
  if (previousSnapSize === 0 && target.size > 0) {
@@ -3342,23 +3343,25 @@ var BottomSheetEngine = class {
3342
3343
  }
3343
3344
  }
3344
3345
  applySize(size) {
3345
- this.size = size;
3346
- const offset = this.snaps.getMaxAxisSize() - size;
3346
+ const cap = this.snaps.getMaxAxisSize();
3347
+ const clamped = cap > 0 && size > cap && !this.gesture?.isDragging ? cap : size;
3348
+ this.size = clamped;
3349
+ const offset = cap - clamped;
3347
3350
  const style = this.element.style;
3348
3351
  style.transform = this.transformTemplate(offset);
3349
- if (this.sizeWriteSentinel.shouldWrite(size, SIZE_WRITE_EPSILON)) {
3350
- style.setProperty("--bs-size", `${size}px`);
3352
+ if (this.sizeWriteSentinel.shouldWrite(clamped, SIZE_WRITE_EPSILON)) {
3353
+ style.setProperty("--bs-size", `${clamped}px`);
3351
3354
  if (this.scrimParent) {
3352
- this.scrimParent.style.setProperty("--bs-size", `${size}px`);
3355
+ this.scrimParent.style.setProperty("--bs-size", `${clamped}px`);
3353
3356
  }
3354
3357
  if (this.anchorHost && this.anchorHost !== this.scrimParent) {
3355
- this.anchorHost.style.setProperty("--bs-size", `${size}px`);
3358
+ this.anchorHost.style.setProperty("--bs-size", `${clamped}px`);
3356
3359
  }
3357
3360
  if (this.rootEl && this.rootEl !== this.scrimParent && this.rootEl !== this.anchorHost) {
3358
- this.rootEl.style.setProperty("--bs-size", `${size}px`);
3361
+ this.rootEl.style.setProperty("--bs-size", `${clamped}px`);
3359
3362
  }
3360
3363
  }
3361
- const progress = this.computeProgress(size);
3364
+ const progress = this.computeProgress(clamped);
3362
3365
  const progressChanged = this.progressWriteSentinel.shouldWrite(
3363
3366
  progress,
3364
3367
  OPACITY_WRITE_EPSILON
@@ -3375,14 +3378,15 @@ var BottomSheetEngine = class {
3375
3378
  this.scrim.applyOpacity(progress, progressChanged);
3376
3379
  if (progressChanged && this.bus.listenerCount("progress") > 0) {
3377
3380
  this.progressPayload.value = progress;
3378
- this.progressPayload.size = size;
3381
+ this.progressPayload.size = clamped;
3379
3382
  this.emit("progress", this.progressPayload);
3380
3383
  }
3381
3384
  }
3382
3385
  computeProgress(size) {
3383
3386
  const { min, max } = this.getAllowedRange();
3384
- if (max <= min) return 0;
3385
- return Math.min(Math.max((size - min) / (max - min), 0), 1);
3387
+ const reachableMax = Math.min(max, this.snaps.getMaxAxisSize());
3388
+ if (reachableMax <= min) return 0;
3389
+ return Math.min(Math.max((size - min) / (reachableMax - min), 0), 1);
3386
3390
  }
3387
3391
  handleOpen() {
3388
3392
  sheetStack.promote(this.id);
@@ -3406,8 +3410,8 @@ var BottomSheetEngine = class {
3406
3410
  this.updateAriaSlider();
3407
3411
  this.emit("snap", {
3408
3412
  id: target.id,
3409
- size: target.size,
3410
- progress: this.computeProgress(target.size)
3413
+ size: this.size,
3414
+ progress: this.computeProgress(this.size)
3411
3415
  });
3412
3416
  if (target.size > 0 && !this.lifecycle.isInstalled) {
3413
3417
  this.emit("open", { id: target.id });