@surdeddd/bottom-sheet 0.4.1 → 0.5.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.
Files changed (41) hide show
  1. package/dist/{BottomSheetEngine-L05jGZvU.d.ts → BottomSheetEngine-BHjKFtnM.d.ts} +2 -0
  2. package/dist/{BottomSheetEngine-BJrH7qY3.d.cts → BottomSheetEngine-CqiCz64W.d.cts} +2 -0
  3. package/dist/element.cjs +111 -12
  4. package/dist/element.d.cts +1 -1
  5. package/dist/element.d.ts +1 -1
  6. package/dist/element.iife.global.js +2 -2
  7. package/dist/element.js +111 -12
  8. package/dist/index.cjs +91 -8
  9. package/dist/index.d.cts +2 -2
  10. package/dist/index.d.ts +2 -2
  11. package/dist/index.js +91 -8
  12. package/dist/integrations/formik.d.cts +1 -1
  13. package/dist/integrations/formik.d.ts +1 -1
  14. package/dist/integrations/react-hook-form.d.cts +1 -1
  15. package/dist/integrations/react-hook-form.d.ts +1 -1
  16. package/dist/preact.d.cts +1 -1
  17. package/dist/preact.d.ts +1 -1
  18. package/dist/qwik.cjs +94 -10
  19. package/dist/qwik.d.cts +2 -2
  20. package/dist/qwik.d.ts +2 -2
  21. package/dist/qwik.js +94 -10
  22. package/dist/react.cjs +95 -10
  23. package/dist/react.d.cts +4 -2
  24. package/dist/react.d.ts +4 -2
  25. package/dist/react.js +95 -10
  26. package/dist/solid.cjs +122 -18
  27. package/dist/solid.d.cts +3 -0
  28. package/dist/solid.d.ts +3 -0
  29. package/dist/solid.js +124 -20
  30. package/dist/solid.source.jsx +100 -12
  31. package/dist/styles.css +17 -0
  32. package/dist/svelte-core.cjs +91 -8
  33. package/dist/svelte-core.js +91 -8
  34. package/dist/svelte-src/BottomSheet.svelte +5 -3
  35. package/dist/svelte.cjs +143 -45
  36. package/dist/svelte.d.cts +1 -0
  37. package/dist/svelte.d.ts +1 -0
  38. package/dist/svelte.js +143 -45
  39. package/dist/vue.cjs +106 -18
  40. package/dist/vue.js +106 -18
  41. package/package.json +1 -1
package/dist/element.js CHANGED
@@ -3135,11 +3135,54 @@ var init_BottomSheetEngine = __esm({
3135
3135
  this.updateAriaSlider();
3136
3136
  }
3137
3137
  }
3138
+ contentTargets() {
3139
+ const scroller = this.scrollContainer;
3140
+ if (!scroller) return [];
3141
+ const hasSlot = typeof HTMLSlotElement !== "undefined";
3142
+ const out = [];
3143
+ for (const child of Array.from(scroller.children)) {
3144
+ if (hasSlot && child instanceof HTMLSlotElement) {
3145
+ for (const el of child.assignedElements()) out.push(el);
3146
+ } else {
3147
+ out.push(child);
3148
+ }
3149
+ }
3150
+ return out;
3151
+ }
3152
+ measureContentExtent(vertical) {
3153
+ const content = this.scrollContainer;
3154
+ if (!content) return 0;
3155
+ const targets = this.contentTargets();
3156
+ if (targets.length === 0) {
3157
+ return vertical ? content.scrollHeight : content.scrollWidth;
3158
+ }
3159
+ let min = Infinity;
3160
+ let max = -Infinity;
3161
+ for (const el of targets) {
3162
+ const r = el.getBoundingClientRect();
3163
+ if (vertical) {
3164
+ if (r.top < min) min = r.top;
3165
+ if (r.bottom > max) max = r.bottom;
3166
+ } else {
3167
+ if (r.left < min) min = r.left;
3168
+ if (r.right > max) max = r.right;
3169
+ }
3170
+ }
3171
+ if (!isFinite(min) || !isFinite(max) || max <= min) {
3172
+ return vertical ? content.scrollHeight : content.scrollWidth;
3173
+ }
3174
+ let pad = 0;
3175
+ if (typeof getComputedStyle !== "undefined") {
3176
+ const cs = getComputedStyle(content);
3177
+ pad = vertical ? (parseFloat(cs.paddingTop) || 0) + (parseFloat(cs.paddingBottom) || 0) : (parseFloat(cs.paddingLeft) || 0) + (parseFloat(cs.paddingRight) || 0);
3178
+ }
3179
+ return max - min + pad;
3180
+ }
3138
3181
  measureFitSize() {
3139
3182
  const vertical = layoutAxis(this.mode) === "height";
3140
3183
  const handleSize = vertical ? this.handle.offsetHeight : this.handle.offsetWidth;
3141
3184
  const content = this.scrollContainer;
3142
- const natural = content ? handleSize + (vertical ? content.scrollHeight : content.scrollWidth) : handleSize;
3185
+ const natural = content ? handleSize + this.measureContentExtent(vertical) : handleSize;
3143
3186
  if (typeof window === "undefined") return natural;
3144
3187
  const viewport = vertical ? window.innerHeight : window.innerWidth;
3145
3188
  return viewport > 0 ? Math.min(natural, viewport) : natural;
@@ -3148,22 +3191,62 @@ var init_BottomSheetEngine = __esm({
3148
3191
  if (typeof ResizeObserver === "undefined") return;
3149
3192
  if (!this.snapPointsRaw.some((p) => p.size === "fit" || p.size === "content"))
3150
3193
  return;
3151
- const targets = [this.handle];
3152
- if (this.scrollContainer && this.scrollContainer !== this.handle) {
3153
- targets.push(this.scrollContainer);
3154
- }
3155
3194
  let raf = 0;
3156
- const ro = new ResizeObserver(() => {
3195
+ const schedule = () => {
3157
3196
  if (raf) return;
3158
3197
  raf = requestAnimationFrame(() => {
3159
3198
  raf = 0;
3160
3199
  if (this.destroyed || this.gesture?.isDragging) return;
3161
3200
  this.recompute();
3162
3201
  });
3163
- });
3164
- for (const t of targets) ro.observe(t);
3202
+ };
3203
+ const ro = new ResizeObserver(schedule);
3204
+ ro.observe(this.handle);
3205
+ const scroller = this.scrollContainer;
3206
+ const observed = /* @__PURE__ */ new Set();
3207
+ const slots = /* @__PURE__ */ new Set();
3208
+ const hasSlot = typeof HTMLSlotElement !== "undefined";
3209
+ const onSlotChange = () => resync();
3210
+ const trackSlots = () => {
3211
+ if (!scroller || !hasSlot) return;
3212
+ for (const child of Array.from(scroller.children)) {
3213
+ if (child instanceof HTMLSlotElement && !slots.has(child)) {
3214
+ child.addEventListener("slotchange", onSlotChange);
3215
+ slots.add(child);
3216
+ }
3217
+ }
3218
+ };
3219
+ const resync = () => {
3220
+ trackSlots();
3221
+ const targets = this.contentTargets();
3222
+ for (const el of observed) {
3223
+ if (!targets.includes(el)) {
3224
+ ro.unobserve(el);
3225
+ observed.delete(el);
3226
+ }
3227
+ }
3228
+ for (const el of targets) {
3229
+ if (!observed.has(el)) {
3230
+ ro.observe(el);
3231
+ observed.add(el);
3232
+ }
3233
+ }
3234
+ schedule();
3235
+ };
3236
+ let mo;
3237
+ if (scroller) {
3238
+ resync();
3239
+ if (typeof MutationObserver !== "undefined") {
3240
+ mo = new MutationObserver(resync);
3241
+ mo.observe(scroller, { childList: true });
3242
+ }
3243
+ }
3165
3244
  this.teardowns.add(() => {
3166
3245
  ro.disconnect();
3246
+ mo?.disconnect();
3247
+ for (const slot of slots) {
3248
+ slot.removeEventListener("slotchange", onSlotChange);
3249
+ }
3167
3250
  if (raf) cancelAnimationFrame(raf);
3168
3251
  });
3169
3252
  }
@@ -3590,7 +3673,7 @@ var init_BottomSheetEngine = __esm({
3590
3673
  var baseStyles;
3591
3674
  var init_baseStyles = __esm({
3592
3675
  "src/web-component/baseStyles.ts"() {
3593
- 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-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-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}}`;
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}}`;
3594
3677
  }
3595
3678
  });
3596
3679
 
@@ -3600,7 +3683,7 @@ __export(BottomSheetElement_exports, {
3600
3683
  BottomSheetElement: () => BottomSheetElement,
3601
3684
  defineBottomSheet: () => defineBottomSheet
3602
3685
  });
3603
- var ATTR_SNAP_POINTS, ATTR_ALLOWED, ATTR_INITIAL, ATTR_MODE, ATTR_BACKDROP, ATTR_STYLESHEET, ATTR_ANIMATION, ATTR_FOCUS_TRAP, ATTR_CLOSE_ON_ESCAPE, ATTR_LOCK_BODY_SCROLL, ATTR_SHEET_LABEL, ATTR_STACK_EFFECT, ATTR_PERSISTENT, ATTR_DISABLE_CLOSE, ATTR_DISABLE_DRAG, ATTR_CLOSE_ON_ROUTE_CHANGE, ATTR_RADIUS, ATTR_MAX_HEIGHT, ATTR_RETURN_FOCUS_TO, ATTR_BACKDROP_COLOR, ATTR_SCRIM_COLOR, ATTR_SNAP, LIVE_ATTRS, isValidSnapPoint, DEFAULT_SNAP_POINTS, parseSnapPoints, VALID_MODES, VALID_ANIMATIONS, parseMode, parseAnimation, parseList, parseDimension, ANCHOR_POSITIONS, ANCHOR_ANIMATIONS, parseAnchorOptions, buildSlot, buildShadowTree, BaseHTMLElement, BottomSheetElement, defineBottomSheet;
3686
+ var ATTR_SNAP_POINTS, ATTR_ALLOWED, ATTR_INITIAL, ATTR_MODE, ATTR_BACKDROP, ATTR_STYLESHEET, ATTR_ANIMATION, ATTR_FOCUS_TRAP, ATTR_CLOSE_ON_ESCAPE, ATTR_LOCK_BODY_SCROLL, ATTR_SHEET_LABEL, ATTR_STACK_EFFECT, ATTR_PERSISTENT, ATTR_DISABLE_CLOSE, ATTR_DISABLE_DRAG, ATTR_CLOSE_ON_ROUTE_CHANGE, ATTR_RADIUS, ATTR_MAX_HEIGHT, ATTR_RETURN_FOCUS_TO, ATTR_BACKDROP_COLOR, ATTR_SCRIM_COLOR, ATTR_SNAP, LIVE_ATTRS, isValidSnapPoint, DEFAULT_SNAP_POINTS, parseSnapPoints, VALID_MODES, VALID_ANIMATIONS, parseMode, parseAnimation, parseList, parseDimension, ANCHOR_POSITIONS, ANCHOR_ANIMATIONS, parseAnchorOptions, buildSlot, buildSlotRegion, buildShadowTree, BaseHTMLElement, BottomSheetElement, defineBottomSheet;
3604
3687
  var init_BottomSheetElement = __esm({
3605
3688
  "src/web-component/BottomSheetElement.ts"() {
3606
3689
  init_BottomSheetEngine();
@@ -3711,6 +3794,19 @@ var init_BottomSheetElement = __esm({
3711
3794
  slot.name = name;
3712
3795
  return slot;
3713
3796
  };
3797
+ buildSlotRegion = (name, className) => {
3798
+ const region = document.createElement("div");
3799
+ region.className = className;
3800
+ region.setAttribute("part", name);
3801
+ const slot = buildSlot(name);
3802
+ region.appendChild(slot);
3803
+ const sync = () => {
3804
+ region.hidden = slot.assignedNodes({ flatten: true }).length === 0;
3805
+ };
3806
+ slot.addEventListener("slotchange", sync);
3807
+ sync();
3808
+ return region;
3809
+ };
3714
3810
  buildShadowTree = () => {
3715
3811
  const root = document.createElement("div");
3716
3812
  root.className = "bs-root";
@@ -3742,7 +3838,7 @@ var init_BottomSheetElement = __esm({
3742
3838
  handle.setAttribute("role", "slider");
3743
3839
  handle.setAttribute("tabindex", "0");
3744
3840
  handle.setAttribute("aria-label", "Resize sheet");
3745
- handle.appendChild(buildSlot("header"));
3841
+ const header = buildSlotRegion("header", "bs-header");
3746
3842
  const content = document.createElement("div");
3747
3843
  content.className = "bs-content";
3748
3844
  content.setAttribute("part", "content");
@@ -3751,13 +3847,14 @@ var init_BottomSheetElement = __esm({
3751
3847
  content.setAttribute("aria-label", "Sheet content");
3752
3848
  const defaultSlot = document.createElement("slot");
3753
3849
  content.appendChild(defaultSlot);
3850
+ const footer = buildSlotRegion("footer", "bs-footer");
3754
3851
  const announcer = document.createElement("span");
3755
3852
  announcer.className = "bs-sr-announce";
3756
3853
  announcer.setAttribute("role", "status");
3757
3854
  announcer.setAttribute("aria-live", "polite");
3758
3855
  announcer.setAttribute("aria-atomic", "true");
3759
3856
  announcer.style.cssText = "position:absolute;left:-10000px;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);";
3760
- sheet.append(handle, content);
3857
+ sheet.append(handle, header, content, footer);
3761
3858
  root.append(backdrop, screen, sheet, leftButton, rightButton, announcer);
3762
3859
  const fragment = document.createDocumentFragment();
3763
3860
  fragment.appendChild(root);
@@ -3766,7 +3863,9 @@ var init_BottomSheetElement = __esm({
3766
3863
  refs: {
3767
3864
  sheet,
3768
3865
  handle,
3866
+ header,
3769
3867
  content,
3868
+ footer,
3770
3869
  backdrop,
3771
3870
  screen,
3772
3871
  leftButton,
package/dist/index.cjs CHANGED
@@ -2902,11 +2902,54 @@ var BottomSheetEngine = class {
2902
2902
  this.updateAriaSlider();
2903
2903
  }
2904
2904
  }
2905
+ contentTargets() {
2906
+ const scroller = this.scrollContainer;
2907
+ if (!scroller) return [];
2908
+ const hasSlot = typeof HTMLSlotElement !== "undefined";
2909
+ const out = [];
2910
+ for (const child of Array.from(scroller.children)) {
2911
+ if (hasSlot && child instanceof HTMLSlotElement) {
2912
+ for (const el of child.assignedElements()) out.push(el);
2913
+ } else {
2914
+ out.push(child);
2915
+ }
2916
+ }
2917
+ return out;
2918
+ }
2919
+ measureContentExtent(vertical) {
2920
+ const content = this.scrollContainer;
2921
+ if (!content) return 0;
2922
+ const targets = this.contentTargets();
2923
+ if (targets.length === 0) {
2924
+ return vertical ? content.scrollHeight : content.scrollWidth;
2925
+ }
2926
+ let min = Infinity;
2927
+ let max = -Infinity;
2928
+ for (const el of targets) {
2929
+ const r = el.getBoundingClientRect();
2930
+ if (vertical) {
2931
+ if (r.top < min) min = r.top;
2932
+ if (r.bottom > max) max = r.bottom;
2933
+ } else {
2934
+ if (r.left < min) min = r.left;
2935
+ if (r.right > max) max = r.right;
2936
+ }
2937
+ }
2938
+ if (!isFinite(min) || !isFinite(max) || max <= min) {
2939
+ return vertical ? content.scrollHeight : content.scrollWidth;
2940
+ }
2941
+ let pad = 0;
2942
+ if (typeof getComputedStyle !== "undefined") {
2943
+ const cs = getComputedStyle(content);
2944
+ pad = vertical ? (parseFloat(cs.paddingTop) || 0) + (parseFloat(cs.paddingBottom) || 0) : (parseFloat(cs.paddingLeft) || 0) + (parseFloat(cs.paddingRight) || 0);
2945
+ }
2946
+ return max - min + pad;
2947
+ }
2905
2948
  measureFitSize() {
2906
2949
  const vertical = layoutAxis(this.mode) === "height";
2907
2950
  const handleSize = vertical ? this.handle.offsetHeight : this.handle.offsetWidth;
2908
2951
  const content = this.scrollContainer;
2909
- const natural = content ? handleSize + (vertical ? content.scrollHeight : content.scrollWidth) : handleSize;
2952
+ const natural = content ? handleSize + this.measureContentExtent(vertical) : handleSize;
2910
2953
  if (typeof window === "undefined") return natural;
2911
2954
  const viewport = vertical ? window.innerHeight : window.innerWidth;
2912
2955
  return viewport > 0 ? Math.min(natural, viewport) : natural;
@@ -2915,22 +2958,62 @@ var BottomSheetEngine = class {
2915
2958
  if (typeof ResizeObserver === "undefined") return;
2916
2959
  if (!this.snapPointsRaw.some((p) => p.size === "fit" || p.size === "content"))
2917
2960
  return;
2918
- const targets = [this.handle];
2919
- if (this.scrollContainer && this.scrollContainer !== this.handle) {
2920
- targets.push(this.scrollContainer);
2921
- }
2922
2961
  let raf = 0;
2923
- const ro = new ResizeObserver(() => {
2962
+ const schedule = () => {
2924
2963
  if (raf) return;
2925
2964
  raf = requestAnimationFrame(() => {
2926
2965
  raf = 0;
2927
2966
  if (this.destroyed || this.gesture?.isDragging) return;
2928
2967
  this.recompute();
2929
2968
  });
2930
- });
2931
- for (const t of targets) ro.observe(t);
2969
+ };
2970
+ const ro = new ResizeObserver(schedule);
2971
+ ro.observe(this.handle);
2972
+ const scroller = this.scrollContainer;
2973
+ const observed = /* @__PURE__ */ new Set();
2974
+ const slots = /* @__PURE__ */ new Set();
2975
+ const hasSlot = typeof HTMLSlotElement !== "undefined";
2976
+ const onSlotChange = () => resync();
2977
+ const trackSlots = () => {
2978
+ if (!scroller || !hasSlot) return;
2979
+ for (const child of Array.from(scroller.children)) {
2980
+ if (child instanceof HTMLSlotElement && !slots.has(child)) {
2981
+ child.addEventListener("slotchange", onSlotChange);
2982
+ slots.add(child);
2983
+ }
2984
+ }
2985
+ };
2986
+ const resync = () => {
2987
+ trackSlots();
2988
+ const targets = this.contentTargets();
2989
+ for (const el of observed) {
2990
+ if (!targets.includes(el)) {
2991
+ ro.unobserve(el);
2992
+ observed.delete(el);
2993
+ }
2994
+ }
2995
+ for (const el of targets) {
2996
+ if (!observed.has(el)) {
2997
+ ro.observe(el);
2998
+ observed.add(el);
2999
+ }
3000
+ }
3001
+ schedule();
3002
+ };
3003
+ let mo;
3004
+ if (scroller) {
3005
+ resync();
3006
+ if (typeof MutationObserver !== "undefined") {
3007
+ mo = new MutationObserver(resync);
3008
+ mo.observe(scroller, { childList: true });
3009
+ }
3010
+ }
2932
3011
  this.teardowns.add(() => {
2933
3012
  ro.disconnect();
3013
+ mo?.disconnect();
3014
+ for (const slot of slots) {
3015
+ slot.removeEventListener("slotchange", onSlotChange);
3016
+ }
2934
3017
  if (raf) cancelAnimationFrame(raf);
2935
3018
  });
2936
3019
  }
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { d as SnapPoint, b as SheetMode, a as SnapPointDef, c as EngineOptions, f as ScrimOverlayPosition } from './BottomSheetEngine-BJrH7qY3.cjs';
2
- export { g as AnchorAnimationPreset, h as AnchorAnimationSpec, i as AnchorHandle, A as AnchorOptions, j as AnchorPosition, k as AnchorState, B as BottomSheetEngine, C as CloseReason, E as EngineState, P as Plugin, l as SCRIM_PRESETS, m as ScrimOverlayOptions, n as ScrimPreset, o as ScrimPresetConfig, p as ScrimStageDef, S as ScrimStagesOptions, q as ScrimUpdate, e as SheetEventMap, r as SnapId, T as TeardownScope, s as runAnchorTransition } from './BottomSheetEngine-BJrH7qY3.cjs';
1
+ import { d as SnapPoint, b as SheetMode, a as SnapPointDef, c as EngineOptions, f as ScrimOverlayPosition } from './BottomSheetEngine-CqiCz64W.cjs';
2
+ export { g as AnchorAnimationPreset, h as AnchorAnimationSpec, i as AnchorHandle, A as AnchorOptions, j as AnchorPosition, k as AnchorState, B as BottomSheetEngine, C as CloseReason, E as EngineState, P as Plugin, l as SCRIM_PRESETS, m as ScrimOverlayOptions, n as ScrimPreset, o as ScrimPresetConfig, p as ScrimStageDef, S as ScrimStagesOptions, q as ScrimUpdate, e as SheetEventMap, r as SnapId, T as TeardownScope, s as runAnchorTransition } from './BottomSheetEngine-CqiCz64W.cjs';
3
3
  export { OVERLAY_PRESETS, Overlay, OverlayAnimation, OverlayCloseReason, OverlayEdge, Overlay as OverlayEngine, OverlayEventMap, OverlayMountTarget, OverlayOptions, OverlayPreset, OverlayState, OverlayUpdate, SwipeToCloseConfig, createOverlay } from './overlay.cjs';
4
4
  import './transform-jVfAikE9.cjs';
5
5
 
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { d as SnapPoint, b as SheetMode, a as SnapPointDef, c as EngineOptions, f as ScrimOverlayPosition } from './BottomSheetEngine-L05jGZvU.js';
2
- export { g as AnchorAnimationPreset, h as AnchorAnimationSpec, i as AnchorHandle, A as AnchorOptions, j as AnchorPosition, k as AnchorState, B as BottomSheetEngine, C as CloseReason, E as EngineState, P as Plugin, l as SCRIM_PRESETS, m as ScrimOverlayOptions, n as ScrimPreset, o as ScrimPresetConfig, p as ScrimStageDef, S as ScrimStagesOptions, q as ScrimUpdate, e as SheetEventMap, r as SnapId, T as TeardownScope, s as runAnchorTransition } from './BottomSheetEngine-L05jGZvU.js';
1
+ import { d as SnapPoint, b as SheetMode, a as SnapPointDef, c as EngineOptions, f as ScrimOverlayPosition } from './BottomSheetEngine-BHjKFtnM.js';
2
+ export { g as AnchorAnimationPreset, h as AnchorAnimationSpec, i as AnchorHandle, A as AnchorOptions, j as AnchorPosition, k as AnchorState, B as BottomSheetEngine, C as CloseReason, E as EngineState, P as Plugin, l as SCRIM_PRESETS, m as ScrimOverlayOptions, n as ScrimPreset, o as ScrimPresetConfig, p as ScrimStageDef, S as ScrimStagesOptions, q as ScrimUpdate, e as SheetEventMap, r as SnapId, T as TeardownScope, s as runAnchorTransition } from './BottomSheetEngine-BHjKFtnM.js';
3
3
  export { OVERLAY_PRESETS, Overlay, OverlayAnimation, OverlayCloseReason, OverlayEdge, Overlay as OverlayEngine, OverlayEventMap, OverlayMountTarget, OverlayOptions, OverlayPreset, OverlayState, OverlayUpdate, SwipeToCloseConfig, createOverlay } from './overlay.js';
4
4
  import './transform-jVfAikE9.js';
5
5
 
package/dist/index.js CHANGED
@@ -2900,11 +2900,54 @@ var BottomSheetEngine = class {
2900
2900
  this.updateAriaSlider();
2901
2901
  }
2902
2902
  }
2903
+ contentTargets() {
2904
+ const scroller = this.scrollContainer;
2905
+ if (!scroller) return [];
2906
+ const hasSlot = typeof HTMLSlotElement !== "undefined";
2907
+ const out = [];
2908
+ for (const child of Array.from(scroller.children)) {
2909
+ if (hasSlot && child instanceof HTMLSlotElement) {
2910
+ for (const el of child.assignedElements()) out.push(el);
2911
+ } else {
2912
+ out.push(child);
2913
+ }
2914
+ }
2915
+ return out;
2916
+ }
2917
+ measureContentExtent(vertical) {
2918
+ const content = this.scrollContainer;
2919
+ if (!content) return 0;
2920
+ const targets = this.contentTargets();
2921
+ if (targets.length === 0) {
2922
+ return vertical ? content.scrollHeight : content.scrollWidth;
2923
+ }
2924
+ let min = Infinity;
2925
+ let max = -Infinity;
2926
+ for (const el of targets) {
2927
+ const r = el.getBoundingClientRect();
2928
+ if (vertical) {
2929
+ if (r.top < min) min = r.top;
2930
+ if (r.bottom > max) max = r.bottom;
2931
+ } else {
2932
+ if (r.left < min) min = r.left;
2933
+ if (r.right > max) max = r.right;
2934
+ }
2935
+ }
2936
+ if (!isFinite(min) || !isFinite(max) || max <= min) {
2937
+ return vertical ? content.scrollHeight : content.scrollWidth;
2938
+ }
2939
+ let pad = 0;
2940
+ if (typeof getComputedStyle !== "undefined") {
2941
+ const cs = getComputedStyle(content);
2942
+ pad = vertical ? (parseFloat(cs.paddingTop) || 0) + (parseFloat(cs.paddingBottom) || 0) : (parseFloat(cs.paddingLeft) || 0) + (parseFloat(cs.paddingRight) || 0);
2943
+ }
2944
+ return max - min + pad;
2945
+ }
2903
2946
  measureFitSize() {
2904
2947
  const vertical = layoutAxis(this.mode) === "height";
2905
2948
  const handleSize = vertical ? this.handle.offsetHeight : this.handle.offsetWidth;
2906
2949
  const content = this.scrollContainer;
2907
- const natural = content ? handleSize + (vertical ? content.scrollHeight : content.scrollWidth) : handleSize;
2950
+ const natural = content ? handleSize + this.measureContentExtent(vertical) : handleSize;
2908
2951
  if (typeof window === "undefined") return natural;
2909
2952
  const viewport = vertical ? window.innerHeight : window.innerWidth;
2910
2953
  return viewport > 0 ? Math.min(natural, viewport) : natural;
@@ -2913,22 +2956,62 @@ var BottomSheetEngine = class {
2913
2956
  if (typeof ResizeObserver === "undefined") return;
2914
2957
  if (!this.snapPointsRaw.some((p) => p.size === "fit" || p.size === "content"))
2915
2958
  return;
2916
- const targets = [this.handle];
2917
- if (this.scrollContainer && this.scrollContainer !== this.handle) {
2918
- targets.push(this.scrollContainer);
2919
- }
2920
2959
  let raf = 0;
2921
- const ro = new ResizeObserver(() => {
2960
+ const schedule = () => {
2922
2961
  if (raf) return;
2923
2962
  raf = requestAnimationFrame(() => {
2924
2963
  raf = 0;
2925
2964
  if (this.destroyed || this.gesture?.isDragging) return;
2926
2965
  this.recompute();
2927
2966
  });
2928
- });
2929
- for (const t of targets) ro.observe(t);
2967
+ };
2968
+ const ro = new ResizeObserver(schedule);
2969
+ ro.observe(this.handle);
2970
+ const scroller = this.scrollContainer;
2971
+ const observed = /* @__PURE__ */ new Set();
2972
+ const slots = /* @__PURE__ */ new Set();
2973
+ const hasSlot = typeof HTMLSlotElement !== "undefined";
2974
+ const onSlotChange = () => resync();
2975
+ const trackSlots = () => {
2976
+ if (!scroller || !hasSlot) return;
2977
+ for (const child of Array.from(scroller.children)) {
2978
+ if (child instanceof HTMLSlotElement && !slots.has(child)) {
2979
+ child.addEventListener("slotchange", onSlotChange);
2980
+ slots.add(child);
2981
+ }
2982
+ }
2983
+ };
2984
+ const resync = () => {
2985
+ trackSlots();
2986
+ const targets = this.contentTargets();
2987
+ for (const el of observed) {
2988
+ if (!targets.includes(el)) {
2989
+ ro.unobserve(el);
2990
+ observed.delete(el);
2991
+ }
2992
+ }
2993
+ for (const el of targets) {
2994
+ if (!observed.has(el)) {
2995
+ ro.observe(el);
2996
+ observed.add(el);
2997
+ }
2998
+ }
2999
+ schedule();
3000
+ };
3001
+ let mo;
3002
+ if (scroller) {
3003
+ resync();
3004
+ if (typeof MutationObserver !== "undefined") {
3005
+ mo = new MutationObserver(resync);
3006
+ mo.observe(scroller, { childList: true });
3007
+ }
3008
+ }
2930
3009
  this.teardowns.add(() => {
2931
3010
  ro.disconnect();
3011
+ mo?.disconnect();
3012
+ for (const slot of slots) {
3013
+ slot.removeEventListener("slotchange", onSlotChange);
3014
+ }
2932
3015
  if (raf) cancelAnimationFrame(raf);
2933
3016
  });
2934
3017
  }
@@ -1,4 +1,4 @@
1
- import { e as SheetEventMap } from '../BottomSheetEngine-BJrH7qY3.cjs';
1
+ import { e as SheetEventMap } from '../BottomSheetEngine-CqiCz64W.cjs';
2
2
  import '../transform-jVfAikE9.cjs';
3
3
 
4
4
  type FormikStateLike = {
@@ -1,4 +1,4 @@
1
- import { e as SheetEventMap } from '../BottomSheetEngine-L05jGZvU.js';
1
+ import { e as SheetEventMap } from '../BottomSheetEngine-BHjKFtnM.js';
2
2
  import '../transform-jVfAikE9.js';
3
3
 
4
4
  type FormikStateLike = {
@@ -1,4 +1,4 @@
1
- import { e as SheetEventMap } from '../BottomSheetEngine-BJrH7qY3.cjs';
1
+ import { e as SheetEventMap } from '../BottomSheetEngine-CqiCz64W.cjs';
2
2
  import '../transform-jVfAikE9.cjs';
3
3
 
4
4
  type RhfFormStateLike = {
@@ -1,4 +1,4 @@
1
- import { e as SheetEventMap } from '../BottomSheetEngine-L05jGZvU.js';
1
+ import { e as SheetEventMap } from '../BottomSheetEngine-BHjKFtnM.js';
2
2
  import '../transform-jVfAikE9.js';
3
3
 
4
4
  type RhfFormStateLike = {
package/dist/preact.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { BottomSheet, BottomSheetFromConfig, BottomSheetFromConfigProps, BottomSheetHandle, BottomSheetProps, HeaderProp, Overlay, OverlayHandle, OverlayProps, SheetConfig, UseBottomSheetRefs, UseBottomSheetReturn, UseOverlayReturn, useBottomSheet, useOverlay } from './react.cjs';
2
- export { E as EngineState, b as SheetMode, d as SnapPoint, a as SnapPointDef } from './BottomSheetEngine-BJrH7qY3.cjs';
2
+ export { E as EngineState, b as SheetMode, d as SnapPoint, a as SnapPointDef } from './BottomSheetEngine-CqiCz64W.cjs';
3
3
  export { OverlayEdge, OverlayOptions, OverlayState } from './overlay.cjs';
4
4
  import 'react';
5
5
  import './transform-jVfAikE9.cjs';
package/dist/preact.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { BottomSheet, BottomSheetFromConfig, BottomSheetFromConfigProps, BottomSheetHandle, BottomSheetProps, HeaderProp, Overlay, OverlayHandle, OverlayProps, SheetConfig, UseBottomSheetRefs, UseBottomSheetReturn, UseOverlayReturn, useBottomSheet, useOverlay } from './react.js';
2
- export { E as EngineState, b as SheetMode, d as SnapPoint, a as SnapPointDef } from './BottomSheetEngine-L05jGZvU.js';
2
+ export { E as EngineState, b as SheetMode, d as SnapPoint, a as SnapPointDef } from './BottomSheetEngine-BHjKFtnM.js';
3
3
  export { OverlayEdge, OverlayOptions, OverlayState } from './overlay.js';
4
4
  import 'react';
5
5
  import './transform-jVfAikE9.js';