@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/svelte.js CHANGED
@@ -2897,11 +2897,54 @@ var BottomSheetEngine = class {
2897
2897
  this.updateAriaSlider();
2898
2898
  }
2899
2899
  }
2900
+ contentTargets() {
2901
+ const scroller = this.scrollContainer;
2902
+ if (!scroller) return [];
2903
+ const hasSlot = typeof HTMLSlotElement !== "undefined";
2904
+ const out = [];
2905
+ for (const child2 of Array.from(scroller.children)) {
2906
+ if (hasSlot && child2 instanceof HTMLSlotElement) {
2907
+ for (const el of child2.assignedElements()) out.push(el);
2908
+ } else {
2909
+ out.push(child2);
2910
+ }
2911
+ }
2912
+ return out;
2913
+ }
2914
+ measureContentExtent(vertical) {
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);
2940
+ }
2941
+ return max - min + pad;
2942
+ }
2900
2943
  measureFitSize() {
2901
2944
  const vertical = layoutAxis(this.mode) === "height";
2902
2945
  const handleSize = vertical ? this.handle.offsetHeight : this.handle.offsetWidth;
2903
2946
  const content = this.scrollContainer;
2904
- const natural = content ? handleSize + (vertical ? content.scrollHeight : content.scrollWidth) : handleSize;
2947
+ const natural = content ? handleSize + this.measureContentExtent(vertical) : handleSize;
2905
2948
  if (typeof window === "undefined") return natural;
2906
2949
  const viewport = vertical ? window.innerHeight : window.innerWidth;
2907
2950
  return viewport > 0 ? Math.min(natural, viewport) : natural;
@@ -2910,22 +2953,62 @@ var BottomSheetEngine = class {
2910
2953
  if (typeof ResizeObserver === "undefined") return;
2911
2954
  if (!this.snapPointsRaw.some((p) => p.size === "fit" || p.size === "content"))
2912
2955
  return;
2913
- const targets = [this.handle];
2914
- if (this.scrollContainer && this.scrollContainer !== this.handle) {
2915
- targets.push(this.scrollContainer);
2916
- }
2917
2956
  let raf = 0;
2918
- const ro = new ResizeObserver(() => {
2957
+ const schedule = () => {
2919
2958
  if (raf) return;
2920
2959
  raf = requestAnimationFrame(() => {
2921
2960
  raf = 0;
2922
2961
  if (this.destroyed || this.gesture?.isDragging) return;
2923
2962
  this.recompute();
2924
2963
  });
2925
- });
2926
- for (const t of targets) ro.observe(t);
2964
+ };
2965
+ const ro = new ResizeObserver(schedule);
2966
+ ro.observe(this.handle);
2967
+ const scroller = this.scrollContainer;
2968
+ const observed = /* @__PURE__ */ new Set();
2969
+ const slots = /* @__PURE__ */ new Set();
2970
+ const hasSlot = typeof HTMLSlotElement !== "undefined";
2971
+ const onSlotChange = () => resync();
2972
+ const trackSlots = () => {
2973
+ if (!scroller || !hasSlot) return;
2974
+ for (const child2 of Array.from(scroller.children)) {
2975
+ if (child2 instanceof HTMLSlotElement && !slots.has(child2)) {
2976
+ child2.addEventListener("slotchange", onSlotChange);
2977
+ slots.add(child2);
2978
+ }
2979
+ }
2980
+ };
2981
+ const resync = () => {
2982
+ trackSlots();
2983
+ const targets = this.contentTargets();
2984
+ for (const el of observed) {
2985
+ if (!targets.includes(el)) {
2986
+ ro.unobserve(el);
2987
+ observed.delete(el);
2988
+ }
2989
+ }
2990
+ for (const el of targets) {
2991
+ if (!observed.has(el)) {
2992
+ ro.observe(el);
2993
+ observed.add(el);
2994
+ }
2995
+ }
2996
+ schedule();
2997
+ };
2998
+ let mo;
2999
+ if (scroller) {
3000
+ resync();
3001
+ if (typeof MutationObserver !== "undefined") {
3002
+ mo = new MutationObserver(resync);
3003
+ mo.observe(scroller, { childList: true });
3004
+ }
3005
+ }
2927
3006
  this.teardowns.add(() => {
2928
3007
  ro.disconnect();
3008
+ mo?.disconnect();
3009
+ for (const slot of slots) {
3010
+ slot.removeEventListener("slotchange", onSlotChange);
3011
+ }
2929
3012
  if (raf) cancelAnimationFrame(raf);
2930
3013
  });
2931
3014
  }
@@ -3416,9 +3499,11 @@ function createBottomSheet(opts) {
3416
3499
  };
3417
3500
  }
3418
3501
  var root_1 = $2.from_html(`<div class="bs-backdrop" aria-hidden="true"></div>`);
3419
- var root_5 = $2.from_html(`<div class="bs-button-slot" data-side="left"><!></div>`);
3420
- var root_6 = $2.from_html(`<div class="bs-button-slot" data-side="right"><!></div>`);
3421
- var root = $2.from_html(`<div class="bs-root"><!> <div class="bs-screen"><!></div> <section class="bs-sheet" role="dialog"><div class="bs-handle" role="slider" tabindex="0" aria-label="Resize sheet"><!></div> <div class="bs-content" tabindex="0" role="region" aria-label="Sheet content"><!></div> <span class="bs-sr-only" role="status" aria-live="polite"> </span></section> <!> <!></div>`);
3502
+ var root_3 = $2.from_html(`<div class="bs-header"><!></div>`);
3503
+ var root_5 = $2.from_html(`<div class="bs-footer"><!></div>`);
3504
+ var root_6 = $2.from_html(`<div class="bs-button-slot" data-side="left"><!></div>`);
3505
+ var root_7 = $2.from_html(`<div class="bs-button-slot" data-side="right"><!></div>`);
3506
+ var root = $2.from_html(`<div class="bs-root"><!> <div class="bs-screen"><!></div> <section class="bs-sheet" role="dialog"><div class="bs-handle" role="slider" tabindex="0" aria-label="Resize sheet"></div> <!> <div class="bs-content" tabindex="0" role="region" aria-label="Sheet content"><!></div> <!> <span class="bs-sr-only" role="status" aria-live="polite"> </span></section> <!> <!></div>`);
3422
3507
  function BottomSheet($$anchor, $$props) {
3423
3508
  $2.push($$props, true);
3424
3509
  let mode = $2.prop($$props, "mode", 3, "bottom"), animation = $2.prop($$props, "animation", 3, "spring"), focusTrap = $2.prop($$props, "focusTrap", 3, false), closeOnEscape = $2.prop($$props, "closeOnEscape", 3, true), closeOnBack = $2.prop($$props, "closeOnBack", 3, false), lockBodyScroll2 = $2.prop($$props, "lockBodyScroll", 3, true), rubberBand2 = $2.prop($$props, "rubberBand", 3, true), backdrop = $2.prop($$props, "backdrop", 3, true), closeOnBackdrop = $2.prop($$props, "closeOnBackdrop", 3, true), persistent = $2.prop($$props, "persistent", 3, false), disableClose = $2.prop($$props, "disableClose", 3, false), disableDrag = $2.prop($$props, "disableDrag", 3, false), closeOnRouteChange = $2.prop($$props, "closeOnRouteChange", 3, false), openProp = $2.prop($$props, "open", 15), snap = $2.prop($$props, "snap", 15), ariaLabel = $2.prop($$props, "ariaLabel", 3, "Bottom sheet");
@@ -3599,66 +3684,79 @@ function BottomSheet($$anchor, $$props) {
3599
3684
  var section = $2.sibling(div_2, 2);
3600
3685
  var div_3 = $2.child(section);
3601
3686
  $2.set_attribute(div_3, "aria-valuemin", 0);
3602
- var node_3 = $2.child(div_3);
3687
+ $2.bind_this(div_3, ($$value) => $2.set(handleEl, $$value), () => $2.get(handleEl));
3688
+ var node_3 = $2.sibling(div_3, 2);
3603
3689
  {
3604
3690
  var consequent_2 = ($$anchor2) => {
3605
- var fragment_1 = $2.comment();
3606
- var node_4 = $2.first_child(fragment_1);
3691
+ var div_4 = root_3();
3692
+ var node_4 = $2.child(div_4);
3607
3693
  $2.snippet(node_4, () => $$props.header, () => $2.get(viewState));
3608
- $2.append($$anchor2, fragment_1);
3694
+ $2.reset(div_4);
3695
+ $2.append($$anchor2, div_4);
3609
3696
  };
3610
3697
  $2.if(node_3, ($$render) => {
3611
3698
  if ($$props.header) $$render(consequent_2);
3612
3699
  });
3613
3700
  }
3614
- $2.reset(div_3);
3615
- $2.bind_this(div_3, ($$value) => $2.set(handleEl, $$value), () => $2.get(handleEl));
3616
- var div_4 = $2.sibling(div_3, 2);
3617
- var node_5 = $2.child(div_4);
3701
+ var div_5 = $2.sibling(node_3, 2);
3702
+ var node_5 = $2.child(div_5);
3618
3703
  {
3619
3704
  var consequent_3 = ($$anchor2) => {
3620
- var fragment_2 = $2.comment();
3621
- var node_6 = $2.first_child(fragment_2);
3705
+ var fragment_1 = $2.comment();
3706
+ var node_6 = $2.first_child(fragment_1);
3622
3707
  $2.snippet(node_6, () => $$props.children);
3623
- $2.append($$anchor2, fragment_2);
3708
+ $2.append($$anchor2, fragment_1);
3624
3709
  };
3625
3710
  $2.if(node_5, ($$render) => {
3626
3711
  if ($$props.children) $$render(consequent_3);
3627
3712
  });
3628
3713
  }
3629
- $2.reset(div_4);
3630
- $2.bind_this(div_4, ($$value) => $2.set(contentEl, $$value), () => $2.get(contentEl));
3631
- var span = $2.sibling(div_4, 2);
3632
- var text = $2.child(span, true);
3633
- $2.reset(span);
3634
- $2.reset(section);
3635
- $2.bind_this(section, ($$value) => $2.set(sheetEl, $$value), () => $2.get(sheetEl));
3636
- var node_7 = $2.sibling(section, 2);
3714
+ $2.reset(div_5);
3715
+ $2.bind_this(div_5, ($$value) => $2.set(contentEl, $$value), () => $2.get(contentEl));
3716
+ var node_7 = $2.sibling(div_5, 2);
3637
3717
  {
3638
3718
  var consequent_4 = ($$anchor2) => {
3639
- var div_5 = root_5();
3640
- var node_8 = $2.child(div_5);
3641
- $2.snippet(node_8, () => $$props.leftButton);
3642
- $2.reset(div_5);
3643
- $2.template_effect(() => $2.set_attribute(div_5, "data-mode", mode()));
3644
- $2.append($$anchor2, div_5);
3719
+ var div_6 = root_5();
3720
+ var node_8 = $2.child(div_6);
3721
+ $2.snippet(node_8, () => $$props.footer, () => $2.get(viewState));
3722
+ $2.reset(div_6);
3723
+ $2.append($$anchor2, div_6);
3645
3724
  };
3646
3725
  $2.if(node_7, ($$render) => {
3647
- if ($$props.leftButton) $$render(consequent_4);
3726
+ if ($$props.footer) $$render(consequent_4);
3648
3727
  });
3649
3728
  }
3650
- var node_9 = $2.sibling(node_7, 2);
3729
+ var span = $2.sibling(node_7, 2);
3730
+ var text = $2.child(span, true);
3731
+ $2.reset(span);
3732
+ $2.reset(section);
3733
+ $2.bind_this(section, ($$value) => $2.set(sheetEl, $$value), () => $2.get(sheetEl));
3734
+ var node_9 = $2.sibling(section, 2);
3651
3735
  {
3652
3736
  var consequent_5 = ($$anchor2) => {
3653
- var div_6 = root_6();
3654
- var node_10 = $2.child(div_6);
3655
- $2.snippet(node_10, () => $$props.rightButton);
3656
- $2.reset(div_6);
3657
- $2.template_effect(() => $2.set_attribute(div_6, "data-mode", mode()));
3658
- $2.append($$anchor2, div_6);
3737
+ var div_7 = root_6();
3738
+ var node_10 = $2.child(div_7);
3739
+ $2.snippet(node_10, () => $$props.leftButton);
3740
+ $2.reset(div_7);
3741
+ $2.template_effect(() => $2.set_attribute(div_7, "data-mode", mode()));
3742
+ $2.append($$anchor2, div_7);
3659
3743
  };
3660
3744
  $2.if(node_9, ($$render) => {
3661
- if ($$props.rightButton) $$render(consequent_5);
3745
+ if ($$props.leftButton) $$render(consequent_5);
3746
+ });
3747
+ }
3748
+ var node_11 = $2.sibling(node_9, 2);
3749
+ {
3750
+ var consequent_6 = ($$anchor2) => {
3751
+ var div_8 = root_7();
3752
+ var node_12 = $2.child(div_8);
3753
+ $2.snippet(node_12, () => $$props.rightButton);
3754
+ $2.reset(div_8);
3755
+ $2.template_effect(() => $2.set_attribute(div_8, "data-mode", mode()));
3756
+ $2.append($$anchor2, div_8);
3757
+ };
3758
+ $2.if(node_11, ($$render) => {
3759
+ if ($$props.rightButton) $$render(consequent_6);
3662
3760
  });
3663
3761
  }
3664
3762
  $2.reset(div);
package/dist/vue.cjs CHANGED
@@ -2897,11 +2897,54 @@ var BottomSheetEngine = class {
2897
2897
  this.updateAriaSlider();
2898
2898
  }
2899
2899
  }
2900
+ contentTargets() {
2901
+ const scroller = this.scrollContainer;
2902
+ if (!scroller) return [];
2903
+ const hasSlot = typeof HTMLSlotElement !== "undefined";
2904
+ const out = [];
2905
+ for (const child of Array.from(scroller.children)) {
2906
+ if (hasSlot && child instanceof HTMLSlotElement) {
2907
+ for (const el of child.assignedElements()) out.push(el);
2908
+ } else {
2909
+ out.push(child);
2910
+ }
2911
+ }
2912
+ return out;
2913
+ }
2914
+ measureContentExtent(vertical) {
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);
2940
+ }
2941
+ return max - min + pad;
2942
+ }
2900
2943
  measureFitSize() {
2901
2944
  const vertical = layoutAxis(this.mode) === "height";
2902
2945
  const handleSize = vertical ? this.handle.offsetHeight : this.handle.offsetWidth;
2903
2946
  const content = this.scrollContainer;
2904
- const natural = content ? handleSize + (vertical ? content.scrollHeight : content.scrollWidth) : handleSize;
2947
+ const natural = content ? handleSize + this.measureContentExtent(vertical) : handleSize;
2905
2948
  if (typeof window === "undefined") return natural;
2906
2949
  const viewport = vertical ? window.innerHeight : window.innerWidth;
2907
2950
  return viewport > 0 ? Math.min(natural, viewport) : natural;
@@ -2910,22 +2953,62 @@ var BottomSheetEngine = class {
2910
2953
  if (typeof ResizeObserver === "undefined") return;
2911
2954
  if (!this.snapPointsRaw.some((p) => p.size === "fit" || p.size === "content"))
2912
2955
  return;
2913
- const targets = [this.handle];
2914
- if (this.scrollContainer && this.scrollContainer !== this.handle) {
2915
- targets.push(this.scrollContainer);
2916
- }
2917
2956
  let raf = 0;
2918
- const ro = new ResizeObserver(() => {
2957
+ const schedule = () => {
2919
2958
  if (raf) return;
2920
2959
  raf = requestAnimationFrame(() => {
2921
2960
  raf = 0;
2922
2961
  if (this.destroyed || this.gesture?.isDragging) return;
2923
2962
  this.recompute();
2924
2963
  });
2925
- });
2926
- for (const t of targets) ro.observe(t);
2964
+ };
2965
+ const ro = new ResizeObserver(schedule);
2966
+ ro.observe(this.handle);
2967
+ const scroller = this.scrollContainer;
2968
+ const observed = /* @__PURE__ */ new Set();
2969
+ const slots = /* @__PURE__ */ new Set();
2970
+ const hasSlot = typeof HTMLSlotElement !== "undefined";
2971
+ const onSlotChange = () => resync();
2972
+ const trackSlots = () => {
2973
+ if (!scroller || !hasSlot) return;
2974
+ for (const child of Array.from(scroller.children)) {
2975
+ if (child instanceof HTMLSlotElement && !slots.has(child)) {
2976
+ child.addEventListener("slotchange", onSlotChange);
2977
+ slots.add(child);
2978
+ }
2979
+ }
2980
+ };
2981
+ const resync = () => {
2982
+ trackSlots();
2983
+ const targets = this.contentTargets();
2984
+ for (const el of observed) {
2985
+ if (!targets.includes(el)) {
2986
+ ro.unobserve(el);
2987
+ observed.delete(el);
2988
+ }
2989
+ }
2990
+ for (const el of targets) {
2991
+ if (!observed.has(el)) {
2992
+ ro.observe(el);
2993
+ observed.add(el);
2994
+ }
2995
+ }
2996
+ schedule();
2997
+ };
2998
+ let mo;
2999
+ if (scroller) {
3000
+ resync();
3001
+ if (typeof MutationObserver !== "undefined") {
3002
+ mo = new MutationObserver(resync);
3003
+ mo.observe(scroller, { childList: true });
3004
+ }
3005
+ }
2927
3006
  this.teardowns.add(() => {
2928
3007
  ro.disconnect();
3008
+ mo?.disconnect();
3009
+ for (const slot of slots) {
3010
+ slot.removeEventListener("slotchange", onSlotChange);
3011
+ }
2929
3012
  if (raf) cancelAnimationFrame(raf);
2930
3013
  });
2931
3014
  }
@@ -3900,23 +3983,27 @@ var _hoisted_4 = [
3900
3983
  "aria-valuetext"
3901
3984
  ];
3902
3985
  var _hoisted_5 = {
3986
+ key: 0,
3987
+ class: "bs-header"
3988
+ };
3989
+ var _hoisted_6 = {
3903
3990
  ref: "contentRef",
3904
3991
  class: "bs-content",
3905
3992
  tabindex: "0",
3906
3993
  role: "region",
3907
3994
  "aria-label": "Sheet content"
3908
3995
  };
3909
- var _hoisted_6 = {
3910
- key: 0,
3996
+ var _hoisted_7 = {
3997
+ key: 1,
3911
3998
  class: "bs-footer"
3912
3999
  };
3913
- var _hoisted_7 = {
4000
+ var _hoisted_8 = {
3914
4001
  class: "bs-sr-only",
3915
4002
  role: "status",
3916
4003
  "aria-live": "polite"
3917
4004
  };
3918
- var _hoisted_8 = ["data-mode"];
3919
4005
  var _hoisted_9 = ["data-mode"];
4006
+ var _hoisted_10 = ["data-mode"];
3920
4007
  function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
3921
4008
  return vue.openBlock(), vue.createBlock(vue.Teleport, {
3922
4009
  to: $props.teleportTo,
@@ -3962,18 +4049,19 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
3962
4049
  "aria-valuenow": $setup.activeIdx,
3963
4050
  "aria-valuetext": $setup.state.activeId,
3964
4051
  "aria-label": "Resize sheet"
3965
- }, [vue.renderSlot(_ctx.$slots, "header", { state: $setup.state })], 8, _hoisted_4),
4052
+ }, null, 8, _hoisted_4),
4053
+ _ctx.$slots.header ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_5, [vue.renderSlot(_ctx.$slots, "header", { state: $setup.state })])) : vue.createCommentVNode("v-if", true),
3966
4054
  vue.createElementVNode(
3967
4055
  "div",
3968
- _hoisted_5,
4056
+ _hoisted_6,
3969
4057
  [vue.renderSlot(_ctx.$slots, "default")],
3970
4058
  512
3971
4059
  /* NEED_PATCH */
3972
4060
  ),
3973
- _ctx.$slots.footer ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_6, [vue.renderSlot(_ctx.$slots, "footer", { state: $setup.state })])) : vue.createCommentVNode("v-if", true),
4061
+ _ctx.$slots.footer ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_7, [vue.renderSlot(_ctx.$slots, "footer", { state: $setup.state })])) : vue.createCommentVNode("v-if", true),
3974
4062
  vue.createElementVNode(
3975
4063
  "span",
3976
- _hoisted_7,
4064
+ _hoisted_8,
3977
4065
  vue.toDisplayString($setup.state.activeId),
3978
4066
  1
3979
4067
  /* TEXT */
@@ -3984,13 +4072,13 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
3984
4072
  class: "bs-button-slot",
3985
4073
  "data-side": "left",
3986
4074
  "data-mode": $setup.props.mode ?? "bottom"
3987
- }, [vue.renderSlot(_ctx.$slots, "button-left")], 8, _hoisted_8)) : vue.createCommentVNode("v-if", true),
4075
+ }, [vue.renderSlot(_ctx.$slots, "button-left")], 8, _hoisted_9)) : vue.createCommentVNode("v-if", true),
3988
4076
  _ctx.$slots["button-right"] ? (vue.openBlock(), vue.createElementBlock("div", {
3989
4077
  key: 2,
3990
4078
  class: "bs-button-slot",
3991
4079
  "data-side": "right",
3992
4080
  "data-mode": $setup.props.mode ?? "bottom"
3993
- }, [vue.renderSlot(_ctx.$slots, "button-right")], 8, _hoisted_9)) : vue.createCommentVNode("v-if", true)
4081
+ }, [vue.renderSlot(_ctx.$slots, "button-right")], 8, _hoisted_10)) : vue.createCommentVNode("v-if", true)
3994
4082
  ]), (vue.openBlock(true), vue.createElementBlock(
3995
4083
  vue.Fragment,
3996
4084
  null,
package/dist/vue.js CHANGED
@@ -2895,11 +2895,54 @@ var BottomSheetEngine = class {
2895
2895
  this.updateAriaSlider();
2896
2896
  }
2897
2897
  }
2898
+ contentTargets() {
2899
+ const scroller = this.scrollContainer;
2900
+ if (!scroller) return [];
2901
+ const hasSlot = typeof HTMLSlotElement !== "undefined";
2902
+ const out = [];
2903
+ for (const child of Array.from(scroller.children)) {
2904
+ if (hasSlot && child instanceof HTMLSlotElement) {
2905
+ for (const el of child.assignedElements()) out.push(el);
2906
+ } else {
2907
+ out.push(child);
2908
+ }
2909
+ }
2910
+ return out;
2911
+ }
2912
+ measureContentExtent(vertical) {
2913
+ const content = this.scrollContainer;
2914
+ if (!content) return 0;
2915
+ const targets = this.contentTargets();
2916
+ if (targets.length === 0) {
2917
+ return vertical ? content.scrollHeight : content.scrollWidth;
2918
+ }
2919
+ let min = Infinity;
2920
+ let max = -Infinity;
2921
+ for (const el of targets) {
2922
+ const r = el.getBoundingClientRect();
2923
+ if (vertical) {
2924
+ if (r.top < min) min = r.top;
2925
+ if (r.bottom > max) max = r.bottom;
2926
+ } else {
2927
+ if (r.left < min) min = r.left;
2928
+ if (r.right > max) max = r.right;
2929
+ }
2930
+ }
2931
+ if (!isFinite(min) || !isFinite(max) || max <= min) {
2932
+ return vertical ? content.scrollHeight : content.scrollWidth;
2933
+ }
2934
+ let pad = 0;
2935
+ if (typeof getComputedStyle !== "undefined") {
2936
+ const cs = getComputedStyle(content);
2937
+ pad = vertical ? (parseFloat(cs.paddingTop) || 0) + (parseFloat(cs.paddingBottom) || 0) : (parseFloat(cs.paddingLeft) || 0) + (parseFloat(cs.paddingRight) || 0);
2938
+ }
2939
+ return max - min + pad;
2940
+ }
2898
2941
  measureFitSize() {
2899
2942
  const vertical = layoutAxis(this.mode) === "height";
2900
2943
  const handleSize = vertical ? this.handle.offsetHeight : this.handle.offsetWidth;
2901
2944
  const content = this.scrollContainer;
2902
- const natural = content ? handleSize + (vertical ? content.scrollHeight : content.scrollWidth) : handleSize;
2945
+ const natural = content ? handleSize + this.measureContentExtent(vertical) : handleSize;
2903
2946
  if (typeof window === "undefined") return natural;
2904
2947
  const viewport = vertical ? window.innerHeight : window.innerWidth;
2905
2948
  return viewport > 0 ? Math.min(natural, viewport) : natural;
@@ -2908,22 +2951,62 @@ var BottomSheetEngine = class {
2908
2951
  if (typeof ResizeObserver === "undefined") return;
2909
2952
  if (!this.snapPointsRaw.some((p) => p.size === "fit" || p.size === "content"))
2910
2953
  return;
2911
- const targets = [this.handle];
2912
- if (this.scrollContainer && this.scrollContainer !== this.handle) {
2913
- targets.push(this.scrollContainer);
2914
- }
2915
2954
  let raf = 0;
2916
- const ro = new ResizeObserver(() => {
2955
+ const schedule = () => {
2917
2956
  if (raf) return;
2918
2957
  raf = requestAnimationFrame(() => {
2919
2958
  raf = 0;
2920
2959
  if (this.destroyed || this.gesture?.isDragging) return;
2921
2960
  this.recompute();
2922
2961
  });
2923
- });
2924
- for (const t of targets) ro.observe(t);
2962
+ };
2963
+ const ro = new ResizeObserver(schedule);
2964
+ ro.observe(this.handle);
2965
+ const scroller = this.scrollContainer;
2966
+ const observed = /* @__PURE__ */ new Set();
2967
+ const slots = /* @__PURE__ */ new Set();
2968
+ const hasSlot = typeof HTMLSlotElement !== "undefined";
2969
+ const onSlotChange = () => resync();
2970
+ const trackSlots = () => {
2971
+ if (!scroller || !hasSlot) return;
2972
+ for (const child of Array.from(scroller.children)) {
2973
+ if (child instanceof HTMLSlotElement && !slots.has(child)) {
2974
+ child.addEventListener("slotchange", onSlotChange);
2975
+ slots.add(child);
2976
+ }
2977
+ }
2978
+ };
2979
+ const resync = () => {
2980
+ trackSlots();
2981
+ const targets = this.contentTargets();
2982
+ for (const el of observed) {
2983
+ if (!targets.includes(el)) {
2984
+ ro.unobserve(el);
2985
+ observed.delete(el);
2986
+ }
2987
+ }
2988
+ for (const el of targets) {
2989
+ if (!observed.has(el)) {
2990
+ ro.observe(el);
2991
+ observed.add(el);
2992
+ }
2993
+ }
2994
+ schedule();
2995
+ };
2996
+ let mo;
2997
+ if (scroller) {
2998
+ resync();
2999
+ if (typeof MutationObserver !== "undefined") {
3000
+ mo = new MutationObserver(resync);
3001
+ mo.observe(scroller, { childList: true });
3002
+ }
3003
+ }
2925
3004
  this.teardowns.add(() => {
2926
3005
  ro.disconnect();
3006
+ mo?.disconnect();
3007
+ for (const slot of slots) {
3008
+ slot.removeEventListener("slotchange", onSlotChange);
3009
+ }
2927
3010
  if (raf) cancelAnimationFrame(raf);
2928
3011
  });
2929
3012
  }
@@ -3898,23 +3981,27 @@ var _hoisted_4 = [
3898
3981
  "aria-valuetext"
3899
3982
  ];
3900
3983
  var _hoisted_5 = {
3984
+ key: 0,
3985
+ class: "bs-header"
3986
+ };
3987
+ var _hoisted_6 = {
3901
3988
  ref: "contentRef",
3902
3989
  class: "bs-content",
3903
3990
  tabindex: "0",
3904
3991
  role: "region",
3905
3992
  "aria-label": "Sheet content"
3906
3993
  };
3907
- var _hoisted_6 = {
3908
- key: 0,
3994
+ var _hoisted_7 = {
3995
+ key: 1,
3909
3996
  class: "bs-footer"
3910
3997
  };
3911
- var _hoisted_7 = {
3998
+ var _hoisted_8 = {
3912
3999
  class: "bs-sr-only",
3913
4000
  role: "status",
3914
4001
  "aria-live": "polite"
3915
4002
  };
3916
- var _hoisted_8 = ["data-mode"];
3917
4003
  var _hoisted_9 = ["data-mode"];
4004
+ var _hoisted_10 = ["data-mode"];
3918
4005
  function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
3919
4006
  return openBlock(), createBlock(Teleport, {
3920
4007
  to: $props.teleportTo,
@@ -3960,18 +4047,19 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
3960
4047
  "aria-valuenow": $setup.activeIdx,
3961
4048
  "aria-valuetext": $setup.state.activeId,
3962
4049
  "aria-label": "Resize sheet"
3963
- }, [renderSlot(_ctx.$slots, "header", { state: $setup.state })], 8, _hoisted_4),
4050
+ }, null, 8, _hoisted_4),
4051
+ _ctx.$slots.header ? (openBlock(), createElementBlock("div", _hoisted_5, [renderSlot(_ctx.$slots, "header", { state: $setup.state })])) : createCommentVNode("v-if", true),
3964
4052
  createElementVNode(
3965
4053
  "div",
3966
- _hoisted_5,
4054
+ _hoisted_6,
3967
4055
  [renderSlot(_ctx.$slots, "default")],
3968
4056
  512
3969
4057
  /* NEED_PATCH */
3970
4058
  ),
3971
- _ctx.$slots.footer ? (openBlock(), createElementBlock("div", _hoisted_6, [renderSlot(_ctx.$slots, "footer", { state: $setup.state })])) : createCommentVNode("v-if", true),
4059
+ _ctx.$slots.footer ? (openBlock(), createElementBlock("div", _hoisted_7, [renderSlot(_ctx.$slots, "footer", { state: $setup.state })])) : createCommentVNode("v-if", true),
3972
4060
  createElementVNode(
3973
4061
  "span",
3974
- _hoisted_7,
4062
+ _hoisted_8,
3975
4063
  toDisplayString($setup.state.activeId),
3976
4064
  1
3977
4065
  /* TEXT */
@@ -3982,13 +4070,13 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
3982
4070
  class: "bs-button-slot",
3983
4071
  "data-side": "left",
3984
4072
  "data-mode": $setup.props.mode ?? "bottom"
3985
- }, [renderSlot(_ctx.$slots, "button-left")], 8, _hoisted_8)) : createCommentVNode("v-if", true),
4073
+ }, [renderSlot(_ctx.$slots, "button-left")], 8, _hoisted_9)) : createCommentVNode("v-if", true),
3986
4074
  _ctx.$slots["button-right"] ? (openBlock(), createElementBlock("div", {
3987
4075
  key: 2,
3988
4076
  class: "bs-button-slot",
3989
4077
  "data-side": "right",
3990
4078
  "data-mode": $setup.props.mode ?? "bottom"
3991
- }, [renderSlot(_ctx.$slots, "button-right")], 8, _hoisted_9)) : createCommentVNode("v-if", true)
4079
+ }, [renderSlot(_ctx.$slots, "button-right")], 8, _hoisted_10)) : createCommentVNode("v-if", true)
3992
4080
  ]), (openBlock(true), createElementBlock(
3993
4081
  Fragment,
3994
4082
  null,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@surdeddd/bottom-sheet",
3
- "version": "0.4.1",
3
+ "version": "0.5.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",