@maas/vue-equipment 0.14.4 → 0.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/nuxt/module.json +1 -1
- package/dist/plugins/MagicDrawer/src/components/MagicDrawer.vue +49 -34
- package/dist/plugins/MagicDrawer/src/composables/private/useDrawerDrag.d.ts +6 -0
- package/dist/plugins/MagicDrawer/src/composables/private/useDrawerDrag.mjs +211 -49
- package/dist/plugins/MagicDrawer/src/composables/private/useDrawerSnap.d.ts +22 -0
- package/dist/plugins/MagicDrawer/src/composables/private/useDrawerSnap.mjs +138 -0
- package/dist/plugins/MagicDrawer/src/types/index.d.ts +4 -0
- package/dist/plugins/MagicDrawer/src/utils/defaultOptions.mjs +5 -2
- package/dist/plugins/MagicScroll/src/components/MagicScrollMotion.vue +1 -1
- package/dist/utils/index.js +13 -18
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/index.mjs +13 -18
- package/dist/utils/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/nuxt/module.json
CHANGED
|
@@ -24,13 +24,13 @@
|
|
|
24
24
|
<div
|
|
25
25
|
v-show="innerActive"
|
|
26
26
|
class="magic-drawer__backdrop"
|
|
27
|
-
@click.self="
|
|
27
|
+
@click.self="closeIfAllowed"
|
|
28
28
|
>
|
|
29
29
|
<slot name="backdrop" />
|
|
30
30
|
</div>
|
|
31
31
|
</transition>
|
|
32
32
|
|
|
33
|
-
<div class="magic-drawer__wrapper">
|
|
33
|
+
<div class="magic-drawer__wrapper" ref="wrapperRef">
|
|
34
34
|
<transition
|
|
35
35
|
:name="contentTransition"
|
|
36
36
|
@before-leave="onBeforeLeave"
|
|
@@ -40,20 +40,21 @@
|
|
|
40
40
|
@enter="onEnter"
|
|
41
41
|
@after-enter="onAfterEnter"
|
|
42
42
|
>
|
|
43
|
-
<div
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
43
|
+
<div v-show="innerActive" class="magic-drawer__content">
|
|
44
|
+
<div
|
|
45
|
+
ref="elRef"
|
|
46
|
+
class="magic-drawer__drag"
|
|
47
|
+
:style="style"
|
|
48
|
+
@pointerdown="onPointerdown"
|
|
49
|
+
>
|
|
50
|
+
<component
|
|
51
|
+
v-if="component"
|
|
52
|
+
v-bind="props"
|
|
53
|
+
:is="component"
|
|
54
|
+
@close="closeIfAllowed"
|
|
55
|
+
/>
|
|
56
|
+
<slot v-else />
|
|
57
|
+
</div>
|
|
57
58
|
</div>
|
|
58
59
|
</transition>
|
|
59
60
|
</div>
|
|
@@ -94,9 +95,9 @@ import '@maas/vue-equipment/utils/css/animations/slide-rtl-out.css'
|
|
|
94
95
|
import '@maas/vue-equipment/utils/css/animations/slide-ttb-out.css'
|
|
95
96
|
import '@maas/vue-equipment/utils/css/animations/slide-btt-out.css'
|
|
96
97
|
|
|
97
|
-
// Prevent
|
|
98
|
+
// Prevent deep merge of certain options
|
|
98
99
|
const customDefu = createDefu((obj, key, value) => {
|
|
99
|
-
if (key === 'keys') {
|
|
100
|
+
if (key === 'keys' || key === 'snapPoints') {
|
|
100
101
|
obj[key] = value
|
|
101
102
|
return true
|
|
102
103
|
}
|
|
@@ -116,6 +117,7 @@ const props = withDefaults(defineProps<MagicDrawerProps>(), {
|
|
|
116
117
|
|
|
117
118
|
const elRef = ref<HTMLDivElement | undefined>(undefined)
|
|
118
119
|
const drawerRef = ref<HTMLElement | undefined>(undefined)
|
|
120
|
+
const wrapperRef = ref<HTMLDivElement | undefined>(undefined)
|
|
119
121
|
const drawerApi = useDrawerApi(props.id, { focusTarget: drawerRef })
|
|
120
122
|
|
|
121
123
|
const mappedOptions: typeof defaultOptions = customDefu(
|
|
@@ -124,7 +126,7 @@ const mappedOptions: typeof defaultOptions = customDefu(
|
|
|
124
126
|
)
|
|
125
127
|
|
|
126
128
|
const overshoot = ref(0)
|
|
127
|
-
const { position, threshold } = mappedOptions
|
|
129
|
+
const { position, threshold, snapPoints, snapPoint, canClose } = mappedOptions
|
|
128
130
|
|
|
129
131
|
const {
|
|
130
132
|
isActive,
|
|
@@ -139,10 +141,14 @@ const {
|
|
|
139
141
|
} = drawerApi
|
|
140
142
|
|
|
141
143
|
const { onPointerdown, dragging, style } = useDrawerDrag({
|
|
144
|
+
elRef,
|
|
145
|
+
wrapperRef,
|
|
142
146
|
position,
|
|
143
147
|
threshold,
|
|
144
148
|
overshoot,
|
|
145
|
-
|
|
149
|
+
snapPoints,
|
|
150
|
+
snapPoint,
|
|
151
|
+
canClose,
|
|
146
152
|
close,
|
|
147
153
|
})
|
|
148
154
|
|
|
@@ -193,17 +199,7 @@ const contentTransition = computed(() => {
|
|
|
193
199
|
: mappedOptions.transitions?.content
|
|
194
200
|
})
|
|
195
201
|
|
|
196
|
-
//
|
|
197
|
-
async function onOpen() {
|
|
198
|
-
wrapperActive.value = true
|
|
199
|
-
await nextTick()
|
|
200
|
-
innerActive.value = true
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
function onClose() {
|
|
204
|
-
innerActive.value = false
|
|
205
|
-
}
|
|
206
|
-
|
|
202
|
+
// Private functions
|
|
207
203
|
function convertToPixels(value: string) {
|
|
208
204
|
const regex = /^(\d*\.?\d+)\s*(rem|px)$/
|
|
209
205
|
|
|
@@ -229,6 +225,23 @@ function convertToPixels(value: string) {
|
|
|
229
225
|
}
|
|
230
226
|
}
|
|
231
227
|
|
|
228
|
+
async function onOpen() {
|
|
229
|
+
wrapperActive.value = true
|
|
230
|
+
await nextTick()
|
|
231
|
+
innerActive.value = true
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
function onClose() {
|
|
235
|
+
innerActive.value = false
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Public functions
|
|
239
|
+
function closeIfAllowed() {
|
|
240
|
+
if (canClose) {
|
|
241
|
+
close()
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
232
245
|
function saveOvershoot() {
|
|
233
246
|
const element = unrefElement(drawerRef)
|
|
234
247
|
const overshootVar = getComputedStyle(element!).getPropertyValue(
|
|
@@ -238,7 +251,8 @@ function saveOvershoot() {
|
|
|
238
251
|
overshoot.value = convertToPixels(overshootVar) || 0
|
|
239
252
|
}
|
|
240
253
|
|
|
241
|
-
|
|
254
|
+
// Lifecycle hooks and listeners
|
|
255
|
+
if (mappedOptions.keys && canClose) {
|
|
242
256
|
for (const key of mappedOptions.keys) {
|
|
243
257
|
onKeyStroke(key, (e) => {
|
|
244
258
|
e.preventDefault()
|
|
@@ -260,7 +274,8 @@ watch(innerActive, () => {
|
|
|
260
274
|
saveOvershoot()
|
|
261
275
|
})
|
|
262
276
|
|
|
263
|
-
onBeforeMount(() => {
|
|
277
|
+
onBeforeMount(async () => {
|
|
278
|
+
// Force open
|
|
264
279
|
if (mappedOptions.beforeMount.open) {
|
|
265
280
|
open()
|
|
266
281
|
}
|
|
@@ -273,5 +288,5 @@ onBeforeUnmount(() => {
|
|
|
273
288
|
</script>
|
|
274
289
|
|
|
275
290
|
<style>
|
|
276
|
-
:root{--magic-drawer-z-index:999;--magic-drawer-justify-content:center;--magic-drawer-align-items:flex-end;--magic-drawer-backdrop-color:rgba(0,0,0,.5);--magic-drawer-backdrop-filter:unset;--magic-drawer-content-overflow-y:auto;--magic-drawer-handle-wrapper-height:2rem;--magic-drawer-handle-width:3rem;--magic-drawer-handle-height:0.375rem;--magic-drawer-handle-color:#d4d4d8;--magic-drawer-handle-border-radius:0.25rem;--magic-drawer-enter-animation:slide-btt-in 300ms ease;--magic-drawer-leave-animation:slide-btt-out 300ms ease;--magic-drawer-drag-overshoot:4rem;--magic-drawer-drag-overshoot-x:0;--magic-drawer-drag-overshoot-y:0}.magic-drawer{align-items:var(--magic-drawer-align-items);background:transparent;border:none;color:inherit;display:flex;height:100%;inset:0;justify-content:var(--magic-drawer-justify-content);padding:0;position:fixed;width:100%;z-index:var(--magic-drawer-z-index)}.magic-drawer.-bottom{--magic-drawer-drag-overshoot-y:var(--magic-drawer-drag-overshoot)}.magic-drawer.-top{--magic-drawer-enter-animation:slide-ttb-in 300ms ease;--magic-drawer-leave-animation:slide-ttb-out 300ms ease;--magic-drawer-align-items:flex-start;--magic-drawer-drag-overshoot-y:calc(var(--magic-drawer-drag-overshoot)*-1)}.magic-drawer.-right{--magic-drawer-enter-animation:slide-rtl-in 300ms ease;--magic-drawer-leave-animation:slide-rtl-out 300ms ease;--magic-drawer-align-items:center;--magic-drawer-justify-content:flex-end;--magic-drawer-drag-overshoot-x:var(--magic-drawer-drag-overshoot)}.magic-drawer.-left{--magic-drawer-enter-animation:slide-ltr-in 300ms ease;--magic-drawer-leave-animation:slide-ltr-out 300ms ease;--magic-drawer-align-items:center;--magic-drawer-justify-content:flex-start;--magic-drawer-drag-overshoot-x:calc(var(--magic-drawer-drag-overshoot)*-1)}.magic-drawer__wrapper{transform:translate(var(--magic-drawer-drag-overshoot-x),var(--magic-drawer-drag-overshoot-y));width:100%}.magic-drawer__content{-webkit-overflow-scrolling:touch;align-items:var(--magic-drawer-align-items);cursor:grab;display:flex;justify-content:var(--magic-drawer-justify-content);
|
|
291
|
+
:root{--magic-drawer-height:75svh;--magic-drawer-z-index:999;--magic-drawer-justify-content:center;--magic-drawer-align-items:flex-end;--magic-drawer-backdrop-color:rgba(0,0,0,.5);--magic-drawer-backdrop-filter:unset;--magic-drawer-content-overflow-y:auto;--magic-drawer-handle-wrapper-height:2rem;--magic-drawer-handle-width:3rem;--magic-drawer-handle-height:0.375rem;--magic-drawer-handle-color:#d4d4d8;--magic-drawer-handle-border-radius:0.25rem;--magic-drawer-enter-animation:slide-btt-in 300ms ease;--magic-drawer-leave-animation:slide-btt-out 300ms ease;--magic-drawer-drag-overshoot:4rem;--magic-drawer-drag-overshoot-x:0;--magic-drawer-drag-overshoot-y:0}.magic-drawer{align-items:var(--magic-drawer-align-items);background:transparent;border:none;color:inherit;display:flex;height:100%;inset:0;justify-content:var(--magic-drawer-justify-content);padding:0;position:fixed;width:100%;z-index:var(--magic-drawer-z-index)}.magic-drawer.-bottom{--magic-drawer-drag-overshoot-y:var(--magic-drawer-drag-overshoot)}.magic-drawer.-top{--magic-drawer-enter-animation:slide-ttb-in 300ms ease;--magic-drawer-leave-animation:slide-ttb-out 300ms ease;--magic-drawer-align-items:flex-start;--magic-drawer-drag-overshoot-y:calc(var(--magic-drawer-drag-overshoot)*-1)}.magic-drawer.-right{--magic-drawer-enter-animation:slide-rtl-in 300ms ease;--magic-drawer-leave-animation:slide-rtl-out 300ms ease;--magic-drawer-align-items:center;--magic-drawer-justify-content:flex-end;--magic-drawer-drag-overshoot-x:var(--magic-drawer-drag-overshoot)}.magic-drawer.-left{--magic-drawer-enter-animation:slide-ltr-in 300ms ease;--magic-drawer-leave-animation:slide-ltr-out 300ms ease;--magic-drawer-align-items:center;--magic-drawer-justify-content:flex-start;--magic-drawer-drag-overshoot-x:calc(var(--magic-drawer-drag-overshoot)*-1)}.magic-drawer__wrapper{height:calc(var(--magic-drawer-height) + var(--magic-drawer-drag-overshoot));pointer-events:none;transform:translate(var(--magic-drawer-drag-overshoot-x),var(--magic-drawer-drag-overshoot-y));width:100%}.magic-drawer__content{height:100%;max-height:100%;position:relative;width:100%}.magic-drawer__drag{-webkit-overflow-scrolling:touch;align-items:var(--magic-drawer-align-items);cursor:grab;display:flex;height:100%;justify-content:var(--magic-drawer-justify-content);overflow-y:var(--magic-drawer-content-overflow-y);pointer-events:auto;position:relative;scroll-behavior:smooth;width:100%}.magic-drawer.-dragging .magic-drawer__content{cursor:grabbing}.magic-drawer__backdrop{-webkit-backdrop-filter:var(--magic-drawer-backdrop-filter);backdrop-filter:var(--magic-drawer-backdrop-filter);background-color:var(--magic-drawer-backdrop-color);bottom:0;height:100%;left:0;position:fixed;right:0;top:0;width:100%;z-index:-1}.magic-drawer--content-enter-active{animation:var(--magic-drawer-enter-animation)}.magic-drawer--content-leave-active{animation:var(--magic-drawer-leave-animation)}.magic-drawer--backdrop-enter-active{animation:fade-in .3s ease}.magic-drawer--backdrop-leave-active{animation:fade-out .3s ease}
|
|
277
292
|
</style>
|
|
@@ -2,13 +2,19 @@ import { type MaybeRef } from 'vue';
|
|
|
2
2
|
import { type DefaultOptions } from '../../utils/defaultOptions.js';
|
|
3
3
|
type UseDrawerDragArgs = {
|
|
4
4
|
elRef: MaybeRef<HTMLDivElement | undefined>;
|
|
5
|
+
wrapperRef: MaybeRef<HTMLDivElement | undefined>;
|
|
5
6
|
position: MaybeRef<DefaultOptions['position']>;
|
|
6
7
|
threshold: MaybeRef<DefaultOptions['threshold']>;
|
|
8
|
+
snapPoints: MaybeRef<DefaultOptions['snapPoints']>;
|
|
9
|
+
snapPoint: MaybeRef<DefaultOptions['snapPoint']>;
|
|
10
|
+
canClose: MaybeRef<DefaultOptions['canClose']>;
|
|
7
11
|
overshoot: MaybeRef<number>;
|
|
8
12
|
close: () => void;
|
|
9
13
|
};
|
|
10
14
|
export declare function useDrawerDrag(args: UseDrawerDragArgs): {
|
|
11
15
|
style: import("vue").ComputedRef<string>;
|
|
16
|
+
draggedX: import("vue").Ref<number>;
|
|
17
|
+
draggedY: import("vue").Ref<number>;
|
|
12
18
|
dragging: import("vue").Ref<boolean>;
|
|
13
19
|
onPointerdown: (e: PointerEvent) => void;
|
|
14
20
|
};
|
|
@@ -4,75 +4,176 @@ import {
|
|
|
4
4
|
onMounted,
|
|
5
5
|
watch,
|
|
6
6
|
onBeforeUnmount,
|
|
7
|
-
toValue
|
|
7
|
+
toValue,
|
|
8
|
+
nextTick
|
|
8
9
|
} from "vue";
|
|
9
10
|
import { useEventListener, unrefElement } from "@vueuse/core";
|
|
10
11
|
import { interpolate } from "@maas/vue-equipment/utils";
|
|
11
12
|
import { useDrawerEmitter } from "../useDrawerEmitter.mjs";
|
|
13
|
+
import { useDrawerSnap } from "./useDrawerSnap.mjs";
|
|
12
14
|
export function useDrawerDrag(args) {
|
|
13
|
-
const {
|
|
15
|
+
const {
|
|
16
|
+
elRef,
|
|
17
|
+
wrapperRef,
|
|
18
|
+
snapPoints,
|
|
19
|
+
position,
|
|
20
|
+
overshoot,
|
|
21
|
+
threshold,
|
|
22
|
+
snapPoint,
|
|
23
|
+
canClose,
|
|
24
|
+
close
|
|
25
|
+
} = args;
|
|
26
|
+
const elRect = ref(void 0);
|
|
27
|
+
const wrapperRect = ref(void 0);
|
|
28
|
+
const { findClosestSnapPoint, mapSnapPoint, drawerHeight, drawerWidth } = useDrawerSnap({
|
|
29
|
+
wrapperRect,
|
|
30
|
+
snapPoints,
|
|
31
|
+
canClose,
|
|
32
|
+
position,
|
|
33
|
+
overshoot
|
|
34
|
+
});
|
|
14
35
|
const dragStart = ref(void 0);
|
|
15
|
-
const originX = ref(0);
|
|
16
|
-
const originY = ref(0);
|
|
17
36
|
const dragging = ref(false);
|
|
18
37
|
const shouldClose = ref(false);
|
|
19
|
-
const
|
|
38
|
+
const interpolateTo = ref(void 0);
|
|
39
|
+
let cancelPointerup = void 0;
|
|
20
40
|
let cancelPointermove = void 0;
|
|
41
|
+
const originX = ref(0);
|
|
42
|
+
const originY = ref(0);
|
|
43
|
+
const snappedY = ref(0);
|
|
44
|
+
const snappedX = ref(0);
|
|
45
|
+
const directionY = ref("absolute");
|
|
46
|
+
const directionX = ref("absolute");
|
|
47
|
+
const hasSnapPoints = computed(() => toValue(snapPoints).length > 1);
|
|
21
48
|
const draggedX = ref(0);
|
|
22
49
|
const draggedY = ref(0);
|
|
23
50
|
const style = computed(
|
|
24
51
|
() => `transform: translate(${draggedX.value}px, ${draggedY.value}px)`
|
|
25
52
|
);
|
|
26
|
-
function getSizes() {
|
|
53
|
+
async function getSizes() {
|
|
27
54
|
elRect.value = unrefElement(elRef)?.getBoundingClientRect();
|
|
55
|
+
wrapperRect.value = unrefElement(wrapperRef)?.getBoundingClientRect();
|
|
56
|
+
await nextTick();
|
|
28
57
|
}
|
|
29
|
-
function checkPosition() {
|
|
58
|
+
async function checkPosition() {
|
|
30
59
|
switch (position) {
|
|
31
60
|
case "bottom":
|
|
32
|
-
|
|
33
|
-
|
|
61
|
+
const snapPointB = await findClosestSnapPoint({
|
|
62
|
+
draggedX,
|
|
63
|
+
draggedY,
|
|
64
|
+
direction: directionY.value
|
|
65
|
+
});
|
|
66
|
+
if (draggedY.value > toValue(threshold).distance || hasSnapPoints.value) {
|
|
67
|
+
if (snapPointB === drawerHeight.value) {
|
|
68
|
+
shouldClose.value = true;
|
|
69
|
+
} else {
|
|
70
|
+
interpolateTo.value = snapPointB;
|
|
71
|
+
}
|
|
34
72
|
}
|
|
35
73
|
break;
|
|
36
74
|
case "top":
|
|
37
|
-
|
|
38
|
-
|
|
75
|
+
const snapPointT = await findClosestSnapPoint({
|
|
76
|
+
draggedX,
|
|
77
|
+
draggedY,
|
|
78
|
+
direction: directionY.value
|
|
79
|
+
});
|
|
80
|
+
if (draggedY.value < toValue(threshold).distance * -1 || hasSnapPoints.value) {
|
|
81
|
+
if (snapPointT === drawerHeight.value * -1) {
|
|
82
|
+
shouldClose.value = true;
|
|
83
|
+
} else {
|
|
84
|
+
interpolateTo.value = snapPointT;
|
|
85
|
+
}
|
|
39
86
|
}
|
|
40
87
|
break;
|
|
41
88
|
case "right":
|
|
42
|
-
|
|
43
|
-
|
|
89
|
+
const snapPointR = await findClosestSnapPoint({
|
|
90
|
+
draggedX,
|
|
91
|
+
draggedY,
|
|
92
|
+
direction: directionX.value
|
|
93
|
+
});
|
|
94
|
+
if (draggedX.value > toValue(threshold).distance || hasSnapPoints.value) {
|
|
95
|
+
if (snapPointR === drawerWidth.value) {
|
|
96
|
+
shouldClose.value = true;
|
|
97
|
+
} else {
|
|
98
|
+
interpolateTo.value = snapPointR;
|
|
99
|
+
}
|
|
44
100
|
}
|
|
45
101
|
break;
|
|
46
102
|
case "left":
|
|
47
|
-
|
|
48
|
-
|
|
103
|
+
const snapPointL = await findClosestSnapPoint({
|
|
104
|
+
draggedX,
|
|
105
|
+
draggedY,
|
|
106
|
+
direction: directionX.value
|
|
107
|
+
});
|
|
108
|
+
if (draggedX.value < toValue(threshold).distance * -1 || hasSnapPoints.value) {
|
|
109
|
+
if (snapPointL === drawerWidth.value * -1) {
|
|
110
|
+
shouldClose.value = true;
|
|
111
|
+
} else {
|
|
112
|
+
interpolateTo.value = snapPointL;
|
|
113
|
+
}
|
|
49
114
|
}
|
|
50
115
|
break;
|
|
51
116
|
}
|
|
52
117
|
}
|
|
53
|
-
function checkMomentum({ x, y }) {
|
|
118
|
+
async function checkMomentum({ x, y }) {
|
|
54
119
|
const elapsed = Date.now() - dragStart.value.getTime();
|
|
55
120
|
const velocityX = (x - originX.value) / elapsed;
|
|
56
121
|
const velocityY = (y - originY.value) / elapsed;
|
|
57
122
|
switch (position) {
|
|
58
123
|
case "bottom":
|
|
124
|
+
const snapPointB = await findClosestSnapPoint({
|
|
125
|
+
draggedX,
|
|
126
|
+
draggedY,
|
|
127
|
+
direction: directionY.value
|
|
128
|
+
});
|
|
59
129
|
if (velocityY > toValue(threshold).momentum) {
|
|
60
|
-
|
|
130
|
+
if (snapPointB === drawerHeight.value) {
|
|
131
|
+
shouldClose.value = true;
|
|
132
|
+
} else {
|
|
133
|
+
interpolateTo.value = snapPointB;
|
|
134
|
+
}
|
|
61
135
|
}
|
|
62
136
|
break;
|
|
63
137
|
case "top":
|
|
138
|
+
const snapPointT = await findClosestSnapPoint({
|
|
139
|
+
draggedX,
|
|
140
|
+
draggedY,
|
|
141
|
+
direction: directionY.value
|
|
142
|
+
});
|
|
64
143
|
if (velocityY < toValue(threshold).momentum * -1) {
|
|
65
|
-
|
|
144
|
+
if (snapPointT === drawerHeight.value) {
|
|
145
|
+
shouldClose.value = true;
|
|
146
|
+
} else {
|
|
147
|
+
interpolateTo.value = snapPointT;
|
|
148
|
+
}
|
|
66
149
|
}
|
|
67
150
|
break;
|
|
68
151
|
case "right":
|
|
152
|
+
const snapPointR = await findClosestSnapPoint({
|
|
153
|
+
draggedX,
|
|
154
|
+
draggedY,
|
|
155
|
+
direction: directionX.value
|
|
156
|
+
});
|
|
69
157
|
if (velocityX > toValue(threshold).momentum) {
|
|
70
|
-
|
|
158
|
+
if (snapPointR === drawerWidth.value) {
|
|
159
|
+
shouldClose.value = true;
|
|
160
|
+
} else {
|
|
161
|
+
interpolateTo.value = snapPointR;
|
|
162
|
+
}
|
|
71
163
|
}
|
|
72
164
|
break;
|
|
73
165
|
case "left":
|
|
74
|
-
|
|
75
|
-
|
|
166
|
+
const snapPointL = await findClosestSnapPoint({
|
|
167
|
+
draggedX,
|
|
168
|
+
draggedY,
|
|
169
|
+
direction: directionX.value
|
|
170
|
+
});
|
|
171
|
+
if (velocityX > toValue(threshold).momentum) {
|
|
172
|
+
if (snapPointL === drawerWidth.value) {
|
|
173
|
+
shouldClose.value = true;
|
|
174
|
+
} else {
|
|
175
|
+
interpolateTo.value = snapPointL;
|
|
176
|
+
}
|
|
76
177
|
}
|
|
77
178
|
break;
|
|
78
179
|
}
|
|
@@ -99,59 +200,117 @@ export function useDrawerDrag(args) {
|
|
|
99
200
|
function setDragged({ x, y }) {
|
|
100
201
|
switch (position) {
|
|
101
202
|
case "bottom":
|
|
102
|
-
|
|
203
|
+
const newDraggedB = clamp(y - originY.value, 0, toValue(overshoot) * -1);
|
|
204
|
+
directionY.value = newDraggedB < draggedY.value ? "below" : "above";
|
|
205
|
+
draggedY.value = newDraggedB;
|
|
103
206
|
break;
|
|
104
207
|
case "top":
|
|
105
|
-
|
|
208
|
+
const newDraggedT = clamp(y - originY.value, 0, toValue(overshoot));
|
|
209
|
+
directionY.value = newDraggedT < draggedY.value ? "below" : "above";
|
|
210
|
+
draggedY.value = newDraggedT;
|
|
106
211
|
break;
|
|
107
212
|
case "right":
|
|
108
|
-
|
|
213
|
+
const newDraggedR = clamp(x - originX.value, 0, toValue(overshoot) * -1);
|
|
214
|
+
directionX.value = newDraggedR < draggedX.value ? "below" : "above";
|
|
215
|
+
draggedX.value = newDraggedR;
|
|
109
216
|
break;
|
|
110
217
|
case "left":
|
|
111
|
-
|
|
218
|
+
const newDraggedL = clamp(x - originX.value, 0, toValue(overshoot));
|
|
219
|
+
directionX.value = newDraggedL < draggedX.value ? "below" : "above";
|
|
220
|
+
draggedX.value = newDraggedL;
|
|
221
|
+
break;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
async function setInitial() {
|
|
225
|
+
await nextTick();
|
|
226
|
+
switch (position) {
|
|
227
|
+
case "top":
|
|
228
|
+
case "bottom":
|
|
229
|
+
const mappedSnapPointY = mapSnapPoint(toValue(snapPoint));
|
|
230
|
+
console.log("toValue(snapPoint):", toValue(snapPoint));
|
|
231
|
+
console.log("mappedSnapPointY:", mappedSnapPointY);
|
|
232
|
+
if (!mappedSnapPointY)
|
|
233
|
+
return;
|
|
234
|
+
draggedY.value = await findClosestSnapPoint({
|
|
235
|
+
draggedX,
|
|
236
|
+
draggedY: mappedSnapPointY
|
|
237
|
+
}) || 0;
|
|
238
|
+
break;
|
|
239
|
+
case "left":
|
|
240
|
+
case "right":
|
|
241
|
+
const mappedSnapPointX = mapSnapPoint(toValue(snapPoint));
|
|
242
|
+
if (!mappedSnapPointX)
|
|
243
|
+
return;
|
|
244
|
+
draggedX.value = await findClosestSnapPoint({
|
|
245
|
+
draggedX: mappedSnapPointX,
|
|
246
|
+
draggedY
|
|
247
|
+
}) || 0;
|
|
112
248
|
break;
|
|
113
249
|
}
|
|
114
250
|
}
|
|
115
251
|
function resetStateAndListeners() {
|
|
116
252
|
dragging.value = false;
|
|
117
253
|
shouldClose.value = false;
|
|
254
|
+
interpolateTo.value = void 0;
|
|
255
|
+
cancelPointerup?.();
|
|
118
256
|
cancelPointermove?.();
|
|
119
257
|
}
|
|
120
258
|
function resetDragged() {
|
|
121
259
|
draggedX.value = 0;
|
|
122
260
|
draggedY.value = 0;
|
|
123
261
|
}
|
|
262
|
+
function resetSnapped() {
|
|
263
|
+
snappedX.value = 0;
|
|
264
|
+
snappedY.value = 0;
|
|
265
|
+
}
|
|
124
266
|
function emitterCallback(event, _payload) {
|
|
125
267
|
if (event === "afterLeave") {
|
|
126
268
|
resetDragged();
|
|
269
|
+
resetSnapped();
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
async function interpolateDragged(target) {
|
|
273
|
+
switch (position) {
|
|
274
|
+
case "bottom":
|
|
275
|
+
case "top":
|
|
276
|
+
snappedY.value = target;
|
|
277
|
+
interpolate({
|
|
278
|
+
from: draggedY.value,
|
|
279
|
+
to: target,
|
|
280
|
+
duration: 300,
|
|
281
|
+
callback: (value) => {
|
|
282
|
+
draggedY.value = value;
|
|
283
|
+
}
|
|
284
|
+
});
|
|
285
|
+
break;
|
|
286
|
+
case "right":
|
|
287
|
+
case "left":
|
|
288
|
+
snappedX.value = target;
|
|
289
|
+
interpolate({
|
|
290
|
+
from: draggedX.value,
|
|
291
|
+
to: target,
|
|
292
|
+
duration: 300,
|
|
293
|
+
callback: (value) => {
|
|
294
|
+
draggedX.value = value;
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
break;
|
|
127
298
|
}
|
|
128
299
|
}
|
|
129
300
|
function onPointerup(e) {
|
|
130
301
|
if (shouldClose.value) {
|
|
131
302
|
close();
|
|
303
|
+
} else if (interpolateTo.value || interpolateTo.value === 0) {
|
|
304
|
+
interpolateDragged(interpolateTo.value);
|
|
132
305
|
} else {
|
|
133
306
|
switch (position) {
|
|
134
307
|
case "bottom":
|
|
135
308
|
case "top":
|
|
136
|
-
|
|
137
|
-
from: draggedY.value,
|
|
138
|
-
to: 0,
|
|
139
|
-
duration: 50,
|
|
140
|
-
callback: (value) => {
|
|
141
|
-
draggedY.value = value;
|
|
142
|
-
}
|
|
143
|
-
});
|
|
309
|
+
interpolateDragged(snappedY.value);
|
|
144
310
|
break;
|
|
145
311
|
case "right":
|
|
146
312
|
case "left":
|
|
147
|
-
|
|
148
|
-
from: draggedX.value,
|
|
149
|
-
to: 0,
|
|
150
|
-
duration: 50,
|
|
151
|
-
callback: (value) => {
|
|
152
|
-
draggedX.value = value;
|
|
153
|
-
}
|
|
154
|
-
});
|
|
313
|
+
interpolateDragged(snappedX.value);
|
|
155
314
|
break;
|
|
156
315
|
}
|
|
157
316
|
}
|
|
@@ -173,22 +332,23 @@ export function useDrawerDrag(args) {
|
|
|
173
332
|
}
|
|
174
333
|
;
|
|
175
334
|
e.target.setPointerCapture(e.pointerId);
|
|
176
|
-
useEventListener(document, "pointerup", onPointerup);
|
|
335
|
+
cancelPointerup = useEventListener(document, "pointerup", onPointerup);
|
|
177
336
|
cancelPointermove = useEventListener(document, "pointermove", onPointermove);
|
|
178
|
-
originX.value = e.screenX;
|
|
179
|
-
originY.value = e.screenY;
|
|
337
|
+
originX.value = e.screenX - draggedX.value;
|
|
338
|
+
originY.value = e.screenY - draggedY.value;
|
|
180
339
|
dragStart.value = /* @__PURE__ */ new Date();
|
|
181
340
|
onPointermove(e);
|
|
182
341
|
e.preventDefault();
|
|
183
342
|
}
|
|
184
|
-
onMounted(() => {
|
|
185
|
-
getSizes();
|
|
343
|
+
onMounted(async () => {
|
|
344
|
+
await getSizes();
|
|
186
345
|
useDrawerEmitter().on("*", emitterCallback);
|
|
187
346
|
});
|
|
188
347
|
watch(
|
|
189
|
-
() => unrefElement(elRef),
|
|
190
|
-
() => {
|
|
191
|
-
getSizes();
|
|
348
|
+
() => [unrefElement(elRef), unrefElement(wrapperRef)],
|
|
349
|
+
async () => {
|
|
350
|
+
await getSizes();
|
|
351
|
+
setInitial();
|
|
192
352
|
}
|
|
193
353
|
);
|
|
194
354
|
onBeforeUnmount(() => {
|
|
@@ -196,6 +356,8 @@ export function useDrawerDrag(args) {
|
|
|
196
356
|
});
|
|
197
357
|
return {
|
|
198
358
|
style,
|
|
359
|
+
draggedX,
|
|
360
|
+
draggedY,
|
|
199
361
|
dragging,
|
|
200
362
|
onPointerdown
|
|
201
363
|
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type MaybeRef } from 'vue';
|
|
2
|
+
import { type DefaultOptions } from '../../utils/defaultOptions.js';
|
|
3
|
+
import { type SnapPoint } from '../../types.js';
|
|
4
|
+
type UseDrawerSnapArgs = {
|
|
5
|
+
wrapperRect: MaybeRef<DOMRect | undefined>;
|
|
6
|
+
position: MaybeRef<DefaultOptions['position']>;
|
|
7
|
+
snapPoints: MaybeRef<DefaultOptions['snapPoints']>;
|
|
8
|
+
canClose: MaybeRef<DefaultOptions['canClose']>;
|
|
9
|
+
overshoot: MaybeRef<number>;
|
|
10
|
+
};
|
|
11
|
+
type FindClosestSnapPointArgs = {
|
|
12
|
+
draggedY: MaybeRef<number>;
|
|
13
|
+
draggedX: MaybeRef<number>;
|
|
14
|
+
direction?: 'below' | 'above' | 'absolute';
|
|
15
|
+
};
|
|
16
|
+
export declare function useDrawerSnap(args: UseDrawerSnapArgs): {
|
|
17
|
+
findClosestSnapPoint: (args: FindClosestSnapPointArgs) => Promise<number | undefined>;
|
|
18
|
+
mapSnapPoint: (snapPoint: SnapPoint) => number | undefined;
|
|
19
|
+
drawerHeight: import("vue").ComputedRef<number>;
|
|
20
|
+
drawerWidth: import("vue").ComputedRef<number>;
|
|
21
|
+
};
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { computed, toValue } from "vue";
|
|
2
|
+
import { mapValue } from "@maas/vue-equipment/utils";
|
|
3
|
+
export function useDrawerSnap(args) {
|
|
4
|
+
const { snapPoints, position, wrapperRect, overshoot, canClose } = args;
|
|
5
|
+
const mappedSnapPoints = computed(() => {
|
|
6
|
+
const extended = toValue(canClose) ? [...toValue(snapPoints), 0] : toValue(snapPoints);
|
|
7
|
+
const mapped = extended.map((snapPoint) => {
|
|
8
|
+
return mapSnapPoint(snapPoint);
|
|
9
|
+
});
|
|
10
|
+
const filtered = mapped.filter(
|
|
11
|
+
(snapPoint) => !!snapPoint || snapPoint === 0
|
|
12
|
+
).sort((a, b) => a - b);
|
|
13
|
+
return filtered;
|
|
14
|
+
});
|
|
15
|
+
const drawerHeight = computed(() => {
|
|
16
|
+
if (toValue(wrapperRect) === void 0) {
|
|
17
|
+
return 0;
|
|
18
|
+
} else {
|
|
19
|
+
return toValue(wrapperRect)?.height - toValue(overshoot);
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
const drawerWidth = computed(() => {
|
|
23
|
+
if (toValue(wrapperRect) === void 0) {
|
|
24
|
+
return 0;
|
|
25
|
+
} else {
|
|
26
|
+
return toValue(wrapperRect)?.width - toValue(overshoot);
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
function findClosestNumber(args2) {
|
|
30
|
+
const { number, numbers, direction } = args2;
|
|
31
|
+
let filtered = numbers;
|
|
32
|
+
switch (direction) {
|
|
33
|
+
case "above":
|
|
34
|
+
filtered = numbers.filter((num) => num > number);
|
|
35
|
+
break;
|
|
36
|
+
case "below":
|
|
37
|
+
filtered = numbers.filter((num) => num < number);
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
if (filtered.length === 0) {
|
|
41
|
+
switch (direction) {
|
|
42
|
+
case "above":
|
|
43
|
+
return Math.max(...numbers);
|
|
44
|
+
case "below":
|
|
45
|
+
return Math.min(...numbers);
|
|
46
|
+
default:
|
|
47
|
+
return void 0;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const closestNumber = filtered.reduce(
|
|
51
|
+
(closest, current) => Math.abs(current - number) < Math.abs(closest - number) ? current : closest
|
|
52
|
+
);
|
|
53
|
+
return closestNumber;
|
|
54
|
+
}
|
|
55
|
+
function mapSnapPoint(snapPoint) {
|
|
56
|
+
if (typeof snapPoint === "number") {
|
|
57
|
+
const reversedSnapPoint = mapValue(snapPoint, 0, 1, 1, 0);
|
|
58
|
+
const vh = window.innerHeight;
|
|
59
|
+
const vw = window.innerWidth;
|
|
60
|
+
if (toValue(wrapperRect) === void 0) {
|
|
61
|
+
return void 0;
|
|
62
|
+
}
|
|
63
|
+
switch (position) {
|
|
64
|
+
case "bottom":
|
|
65
|
+
if (reversedSnapPoint === 1)
|
|
66
|
+
return drawerHeight.value;
|
|
67
|
+
else if (reversedSnapPoint === 0)
|
|
68
|
+
return 0;
|
|
69
|
+
else
|
|
70
|
+
return vh * reversedSnapPoint - toValue(wrapperRect)?.top;
|
|
71
|
+
case "top":
|
|
72
|
+
if (reversedSnapPoint === 1)
|
|
73
|
+
return drawerHeight.value * -1;
|
|
74
|
+
else if (reversedSnapPoint === 0)
|
|
75
|
+
return 0;
|
|
76
|
+
else
|
|
77
|
+
return vh * reversedSnapPoint - toValue(wrapperRect)?.bottom;
|
|
78
|
+
case "right":
|
|
79
|
+
if (reversedSnapPoint === 1)
|
|
80
|
+
return drawerWidth.value;
|
|
81
|
+
else if (reversedSnapPoint === 0)
|
|
82
|
+
return 0;
|
|
83
|
+
else
|
|
84
|
+
return vw * reversedSnapPoint - toValue(wrapperRect)?.left;
|
|
85
|
+
case "left":
|
|
86
|
+
if (reversedSnapPoint === 1)
|
|
87
|
+
return drawerWidth.value * -1;
|
|
88
|
+
else if (reversedSnapPoint === 0)
|
|
89
|
+
return 0;
|
|
90
|
+
else
|
|
91
|
+
return vw * reversedSnapPoint - toValue(wrapperRect)?.right;
|
|
92
|
+
default:
|
|
93
|
+
return 0;
|
|
94
|
+
}
|
|
95
|
+
} else {
|
|
96
|
+
const parsedSnapPoint = parseFloat(snapPoint);
|
|
97
|
+
if (!drawerHeight.value || !drawerWidth.value) {
|
|
98
|
+
return void 0;
|
|
99
|
+
}
|
|
100
|
+
switch (position) {
|
|
101
|
+
case "bottom":
|
|
102
|
+
return drawerHeight.value - parsedSnapPoint;
|
|
103
|
+
case "top":
|
|
104
|
+
return (drawerHeight.value - parsedSnapPoint) * -1;
|
|
105
|
+
case "right":
|
|
106
|
+
return drawerWidth.value - parsedSnapPoint;
|
|
107
|
+
case "left":
|
|
108
|
+
return (drawerWidth.value - parsedSnapPoint) * -1;
|
|
109
|
+
default:
|
|
110
|
+
return parseFloat(snapPoint);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
async function findClosestSnapPoint(args2) {
|
|
115
|
+
const { draggedY, draggedX, direction = "absolute" } = args2;
|
|
116
|
+
let closest = 0;
|
|
117
|
+
switch (position) {
|
|
118
|
+
case "bottom":
|
|
119
|
+
case "top":
|
|
120
|
+
closest = findClosestNumber({
|
|
121
|
+
number: toValue(draggedY),
|
|
122
|
+
numbers: mappedSnapPoints.value,
|
|
123
|
+
direction
|
|
124
|
+
});
|
|
125
|
+
break;
|
|
126
|
+
case "right":
|
|
127
|
+
case "left":
|
|
128
|
+
closest = findClosestNumber({
|
|
129
|
+
number: toValue(draggedX),
|
|
130
|
+
numbers: mappedSnapPoints.value,
|
|
131
|
+
direction
|
|
132
|
+
});
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
return closest;
|
|
136
|
+
}
|
|
137
|
+
return { findClosestSnapPoint, mapSnapPoint, drawerHeight, drawerWidth };
|
|
138
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export type SnapPoint = number | `${string}px`;
|
|
1
2
|
export type DrawerOptions = {
|
|
2
3
|
position?: 'top' | 'right' | 'bottom' | 'left';
|
|
3
4
|
backdrop?: boolean;
|
|
@@ -22,6 +23,9 @@ export type DrawerOptions = {
|
|
|
22
23
|
open: boolean;
|
|
23
24
|
animate: boolean;
|
|
24
25
|
};
|
|
26
|
+
snapPoints?: SnapPoint[];
|
|
27
|
+
snapPoint?: SnapPoint;
|
|
28
|
+
canClose?: boolean;
|
|
25
29
|
};
|
|
26
30
|
export type DrawerEvents = {
|
|
27
31
|
beforeEnter: string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const defaultOptions = {
|
|
2
2
|
position: "bottom",
|
|
3
3
|
backdrop: true,
|
|
4
|
-
focusTrap:
|
|
4
|
+
focusTrap: false,
|
|
5
5
|
scrollLock: true,
|
|
6
6
|
scrollLockPadding: true,
|
|
7
7
|
teleport: {
|
|
@@ -21,6 +21,9 @@ const defaultOptions = {
|
|
|
21
21
|
beforeMount: {
|
|
22
22
|
open: false,
|
|
23
23
|
animate: false
|
|
24
|
-
}
|
|
24
|
+
},
|
|
25
|
+
snapPoints: [1],
|
|
26
|
+
snapPoint: 1,
|
|
27
|
+
canClose: true
|
|
25
28
|
};
|
|
26
29
|
export { defaultOptions };
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
</template>
|
|
6
6
|
|
|
7
7
|
<script setup lang="ts">
|
|
8
|
-
import { ref, inject, computed, onMounted,
|
|
8
|
+
import { ref, inject, computed, onMounted, watch } from 'vue'
|
|
9
9
|
import { unrefElement } from '@vueuse/core'
|
|
10
10
|
import { animate, type Easing } from 'motion'
|
|
11
11
|
import { ScrollProgressKey } from '../symbols'
|
package/dist/utils/index.js
CHANGED
|
@@ -37,26 +37,21 @@ function clampValue(value, min, max) {
|
|
|
37
37
|
|
|
38
38
|
// src/functions/interpolate.ts
|
|
39
39
|
function interpolate(args) {
|
|
40
|
-
const {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
const stepSize = 1 / steps;
|
|
50
|
-
let currentStep = 0;
|
|
51
|
-
const intervalId = setInterval(() => {
|
|
52
|
-
const progress = currentStep * stepSize;
|
|
53
|
-
const value = from + (to - from) * easing(progress);
|
|
40
|
+
const { from, to, duration, callback, easing = (t) => t * (2 - t) } = args;
|
|
41
|
+
let startTime;
|
|
42
|
+
const speed = 1;
|
|
43
|
+
function animate(timestamp) {
|
|
44
|
+
if (!startTime)
|
|
45
|
+
startTime = timestamp;
|
|
46
|
+
const progress = Math.min(1, (timestamp - startTime) / (duration * speed));
|
|
47
|
+
const easedProgress = easing(progress);
|
|
48
|
+
const value = from + (to - from) * easedProgress;
|
|
54
49
|
callback(value);
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
clearInterval(intervalId);
|
|
50
|
+
if (progress < 1) {
|
|
51
|
+
requestAnimationFrame(animate);
|
|
58
52
|
}
|
|
59
|
-
}
|
|
53
|
+
}
|
|
54
|
+
requestAnimationFrame(animate);
|
|
60
55
|
}
|
|
61
56
|
|
|
62
57
|
// src/functions/isIOS.ts
|
package/dist/utils/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../packages/utils/index.ts","../../packages/utils/src/functions/clampValue.ts","../../packages/utils/src/functions/interpolate.ts","../../packages/utils/src/functions/isIOS.ts","../../packages/utils/src/functions/mapValue.ts","../../packages/utils/src/functions/uuid.ts","../../packages/utils/src/functions/uniq.ts","../../packages/utils/src/functions/slugify.ts"],"sourcesContent":["export * from './src/functions/clampValue'\nexport * from './src/functions/interpolate'\nexport * from './src/functions/isIOS'\nexport * from './src/functions/mapValue'\nexport * from './src/functions/uuid'\nexport * from './src/functions/uniq'\nexport * from './src/functions/slugify'\n\nexport type * from './src/types'\n","export function clampValue(value: number, min: number, max: number) {\n return value <= min ? min : value >= max ? max : value\n}\n","export type InterpolateArgs = {\n from: number\n to: number\n duration: number\n interval?: number\n easing?: (t: number) => number\n callback: (result: number) => void\n}\n\nexport function interpolate(args: InterpolateArgs) {\n const {
|
|
1
|
+
{"version":3,"sources":["../../packages/utils/index.ts","../../packages/utils/src/functions/clampValue.ts","../../packages/utils/src/functions/interpolate.ts","../../packages/utils/src/functions/isIOS.ts","../../packages/utils/src/functions/mapValue.ts","../../packages/utils/src/functions/uuid.ts","../../packages/utils/src/functions/uniq.ts","../../packages/utils/src/functions/slugify.ts"],"sourcesContent":["export * from './src/functions/clampValue'\nexport * from './src/functions/interpolate'\nexport * from './src/functions/isIOS'\nexport * from './src/functions/mapValue'\nexport * from './src/functions/uuid'\nexport * from './src/functions/uniq'\nexport * from './src/functions/slugify'\n\nexport type * from './src/types'\n","export function clampValue(value: number, min: number, max: number) {\n return value <= min ? min : value >= max ? max : value\n}\n","export type InterpolateArgs = {\n from: number\n to: number\n duration: number\n interval?: number\n easing?: (t: number) => number\n callback: (result: number) => void\n}\n\nexport function interpolate(args: InterpolateArgs) {\n const { from, to, duration, callback, easing = (t) => t * (2 - t) } = args\n\n let startTime: number\n const speed = 1\n\n function animate(timestamp: number) {\n if (!startTime) startTime = timestamp\n\n const progress = Math.min(1, (timestamp - startTime) / (duration * speed))\n const easedProgress = easing(progress)\n const value = from + (to - from) * easedProgress\n\n callback(value)\n\n if (progress < 1) {\n requestAnimationFrame(animate)\n }\n }\n\n requestAnimationFrame(animate)\n}\n","export function isIOS() {\n if (typeof window === 'undefined') return false\n return /iPad|iPhone|iPod/.test(navigator?.userAgent)\n}\n","export function mapValue(\n value: number,\n inMin: number,\n inMax: number,\n outMin: number,\n outMax: number,\n) {\n return ((value - inMin) * (outMax - outMin)) / (inMax - inMin) + outMin\n}\n","// This implementation is meant for internal use only.\n// It is only used to generate a unique IDs for the `key` props.\n// It should not replace crypto.randomUUID() or window.crypto.randomUUID().\n\nexport function uuid() {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'\n .split('')\n .reduce(\n (c, i) =>\n c +\n (i === 'x'\n ? Math.floor(Math.random() * 0xf).toString(16)\n : i === 'y'\n ? Math.floor(Math.random() * 4 + 8).toString(16)\n : i),\n '',\n )\n}\n","export function uniq<T extends any[]>(a: T) {\n return Array.from(new Set(a))\n}\n","export interface SlugifyOptions {\n separator?: string\n trim?: boolean\n remove?: RegExp\n strict?: boolean\n lowercase?: boolean\n}\n\nconst defaultOptions: SlugifyOptions = {\n separator: '-',\n trim: true,\n remove: undefined,\n strict: true,\n lowercase: true,\n}\n\nexport function slugify(string: string, options?: SlugifyOptions): string {\n if (typeof string !== 'string') {\n throw new Error('slugify: string argument expected')\n }\n\n // Merge provided options with default options\n const _options = { ...defaultOptions, ...options }\n\n const charMap: { [key: string]: string } = {}\n\n let slug = string\n .normalize()\n .split('')\n .reduce(function (result, ch) {\n let appendChar = charMap[ch]\n if (appendChar === undefined) appendChar = ch\n if (appendChar === _options?.separator) appendChar = ' '\n return (\n result +\n appendChar.replace(_options?.remove || /[^\\w\\s$*_+~.()'\"!\\-:@]+/g, '')\n )\n }, '')\n\n if (_options.strict) {\n slug = slug.replace(/[^A-Za-z0-9\\s]/g, '')\n }\n\n if (_options.trim) {\n slug = slug.trim()\n }\n\n if (_options.separator) {\n slug = slug.replace(/ +/g, _options.separator)\n }\n\n if (_options.lowercase) {\n slug = slug.toLocaleLowerCase()\n }\n\n return slug\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAO,SAAS,WAAW,OAAe,KAAa,KAAa;AAClE,SAAO,SAAS,MAAM,MAAM,SAAS,MAAM,MAAM;AACnD;;;ACOO,SAAS,YAAY,MAAuB;AACjD,QAAM,EAAE,MAAM,IAAI,UAAU,UAAU,SAAS,CAAC,MAAM,KAAK,IAAI,GAAG,IAAI;AAEtE,MAAI;AACJ,QAAM,QAAQ;AAEd,WAAS,QAAQ,WAAmB;AAClC,QAAI,CAAC;AAAW,kBAAY;AAE5B,UAAM,WAAW,KAAK,IAAI,IAAI,YAAY,cAAc,WAAW,MAAM;AACzE,UAAM,gBAAgB,OAAO,QAAQ;AACrC,UAAM,QAAQ,QAAQ,KAAK,QAAQ;AAEnC,aAAS,KAAK;AAEd,QAAI,WAAW,GAAG;AAChB,4BAAsB,OAAO;AAAA,IAC/B;AAAA,EACF;AAEA,wBAAsB,OAAO;AAC/B;;;AC9BO,SAAS,QAAQ;AACtB,MAAI,OAAO,WAAW;AAAa,WAAO;AAC1C,SAAO,mBAAmB,KAAK,uCAAW,SAAS;AACrD;;;ACHO,SAAS,SACd,OACA,OACA,OACA,QACA,QACA;AACA,UAAS,QAAQ,UAAU,SAAS,WAAY,QAAQ,SAAS;AACnE;;;ACJO,SAAS,OAAO;AACrB,SAAO,uCACJ,MAAM,EAAE,EACR;AAAA,IACC,CAAC,GAAG,MACF,KACC,MAAM,MACH,KAAK,MAAM,KAAK,OAAO,IAAI,EAAG,EAAE,SAAS,EAAE,IAC3C,MAAM,MACN,KAAK,MAAM,KAAK,OAAO,IAAI,IAAI,CAAC,EAAE,SAAS,EAAE,IAC7C;AAAA,IACN;AAAA,EACF;AACJ;;;ACjBO,SAAS,KAAsB,GAAM;AAC1C,SAAO,MAAM,KAAK,IAAI,IAAI,CAAC,CAAC;AAC9B;;;ACMA,IAAM,iBAAiC;AAAA,EACrC,WAAW;AAAA,EACX,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,WAAW;AACb;AAEO,SAAS,QAAQ,QAAgB,SAAkC;AACxE,MAAI,OAAO,WAAW,UAAU;AAC9B,UAAM,IAAI,MAAM,mCAAmC;AAAA,EACrD;AAGA,QAAM,WAAW,EAAE,GAAG,gBAAgB,GAAG,QAAQ;AAEjD,QAAM,UAAqC,CAAC;AAE5C,MAAI,OAAO,OACR,UAAU,EACV,MAAM,EAAE,EACR,OAAO,SAAU,QAAQ,IAAI;AAC5B,QAAI,aAAa,QAAQ,EAAE;AAC3B,QAAI,eAAe;AAAW,mBAAa;AAC3C,QAAI,gBAAe,qCAAU;AAAW,mBAAa;AACrD,WACE,SACA,WAAW,SAAQ,qCAAU,WAAU,4BAA4B,EAAE;AAAA,EAEzE,GAAG,EAAE;AAEP,MAAI,SAAS,QAAQ;AACnB,WAAO,KAAK,QAAQ,mBAAmB,EAAE;AAAA,EAC3C;AAEA,MAAI,SAAS,MAAM;AACjB,WAAO,KAAK,KAAK;AAAA,EACnB;AAEA,MAAI,SAAS,WAAW;AACtB,WAAO,KAAK,QAAQ,OAAO,SAAS,SAAS;AAAA,EAC/C;AAEA,MAAI,SAAS,WAAW;AACtB,WAAO,KAAK,kBAAkB;AAAA,EAChC;AAEA,SAAO;AACT;","names":[]}
|
package/dist/utils/index.mjs
CHANGED
|
@@ -5,26 +5,21 @@ function clampValue(value, min, max) {
|
|
|
5
5
|
|
|
6
6
|
// src/functions/interpolate.ts
|
|
7
7
|
function interpolate(args) {
|
|
8
|
-
const {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const stepSize = 1 / steps;
|
|
18
|
-
let currentStep = 0;
|
|
19
|
-
const intervalId = setInterval(() => {
|
|
20
|
-
const progress = currentStep * stepSize;
|
|
21
|
-
const value = from + (to - from) * easing(progress);
|
|
8
|
+
const { from, to, duration, callback, easing = (t) => t * (2 - t) } = args;
|
|
9
|
+
let startTime;
|
|
10
|
+
const speed = 1;
|
|
11
|
+
function animate(timestamp) {
|
|
12
|
+
if (!startTime)
|
|
13
|
+
startTime = timestamp;
|
|
14
|
+
const progress = Math.min(1, (timestamp - startTime) / (duration * speed));
|
|
15
|
+
const easedProgress = easing(progress);
|
|
16
|
+
const value = from + (to - from) * easedProgress;
|
|
22
17
|
callback(value);
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
clearInterval(intervalId);
|
|
18
|
+
if (progress < 1) {
|
|
19
|
+
requestAnimationFrame(animate);
|
|
26
20
|
}
|
|
27
|
-
}
|
|
21
|
+
}
|
|
22
|
+
requestAnimationFrame(animate);
|
|
28
23
|
}
|
|
29
24
|
|
|
30
25
|
// src/functions/isIOS.ts
|
package/dist/utils/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../packages/utils/src/functions/clampValue.ts","../../packages/utils/src/functions/interpolate.ts","../../packages/utils/src/functions/isIOS.ts","../../packages/utils/src/functions/mapValue.ts","../../packages/utils/src/functions/uuid.ts","../../packages/utils/src/functions/uniq.ts","../../packages/utils/src/functions/slugify.ts"],"sourcesContent":["export function clampValue(value: number, min: number, max: number) {\n return value <= min ? min : value >= max ? max : value\n}\n","export type InterpolateArgs = {\n from: number\n to: number\n duration: number\n interval?: number\n easing?: (t: number) => number\n callback: (result: number) => void\n}\n\nexport function interpolate(args: InterpolateArgs) {\n const {
|
|
1
|
+
{"version":3,"sources":["../../packages/utils/src/functions/clampValue.ts","../../packages/utils/src/functions/interpolate.ts","../../packages/utils/src/functions/isIOS.ts","../../packages/utils/src/functions/mapValue.ts","../../packages/utils/src/functions/uuid.ts","../../packages/utils/src/functions/uniq.ts","../../packages/utils/src/functions/slugify.ts"],"sourcesContent":["export function clampValue(value: number, min: number, max: number) {\n return value <= min ? min : value >= max ? max : value\n}\n","export type InterpolateArgs = {\n from: number\n to: number\n duration: number\n interval?: number\n easing?: (t: number) => number\n callback: (result: number) => void\n}\n\nexport function interpolate(args: InterpolateArgs) {\n const { from, to, duration, callback, easing = (t) => t * (2 - t) } = args\n\n let startTime: number\n const speed = 1\n\n function animate(timestamp: number) {\n if (!startTime) startTime = timestamp\n\n const progress = Math.min(1, (timestamp - startTime) / (duration * speed))\n const easedProgress = easing(progress)\n const value = from + (to - from) * easedProgress\n\n callback(value)\n\n if (progress < 1) {\n requestAnimationFrame(animate)\n }\n }\n\n requestAnimationFrame(animate)\n}\n","export function isIOS() {\n if (typeof window === 'undefined') return false\n return /iPad|iPhone|iPod/.test(navigator?.userAgent)\n}\n","export function mapValue(\n value: number,\n inMin: number,\n inMax: number,\n outMin: number,\n outMax: number,\n) {\n return ((value - inMin) * (outMax - outMin)) / (inMax - inMin) + outMin\n}\n","// This implementation is meant for internal use only.\n// It is only used to generate a unique IDs for the `key` props.\n// It should not replace crypto.randomUUID() or window.crypto.randomUUID().\n\nexport function uuid() {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'\n .split('')\n .reduce(\n (c, i) =>\n c +\n (i === 'x'\n ? Math.floor(Math.random() * 0xf).toString(16)\n : i === 'y'\n ? Math.floor(Math.random() * 4 + 8).toString(16)\n : i),\n '',\n )\n}\n","export function uniq<T extends any[]>(a: T) {\n return Array.from(new Set(a))\n}\n","export interface SlugifyOptions {\n separator?: string\n trim?: boolean\n remove?: RegExp\n strict?: boolean\n lowercase?: boolean\n}\n\nconst defaultOptions: SlugifyOptions = {\n separator: '-',\n trim: true,\n remove: undefined,\n strict: true,\n lowercase: true,\n}\n\nexport function slugify(string: string, options?: SlugifyOptions): string {\n if (typeof string !== 'string') {\n throw new Error('slugify: string argument expected')\n }\n\n // Merge provided options with default options\n const _options = { ...defaultOptions, ...options }\n\n const charMap: { [key: string]: string } = {}\n\n let slug = string\n .normalize()\n .split('')\n .reduce(function (result, ch) {\n let appendChar = charMap[ch]\n if (appendChar === undefined) appendChar = ch\n if (appendChar === _options?.separator) appendChar = ' '\n return (\n result +\n appendChar.replace(_options?.remove || /[^\\w\\s$*_+~.()'\"!\\-:@]+/g, '')\n )\n }, '')\n\n if (_options.strict) {\n slug = slug.replace(/[^A-Za-z0-9\\s]/g, '')\n }\n\n if (_options.trim) {\n slug = slug.trim()\n }\n\n if (_options.separator) {\n slug = slug.replace(/ +/g, _options.separator)\n }\n\n if (_options.lowercase) {\n slug = slug.toLocaleLowerCase()\n }\n\n return slug\n}\n"],"mappings":";AAAO,SAAS,WAAW,OAAe,KAAa,KAAa;AAClE,SAAO,SAAS,MAAM,MAAM,SAAS,MAAM,MAAM;AACnD;;;ACOO,SAAS,YAAY,MAAuB;AACjD,QAAM,EAAE,MAAM,IAAI,UAAU,UAAU,SAAS,CAAC,MAAM,KAAK,IAAI,GAAG,IAAI;AAEtE,MAAI;AACJ,QAAM,QAAQ;AAEd,WAAS,QAAQ,WAAmB;AAClC,QAAI,CAAC;AAAW,kBAAY;AAE5B,UAAM,WAAW,KAAK,IAAI,IAAI,YAAY,cAAc,WAAW,MAAM;AACzE,UAAM,gBAAgB,OAAO,QAAQ;AACrC,UAAM,QAAQ,QAAQ,KAAK,QAAQ;AAEnC,aAAS,KAAK;AAEd,QAAI,WAAW,GAAG;AAChB,4BAAsB,OAAO;AAAA,IAC/B;AAAA,EACF;AAEA,wBAAsB,OAAO;AAC/B;;;AC9BO,SAAS,QAAQ;AACtB,MAAI,OAAO,WAAW;AAAa,WAAO;AAC1C,SAAO,mBAAmB,KAAK,uCAAW,SAAS;AACrD;;;ACHO,SAAS,SACd,OACA,OACA,OACA,QACA,QACA;AACA,UAAS,QAAQ,UAAU,SAAS,WAAY,QAAQ,SAAS;AACnE;;;ACJO,SAAS,OAAO;AACrB,SAAO,uCACJ,MAAM,EAAE,EACR;AAAA,IACC,CAAC,GAAG,MACF,KACC,MAAM,MACH,KAAK,MAAM,KAAK,OAAO,IAAI,EAAG,EAAE,SAAS,EAAE,IAC3C,MAAM,MACN,KAAK,MAAM,KAAK,OAAO,IAAI,IAAI,CAAC,EAAE,SAAS,EAAE,IAC7C;AAAA,IACN;AAAA,EACF;AACJ;;;ACjBO,SAAS,KAAsB,GAAM;AAC1C,SAAO,MAAM,KAAK,IAAI,IAAI,CAAC,CAAC;AAC9B;;;ACMA,IAAM,iBAAiC;AAAA,EACrC,WAAW;AAAA,EACX,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,WAAW;AACb;AAEO,SAAS,QAAQ,QAAgB,SAAkC;AACxE,MAAI,OAAO,WAAW,UAAU;AAC9B,UAAM,IAAI,MAAM,mCAAmC;AAAA,EACrD;AAGA,QAAM,WAAW,EAAE,GAAG,gBAAgB,GAAG,QAAQ;AAEjD,QAAM,UAAqC,CAAC;AAE5C,MAAI,OAAO,OACR,UAAU,EACV,MAAM,EAAE,EACR,OAAO,SAAU,QAAQ,IAAI;AAC5B,QAAI,aAAa,QAAQ,EAAE;AAC3B,QAAI,eAAe;AAAW,mBAAa;AAC3C,QAAI,gBAAe,qCAAU;AAAW,mBAAa;AACrD,WACE,SACA,WAAW,SAAQ,qCAAU,WAAU,4BAA4B,EAAE;AAAA,EAEzE,GAAG,EAAE;AAEP,MAAI,SAAS,QAAQ;AACnB,WAAO,KAAK,QAAQ,mBAAmB,EAAE;AAAA,EAC3C;AAEA,MAAI,SAAS,MAAM;AACjB,WAAO,KAAK,KAAK;AAAA,EACnB;AAEA,MAAI,SAAS,WAAW;AACtB,WAAO,KAAK,QAAQ,OAAO,SAAS,SAAS;AAAA,EAC/C;AAEA,MAAI,SAAS,WAAW;AACtB,WAAO,KAAK,kBAAkB;AAAA,EAChC;AAEA,SAAO;AACT;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maas/vue-equipment",
|
|
3
3
|
"description": "A magic collection of Vue composables, plugins, components and directives",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.15.1",
|
|
5
5
|
"author": "Robin Scholz <https://github.com/robinscholz>, Christoph Jeworutzki <https://github.com/ChristophJeworutzki>",
|
|
6
6
|
"devDependencies": {
|
|
7
7
|
"@antfu/ni": "^0.21.12",
|