@douxcode/vue-spring-bottom-sheet 3.0.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -25,9 +25,9 @@ bun install @douxcode/vue-spring-bottom-sheet
25
25
  <script setup>
26
26
  import BottomSheet from '@douxcode/vue-spring-bottom-sheet'
27
27
  import '@douxcode/vue-spring-bottom-sheet/dist/style.css'
28
- import { ref } from 'vue'
28
+ import { useTemplateRef } from 'vue'
29
29
 
30
- const bottomSheet = ref(null)
30
+ const bottomSheet = useTemplateRef('bottomSheet')
31
31
 
32
32
  const open = () => {
33
33
  bottomSheet.value.open()
@@ -130,21 +130,24 @@ For Nuxt 3, just wrap component in `<ClientOnly>`
130
130
 
131
131
  ### Prop Definitions
132
132
 
133
- | Prop | Type | Default | Description |
134
- | ------------------- | ------------------------- | ---------------- | ------------------------------------------------------------------------- |
135
- | duration | Number | 250 | Animation duration in milliseconds |
136
- | snapPoints | Array<number\|string> | [instinctHeight] | Custom snapping positions |
137
- | initialSnapPoint | Number | minHeight | Initial snap point index |
138
- | blocking | Boolean | true | Block interactions with underlying content |
139
- | canSwipeClose | Boolean | true | Enable swipe-to-close gesture |
140
- | swipeCloseThreshold | Number\|String | "50%" | The amount of translation (in px or %) after which the element will close |
141
- | canBackdropClose | Boolean | true | Allow closing by tapping backdrop |
142
- | expandOnContentDrag | Boolean | true | Enable expanding by dragging content |
143
- | teleportTo | String \| RendererElement | body | Teleport to a specific element |
144
- | teleportDefer | Boolean | false | Defer teleporting until opened (Vue 3.5+ only) |
145
- | headerClass | String | '' | Set header element class |
146
- | contentClass | String | '' | Set content element class |
147
- | footerClass | String | '' | Set footer element class |
133
+ | Prop | Type | Default | Description |
134
+ | ------------------- | --------------------------- | ---------------- | ------------------------------------------------------------------------- |
135
+ | duration | Number | 250 | Animation duration in milliseconds |
136
+ | snapPoints | Array<number\|`${number}%`> | [instinctHeight] | Custom snapping positions |
137
+ | initialSnapPoint | Number | minHeight | Initial snap point index |
138
+ | blocking | Boolean | true | Block interactions with underlying content |
139
+ | canSwipeClose | Boolean | true | Enable swipe-to-close gesture |
140
+ | swipeCloseThreshold | Number\|`${number}%` | "50%" | The amount of translation (in px or %) after which the element will close |
141
+ | canBackdropClose | Boolean | true | Allow closing by tapping backdrop |
142
+ | expandOnContentDrag | Boolean | true | Enable expanding by dragging content |
143
+ | teleportTo | String \| RendererElement | body | Teleport to a specific element |
144
+ | teleportDefer | Boolean | false | Defer teleporting until opened (Vue 3.5+ only) |
145
+ | headerClass | String | '' | Set header element class |
146
+ | contentClass | String | '' | Set content element class |
147
+ | footerClass | String | '' | Set footer element class |
148
+ | forceMount | Boolean | false | Force mount the bottom sheet in the DOM |
149
+
150
+ Interactive content inside the sheet body keeps its native touch behavior. Inputs and editable content do not start sheet dragging, and custom widgets can opt out with data-vsbs-no-drag.
148
151
 
149
152
  ## Exposed methods
150
153
 
@@ -21,7 +21,7 @@ declare const __VLS_component: import('vue').DefineComponent<BottomSheetProps, {
21
21
  open: () => Promise<void>;
22
22
  close: () => void;
23
23
  snapToPoint: (index: number) => void;
24
- }, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {} & {
24
+ }, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
25
25
  opened: () => any;
26
26
  "opening-started": () => any;
27
27
  closed: () => any;
@@ -42,11 +42,12 @@ declare const __VLS_component: import('vue').DefineComponent<BottomSheetProps, {
42
42
  onInstinctHeight?: ((instinctHeight: number) => any) | undefined;
43
43
  "onUpdate:modelValue"?: (() => any) | undefined;
44
44
  }>, {
45
- canSwipeClose: boolean;
46
- expandOnContentDrag: boolean;
47
45
  blocking: boolean;
48
46
  duration: number;
47
+ forceMount: boolean;
48
+ canSwipeClose: boolean;
49
49
  canBackdropClose: boolean;
50
+ expandOnContentDrag: boolean;
50
51
  teleportTo: string | import('vue').RendererElement;
51
52
  teleportDefer: boolean;
52
53
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
@@ -1,47 +1,34 @@
1
- import { Ref, ComputedRef, ShallowRef } from 'vue';
2
- export interface UseDragGesturesOptions {
3
- sheetRef: ShallowRef<HTMLElement | null>;
1
+ import { BottomSheetProps } from '../types';
2
+ import { Ref, ShallowRef } from 'vue';
3
+ type DragHandle = 'header' | 'footer';
4
+ type PointerCaptureTarget = DragHandle | 'content';
5
+ interface UseDragGesturesOptions {
6
+ sheetHeaderRef: ShallowRef<HTMLElement | null>;
7
+ sheetFooterRef: ShallowRef<HTMLElement | null>;
8
+ sheetContentRef: ShallowRef<HTMLElement | null>;
4
9
  sheetScrollRef: ShallowRef<HTMLElement | null>;
5
10
  height: Ref<number>;
6
11
  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>;
12
+ minSnapPoint: Readonly<Ref<number>>;
13
+ maxSnapPoint: Readonly<Ref<number>>;
14
+ closestSnapPointIndex: Readonly<Ref<number>>;
15
+ flattenedSnapPoints: Readonly<Ref<number[]>>;
16
+ canSwipeClose: Readonly<Ref<boolean>>;
17
+ expandOnContentDrag: Readonly<Ref<boolean>>;
18
+ swipeCloseThreshold: Readonly<Ref<BottomSheetProps['swipeCloseThreshold']>>;
18
19
  onClose: () => void;
19
- onSnapped: (index: number) => void;
20
- onDraggingUp: () => void;
21
- onDraggingDown: () => void;
20
+ onSnapToPoint: (index: number) => void;
21
+ onDraggingUp?: () => void;
22
+ onDraggingDown?: () => void;
22
23
  }
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;
24
+ export declare const useDragGestures: (options: UseDragGesturesOptions) => {
25
+ isDragging: ShallowRef<boolean, boolean>;
26
+ handleSheetScroll: (event: TouchEvent) => void;
27
+ handlePointerDown: (event: PointerEvent, type: DragHandle) => void;
28
+ handleContentPointerDown: (event: PointerEvent) => void;
29
+ handlePointerMove: (event: PointerEvent) => void;
30
+ handleContentPointerMove: (event: PointerEvent) => void;
31
+ handleLostPointerCapture: (event: PointerEvent, type: PointerCaptureTarget) => void;
32
+ handleTouchStart: (event: TouchEvent) => void;
47
33
  };
34
+ export {};
@@ -3,10 +3,7 @@ export interface SwipeResult {
3
3
  velocity: number;
4
4
  isSwipe: boolean;
5
5
  }
6
- export interface UseSwipeDetectionOptions {
7
- velocityThreshold?: number;
8
- }
9
- export declare function useSwipeDetection(options?: UseSwipeDetectionOptions): {
6
+ export declare function useSwipeDetection(): {
10
7
  start: (y: number) => void;
11
8
  update: (y: number) => void;
12
9
  end: () => SwipeResult;
package/dist/index.mjs CHANGED
@@ -1,378 +1,294 @@
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, openBlock as X, createElementBlock as ie, Fragment as Ie, createBlock as pe, Teleport as he, createVNode as ge, Transition as me, withCtx as Se, unref as E, createCommentVNode as be, normalizeStyle as Me, createElementVNode as j, mergeProps as ce, renderSlot as ve, normalizeClass as Ye } 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;
1
+ import { ref as H, shallowRef as y, computed as D, defineComponent as Ae, useCssVars as Fe, watch as A, nextTick as _, onMounted as $e, toRef as F, onUnmounted as Ve, openBlock as $, createElementBlock as ee, Fragment as ze, createBlock as fe, Teleport as ve, createElementVNode as V, createVNode as he, Transition as ge, withCtx as me, unref as f, withDirectives as pe, vShow as Se, createCommentVNode as be, normalizeStyle as Ne, normalizeClass as te, renderSlot as ne } from "vue";
2
+ import { useScrollLock as qe, useVModel as Ke, useWindowSize as Ue, useElementBounding as U } from "@vueuse/core";
3
+ import { useFocusTrap as We } from "@vueuse/integrations/useFocusTrap";
4
+ function Ge(e, t, o) {
5
+ let a = (l) => e(l, ...t);
6
+ return o === void 0 ? a : Object.assign(a, { lazy: o, lazyArgs: t });
7
7
  }
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
- );
13
- return n.value.indexOf(f);
14
- });
15
- return {
16
- currentSnapPointIndex: e,
17
- flattenedSnapPoints: n,
18
- minSnapPoint: i,
19
- maxSnapPoint: r,
20
- closestSnapPointIndex: p
21
- };
22
- }
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);
8
+ function Qe(e, t, o) {
9
+ let a = e.length - t.length;
10
+ if (a === 0) return e(...t);
11
+ if (a === 1) return Ge(e, t, o);
31
12
  throw Error("Wrong number of arguments");
32
13
  }
33
- function I(...t) {
34
- return $e(Ne, t);
14
+ function T(...e) {
15
+ return Qe(Xe, e);
35
16
  }
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();
17
+ const Xe = (e, { min: t, max: o }) => t !== void 0 && e < t ? t : o !== void 0 && e > o ? o : e, ye = /* @__PURE__ */ Symbol("funnel/voidReducer"), je = () => ye;
18
+ function Je(e, { triggerAt: t = "end", minQuietPeriodMs: o, maxBurstDurationMs: a, minGapMs: l, reducer: u = je }) {
19
+ let i, v, d, h, p = () => {
20
+ let m = d;
21
+ m !== void 0 && (d = void 0, m === ye ? e() : e(m), l !== void 0 && (v = setTimeout(P, l)));
22
+ }, P = () => {
23
+ clearTimeout(v), v = void 0, i === void 0 && p();
24
+ }, C = () => {
25
+ clearTimeout(i), i = void 0, h = void 0, v === void 0 && p();
45
26
  };
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, Math.max(0, e - (C - b)));
54
- r = setTimeout(h, x);
27
+ return { call: (...m) => {
28
+ let k = i === void 0 && v === void 0;
29
+ if ((t !== "start" || k) && (d = u(d, ...m)), !(i === void 0 && !k)) {
30
+ if (o !== void 0 || a !== void 0 || l === void 0) {
31
+ clearTimeout(i);
32
+ let E = Date.now();
33
+ h ??= E;
34
+ let M = a === void 0 ? o ?? 0 : Math.min(o ?? a, Math.max(0, a - (E - h)));
35
+ i = setTimeout(C, M);
55
36
  }
56
- a !== "end" && w && v();
37
+ t !== "end" && k && p();
57
38
  }
58
39
  }, cancel: () => {
59
- clearTimeout(r), r = void 0, b = void 0, clearTimeout(p), p = void 0, f = void 0;
40
+ clearTimeout(i), i = void 0, h = void 0, clearTimeout(v), v = void 0, d = void 0;
60
41
  }, flush: () => {
61
- h(), d();
42
+ C(), P();
62
43
  }, get isIdle() {
63
- return r === void 0 && p === void 0;
44
+ return i === void 0 && v === void 0;
64
45
  } };
65
46
  }
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([]);
68
- return {
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 }];
72
- },
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);
78
- },
79
- end: () => {
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
- }
88
- }
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
95
- };
96
- }
97
- };
47
+ const Ze = 5, _e = 30, et = 400;
48
+ function tt() {
49
+ const e = H([]);
50
+ function t(l) {
51
+ e.value = [{ y: l, time: performance.now() }];
52
+ }
53
+ function o(l) {
54
+ const u = e.value;
55
+ u.push({ y: l, time: performance.now() }), u.length > Ze && u.shift();
56
+ }
57
+ function a() {
58
+ const l = e.value;
59
+ if (l.length < 2)
60
+ return { direction: "none", velocity: 0, isSwipe: !1 };
61
+ const u = l[0], i = l[l.length - 1];
62
+ if (!u || !i)
63
+ return { direction: "none", velocity: 0, isSwipe: !1 };
64
+ const v = u.y - i.y, d = (i.time - u.time) / 1e3, h = d > 0 ? Math.abs(v) / d : 0, p = Math.abs(v) >= _e && h >= et;
65
+ let P = "none";
66
+ return p && (P = v > 0 ? "up" : "down"), e.value = [], { direction: P, velocity: h, isSwipe: p };
67
+ }
68
+ return { start: t, update: o, end: a };
98
69
  }
99
- function qe(t, a, u) {
100
- return Math.max(a, Math.min(t, u));
70
+ function nt(e, t) {
71
+ if (e === void 0)
72
+ return t / 2;
73
+ if (typeof e == "number")
74
+ return e;
75
+ if (typeof e == "string" && e.includes("%")) {
76
+ const o = Number(e.replace("%", ""));
77
+ return t * (o / 100);
78
+ }
79
+ return t / 2;
101
80
  }
102
- function ze(t, a) {
103
- return Math.pow(t, a * 5);
81
+ const at = 10, we = 0.25;
82
+ function Pe(e) {
83
+ return !!e.closest(
84
+ 'input, textarea, [contenteditable="true"], [contenteditable=""], [data-vsbs-no-drag]'
85
+ );
104
86
  }
105
- function we(t, a, u) {
106
- return a === 0 || Math.abs(a) === 1 / 0 ? ze(t, u) : t * a * u / (a + u * t);
87
+ function ot(e, t, o) {
88
+ return Math.max(t, Math.min(e, o));
107
89
  }
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;
90
+ function rt(e, t) {
91
+ return Math.pow(e, t * 5);
110
92
  }
111
- function ae(t, a) {
112
- return typeof t == "number" ? I(t, { max: a }) : Te(t, a);
93
+ function Ce(e, t, o) {
94
+ return t === 0 || Math.abs(t) === 1 / 0 ? rt(e, o) : e * t * o / (t + o * e);
113
95
  }
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;
96
+ function ke(e, t, o, a = 0.15) {
97
+ return a === 0 ? ot(e, t, o) : e < t ? -Ce(t - e, o - t, a) + t : e > o ? +Ce(e - o, o - t, a) + o : e;
124
98
  }
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), V = P(0), k = P(0), M = 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 Y = [...f.value].sort((y, L) => y - L);
168
- if (c.direction === "up") {
169
- const y = Y.find((L) => L > e.value + 1);
170
- l = y !== void 0 ? f.value.indexOf(y) : v.value;
171
- } else {
172
- const y = [...Y].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, V.value = e.value, k.value = n.value, M.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 = V.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 - M.value), O.update(o.clientY), M.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();
99
+ const lt = (e) => {
100
+ const t = tt(), o = y(!1);
101
+ let a = !0, l = 0, u = 0, i = !1, v = 0, d = !1, h = 0;
102
+ const p = (n) => {
103
+ n > 0 ? e.onDraggingDown?.() : n < 0 && e.onDraggingUp?.();
104
+ }, P = () => {
105
+ if (i) return;
106
+ const n = document.activeElement;
107
+ n instanceof HTMLElement && n !== document.body && (n.blur(), i = !0);
108
+ }, C = (n) => {
109
+ const g = n.target;
110
+ g && Pe(g) && n.preventDefault(), typeof n.cancelable != "boolean" || n.cancelable ? a && n.preventDefault() : console.warn("The following event couldn't be canceled:");
111
+ }, m = (n, g) => {
112
+ const b = g === "header" ? e.sheetHeaderRef.value : e.sheetFooterRef.value;
113
+ b && n.button === 0 && (l = e.height.value, u = e.translateY.value, i = !1, h = 0, d = !1, a = !0, o.value = !0, t.start(n.clientY), b.setPointerCapture(n.pointerId));
114
+ }, k = (n) => {
115
+ const g = n.target;
116
+ e.sheetContentRef.value && n.button === 0 && e.expandOnContentDrag.value !== !1 && (g && Pe(g) || (l = e.height.value, u = e.translateY.value, v = n.clientY, i = !1, h = 0, d = !1, a = !0, o.value = !0, t.start(n.clientY), e.sheetContentRef.value.setPointerCapture(n.pointerId)));
117
+ }, E = (n) => {
118
+ if (o.value) {
119
+ if (Math.abs(n.movementY) > 0 && P(), t.update(n.clientY), p(n.movementY), e.translateY.value > 0) {
120
+ e.canSwipeClose.value ? e.translateY.value = e.translateY.value + n.movementY : (u = u + n.movementY, e.translateY.value = ke(
121
+ u,
122
+ -e.minSnapPoint.value,
123
+ 0,
124
+ we
125
+ ));
212
126
  return;
213
127
  }
214
- } else
215
- n.value = 0;
216
- if (n.value === e.value) {
217
- n.value = 0, x();
218
- return;
128
+ l = T(l - n.movementY, {
129
+ min: e.minSnapPoint.value
130
+ }), e.height.value = ke(
131
+ l,
132
+ 0,
133
+ e.maxSnapPoint.value,
134
+ we
135
+ ), e.height.value <= e.minSnapPoint.value && (e.translateY.value = e.translateY.value + n.movementY);
219
136
  }
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;
137
+ }, M = (n) => {
138
+ if (h >= 2)
139
+ return;
140
+ const g = e.sheetScrollRef.value, b = g?.scrollTop === 0, w = n.clientY - v > 0, S = e.flattenedSnapPoints.value.length === 1, N = 0.5 > Math.abs(e.height.value - e.maxSnapPoint.value), R = (g?.scrollHeight ?? 0) > (g?.clientHeight ?? 0);
141
+ if (S) {
142
+ if (!e.expandOnContentDrag.value) {
143
+ a = !1;
233
144
  return;
234
145
  }
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, V.value = e.value, k.value = n.value, M.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
- U(o);
146
+ e.translateY.value === 0 && b && w && (a = !0), e.translateY.value === 0 && b && !w && (a = !1);
147
+ } else
148
+ a = !0, N && (w && b && (a = !0), !w && b && (a = !1), b || (a = !1));
149
+ d = !R, h++;
150
+ }, B = (n) => {
151
+ if (!o.value || !e.sheetScrollRef.value || (Math.abs(n.movementY) > 0 && P(), M(n), h <= 1)) return;
152
+ if (t.update(n.clientY), p(n.movementY), e.translateY.value > 0) {
153
+ e.canSwipeClose.value && (e.translateY.value = T(e.translateY.value + n.movementY, { min: 0 }));
243
154
  return;
244
155
  }
245
- if (!C.value) {
246
- S.value = !1;
156
+ e.height.value = T(e.height.value - n.movementY, {
157
+ min: e.minSnapPoint.value,
158
+ max: e.maxSnapPoint.value
159
+ }), !(e.flattenedSnapPoints.value.length === 1) && e.height.value === e.maxSnapPoint.value && (a = !1), e.height.value <= e.minSnapPoint.value && (e.translateY.value = T(e.translateY.value + n.movementY, {
160
+ min: 0,
161
+ ...e.canSwipeClose.value === !1 ? { max: 0 } : {}
162
+ }));
163
+ }, z = () => {
164
+ const n = t.end();
165
+ if (n.isSwipe && n.direction === "down" && e.canSwipeClose.value && e.height.value <= e.minSnapPoint.value + at) {
166
+ e.onClose();
247
167
  return;
248
168
  }
249
- const c = o.clientY - F.value, l = o.clientY, s = o.clientY - M.value;
250
- if (B.value) {
251
- const Y = o.clientY - F.value;
252
- if (Math.abs(Y) > Qe)
253
- B.value = !1, re(Y);
254
- else {
255
- M.value = l;
169
+ if (e.canSwipeClose.value) {
170
+ const g = nt(
171
+ e.swipeCloseThreshold.value,
172
+ e.height.value
173
+ );
174
+ if (e.translateY.value > g) {
175
+ e.onClose();
256
176
  return;
257
177
  }
258
178
  }
259
- n.value === 0 && S.value && C.value && (e.value = V.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), M.value = l;
268
- }, U = (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;
179
+ if (n.isSwipe && e.flattenedSnapPoints.value.length > 1) {
180
+ const g = [...e.flattenedSnapPoints.value].sort((w, S) => w - S);
181
+ let b = e.closestSnapPointIndex.value;
182
+ if (n.direction === "up") {
183
+ const w = g.find((S) => S > e.height.value + 1);
184
+ w !== void 0 && (b = e.flattenedSnapPoints.value.indexOf(w));
185
+ } else if (n.direction === "down") {
186
+ const w = [...g].reverse().find((S) => S < e.height.value - 1);
187
+ w !== void 0 && (b = e.flattenedSnapPoints.value.indexOf(w));
274
188
  }
275
- } else
276
- n.value = 0;
277
- if (n.value === e.value) {
278
- n.value = 0, x();
189
+ e.onSnapToPoint(b), e.translateY.value = 0;
279
190
  return;
280
191
  }
281
- const c = S.value;
282
- _(c);
283
- }, W = (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
- }, N = D(() => ({
294
- onPointerdown: ue,
295
- onPointermove: A,
296
- onPointerup: $,
297
- onPointercancel: $,
298
- onContextmenu: W,
299
- onTouchmove: G
300
- })), ee = D(() => ({
301
- onPointerdown: J,
302
- onPointermove: se,
303
- onPointerup: U,
304
- onPointercancel: U,
305
- onContextmenu: W,
306
- onTouchmove: Z
307
- }));
308
- return {
309
- isDragging: T,
310
- preventContentScroll: S,
311
- headerFooterHandlers: N,
312
- contentWrapperHandlers: ee,
313
- scrollEnd: Q
314
- };
315
- }
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;
192
+ e.onSnapToPoint(e.closestSnapPointIndex.value), e.translateY.value = 0;
321
193
  };
322
194
  return {
323
- lock: n,
324
- unlock: i,
325
- lockIfBlocking: () => {
326
- a.value && n();
195
+ isDragging: o,
196
+ handleSheetScroll: C,
197
+ handlePointerDown: m,
198
+ handleContentPointerDown: k,
199
+ handlePointerMove: E,
200
+ handleContentPointerMove: B,
201
+ handleLostPointerCapture: (n, g) => {
202
+ o.value = !1, g === "header" ? e.sheetHeaderRef.value?.releasePointerCapture(n.pointerId) : g === "footer" ? e.sheetFooterRef.value?.releasePointerCapture(n.pointerId) : e.sheetContentRef.value?.releasePointerCapture(n.pointerId), h = 0, d = !1, i = !1, z();
327
203
  },
328
- unlockIfBlocking: () => {
329
- a.value && i();
330
- },
331
- touchStartHandler: () => {
332
- a.value || n();
333
- },
334
- touchEndHandler: () => {
335
- a.value || i();
204
+ handleTouchStart: (n) => {
205
+ d && n.preventDefault();
336
206
  }
337
207
  };
338
- }
339
- function Je(t) {
340
- const { sheetRef: a, backdropRef: u, blocking: e, onEscape: n } = t, i = P(null), r = Ae([a, u], {
208
+ };
209
+ function st(e) {
210
+ const { sheetRef: t, backdropRef: o, blocking: a, onEscape: l } = e, u = H(null), i = We([t, o], {
341
211
  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, {
212
+ fallbackFocus: () => t.value || document.body
213
+ }), v = (m) => {
214
+ m.key === "Escape" && l();
215
+ }, d = () => {
216
+ t.value && (u.value = new MutationObserver((m) => {
217
+ for (const k of m)
218
+ k.type === "attributes" && k.attributeName === "aria-expanded" && (k.target.getAttribute("aria-expanded") === "true" ? i.pause() : t.value?.querySelector('[aria-expanded="true"]') || i.unpause());
219
+ }), u.value.observe(t.value, {
350
220
  attributes: !0,
351
221
  attributeFilter: ["aria-expanded"],
352
222
  subtree: !0
353
223
  }));
354
- }, b = () => {
355
- i.value && (i.value.disconnect(), i.value = null);
224
+ }, h = () => {
225
+ u.value && (u.value.disconnect(), u.value = null);
356
226
  };
357
227
  return {
358
228
  activate: () => {
359
- e.value && (r.activate(), f()), window.addEventListener("keydown", p);
229
+ a.value && (i.activate(), d()), window.addEventListener("keydown", v);
360
230
  },
361
231
  deactivate: () => {
362
- window.removeEventListener("keydown", p), b(), e.value && r.deactivate();
232
+ window.removeEventListener("keydown", v), h(), a.value && i.deactivate();
363
233
  },
364
234
  cleanup: () => {
365
- b(), r.deactivate();
235
+ h(), i.deactivate();
366
236
  }
367
237
  };
368
238
  }
369
- const Ze = ["data-vsbs-shadow", "data-vsbs-sheet-show"], et = /* @__PURE__ */ ye({
239
+ function ut(e) {
240
+ const { blocking: t } = e, o = qe(document.documentElement), a = () => {
241
+ o.value = !0;
242
+ }, l = () => {
243
+ o.value = !1;
244
+ };
245
+ return {
246
+ lock: a,
247
+ unlock: l,
248
+ lockIfBlocking: () => {
249
+ t.value && a();
250
+ },
251
+ unlockIfBlocking: () => {
252
+ t.value && l();
253
+ },
254
+ touchStartHandler: () => {
255
+ t.value || a();
256
+ },
257
+ touchEndHandler: () => {
258
+ t.value || l();
259
+ }
260
+ };
261
+ }
262
+ function Te(e, t) {
263
+ const o = parseFloat(e);
264
+ return t * o / 100;
265
+ }
266
+ function it(e, t, o) {
267
+ const a = H(0), l = D(() => e.value.map((d) => typeof d == "string" ? Te(d, o.value) : d)), u = D(() => Math.min(...l.value)), i = D(() => Math.max(...l.value)), v = D(() => {
268
+ const d = l.value.reduce(
269
+ (h, p) => Math.abs(p - t.value) < Math.abs(h - t.value) ? p : h
270
+ );
271
+ return l.value.indexOf(d);
272
+ });
273
+ return {
274
+ currentSnapPointIndex: a,
275
+ flattenedSnapPoints: l,
276
+ minSnapPoint: u,
277
+ maxSnapPoint: i,
278
+ closestSnapPointIndex: v
279
+ };
280
+ }
281
+ function xe(e, t) {
282
+ return typeof e == "number" ? T(e, { max: t }) : Te(e, t);
283
+ }
284
+ const ct = ["data-vsbs-shadow", "data-vsbs-sheet-show"], dt = /* @__PURE__ */ Ae({
370
285
  __name: "BottomSheet",
371
286
  props: {
372
287
  duration: { default: 250 },
373
288
  snapPoints: {},
374
289
  initialSnapPoint: {},
375
290
  blocking: { type: Boolean, default: !0 },
291
+ forceMount: { type: Boolean, default: !1 },
376
292
  canSwipeClose: { type: Boolean, default: !0 },
377
293
  swipeCloseThreshold: {},
378
294
  canBackdropClose: { type: Boolean, default: !0 },
@@ -385,213 +301,259 @@ const Ze = ["data-vsbs-shadow", "data-vsbs-sheet-show"], et = /* @__PURE__ */ ye
385
301
  footerClass: {}
386
302
  },
387
303
  emits: ["opened", "opening-started", "closed", "closing-started", "dragging-up", "dragging-down", "snapped", "instinctHeight", "update:modelValue"],
388
- setup(t, { expose: a, emit: u }) {
389
- Ee((l) => ({
390
- v76198695: F.value
304
+ setup(e, { expose: t, emit: o }) {
305
+ Fe((s) => ({
306
+ v5acd7ef8: b.value
391
307
  }));
392
- const e = t, n = u, i = Re(e, "modelValue", n, {
308
+ const a = e, l = o, u = Ke(a, "modelValue", l, {
393
309
  passive: !0
394
310
  });
395
- te(i, (l) => {
396
- l ? Q() : N();
397
- }), De(() => {
398
- i.value && Q();
311
+ A(u, (s) => {
312
+ s ? j() : L();
313
+ }), A(u, async (s) => {
314
+ if (!s) {
315
+ C.value = 0;
316
+ return;
317
+ }
318
+ await _(), Y();
319
+ }), $e(() => {
320
+ He(), u.value && j();
399
321
  });
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: V } = He(e), k = D(() => V.value ?? [R.value]), {
406
- flattenedSnapPoints: M,
407
- currentSnapPointIndex: B,
408
- closestSnapPointIndex: S,
409
- minSnapPoint: O,
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: () => N()
416
- }), { isDragging: re, headerFooterHandlers: J, contentWrapperHandlers: se, scrollEnd: U } = Ke({
417
- sheetRef: r,
418
- sheetScrollRef: b,
419
- height: H,
420
- translateY: T,
421
- sheetHeight: g,
422
- windowHeight: h,
423
- snapPointsRef: k,
424
- flattenedSnapPoints: M,
425
- currentSnapPointIndex: B,
426
- closestSnapPointIndex: S,
427
- minSnapPoint: O,
428
- maxSnapPoint: K,
429
- canSwipeClose: le,
430
- swipeCloseThreshold: _,
431
- expandOnContentDrag: ue,
432
- onClose: () => N(),
433
- onSnapped: (l) => n("snapped", l),
434
- onDraggingUp: () => n("dragging-up"),
435
- onDraggingDown: () => n("dragging-down")
436
- }), W = P(!1), G = P(!1), Z = () => {
437
- e.canBackdropClose && N();
438
- }, Q = async () => {
439
- if (W.value) return;
440
- i.value = !0, W.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]"), Y = l.querySelector("[data-vsbs-footer]");
444
- if (oe(
445
- m.getBoundingClientRect().height,
446
- s.getBoundingClientRect().height,
447
- Y.getBoundingClientRect().height
448
- ), await fe(), B.value = M.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) {
322
+ const i = y(null), v = y(null), d = y(null), h = y(null), p = y(null), P = y(null), C = H(0), { height: m } = Ue(), { height: k } = U(i), { height: E } = U(v), { height: M } = U(p), { height: B } = U(d), z = D(() => T(
323
+ Math.ceil(M.value + E.value + B.value),
324
+ { max: m.value }
325
+ )), ae = (s, r, c) => {
326
+ E.value = s, M.value = r, B.value = c;
327
+ }, x = H(0), n = H(0), g = D(() => T(x.value + C.value, {
328
+ max: m.value
329
+ })), b = D(() => a.duration + "ms"), w = F(() => a.snapPoints), S = D(() => w.value ?? [z.value]), {
330
+ flattenedSnapPoints: N,
331
+ currentSnapPointIndex: R,
332
+ closestSnapPointIndex: Ee,
333
+ minSnapPoint: W,
334
+ maxSnapPoint: Ye
335
+ } = it(S, x, m), oe = F(() => a.blocking), De = F(() => a.canSwipeClose), Me = F(() => a.swipeCloseThreshold), Re = F(() => a.expandOnContentDrag), I = ut({ blocking: oe }), G = st({
336
+ sheetRef: i,
337
+ backdropRef: P,
338
+ blocking: oe,
339
+ onEscape: () => L()
340
+ }), Q = y(!1), X = y(!1), Ie = () => {
341
+ a.canBackdropClose && L();
342
+ }, Y = () => {
343
+ const s = window.visualViewport;
344
+ if (!s || !u.value) {
345
+ C.value = 0;
346
+ return;
347
+ }
348
+ const r = Math.max(0, window.innerHeight - s.height - s.offsetTop);
349
+ C.value = Math.round(r);
350
+ };
351
+ let re = null;
352
+ const He = () => {
353
+ const s = window.visualViewport;
354
+ s && (s.addEventListener("resize", Y), s.addEventListener("scroll", Y), window.addEventListener("resize", Y), re = () => {
355
+ s.removeEventListener("resize", Y), s.removeEventListener("scroll", Y), window.removeEventListener("resize", Y);
356
+ });
357
+ }, j = async () => {
358
+ if (Q.value) return;
359
+ u.value = !0, Q.value = !0, l("opening-started"), I.lockIfBlocking(), await _(), Y();
360
+ const s = i.value;
361
+ k.value = s.getBoundingClientRect().height;
362
+ const r = s.querySelector("[data-vsbs-content]"), c = s.querySelector("[data-vsbs-header]"), K = s.querySelector("[data-vsbs-footer]");
363
+ if (ae(
364
+ c.getBoundingClientRect().height,
365
+ r.getBoundingClientRect().height,
366
+ K.getBoundingClientRect().height
367
+ ), await _(), R.value = N.value.findIndex(
368
+ (O) => O === W.value
369
+ ), a.initialSnapPoint !== void 0) {
370
+ const O = a.initialSnapPoint;
371
+ if (O < 0 || O >= S.value.length) {
453
372
  console.warn("Index out of bounds");
454
373
  return;
455
374
  }
456
- const L = k.value[y];
457
- if (!L) return;
458
- H.value = ae(L, h.value);
375
+ const de = S.value[O];
376
+ if (!de) return;
377
+ x.value = xe(de, m.value);
459
378
  } else
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
- }), W.value = !1;
466
- }, N = () => {
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) {
379
+ x.value = T(W.value, { max: m.value });
380
+ n.value = x.value, requestAnimationFrame(() => {
381
+ n.value = 0, a.blocking && setTimeout(() => {
382
+ u.value && (l("opened"), G.activate());
383
+ }, a.duration);
384
+ }), Q.value = !1;
385
+ }, L = () => {
386
+ X.value || (u.value = !1, X.value = !0, l("closing-started"), I.unlockIfBlocking(), G.deactivate(), n.value = x.value, setTimeout(() => {
387
+ l("closed"), X.value = !1;
388
+ }, a.duration));
389
+ }, J = (s) => {
390
+ if (!S.value) return;
391
+ if (s < 0 || s >= S.value.length) {
473
392
  console.warn("Index out of bounds");
474
393
  return;
475
394
  }
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
395
+ R.value = s;
396
+ const r = S.value[s];
397
+ r && (x.value = xe(r, m.value), l("snapped", S.value.indexOf(r)));
398
+ }, {
399
+ isDragging: Be,
400
+ handleSheetScroll: le,
401
+ handlePointerDown: se,
402
+ handleContentPointerDown: ue,
403
+ handlePointerMove: q,
404
+ handleContentPointerMove: ie,
405
+ handleLostPointerCapture: Z,
406
+ handleTouchStart: ce
407
+ } = lt({
408
+ sheetHeaderRef: v,
409
+ sheetFooterRef: d,
410
+ sheetContentRef: p,
411
+ sheetScrollRef: h,
412
+ height: x,
413
+ translateY: n,
414
+ minSnapPoint: W,
415
+ maxSnapPoint: Ye,
416
+ closestSnapPointIndex: Ee,
417
+ flattenedSnapPoints: N,
418
+ canSwipeClose: De,
419
+ expandOnContentDrag: Re,
420
+ swipeCloseThreshold: Me,
421
+ onClose: L,
422
+ onSnapToPoint: J,
423
+ onDraggingUp: () => l("dragging-up"),
424
+ onDraggingDown: () => l("dragging-down")
425
+ }), Le = Je((s) => J(s), {
426
+ minQuietPeriodMs: a.duration,
427
+ reducer: (s, r) => r
482
428
  });
483
- te(k, (l, s) => {
484
- if (i.value === !1 || !l || !s) return;
485
- const m = l[B.value], Y = s[B.value];
486
- !m || typeof m == "string" || !Y || typeof Y == "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();
429
+ A(S, (s, r) => {
430
+ if (u.value === !1 || !s || !r) return;
431
+ const c = s[R.value], K = r[R.value];
432
+ !c || typeof c == "string" || !K || typeof K == "string" || (x.value = T(c, { max: m.value }));
433
+ }), A(m, () => {
434
+ Le.call(R.value);
435
+ }), A(z, (s) => {
436
+ l("instinctHeight", s);
437
+ }), Ve(() => {
438
+ re?.(), G.cleanup();
493
439
  });
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)`;
440
+ const Oe = (s) => {
441
+ const r = s;
442
+ r.style.transition = `transform ${a.duration}ms ease, height ${a.duration}ms ease`, r.style.transform = `translateY(${g.value}px)`;
497
443
  };
498
- return a({ open: Q, close: N, snapToPoint: ee }), (l, s) => (X(), ie(Ie, null, [
499
- (X(), pe(he, {
500
- to: t.teleportTo,
501
- defer: t.teleportDefer
444
+ return t({ open: j, close: L, snapToPoint: J }), (s, r) => ($(), ee(ze, null, [
445
+ ($(), fe(ve, {
446
+ to: e.teleportTo,
447
+ defer: e.teleportDefer
502
448
  }, [
503
- ge(me, { name: "vsbs-backdrop" }, {
504
- default: Se(() => [
505
- E(i) && t.blocking ? (X(), ie("div", {
506
- key: 0,
507
- ref_key: "backdrop",
508
- ref: d,
509
- "data-vsbs-backdrop": "",
510
- onClick: s[0] || (s[0] = (m) => Z())
511
- }, null, 512)) : be("", !0)
512
- ]),
513
- _: 1
514
- })
449
+ V("div", null, [
450
+ he(ge, { name: "vsbs-backdrop" }, {
451
+ default: me(() => [
452
+ e.forceMount || f(u) && e.blocking ? pe(($(), ee("div", {
453
+ key: 0,
454
+ ref_key: "backdrop",
455
+ ref: P,
456
+ "data-vsbs-backdrop": "",
457
+ onClick: r[0] || (r[0] = (c) => Ie())
458
+ }, null, 512)), [
459
+ [Se, f(u) && e.blocking]
460
+ ]) : be("", !0)
461
+ ]),
462
+ _: 1
463
+ })
464
+ ])
515
465
  ], 8, ["to", "defer"])),
516
- (X(), pe(he, {
517
- to: t.teleportTo,
518
- defer: t.teleportDefer
466
+ ($(), fe(ve, {
467
+ to: e.teleportTo,
468
+ defer: e.teleportDefer
519
469
  }, [
520
- ge(me, {
470
+ he(ge, {
521
471
  name: "vsbs-sheet",
522
- onLeave: c
472
+ onLeave: Oe
523
473
  }, {
524
- default: Se(() => [
525
- E(i) ? (X(), ie("div", {
474
+ default: me(() => [
475
+ e.forceMount || f(u) ? pe(($(), ee("div", {
526
476
  key: 0,
527
477
  ref_key: "sheet",
528
- ref: r,
529
- style: Me({
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`
478
+ ref: i,
479
+ style: Ne({
480
+ transform: `translateY(${n.value}px)`,
481
+ height: `${g.value}px`,
482
+ paddingBottom: `${C.value}px`,
483
+ transition: f(Be) ? "none" : `transform ${e.duration}ms ease, height ${e.duration}ms ease`
533
484
  }),
534
- "data-vsbs-shadow": !t.blocking,
535
- "data-vsbs-sheet-show": E(i),
485
+ "data-vsbs-shadow": !e.blocking,
486
+ "data-vsbs-sheet-show": f(u),
536
487
  "aria-modal": "true",
537
488
  "data-vsbs-sheet": "",
538
489
  tabindex: "-1",
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))
490
+ onTouchstart: r[12] || (r[12] = //@ts-ignore
491
+ (...c) => f(I).touchStartHandler && f(I).touchStartHandler(...c)),
492
+ onTouchend: r[13] || (r[13] = //@ts-ignore
493
+ (...c) => f(I).touchEndHandler && f(I).touchEndHandler(...c))
543
494
  }, [
544
- j("div", ce({
495
+ V("div", {
545
496
  ref_key: "sheetHeader",
546
- ref: p,
547
- "data-vsbs-header": ""
548
- }, E(J), {
549
- class: t.headerClass,
550
- style: { "touch-action": "none" }
551
- }), [
552
- ve(l.$slots, "header", {}, void 0, !0)
553
- ], 16),
554
- j("div", {
497
+ ref: v,
498
+ "data-vsbs-header": "",
499
+ class: te(e.headerClass),
500
+ onPointerdown: r[1] || (r[1] = (c) => f(se)(c, "header")),
501
+ onPointermove: r[2] || (r[2] = //@ts-ignore
502
+ (...c) => f(q) && f(q)(...c)),
503
+ onLostpointercapture: r[3] || (r[3] = (c) => f(Z)(c, "header"))
504
+ }, [
505
+ ne(s.$slots, "header", {}, void 0, !0)
506
+ ], 34),
507
+ V("div", {
555
508
  ref_key: "sheetScroll",
556
- ref: b,
509
+ ref: h,
557
510
  "data-vsbs-scroll": "",
558
- onScrollend: s[1] || (s[1] = //@ts-ignore
559
- (...m) => E(U) && E(U)(...m))
511
+ onTouchstart: r[4] || (r[4] = //@ts-ignore
512
+ (...c) => f(ce) && f(ce)(...c)),
513
+ onTouchmove: r[5] || (r[5] = //@ts-ignore
514
+ (...c) => f(le) && f(le)(...c)),
515
+ onPointerdown: r[6] || (r[6] = //@ts-ignore
516
+ (...c) => f(ue) && f(ue)(...c)),
517
+ onPointermove: r[7] || (r[7] = //@ts-ignore
518
+ (...c) => f(ie) && f(ie)(...c)),
519
+ onLostpointercapture: r[8] || (r[8] = (c) => f(Z)(c, "content"))
560
520
  }, [
561
- j("div", ce({ "data-vsbs-content-wrapper": "" }, E(se), { style: { touchAction: "pan-y" } }), [
562
- j("div", {
563
- ref_key: "sheetContent",
564
- ref: v,
565
- "data-vsbs-content": "",
566
- class: Ye(t.contentClass)
567
- }, [
568
- ve(l.$slots, "default", {}, void 0, !0)
569
- ], 2)
570
- ], 16)
521
+ V("div", {
522
+ ref_key: "sheetContent",
523
+ ref: p,
524
+ "data-vsbs-content": "",
525
+ class: te(e.contentClass)
526
+ }, [
527
+ ne(s.$slots, "default", {}, void 0, !0)
528
+ ], 2)
571
529
  ], 544),
572
- j("div", ce({
530
+ V("div", {
573
531
  ref_key: "sheetFooter",
574
- ref: f,
575
- "data-vsbs-footer": ""
576
- }, E(J), {
577
- class: t.footerClass,
578
- style: { "touch-action": "none" }
579
- }), [
580
- ve(l.$slots, "footer", {}, void 0, !0)
581
- ], 16)
582
- ], 44, Ze)) : be("", !0)
532
+ ref: d,
533
+ "data-vsbs-footer": "",
534
+ class: te(e.footerClass),
535
+ onPointerdown: r[9] || (r[9] = (c) => f(se)(c, "footer")),
536
+ onPointermove: r[10] || (r[10] = //@ts-ignore
537
+ (...c) => f(q) && f(q)(...c)),
538
+ onLostpointercapture: r[11] || (r[11] = (c) => f(Z)(c, "footer"))
539
+ }, [
540
+ ne(s.$slots, "footer", {}, void 0, !0)
541
+ ], 34)
542
+ ], 44, ct)), [
543
+ [Se, f(u)]
544
+ ]) : be("", !0)
583
545
  ]),
584
546
  _: 3
585
547
  })
586
548
  ], 8, ["to", "defer"]))
587
549
  ], 64));
588
550
  }
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-533b8a6d"]]);
551
+ }), ft = (e, t) => {
552
+ const o = e.__vccOpts || e;
553
+ for (const [a, l] of t)
554
+ o[a] = l;
555
+ return o;
556
+ }, mt = /* @__PURE__ */ ft(dt, [["__scopeId", "data-v-1fe5991a"]]);
595
557
  export {
596
- lt as default
558
+ mt as default
597
559
  };
package/dist/style.css CHANGED
@@ -1 +1 @@
1
- [data-vsbs-backdrop][data-v-533b8a6d]{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(--v76198695)}[data-vsbs-shadow=true][data-v-533b8a6d]: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-533b8a6d]{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-533b8a6d]{visibility:visible}[data-vsbs-header][data-v-533b8a6d]{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-533b8a6d]: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-533b8a6d]:empty{box-shadow:none;padding:14px var(--vsbs-padding-x, 16px) 10px}[data-vsbs-footer][data-v-533b8a6d]{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-533b8a6d]:empty{display:none}[data-vsbs-scroll][data-v-533b8a6d]{flex-grow:1;overflow-y:auto;overscroll-behavior:none}[data-vsbs-content-wrapper][data-v-533b8a6d]{height:100%}[data-vsbs-content][data-v-533b8a6d]{display:grid;padding:8px var(--vsbs-padding-x, 16px);-webkit-user-select:none;user-select:none}.vsbs-backdrop-enter-active[data-v-533b8a6d],.vsbs-backdrop-leave-active[data-v-533b8a6d]{transition:opacity var(--vsbs-duration) ease}.vsbs-backdrop-enter-from[data-v-533b8a6d],.vsbs-backdrop-leave-to[data-v-533b8a6d]{opacity:0}
1
+ [data-vsbs-backdrop][data-v-1fe5991a]{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(--v5acd7ef8)}[data-vsbs-shadow=true][data-v-1fe5991a]: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-1fe5991a]{background-color:var(--vsbs-background, #fff);box-sizing:border-box;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-1fe5991a]{visibility:visible}[data-vsbs-header][data-v-1fe5991a]{touch-action:none;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-1fe5991a]: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-1fe5991a]:empty{box-shadow:none;padding:14px var(--vsbs-padding-x, 16px) 10px}[data-vsbs-footer][data-v-1fe5991a]{touch-action:none;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-1fe5991a]:empty{display:none}[data-vsbs-scroll][data-v-1fe5991a]{flex-grow:1;overflow-y:auto;overscroll-behavior:none}[data-vsbs-content][data-v-1fe5991a]{display:grid;padding:8px var(--vsbs-padding-x, 16px);-webkit-user-select:none;user-select:none}.vsbs-backdrop-enter-active[data-v-1fe5991a],.vsbs-backdrop-leave-active[data-v-1fe5991a]{transition:opacity var(--vsbs-duration) ease}.vsbs-backdrop-enter-from[data-v-1fe5991a],.vsbs-backdrop-leave-to[data-v-1fe5991a]{opacity:0}
package/dist/types.d.ts CHANGED
@@ -4,6 +4,7 @@ export interface BottomSheetProps {
4
4
  snapPoints?: Array<number | `${number}%`>;
5
5
  initialSnapPoint?: number;
6
6
  blocking?: boolean;
7
+ forceMount?: boolean;
7
8
  canSwipeClose?: boolean;
8
9
  swipeCloseThreshold?: string | number;
9
10
  canBackdropClose?: boolean;
@@ -1,5 +1,3 @@
1
1
  export declare const SNAP_POINT_TOLERANCE_PX = 10;
2
2
  export declare const MOVEMENT_THRESHOLD_PX = 3;
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 @@
1
+ export declare function isInteractable(element: Element): boolean;
package/package.json CHANGED
@@ -30,7 +30,7 @@
30
30
  "url": "https://github.com/megaarmos/vue-spring-bottom-sheet/issues"
31
31
  },
32
32
  "private": false,
33
- "version": "3.0.0",
33
+ "version": "3.2.0",
34
34
  "type": "module",
35
35
  "exports": {
36
36
  ".": {