@douxcode/vue-spring-bottom-sheet 3.0.0-next.2 → 3.0.0-next.4

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.
@@ -11,7 +11,6 @@ declare function __VLS_template(): {
11
11
  sheet: HTMLDivElement;
12
12
  sheetHeader: HTMLDivElement;
13
13
  sheetScroll: HTMLDivElement;
14
- sheetContentWrapper: HTMLDivElement;
15
14
  sheetContent: HTMLDivElement;
16
15
  sheetFooter: HTMLDivElement;
17
16
  };
@@ -22,18 +21,34 @@ declare const __VLS_component: import('vue').DefineComponent<BottomSheetProps, {
22
21
  open: () => Promise<void>;
23
22
  close: () => void;
24
23
  snapToPoint: (index: number) => void;
25
- }, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
26
- [x: string]: any;
27
- } & {
28
- [x: string]: any;
24
+ }, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {} & {
25
+ opened: () => any;
26
+ "opening-started": () => any;
27
+ closed: () => any;
28
+ "closing-started": () => any;
29
+ ready: () => any;
30
+ "dragging-up": () => any;
31
+ "dragging-down": () => any;
32
+ snapped: (snapPointIndex?: number | undefined) => any;
33
+ instinctHeight: (instinctHeight: number) => any;
34
+ "update:modelValue": () => any;
29
35
  }, string, import('vue').PublicProps, Readonly<BottomSheetProps> & Readonly<{
30
- [x: `on${Capitalize<any>}`]: ((...args: any) => any) | undefined;
36
+ onOpened?: (() => any) | undefined;
37
+ "onOpening-started"?: (() => any) | undefined;
38
+ onClosed?: (() => any) | undefined;
39
+ "onClosing-started"?: (() => any) | undefined;
40
+ onReady?: (() => any) | undefined;
41
+ "onDragging-up"?: (() => any) | undefined;
42
+ "onDragging-down"?: (() => any) | undefined;
43
+ onSnapped?: ((snapPointIndex?: number | undefined) => any) | undefined;
44
+ onInstinctHeight?: ((instinctHeight: number) => any) | undefined;
45
+ "onUpdate:modelValue"?: (() => any) | undefined;
31
46
  }>, {
32
- duration: number;
33
- blocking: boolean;
34
47
  canSwipeClose: boolean;
35
- canBackdropClose: boolean;
36
48
  expandOnContentDrag: boolean;
49
+ blocking: boolean;
50
+ duration: number;
51
+ canBackdropClose: boolean;
37
52
  teleportTo: string | import('vue').RendererElement;
38
53
  teleportDefer: boolean;
39
54
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
@@ -41,7 +56,6 @@ declare const __VLS_component: import('vue').DefineComponent<BottomSheetProps, {
41
56
  sheet: HTMLDivElement;
42
57
  sheetHeader: HTMLDivElement;
43
58
  sheetScroll: HTMLDivElement;
44
- sheetContentWrapper: HTMLDivElement;
45
59
  sheetContent: HTMLDivElement;
46
60
  sheetFooter: HTMLDivElement;
47
61
  }, any>;
@@ -0,0 +1,47 @@
1
+ import { Ref, ComputedRef, ShallowRef } from 'vue';
2
+ export interface UseDragGesturesOptions {
3
+ sheetRef: ShallowRef<HTMLElement | null>;
4
+ sheetScrollRef: ShallowRef<HTMLElement | null>;
5
+ height: Ref<number>;
6
+ translateY: Ref<number>;
7
+ sheetHeight: Ref<number>;
8
+ windowHeight: Ref<number>;
9
+ snapPointsRef: ComputedRef<Array<number | `${number}%`>>;
10
+ flattenedSnapPoints: ComputedRef<number[]>;
11
+ currentSnapPointIndex: Ref<number>;
12
+ closestSnapPointIndex: ComputedRef<number>;
13
+ minSnapPoint: ComputedRef<number>;
14
+ maxSnapPoint: ComputedRef<number>;
15
+ canSwipeClose: Ref<boolean>;
16
+ swipeCloseThreshold: Ref<string | number | undefined>;
17
+ expandOnContentDrag: Ref<boolean>;
18
+ onClose: () => void;
19
+ onSnapped: (index: number) => void;
20
+ onDraggingUp: () => void;
21
+ onDraggingDown: () => void;
22
+ }
23
+ /**
24
+ * Composable that handles all drag/pan gesture logic for the bottom sheet.
25
+ * Manages header/footer dragging, content area dragging, and snap point navigation.
26
+ */
27
+ export declare function useDragGestures(options: UseDragGesturesOptions): {
28
+ isDragging: Ref<boolean, boolean>;
29
+ preventContentScroll: Ref<boolean, boolean>;
30
+ headerFooterHandlers: ComputedRef<{
31
+ onPointerdown: (event: PointerEvent) => void;
32
+ onPointermove: (event: PointerEvent) => void;
33
+ onPointerup: (event: PointerEvent) => void;
34
+ onPointercancel: (event: PointerEvent) => void;
35
+ onContextmenu: (event: MouseEvent) => void;
36
+ onTouchmove: (event: TouchEvent) => void;
37
+ }>;
38
+ contentWrapperHandlers: ComputedRef<{
39
+ onPointerdown: (event: PointerEvent) => void;
40
+ onPointermove: (event: PointerEvent) => void;
41
+ onPointerup: (event: PointerEvent) => void;
42
+ onPointercancel: (event: PointerEvent) => void;
43
+ onContextmenu: (event: MouseEvent) => void;
44
+ onTouchmove: (event: TouchEvent) => void;
45
+ }>;
46
+ scrollEnd: () => void;
47
+ };
@@ -0,0 +1,17 @@
1
+ import { Ref, ShallowRef } from 'vue';
2
+ export interface UseFocusManagementOptions {
3
+ sheetRef: ShallowRef<HTMLElement | null>;
4
+ backdropRef: ShallowRef<HTMLElement | null>;
5
+ blocking: Ref<boolean>;
6
+ onEscape: () => void;
7
+ }
8
+ /**
9
+ * Manage focus trap and aria-expanded observer for accessibility.
10
+ * Handles keyboard escape, focus trapping, and pausing trap when
11
+ * nested aria-expanded elements (like dropdowns) are open.
12
+ */
13
+ export declare function useFocusManagement(options: UseFocusManagementOptions): {
14
+ activate: () => void;
15
+ deactivate: () => void;
16
+ cleanup: () => void;
17
+ };
@@ -0,0 +1,17 @@
1
+ import { Ref } from 'vue';
2
+ export interface UseSheetScrollLockOptions {
3
+ blocking: Ref<boolean>;
4
+ }
5
+ /**
6
+ * Manage scroll locking for the sheet.
7
+ * When blocking mode is enabled, locks body scroll when sheet is open.
8
+ * When non-blocking, temporarily locks during touch interactions.
9
+ */
10
+ export declare function useSheetScrollLock(options: UseSheetScrollLockOptions): {
11
+ lock: () => void;
12
+ unlock: () => void;
13
+ lockIfBlocking: () => void;
14
+ unlockIfBlocking: () => void;
15
+ touchStartHandler: () => void;
16
+ touchEndHandler: () => void;
17
+ };
package/dist/index.mjs CHANGED
@@ -1,112 +1,372 @@
1
- import { ref as g, computed as I, defineComponent as Ve, useCssVars as Ne, watch as Z, onMounted as We, toRefs as qe, nextTick as Se, onUnmounted as ze, createElementBlock as oe, openBlock as q, Fragment as Qe, createBlock as Ce, Teleport as ye, createVNode as Pe, Transition as Te, withCtx as xe, createCommentVNode as ke, unref as ue, normalizeStyle as je, createElementVNode as z, normalizeClass as se, renderSlot as re } from "vue";
2
- import { useVModel as Ge, useWindowSize as Ke, useElementBounding as ee, useScrollLock as Ye } from "@vueuse/core";
3
- import { useFocusTrap as Ue } from "@vueuse/integrations/useFocusTrap";
4
- function Q(o, l) {
5
- const s = parseFloat(o);
6
- return l * s / 100;
1
+ import { ref as P, computed as D, defineComponent as ye, useCssVars as Ee, watch as te, onMounted as De, shallowRef as q, toRefs as He, nextTick as fe, onUnmounted as Be, createElementBlock as ie, openBlock as X, Fragment as Ie, createBlock as pe, Teleport as he, createVNode as ge, Transition as me, withCtx as Se, createCommentVNode as be, unref as E, normalizeStyle as Ye, createElementVNode as j, mergeProps as ce, renderSlot as ve, normalizeClass as Me } from "vue";
2
+ import { useScrollLock as Pe, useVModel as Re, useWindowSize as Oe, useElementBounding as ne } from "@vueuse/core";
3
+ import { useFocusTrap as Ae } from "@vueuse/integrations/useFocusTrap";
4
+ function Te(t, a) {
5
+ const u = parseFloat(t);
6
+ return a * u / 100;
7
7
  }
8
- function Je(o, l, s) {
9
- const t = g(0), v = I(() => o.value.map((C) => typeof C == "string" ? Q(C, s.value) : C)), S = I(() => Math.min(...v.value)), i = I(() => Math.max(...v.value)), y = I(() => {
10
- const C = v.value.reduce(
11
- (P, w) => Math.abs(w - l.value) < Math.abs(P - l.value) ? w : P
8
+ function Le(t, a, u) {
9
+ const e = P(0), n = D(() => t.value.map((f) => typeof f == "string" ? Te(f, u.value) : f)), i = D(() => Math.min(...n.value)), r = D(() => Math.max(...n.value)), p = D(() => {
10
+ const f = n.value.reduce(
11
+ (b, v) => Math.abs(v - a.value) < Math.abs(b - a.value) ? v : b
12
12
  );
13
- return v.value.indexOf(C);
13
+ return n.value.indexOf(f);
14
14
  });
15
15
  return {
16
- currentSnapPointIndex: t,
17
- flattenedSnapPoints: v,
18
- minSnapPoint: S,
19
- maxSnapPoint: i,
20
- closestSnapPointIndex: y
16
+ currentSnapPointIndex: e,
17
+ flattenedSnapPoints: n,
18
+ minSnapPoint: i,
19
+ maxSnapPoint: r,
20
+ closestSnapPointIndex: p
21
21
  };
22
22
  }
23
- function Xe(o = {}) {
24
- const { velocityThreshold: l = 0.5 } = o, s = g(0), t = g(0), v = g(0), S = g(0), i = g([]);
23
+ function Fe(t, a, u) {
24
+ let e = (n) => t(n, ...a);
25
+ return u === void 0 ? e : Object.assign(e, { lazy: u, lazyArgs: a });
26
+ }
27
+ function $e(t, a, u) {
28
+ let e = t.length - a.length;
29
+ if (e === 0) return t(...a);
30
+ if (e === 1) return Fe(t, a, u);
31
+ throw Error("Wrong number of arguments");
32
+ }
33
+ function I(...t) {
34
+ return $e(Ne, t);
35
+ }
36
+ const Ne = (t, { min: a, max: u }) => a !== void 0 && t < a ? a : u !== void 0 && t > u ? u : t, ke = /* @__PURE__ */ Symbol("funnel/voidReducer"), Ve = () => ke;
37
+ function Ue(t, { triggerAt: a = "end", minQuietPeriodMs: u, maxBurstDurationMs: e, minGapMs: n, reducer: i = Ve }) {
38
+ let r, p, f, b, v = () => {
39
+ let g = f;
40
+ g !== void 0 && (f = void 0, g === ke ? t() : t(g), n !== void 0 && (p = setTimeout(d, n)));
41
+ }, d = () => {
42
+ clearTimeout(p), p = void 0, r === void 0 && v();
43
+ }, h = () => {
44
+ clearTimeout(r), r = void 0, b = void 0, p === void 0 && v();
45
+ };
46
+ return { call: (...g) => {
47
+ let w = r === void 0 && p === void 0;
48
+ if ((a !== "start" || w) && (f = i(f, ...g)), !(r === void 0 && !w)) {
49
+ if (u !== void 0 || e !== void 0 || n === void 0) {
50
+ clearTimeout(r);
51
+ let C = Date.now();
52
+ b ??= C;
53
+ let x = e === void 0 ? u ?? 0 : Math.min(u ?? e, e - (C - b));
54
+ r = setTimeout(h, x);
55
+ }
56
+ a !== "end" && w && v();
57
+ }
58
+ }, cancel: () => {
59
+ clearTimeout(r), r = void 0, b = void 0, clearTimeout(p), p = void 0, f = void 0;
60
+ }, flush: () => {
61
+ h(), d();
62
+ }, get isIdle() {
63
+ return r === void 0 && p === void 0;
64
+ } };
65
+ }
66
+ function We(t = {}) {
67
+ const { velocityThreshold: a = 0.5 } = t, u = P(0), e = P(0), n = P(0), i = P(0), r = P([]);
25
68
  return {
26
- start: (w) => {
27
- const b = performance.now();
28
- s.value = w, t.value = b, v.value = w, S.value = b, i.value = [{ y: w, time: b }];
69
+ start: (v) => {
70
+ const d = performance.now();
71
+ u.value = v, e.value = d, n.value = v, i.value = d, r.value = [{ y: v, time: d }];
29
72
  },
30
- update: (w) => {
31
- const b = performance.now();
32
- v.value = w, S.value = b, i.value.push({ y: w, time: b });
33
- const M = b - 100;
34
- i.value = i.value.filter((d) => d.time > M).slice(-5);
73
+ update: (v) => {
74
+ const d = performance.now();
75
+ n.value = v, i.value = d, r.value.push({ y: v, time: d });
76
+ const h = d - 100;
77
+ r.value = r.value.filter((g) => g.time > h).slice(-5);
35
78
  },
36
79
  end: () => {
37
- const w = i.value;
38
- let b = 0;
39
- if (w.length >= 2) {
40
- const h = w[0], E = w[w.length - 1], F = E.y - h.y, R = E.time - h.time;
41
- R > 0 && (b = F / R);
80
+ const v = r.value;
81
+ let d = 0;
82
+ if (v.length >= 2) {
83
+ const w = v[0], C = v[v.length - 1];
84
+ if (w && C) {
85
+ const x = C.y - w.y, R = C.time - w.time;
86
+ R > 0 && (d = x / R);
87
+ }
42
88
  }
43
- const M = Math.abs(b) >= l;
44
- let d = "none";
45
- return M && (d = b < 0 ? "up" : "down"), i.value = [], {
46
- direction: d,
47
- velocity: Math.abs(b),
48
- isSwipe: M
89
+ const h = Math.abs(d) >= a;
90
+ let g = "none";
91
+ return h && (g = d < 0 ? "up" : "down"), r.value = [], {
92
+ direction: g,
93
+ velocity: Math.abs(d),
94
+ isSwipe: h
49
95
  };
50
96
  }
51
97
  };
52
98
  }
53
- function Ze(o, l, s) {
54
- let t = (v) => o(v, ...l);
55
- return s === void 0 ? t : Object.assign(t, { lazy: s, lazyArgs: l });
99
+ function qe(t, a, u) {
100
+ return Math.max(a, Math.min(t, u));
56
101
  }
57
- function et(o, l, s) {
58
- let t = o.length - l.length;
59
- if (t === 0) return o(...l);
60
- if (t === 1) return Ze(o, l, s);
61
- throw new Error("Wrong number of arguments");
102
+ function ze(t, a) {
103
+ return Math.pow(t, a * 5);
62
104
  }
63
- function tt(o, { triggerAt: l = "end", minQuietPeriodMs: s, maxBurstDurationMs: t, minGapMs: v, reducer: S = at }) {
64
- let i, y, C, P, w = () => {
65
- let d = C;
66
- d !== void 0 && (C = void 0, o(d), v !== void 0 && (y = setTimeout(b, v)));
67
- }, b = () => {
68
- clearTimeout(y), y = void 0, i === void 0 && w();
69
- }, M = () => {
70
- clearTimeout(i), i = void 0, P = void 0, y === void 0 && w();
71
- };
72
- return { call: (...d) => {
73
- let h = i === void 0 && y === void 0;
74
- if ((l !== "start" || h) && (C = S(C, ...d)), !(i === void 0 && !h)) {
75
- if (s !== void 0 || t !== void 0 || v === void 0) {
76
- clearTimeout(i);
77
- let E = Date.now();
78
- P ?? (P = E);
79
- let F = t === void 0 ? s ?? 0 : Math.min(s ?? t, t - (E - P));
80
- i = setTimeout(M, F);
81
- }
82
- l !== "end" && h && w();
83
- }
84
- }, cancel: () => {
85
- clearTimeout(i), i = void 0, P = void 0, clearTimeout(y), y = void 0, C = void 0;
86
- }, flush: () => {
87
- M(), b();
88
- }, get isIdle() {
89
- return i === void 0 && y === void 0;
90
- } };
105
+ function we(t, a, u) {
106
+ return a === 0 || Math.abs(a) === 1 / 0 ? ze(t, u) : t * a * u / (a + u * t);
91
107
  }
92
- var at = () => "";
93
- function T(...o) {
94
- return et(nt, o);
108
+ function de(t, a, u, e = 0.15) {
109
+ return e === 0 ? qe(t, a, u) : t < a ? -we(a - t, u - a, e) + a : t > u ? +we(t - u, u - a, e) + u : t;
95
110
  }
96
- var nt = (o, { min: l, max: s }) => l !== void 0 && o < l ? l : s !== void 0 && o > s ? s : o;
97
- function lt(o, l, s) {
98
- return Math.max(l, Math.min(o, s));
111
+ function ae(t, a) {
112
+ return typeof t == "number" ? I(t, { max: a }) : Te(t, a);
99
113
  }
100
- function ot(o, l) {
101
- return Math.pow(o, l * 5);
114
+ function Ce(t, a) {
115
+ if (t === void 0)
116
+ return a / 2;
117
+ if (typeof t == "number")
118
+ return t;
119
+ if (typeof t == "string" && t.includes("%")) {
120
+ const u = Number(t.replace("%", ""));
121
+ return a * (u / 100);
122
+ }
123
+ return a / 2;
102
124
  }
103
- function Me(o, l, s) {
104
- return l === 0 || Math.abs(l) === 1 / 0 ? ot(o, s) : o * l * s / (l + s * o);
125
+ const Ge = 10, Qe = 3, Xe = 0.25, xe = 0.5, je = 0.5;
126
+ function Ke(t) {
127
+ const {
128
+ sheetRef: a,
129
+ sheetScrollRef: u,
130
+ height: e,
131
+ translateY: n,
132
+ sheetHeight: i,
133
+ windowHeight: r,
134
+ snapPointsRef: p,
135
+ flattenedSnapPoints: f,
136
+ currentSnapPointIndex: b,
137
+ closestSnapPointIndex: v,
138
+ minSnapPoint: d,
139
+ maxSnapPoint: h,
140
+ canSwipeClose: g,
141
+ swipeCloseThreshold: w,
142
+ expandOnContentDrag: C,
143
+ onClose: x,
144
+ onSnapped: R,
145
+ onDraggingUp: oe,
146
+ onDraggingDown: H
147
+ } = t, T = P(!1), F = P(0), N = P(0), k = P(0), Y = P(0), B = P(!0), S = P(!0), O = We({ velocityThreshold: je }), K = (o) => {
148
+ o > 0 ? H() : o < 0 && oe();
149
+ }, z = () => {
150
+ if (!a.value) return;
151
+ const o = window.getComputedStyle(a.value), c = parseFloat(o.height);
152
+ let l = 0;
153
+ o.transform && o.transform !== "none" && (l = new DOMMatrix(o.transform).m42), e.value = c, n.value = l;
154
+ }, le = () => {
155
+ const o = v.value;
156
+ b.value = o;
157
+ const c = p.value[o];
158
+ if (!c) return;
159
+ const l = ae(c, r.value);
160
+ e.value = l, n.value = 0, R(p.value.indexOf(c));
161
+ }, _ = (o = !0) => {
162
+ const c = O.end();
163
+ if (o && c.isSwipe && c.direction === "down" && g.value && e.value <= d.value + Ge)
164
+ return n.value = e.value, x(), !0;
165
+ let l;
166
+ if (o && c.isSwipe && f.value.length > 1) {
167
+ const M = [...f.value].sort((y, L) => y - L);
168
+ if (c.direction === "up") {
169
+ const y = M.find((L) => L > e.value + 1);
170
+ l = y !== void 0 ? f.value.indexOf(y) : v.value;
171
+ } else {
172
+ const y = [...M].reverse().find((L) => L < e.value - 1);
173
+ l = y !== void 0 ? f.value.indexOf(y) : v.value;
174
+ }
175
+ } else
176
+ l = v.value;
177
+ b.value = l;
178
+ const s = p.value[l];
179
+ if (!s)
180
+ return x(), !0;
181
+ const m = ae(s, r.value);
182
+ return m === 0 ? (x(), !0) : (e.value = m, n.value = 0, R(p.value.indexOf(s)), !1);
183
+ }, ue = (o) => {
184
+ a.value && o.button === 0 && (z(), T.value = !0, F.value = o.clientY, N.value = e.value, k.value = n.value, Y.value = o.clientY, O.start(o.clientY), o.target.setPointerCapture(o.pointerId));
185
+ }, A = (o) => {
186
+ if (!T.value) return;
187
+ if (o.buttons !== 1) {
188
+ $(o);
189
+ return;
190
+ }
191
+ const c = o.clientY - F.value, l = o.clientY;
192
+ n.value <= 0 && (e.value = N.value - c), e.value <= d.value && (e.value = d.value, n.value = k.value + c, g.value ? n.value = I(n.value, { min: 0 }) : n.value = I(
193
+ de(
194
+ n.value,
195
+ -i.value,
196
+ 0,
197
+ xe
198
+ ),
199
+ { min: 0 }
200
+ )), e.value = I(
201
+ de(e.value, 0, h.value, Xe),
202
+ {
203
+ min: 0,
204
+ max: r.value
205
+ }
206
+ ), K(o.clientY - Y.value), O.update(o.clientY), Y.value = l;
207
+ }, $ = (o) => {
208
+ if (T.value = !1, o.target.releasePointerCapture(o.pointerId), g.value) {
209
+ const c = Ce(w.value, e.value);
210
+ if (n.value > c) {
211
+ n.value = e.value, x();
212
+ return;
213
+ }
214
+ } else
215
+ n.value = 0;
216
+ if (n.value === e.value) {
217
+ n.value = 0, x();
218
+ return;
219
+ }
220
+ _();
221
+ }, re = (o) => {
222
+ if (!u.value) return;
223
+ const c = u.value.scrollTop === 0, l = o > 0, s = f.value.length === 1, m = 0.5 > Math.abs(e.value - h.value);
224
+ if (s) {
225
+ if (!C.value) {
226
+ S.value = !1;
227
+ return;
228
+ }
229
+ n.value === 0 && c && l && (S.value = !0), n.value === 0 && c && !l && (S.value = !1);
230
+ } else {
231
+ if (!C.value) {
232
+ S.value = !1;
233
+ return;
234
+ }
235
+ S.value = !0, m && (l && c && (S.value = !0), !l && c && (S.value = !1), c || (S.value = !1));
236
+ }
237
+ }, J = (o) => {
238
+ a.value && o.button === 0 && (z(), T.value = !0, F.value = o.clientY, N.value = e.value, k.value = n.value, Y.value = o.clientY, B.value = !0, O.start(o.clientY), o.target.setPointerCapture(o.pointerId));
239
+ }, se = (o) => {
240
+ if (!T.value) return;
241
+ if (o.buttons !== 1) {
242
+ V(o);
243
+ return;
244
+ }
245
+ if (!C.value) {
246
+ S.value = !1;
247
+ return;
248
+ }
249
+ const c = o.clientY - F.value, l = o.clientY, s = o.clientY - Y.value;
250
+ if (B.value) {
251
+ const M = o.clientY - F.value;
252
+ if (Math.abs(M) > Qe)
253
+ B.value = !1, re(M);
254
+ else {
255
+ Y.value = l;
256
+ return;
257
+ }
258
+ }
259
+ n.value === 0 && S.value && C.value && (e.value = N.value - c), e.value <= d.value && (e.value = d.value, S.value && C.value && (n.value = k.value + c), n.value = I(n.value, { min: 0, max: d.value }), g.value ? n.value = I(n.value, { min: 0 }) : n.value = I(
260
+ de(
261
+ n.value,
262
+ -i.value,
263
+ 0,
264
+ xe
265
+ ),
266
+ { min: 0 }
267
+ )), e.value > h.value && (e.value = h.value), e.value = I(e.value, { max: r.value }), f.value.length === 1 || e.value === h.value && (S.value = !1), K(s), O.update(o.clientY), Y.value = l;
268
+ }, V = (o) => {
269
+ if (T.value = !1, B.value = !0, o.target.releasePointerCapture(o.pointerId), g.value) {
270
+ const l = Ce(w.value, e.value);
271
+ if (n.value > l) {
272
+ n.value = e.value, x();
273
+ return;
274
+ }
275
+ } else
276
+ n.value = 0;
277
+ if (n.value === e.value) {
278
+ n.value = 0, x();
279
+ return;
280
+ }
281
+ const c = S.value;
282
+ _(c);
283
+ }, U = (o) => {
284
+ T.value && (o.preventDefault(), T.value = !1, B.value = !0, le());
285
+ }, G = (o) => {
286
+ S.value = !0, Z(o);
287
+ }, Z = (o) => {
288
+ S.value && o.preventDefault();
289
+ }, Q = () => {
290
+ if (!u.value) return;
291
+ const o = u.value.scrollTop === 0;
292
+ S.value = o;
293
+ }, W = D(() => ({
294
+ onPointerdown: ue,
295
+ onPointermove: A,
296
+ onPointerup: $,
297
+ onPointercancel: $,
298
+ onContextmenu: U,
299
+ onTouchmove: G
300
+ })), ee = D(() => ({
301
+ onPointerdown: J,
302
+ onPointermove: se,
303
+ onPointerup: V,
304
+ onPointercancel: V,
305
+ onContextmenu: U,
306
+ onTouchmove: Z
307
+ }));
308
+ return {
309
+ isDragging: T,
310
+ preventContentScroll: S,
311
+ headerFooterHandlers: W,
312
+ contentWrapperHandlers: ee,
313
+ scrollEnd: Q
314
+ };
105
315
  }
106
- function ie(o, l, s, t = 0.15) {
107
- return t === 0 ? lt(o, l, s) : o < l ? -Me(l - o, s - l, t) + l : o > s ? +Me(o - s, s - l, t) + s : o;
316
+ function _e(t) {
317
+ const { blocking: a } = t, u = Pe(document.body), e = Pe(document.documentElement), n = () => {
318
+ u.value = !0, e.value = !0;
319
+ }, i = () => {
320
+ u.value = !1, e.value = !1;
321
+ };
322
+ return {
323
+ lock: n,
324
+ unlock: i,
325
+ lockIfBlocking: () => {
326
+ a.value && n();
327
+ },
328
+ unlockIfBlocking: () => {
329
+ a.value && i();
330
+ },
331
+ touchStartHandler: () => {
332
+ a.value || n();
333
+ },
334
+ touchEndHandler: () => {
335
+ a.value || i();
336
+ }
337
+ };
338
+ }
339
+ function Je(t) {
340
+ const { sheetRef: a, backdropRef: u, blocking: e, onEscape: n } = t, i = P(null), r = Ae([a, u], {
341
+ immediate: !1,
342
+ fallbackFocus: () => a.value || document.body
343
+ }), p = (g) => {
344
+ g.key === "Escape" && n();
345
+ }, f = () => {
346
+ a.value && (i.value = new MutationObserver((g) => {
347
+ for (const w of g)
348
+ w.type === "attributes" && w.attributeName === "aria-expanded" && (w.target.getAttribute("aria-expanded") === "true" ? r.pause() : a.value?.querySelector('[aria-expanded="true"]') || r.unpause());
349
+ }), i.value.observe(a.value, {
350
+ attributes: !0,
351
+ attributeFilter: ["aria-expanded"],
352
+ subtree: !0
353
+ }));
354
+ }, b = () => {
355
+ i.value && (i.value.disconnect(), i.value = null);
356
+ };
357
+ return {
358
+ activate: () => {
359
+ e.value && (r.activate(), f()), window.addEventListener("keydown", p);
360
+ },
361
+ deactivate: () => {
362
+ window.removeEventListener("keydown", p), b(), e.value && r.deactivate();
363
+ },
364
+ cleanup: () => {
365
+ b(), r.deactivate();
366
+ }
367
+ };
108
368
  }
109
- const ut = ["data-vsbs-shadow", "data-vsbs-sheet-show"], st = /* @__PURE__ */ Ve({
369
+ const Ze = ["data-vsbs-shadow", "data-vsbs-sheet-show"], et = /* @__PURE__ */ ye({
110
370
  __name: "BottomSheet",
111
371
  props: {
112
372
  duration: { default: 250 },
@@ -125,399 +385,213 @@ const ut = ["data-vsbs-shadow", "data-vsbs-sheet-show"], st = /* @__PURE__ */ Ve
125
385
  footerClass: {}
126
386
  },
127
387
  emits: ["opened", "opening-started", "closed", "closing-started", "ready", "dragging-up", "dragging-down", "snapped", "instinctHeight", "update:modelValue"],
128
- setup(o, { expose: l, emit: s }) {
129
- Ne((e) => ({
130
- "0a9ba53d": Ee.value
388
+ setup(t, { expose: a, emit: u }) {
389
+ Ee((l) => ({
390
+ v531b2f52: F.value
131
391
  }));
132
- const t = o, v = s, S = Ge(t, "modelValue", v, {
392
+ const e = t, n = u, i = Re(e, "modelValue", n, {
133
393
  passive: !0
134
394
  });
135
- Z(S, (e) => {
136
- e && ne();
137
- }), We(() => {
138
- S.value && ne();
395
+ te(i, (l) => {
396
+ l && Q();
397
+ }), De(() => {
398
+ i.value && Q();
139
399
  });
140
- const i = g(null), y = g(null), C = g(null), P = g(null), w = g(null), b = g(null), M = g(null), d = g(t.expandOnContentDrag), { height: h } = Ke(), { height: E } = ee(i), { height: F } = ee(y), { height: R } = ee(b), { height: ve } = ee(C), te = I({
141
- get() {
142
- return T(
143
- Math.ceil(R.value + F.value + ve.value),
144
- {
145
- max: h.value
146
- }
147
- );
148
- },
149
- set(e) {
150
- [F.value, R.value, ve.value] = e;
151
- }
152
- }), n = g(0), u = g(0), Ee = I(() => t.duration + "ms"), { snapPoints: Oe } = qe(t), p = I(() => Oe.value ?? [te.value]), {
153
- flattenedSnapPoints: k,
154
- currentSnapPointIndex: D,
155
- closestSnapPointIndex: $,
400
+ const r = q(null), p = q(null), f = q(null), b = q(null), v = q(null), d = q(null), { height: h } = Oe(), { height: g } = ne(r), { height: w } = ne(p), { height: C } = ne(v), { height: x } = ne(f), R = D(() => I(
401
+ Math.ceil(C.value + w.value + x.value),
402
+ { max: h.value }
403
+ )), oe = (l, s, m) => {
404
+ w.value = l, C.value = s, x.value = m;
405
+ }, H = P(0), T = P(0), F = D(() => e.duration + "ms"), { snapPoints: N } = He(e), k = D(() => N.value ?? [R.value]), {
406
+ flattenedSnapPoints: Y,
407
+ currentSnapPointIndex: B,
408
+ closestSnapPointIndex: S,
156
409
  minSnapPoint: O,
157
- maxSnapPoint: L
158
- } = Je(p, n, h), j = Ye(document.body), G = Ye(document.documentElement), B = g(!1), _ = g(0), K = g(0), U = g(0), H = g(0), J = g(!0), A = Xe({ velocityThreshold: 0.5 }), V = Ue([i, M], {
159
- immediate: !1,
160
- fallbackFocus: () => i.value || document.body
161
- });
162
- let N = null;
163
- const De = () => {
164
- i.value && (N = new MutationObserver((e) => {
165
- var a;
166
- for (const r of e)
167
- r.type === "attributes" && r.attributeName === "aria-expanded" && (r.target.getAttribute("aria-expanded") === "true" ? V.pause() : (a = i.value) != null && a.querySelector('[aria-expanded="true"]') || V.unpause());
168
- }), N.observe(i.value, {
169
- attributes: !0,
170
- attributeFilter: ["aria-expanded"],
171
- subtree: !0
172
- }));
173
- }, ce = () => {
174
- N && (N.disconnect(), N = null);
175
- };
176
- function de(e) {
177
- d.value = !0, fe(e);
178
- }
179
- function fe(e) {
180
- d.value && e.preventDefault();
181
- }
182
- const pe = (e) => {
183
- e.key === "Escape" && Y();
184
- }, Be = () => {
185
- t.canBackdropClose && Y();
186
- };
187
- let ae = !1;
188
- const ne = async () => {
189
- if (ae) return;
190
- S.value = !0, ae = !0, v("opening-started"), t.blocking && (j.value = !0, G.value = !0), await Se();
191
- const e = i.value;
192
- E.value = e.getBoundingClientRect().height;
193
- const a = e.querySelector("[data-vsbs-content]"), r = e.querySelector("[data-vsbs-header]"), c = e.querySelector("[data-vsbs-footer]");
194
- if (te.value = [
195
- r.getBoundingClientRect().height,
196
- a.getBoundingClientRect().height,
197
- c.getBoundingClientRect().height
198
- ], await Se(), D.value = k.value.findIndex(
199
- (f) => f === O.value
200
- ), t.initialSnapPoint) {
201
- const f = t.initialSnapPoint;
202
- if (f < 0 || f >= p.value.length) {
410
+ maxSnapPoint: K
411
+ } = Le(k, H, h), z = D(() => e.blocking), le = D(() => e.canSwipeClose), _ = D(() => e.swipeCloseThreshold), ue = D(() => e.expandOnContentDrag), A = _e({ blocking: z }), $ = Je({
412
+ sheetRef: r,
413
+ backdropRef: d,
414
+ blocking: z,
415
+ onEscape: () => W()
416
+ }), { isDragging: re, headerFooterHandlers: J, contentWrapperHandlers: se, scrollEnd: V } = Ke({
417
+ sheetRef: r,
418
+ sheetScrollRef: b,
419
+ height: H,
420
+ translateY: T,
421
+ sheetHeight: g,
422
+ windowHeight: h,
423
+ snapPointsRef: k,
424
+ flattenedSnapPoints: Y,
425
+ currentSnapPointIndex: B,
426
+ closestSnapPointIndex: S,
427
+ minSnapPoint: O,
428
+ maxSnapPoint: K,
429
+ canSwipeClose: le,
430
+ swipeCloseThreshold: _,
431
+ expandOnContentDrag: ue,
432
+ onClose: () => W(),
433
+ onSnapped: (l) => n("snapped", l),
434
+ onDraggingUp: () => n("dragging-up"),
435
+ onDraggingDown: () => n("dragging-down")
436
+ }), U = P(!1), G = P(!1), Z = () => {
437
+ e.canBackdropClose && W();
438
+ }, Q = async () => {
439
+ if (U.value) return;
440
+ i.value = !0, U.value = !0, n("opening-started"), A.lockIfBlocking(), await fe();
441
+ const l = r.value;
442
+ g.value = l.getBoundingClientRect().height;
443
+ const s = l.querySelector("[data-vsbs-content]"), m = l.querySelector("[data-vsbs-header]"), M = l.querySelector("[data-vsbs-footer]");
444
+ if (oe(
445
+ m.getBoundingClientRect().height,
446
+ s.getBoundingClientRect().height,
447
+ M.getBoundingClientRect().height
448
+ ), await fe(), B.value = Y.value.findIndex(
449
+ (y) => y === O.value
450
+ ), e.initialSnapPoint !== void 0) {
451
+ const y = e.initialSnapPoint;
452
+ if (y < 0 || y >= k.value.length) {
203
453
  console.warn("Index out of bounds");
204
454
  return;
205
455
  }
206
- let m;
207
- typeof p.value[f] == "number" ? m = T(p.value[f], {
208
- max: h.value
209
- }) : m = Q(p.value[f], h.value), n.value = m;
456
+ const L = k.value[y];
457
+ if (!L) return;
458
+ H.value = ae(L, h.value);
210
459
  } else
211
- n.value = T(O.value, {
212
- max: h.value
213
- });
214
- u.value = n.value, requestAnimationFrame(() => {
215
- u.value = 0, t.blocking && setTimeout(() => {
216
- S.value && (v("opened"), V.activate(), De());
217
- }, t.duration);
218
- }), window.addEventListener("keydown", pe), ae = !1;
219
- };
220
- let le = !1;
221
- const Y = () => {
222
- le || (S.value = !1, le = !0, v("closing-started"), t.blocking && (j.value = !1, G.value = !1), window.removeEventListener("keydown", pe), ce(), t.blocking && V.deactivate(), u.value = n.value, setTimeout(() => {
223
- v("closed"), le = !1;
224
- }, t.duration));
225
- }, he = (e) => {
226
- if (!p.value) return;
227
- if (e < 0 || e >= p.value.length) {
460
+ H.value = I(O.value, { max: h.value });
461
+ T.value = H.value, requestAnimationFrame(() => {
462
+ T.value = 0, e.blocking && setTimeout(() => {
463
+ i.value && (n("opened"), $.activate());
464
+ }, e.duration);
465
+ }), U.value = !1;
466
+ }, W = () => {
467
+ G.value || (i.value = !1, G.value = !0, n("closing-started"), A.unlockIfBlocking(), $.deactivate(), T.value = H.value, setTimeout(() => {
468
+ n("closed"), G.value = !1;
469
+ }, e.duration));
470
+ }, ee = (l) => {
471
+ if (!k.value) return;
472
+ if (l < 0 || l >= k.value.length) {
228
473
  console.warn("Index out of bounds");
229
474
  return;
230
475
  }
231
- D.value = e;
232
- let a;
233
- typeof p.value[e] == "number" ? a = T(p.value[e], {
234
- max: h.value
235
- }) : a = Q(p.value[e], h.value), n.value = a, v("snapped", p.value.indexOf(p.value[e]));
236
- };
237
- function me(e) {
238
- e > 0 ? v("dragging-down") : e < 0 && v("dragging-up");
239
- }
240
- const ge = (e) => {
241
- if (!i.value) return;
242
- const a = window.getComputedStyle(i.value), r = parseFloat(a.height);
243
- let c = 0;
244
- a.transform && a.transform !== "none" && (c = new DOMMatrix(a.transform).m42), n.value = r, u.value = c, B.value = !0, _.value = e.clientY, K.value = n.value, U.value = u.value, H.value = e.clientY, A.start(e.clientY), e.target.setPointerCapture(e.pointerId);
245
- }, we = (e) => {
246
- if (!B.value) return;
247
- const a = e.clientY - _.value, r = e.clientY;
248
- u.value <= 0 && (n.value = K.value - a), n.value <= O.value && (n.value = O.value, u.value = U.value + a, t.canSwipeClose ? u.value = T(u.value, { min: 0 }) : u.value = T(
249
- ie(u.value, -E.value, 0, 0.5),
250
- { min: 0 }
251
- )), n.value = T(ie(n.value, 0, L.value, 0.25), {
252
- min: 0,
253
- max: h.value
254
- }), me(e.clientY - H.value), A.update(e.clientY), H.value = r;
255
- }, X = (e) => {
256
- if (B.value = !1, e.target.releasePointerCapture(e.pointerId), t.canSwipeClose) {
257
- let f = n.value / 2;
258
- if (t.swipeCloseThreshold && typeof t.swipeCloseThreshold == "number" && (f = t.swipeCloseThreshold), t.swipeCloseThreshold && typeof t.swipeCloseThreshold == "string" && t.swipeCloseThreshold.includes("%") && (f = n.value * (Number(t.swipeCloseThreshold.replace("%", "")) / 100)), u.value > f) {
259
- u.value = n.value, Y();
260
- return;
261
- }
262
- } else
263
- u.value = 0;
264
- if (u.value === n.value) {
265
- u.value = 0, Y();
266
- return;
267
- }
268
- const a = A.end();
269
- if (a.isSwipe && a.direction === "down" && t.canSwipeClose && n.value <= O.value + 10) {
270
- u.value = n.value, Y();
271
- return;
272
- }
273
- let r;
274
- if (a.isSwipe && k.value.length > 1) {
275
- const f = [...k.value].sort((m, x) => m - x);
276
- if (a.direction === "up") {
277
- const m = f.find((x) => x > n.value + 1);
278
- r = m !== void 0 ? k.value.indexOf(m) : $.value;
279
- } else {
280
- const m = [...f].reverse().find((x) => x < n.value - 1);
281
- r = m !== void 0 ? k.value.indexOf(m) : $.value;
282
- }
283
- } else
284
- r = $.value;
285
- D.value = r;
286
- let c;
287
- if (typeof p.value[r] == "number" ? c = T(p.value[r], {
288
- max: h.value
289
- }) : c = Q(
290
- p.value[r],
291
- h.value
292
- ), c === 0) {
293
- Y();
294
- return;
295
- }
296
- n.value = c, u.value = 0, v("snapped", p.value.indexOf(p.value[r]));
297
- }, He = (e) => {
298
- if (!P.value) return;
299
- const a = P.value.scrollTop === 0, r = e > 0, c = k.value.length === 1, f = 0.5 > Math.abs(n.value - L.value);
300
- if (c) {
301
- if (!t.expandOnContentDrag) {
302
- d.value = !1;
303
- return;
304
- }
305
- u.value === 0 && a && r && (d.value = !0), u.value === 0 && a && !r && (d.value = !1);
306
- } else {
307
- if (!t.expandOnContentDrag) {
308
- d.value = !1;
309
- return;
310
- }
311
- d.value = !0, f && (r && a && (d.value = !0), !r && a && (d.value = !1), a || (d.value = !1));
312
- }
313
- }, Ie = (e) => {
314
- if (!i.value) return;
315
- const a = window.getComputedStyle(i.value), r = parseFloat(a.height);
316
- let c = 0;
317
- a.transform && a.transform !== "none" && (c = new DOMMatrix(a.transform).m42), n.value = r, u.value = c, B.value = !0, _.value = e.clientY, K.value = n.value, U.value = u.value, H.value = e.clientY, J.value = !0, A.start(e.clientY), e.target.setPointerCapture(e.pointerId);
318
- }, Fe = (e) => {
319
- if (!B.value) return;
320
- if (!t.expandOnContentDrag) {
321
- d.value = !1;
322
- return;
323
- }
324
- const a = e.clientY - _.value, r = e.clientY, c = e.clientY - H.value;
325
- if (J.value) {
326
- const m = e.clientY - _.value;
327
- if (Math.abs(m) > 3)
328
- J.value = !1, He(m);
329
- else {
330
- H.value = r;
331
- return;
332
- }
333
- }
334
- u.value === 0 && d.value && t.expandOnContentDrag && (n.value = K.value - a), n.value <= O.value && (n.value = O.value, d.value && t.expandOnContentDrag && (u.value = U.value + a), u.value = T(u.value, { min: 0, max: O.value }), t.canSwipeClose ? u.value = T(u.value, { min: 0 }) : u.value = T(
335
- ie(u.value, -E.value, 0, 0.5),
336
- { min: 0 }
337
- )), n.value > L.value && (n.value = L.value), n.value = T(n.value, { max: h.value }), k.value.length === 1 || n.value === L.value && (d.value = !1), me(c), A.update(e.clientY), H.value = r;
338
- }, be = (e) => {
339
- if (B.value = !1, J.value = !0, e.target.releasePointerCapture(e.pointerId), t.canSwipeClose) {
340
- let m = n.value / 2;
341
- if (t.swipeCloseThreshold && typeof t.swipeCloseThreshold == "number" && (m = t.swipeCloseThreshold), t.swipeCloseThreshold && typeof t.swipeCloseThreshold == "string" && t.swipeCloseThreshold.includes("%") && (m = n.value * (Number(t.swipeCloseThreshold.replace("%", "")) / 100)), u.value > m) {
342
- u.value = n.value, Y();
343
- return;
344
- }
345
- } else
346
- u.value = 0;
347
- if (u.value === n.value) {
348
- u.value = 0, Y();
349
- return;
350
- }
351
- const a = A.end(), r = d.value;
352
- if (r && a.isSwipe && a.direction === "down" && t.canSwipeClose && n.value <= O.value + 10) {
353
- u.value = n.value, Y();
354
- return;
355
- }
356
- let c;
357
- if (r && a.isSwipe && k.value.length > 1) {
358
- const m = [...k.value].sort((x, W) => x - W);
359
- if (a.direction === "up") {
360
- const x = m.find((W) => W > n.value + 1);
361
- c = x !== void 0 ? k.value.indexOf(x) : $.value;
362
- } else {
363
- const x = [...m].reverse().find((W) => W < n.value - 1);
364
- c = x !== void 0 ? k.value.indexOf(x) : $.value;
365
- }
366
- } else
367
- c = $.value;
368
- D.value = c;
369
- let f;
370
- if (typeof p.value[c] == "number" ? f = T(p.value[c], {
371
- max: h.value
372
- }) : f = Q(
373
- p.value[c],
374
- h.value
375
- ), f === 0) {
376
- Y();
377
- return;
378
- }
379
- n.value = f, u.value = 0, v("snapped", p.value.indexOf(p.value[c]));
380
- }, $e = () => {
381
- t.blocking || (j.value = !0, G.value = !0);
382
- }, Ae = () => {
383
- t.blocking || (j.value = !1, G.value = !1);
384
- }, Re = () => {
385
- if (!P.value) return;
386
- const e = P.value.scrollTop === 0;
387
- d.value = e;
388
- }, Le = tt((e) => he(e), {
389
- minQuietPeriodMs: t.duration,
390
- reducer: (e, a) => a
476
+ B.value = l;
477
+ const s = k.value[l];
478
+ s && (H.value = ae(s, h.value), n("snapped", k.value.indexOf(s)));
479
+ }, o = Ue((l) => ee(l), {
480
+ minQuietPeriodMs: e.duration,
481
+ reducer: (l, s) => s
391
482
  });
392
- Z(p, (e, a) => {
393
- if (S.value === !1 || !e || !a) return;
394
- const r = e[D.value], c = a[D.value];
395
- typeof r != "string" && typeof c != "string" && (n.value = T(r, {
396
- max: h.value
397
- }));
398
- }), Z(h, () => {
399
- Le.call(D.value);
400
- }), Z(te, (e) => {
401
- v("instinctHeight", e);
402
- }), ze(() => {
403
- ce(), V.deactivate();
483
+ te(k, (l, s) => {
484
+ if (i.value === !1 || !l || !s) return;
485
+ const m = l[B.value], M = s[B.value];
486
+ !m || typeof m == "string" || !M || typeof M == "string" || (H.value = I(m, { max: h.value }));
487
+ }), te(h, () => {
488
+ o.call(B.value);
489
+ }), te(R, (l) => {
490
+ n("instinctHeight", l);
491
+ }), Be(() => {
492
+ $.cleanup();
404
493
  });
405
- const _e = (e) => {
406
- const a = e;
407
- a.style.transition = `transform ${t.duration}ms ease, height ${t.duration}ms ease`, a.style.transform = `translateY(${n.value}px)`;
494
+ const c = (l) => {
495
+ const s = l;
496
+ s.style.transition = `transform ${e.duration}ms ease, height ${e.duration}ms ease`, s.style.transform = `translateY(${H.value}px)`;
408
497
  };
409
- return l({ open: ne, close: Y, snapToPoint: he }), (e, a) => (q(), oe(Qe, null, [
410
- (q(), Ce(ye, {
411
- to: e.teleportTo,
412
- defer: e.teleportDefer
498
+ return a({ open: Q, close: W, snapToPoint: ee }), (l, s) => (X(), ie(Ie, null, [
499
+ (X(), pe(he, {
500
+ to: t.teleportTo,
501
+ defer: t.teleportDefer
413
502
  }, [
414
- Pe(Te, { name: "vsbs-backdrop" }, {
415
- default: xe(() => [
416
- ue(S) && e.blocking ? (q(), oe("div", {
503
+ ge(me, { name: "vsbs-backdrop" }, {
504
+ default: Se(() => [
505
+ E(i) && t.blocking ? (X(), ie("div", {
417
506
  key: 0,
418
507
  ref_key: "backdrop",
419
- ref: M,
508
+ ref: d,
420
509
  "data-vsbs-backdrop": "",
421
- onClick: a[0] || (a[0] = (r) => Be())
422
- }, null, 512)) : ke("", !0)
510
+ onClick: s[0] || (s[0] = (m) => Z())
511
+ }, null, 512)) : be("", !0)
423
512
  ]),
424
513
  _: 1
425
514
  })
426
515
  ], 8, ["to", "defer"])),
427
- (q(), Ce(ye, {
428
- to: e.teleportTo,
429
- defer: e.teleportDefer
516
+ (X(), pe(he, {
517
+ to: t.teleportTo,
518
+ defer: t.teleportDefer
430
519
  }, [
431
- Pe(Te, {
520
+ ge(me, {
432
521
  name: "vsbs-sheet",
433
- onLeave: _e
522
+ onLeave: c
434
523
  }, {
435
- default: xe(() => [
436
- ue(S) ? (q(), oe("div", {
524
+ default: Se(() => [
525
+ E(i) ? (X(), ie("div", {
437
526
  key: 0,
438
527
  ref_key: "sheet",
439
- ref: i,
440
- style: je({
441
- transform: `translateY(${u.value}px)`,
442
- height: `${n.value}px`,
443
- transition: B.value ? "none" : `transform ${e.duration}ms ease, height ${e.duration}ms ease`
528
+ ref: r,
529
+ style: Ye({
530
+ transform: `translateY(${T.value}px)`,
531
+ height: `${H.value}px`,
532
+ transition: E(re) ? "none" : `transform ${t.duration}ms ease, height ${t.duration}ms ease`
444
533
  }),
445
- "data-vsbs-shadow": !e.blocking,
446
- "data-vsbs-sheet-show": ue(S),
534
+ "data-vsbs-shadow": !t.blocking,
535
+ "data-vsbs-sheet-show": E(i),
447
536
  "aria-modal": "true",
448
537
  "data-vsbs-sheet": "",
449
538
  tabindex: "-1",
450
- onTouchstart: $e,
451
- onTouchend: Ae
539
+ onTouchstart: s[2] || (s[2] = //@ts-ignore
540
+ (...m) => E(A).touchStartHandler && E(A).touchStartHandler(...m)),
541
+ onTouchend: s[3] || (s[3] = //@ts-ignore
542
+ (...m) => E(A).touchEndHandler && E(A).touchEndHandler(...m))
452
543
  }, [
453
- z("div", {
544
+ j("div", ce({
454
545
  ref_key: "sheetHeader",
455
- ref: y,
456
- "data-vsbs-header": "",
457
- onPointerdown: ge,
458
- onPointermove: we,
459
- onPointerup: X,
460
- onPointercancel: X,
461
- onTouchmove: de,
462
- class: se(e.headerClass),
546
+ ref: p,
547
+ "data-vsbs-header": ""
548
+ }, E(J), {
549
+ class: t.headerClass,
463
550
  style: { "touch-action": "none" }
464
- }, [
465
- re(e.$slots, "header", {}, void 0, !0)
466
- ], 34),
467
- z("div", {
551
+ }), [
552
+ ve(l.$slots, "header", {}, void 0, !0)
553
+ ], 16),
554
+ j("div", {
468
555
  ref_key: "sheetScroll",
469
- ref: P,
556
+ ref: b,
470
557
  "data-vsbs-scroll": "",
471
- onScrollend: Re
558
+ onScrollend: s[1] || (s[1] = //@ts-ignore
559
+ (...m) => E(V) && E(V)(...m))
472
560
  }, [
473
- z("div", {
474
- ref_key: "sheetContentWrapper",
475
- ref: w,
476
- "data-vsbs-content-wrapper": "",
477
- onPointerdown: Ie,
478
- onPointermove: Fe,
479
- onPointerup: be,
480
- onPointercancel: be,
481
- onTouchmove: fe,
482
- style: { touchAction: "pan-y" }
483
- }, [
484
- z("div", {
561
+ j("div", ce({ "data-vsbs-content-wrapper": "" }, E(se), { style: { touchAction: "pan-y" } }), [
562
+ j("div", {
485
563
  ref_key: "sheetContent",
486
- ref: b,
564
+ ref: v,
487
565
  "data-vsbs-content": "",
488
- class: se(e.contentClass)
566
+ class: Me(t.contentClass)
489
567
  }, [
490
- re(e.$slots, "default", {}, void 0, !0)
568
+ ve(l.$slots, "default", {}, void 0, !0)
491
569
  ], 2)
492
- ], 544)
570
+ ], 16)
493
571
  ], 544),
494
- z("div", {
572
+ j("div", ce({
495
573
  ref_key: "sheetFooter",
496
- ref: C,
497
- "data-vsbs-footer": "",
498
- onPointerdown: ge,
499
- onPointermove: we,
500
- onPointerup: X,
501
- onPointercancel: X,
502
- onTouchmove: de,
503
- class: se(e.footerClass),
574
+ ref: f,
575
+ "data-vsbs-footer": ""
576
+ }, E(J), {
577
+ class: t.footerClass,
504
578
  style: { "touch-action": "none" }
505
- }, [
506
- re(e.$slots, "footer", {}, void 0, !0)
507
- ], 34)
508
- ], 44, ut)) : ke("", !0)
579
+ }), [
580
+ ve(l.$slots, "footer", {}, void 0, !0)
581
+ ], 16)
582
+ ], 44, Ze)) : be("", !0)
509
583
  ]),
510
584
  _: 3
511
585
  })
512
586
  ], 8, ["to", "defer"]))
513
587
  ], 64));
514
588
  }
515
- }), rt = (o, l) => {
516
- const s = o.__vccOpts || o;
517
- for (const [t, v] of l)
518
- s[t] = v;
519
- return s;
520
- }, dt = /* @__PURE__ */ rt(st, [["__scopeId", "data-v-01259485"]]);
589
+ }), tt = (t, a) => {
590
+ const u = t.__vccOpts || t;
591
+ for (const [e, n] of a)
592
+ u[e] = n;
593
+ return u;
594
+ }, lt = /* @__PURE__ */ tt(et, [["__scopeId", "data-v-9e937e3a"]]);
521
595
  export {
522
- dt as default
596
+ lt as default
523
597
  };
package/dist/style.css CHANGED
@@ -1 +1 @@
1
- [data-vsbs-backdrop][data-v-01259485]{background-color:var(--vsbs-backdrop-bg, rgba(0, 0, 0, .5));top:0;right:0;bottom:0;left:0;pointer-events:auto;position:fixed;-webkit-user-select:none;user-select:none;will-change:opacity;--vsbs-duration: var(--0a9ba53d)}[data-vsbs-shadow=true][data-v-01259485]:before{content:"";z-index:-1;position:absolute;top:0;height:100lvh;width:100%;border-radius:var(--vsbs-border-radius, 16px);box-shadow:0 -5px 60px 0 var(--vsbs-shadow-color, rgba(89, 89, 89, .2))}[data-vsbs-sheet][data-v-01259485]{background-color:var(--vsbs-background, #fff);border-top-left-radius:var(--vsbs-border-radius, 16px);border-top-right-radius:var(--vsbs-border-radius, 16px);border-right:1px solid var(--vsbs-outer-border-color, transparent);border-left:1px solid var(--vsbs-outer-border-color, transparent);bottom:0;display:flex;flex-direction:column;left:0;margin-left:auto;margin-right:auto;max-width:var(--vsbs-max-width, 640px);pointer-events:all;position:fixed;right:0;width:100%;will-change:height,transform}[data-vsbs-sheet-show=true][data-v-01259485]{visibility:visible}[data-vsbs-header][data-v-01259485]{box-shadow:0 1px 0 var(--vsbs-border-color, rgba(46, 59, 66, .125));flex-shrink:0;padding:20px var(--vsbs-padding-x, 16px) 8px;-webkit-user-select:none;user-select:none;z-index:3;border-top-left-radius:var(--vsbs-border-radius, 16px);border-top-right-radius:var(--vsbs-border-radius, 16px);border-top:1px solid var(--vsbs-outer-border-color, transparent)}[data-vsbs-header][data-v-01259485]:before{background-color:var(--vsbs-handle-background, rgba(0, 0, 0, .28));border-radius:2px;content:"";display:block;height:4px;left:50%;position:absolute;top:8px;transform:translate(-50%);width:36px}[data-vsbs-header][data-v-01259485]:empty{box-shadow:none;padding:14px var(--vsbs-padding-x, 16px) 10px}[data-vsbs-footer][data-v-01259485]{box-shadow:0 -1px 0 var(--vsbs-border-color, rgba(46, 59, 66, .125));flex-grow:0;flex-shrink:0;padding:16px var(--vsbs-padding-x, 16px);-webkit-user-select:none;user-select:none}[data-vsbs-footer][data-v-01259485]:empty{display:none}[data-vsbs-scroll][data-v-01259485]{flex-grow:1;overflow-y:auto;overscroll-behavior:none}[data-vsbs-content-wrapper][data-v-01259485]{height:100%}[data-vsbs-content][data-v-01259485]{display:grid;padding:8px var(--vsbs-padding-x, 16px);-webkit-user-select:none;user-select:none}.vsbs-backdrop-enter-active[data-v-01259485],.vsbs-backdrop-leave-active[data-v-01259485]{transition:opacity var(--vsbs-duration) ease}.vsbs-backdrop-enter-from[data-v-01259485],.vsbs-backdrop-leave-to[data-v-01259485]{opacity:0}
1
+ [data-vsbs-backdrop][data-v-9e937e3a]{background-color:var(--vsbs-backdrop-bg, rgba(0, 0, 0, .5));inset:0;pointer-events:auto;position:fixed;-webkit-user-select:none;user-select:none;will-change:opacity;--vsbs-duration: var(--v531b2f52)}[data-vsbs-shadow=true][data-v-9e937e3a]:before{content:"";z-index:-1;position:absolute;top:0;height:100lvh;width:100%;border-radius:var(--vsbs-border-radius, 16px);box-shadow:0 -5px 60px 0 var(--vsbs-shadow-color, rgba(89, 89, 89, .2))}[data-vsbs-sheet][data-v-9e937e3a]{background-color:var(--vsbs-background, #fff);border-top-left-radius:var(--vsbs-border-radius, 16px);border-top-right-radius:var(--vsbs-border-radius, 16px);border-right:1px solid var(--vsbs-outer-border-color, transparent);border-left:1px solid var(--vsbs-outer-border-color, transparent);bottom:0;display:flex;flex-direction:column;left:0;margin-left:auto;margin-right:auto;max-width:var(--vsbs-max-width, 640px);pointer-events:all;position:fixed;right:0;width:100%;will-change:height,transform}[data-vsbs-sheet-show=true][data-v-9e937e3a]{visibility:visible}[data-vsbs-header][data-v-9e937e3a]{box-shadow:0 1px 0 var(--vsbs-border-color, rgba(46, 59, 66, .125));flex-shrink:0;padding:20px var(--vsbs-padding-x, 16px) 8px;-webkit-user-select:none;user-select:none;z-index:3;border-top-left-radius:var(--vsbs-border-radius, 16px);border-top-right-radius:var(--vsbs-border-radius, 16px);border-top:1px solid var(--vsbs-outer-border-color, transparent)}[data-vsbs-header][data-v-9e937e3a]:before{background-color:var(--vsbs-handle-background, rgba(0, 0, 0, .28));border-radius:2px;content:"";display:block;height:4px;left:50%;position:absolute;top:8px;transform:translate(-50%);width:36px}[data-vsbs-header][data-v-9e937e3a]:empty{box-shadow:none;padding:14px var(--vsbs-padding-x, 16px) 10px}[data-vsbs-footer][data-v-9e937e3a]{box-shadow:0 -1px 0 var(--vsbs-border-color, rgba(46, 59, 66, .125));flex-grow:0;flex-shrink:0;padding:16px var(--vsbs-padding-x, 16px);-webkit-user-select:none;user-select:none}[data-vsbs-footer][data-v-9e937e3a]:empty{display:none}[data-vsbs-scroll][data-v-9e937e3a]{flex-grow:1;overflow-y:auto;overscroll-behavior:none}[data-vsbs-content-wrapper][data-v-9e937e3a]{height:100%}[data-vsbs-content][data-v-9e937e3a]{display:grid;padding:8px var(--vsbs-padding-x, 16px);-webkit-user-select:none;user-select:none}.vsbs-backdrop-enter-active[data-v-9e937e3a],.vsbs-backdrop-leave-active[data-v-9e937e3a]{transition:opacity var(--vsbs-duration) ease}.vsbs-backdrop-enter-from[data-v-9e937e3a],.vsbs-backdrop-leave-to[data-v-9e937e3a]{opacity:0}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Calculate the swipe close threshold based on prop value and current height.
3
+ * Supports absolute pixel values, percentage strings, or defaults to half height.
4
+ */
5
+ export declare function calculateSwipeThreshold(threshold: string | number | undefined, height: number): number;
@@ -0,0 +1,5 @@
1
+ export declare const SNAP_POINT_TOLERANCE_PX = 10;
2
+ export declare const MOVEMENT_THRESHOLD_PX = 3;
3
+ export declare const RUBBERBAND_ELASTICITY = 0.25;
4
+ export declare const RUBBERBAND_ELASTICITY_STRONG = 0.5;
5
+ export declare const DEFAULT_VELOCITY_THRESHOLD = 0.5;
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Resolve a snap point value (number or percentage string) to pixels
3
+ */
4
+ export declare function resolveSnapPoint(snapValue: number | `${number}%`, windowHeight: number): number;
package/package.json CHANGED
@@ -32,7 +32,7 @@
32
32
  "url": "https://github.com/megaarmos/vue-spring-bottom-sheet/issues"
33
33
  },
34
34
  "private": false,
35
- "version": "3.0.0-next.2",
35
+ "version": "3.0.0-next.4",
36
36
  "type": "module",
37
37
  "exports": {
38
38
  ".": {
@@ -61,26 +61,26 @@
61
61
  "vue": ">=3.3"
62
62
  },
63
63
  "dependencies": {
64
- "@vueuse/core": "^13.2.0",
65
- "@vueuse/integrations": "^13.2.0",
66
- "focus-trap": "^7.6.4",
67
- "remeda": "^2.21.6",
68
- "vue": "^3.5.14"
64
+ "@vueuse/core": "^14.1.0",
65
+ "@vueuse/integrations": "^14.1.0",
66
+ "focus-trap": "^7.8.0",
67
+ "remeda": "^2.33.3",
68
+ "vue": "^3.5.26"
69
69
  },
70
70
  "devDependencies": {
71
- "@types/node": "^22.15.18",
72
- "@vitejs/plugin-vue": "^5.2.4",
71
+ "@types/node": "^25.0.8",
72
+ "@vitejs/plugin-vue": "^6.0.3",
73
73
  "@vue/eslint-config-prettier": "^10.2.0",
74
- "@vue/eslint-config-typescript": "^14.5.0",
75
- "@vue/tsconfig": "^0.7.0",
74
+ "@vue/eslint-config-typescript": "^14.6.0",
75
+ "@vue/tsconfig": "^0.8.1",
76
76
  "ajv": "^8.17.1",
77
- "eslint": "^9.27.0",
78
- "eslint-plugin-vue": "^10.1.0",
79
- "prettier": "^3.5.3",
80
- "typescript": "~5.6.3",
81
- "vite": "^6.3.5",
82
- "vite-plugin-dts": "4.5.3",
83
- "vue-tsc": "^2.2.10"
77
+ "eslint": "^9.39.2",
78
+ "eslint-plugin-vue": "^10.6.2",
79
+ "prettier": "^3.7.4",
80
+ "typescript": "~5.9.3",
81
+ "vite": "^7.3.1",
82
+ "vite-plugin-dts": "4.5.4",
83
+ "vue-tsc": "^3.2.2"
84
84
  },
85
85
  "files": [
86
86
  "dist",