@maas/vue-equipment 1.1.0 → 1.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.
Files changed (28) hide show
  1. package/dist/nuxt/module.json +1 -1
  2. package/dist/nuxt/module.mjs +1 -1
  3. package/dist/plugins/MagicCarousel/src/utils/defaultOptions.mjs +1 -1
  4. package/dist/plugins/MagicDraggable/src/utils/defaultOptions.mjs +1 -1
  5. package/dist/plugins/MagicDrawer/src/components/MagicDrawerContent.vue +4 -0
  6. package/dist/plugins/MagicDrawer/src/composables/private/useDrawerDrag.mjs +1 -2
  7. package/dist/plugins/MagicDrawer/src/composables/private/useDrawerProgress.mjs +57 -77
  8. package/dist/plugins/MagicDrawer/src/composables/private/useDrawerSnap.mjs +2 -5
  9. package/dist/plugins/MagicDrawer/src/utils/defaultOptions.mjs +1 -1
  10. package/dist/plugins/MagicTray/index.d.ts +2 -1
  11. package/dist/plugins/MagicTray/index.mjs +3 -0
  12. package/dist/plugins/MagicTray/src/components/MagicTrayContent.d.vue.ts +2 -2
  13. package/dist/plugins/MagicTray/src/components/MagicTrayContent.vue +17 -16
  14. package/dist/plugins/MagicTray/src/components/MagicTrayContent.vue.d.ts +2 -2
  15. package/dist/plugins/MagicTray/src/components/MagicTrayTrigger.d.vue.ts +25 -0
  16. package/dist/plugins/MagicTray/src/components/MagicTrayTrigger.vue +90 -0
  17. package/dist/plugins/MagicTray/src/components/MagicTrayTrigger.vue.d.ts +25 -0
  18. package/dist/plugins/MagicTray/src/composables/private/useTrayDrag.d.ts +0 -4
  19. package/dist/plugins/MagicTray/src/composables/private/useTrayDrag.mjs +9 -415
  20. package/dist/plugins/MagicTray/src/composables/private/useTrayGesture.d.ts +16 -0
  21. package/dist/plugins/MagicTray/src/composables/private/useTrayGesture.mjs +426 -0
  22. package/dist/plugins/MagicTray/src/composables/private/useTrayMagnetism.mjs +9 -37
  23. package/dist/plugins/MagicTray/src/composables/private/useTrayProgress.mjs +1 -1
  24. package/dist/plugins/MagicTray/src/composables/private/useTraySnap.mjs +2 -4
  25. package/dist/plugins/MagicTray/src/composables/private/useTrayUtils.d.ts +8 -1
  26. package/dist/plugins/MagicTray/src/composables/private/useTrayUtils.mjs +7 -1
  27. package/dist/plugins/MagicTray/src/utils/defaultOptions.mjs +1 -1
  28. package/package.json +2 -2
@@ -7,30 +7,13 @@ import {
7
7
  toValue,
8
8
  watch
9
9
  } from "vue";
10
- import {
11
- unrefElement,
12
- useEventListener,
13
- useResizeObserver,
14
- useThrottleFn
15
- } from "@vueuse/core";
16
- import {
17
- cancelEdgeNavigation,
18
- convertToPixels,
19
- guardedReleasePointerCapture,
20
- guardedSetPointerCapture,
21
- isAndroid,
22
- isIOS,
23
- isWithinRange,
24
- lockSelection,
25
- snapCommit,
26
- snapRelease
27
- } from "@maas/vue-equipment/utils";
10
+ import { unrefElement, useResizeObserver, useThrottleFn } from "@vueuse/core";
11
+ import { convertToPixels } from "@maas/vue-equipment/utils";
28
12
  import { useMagicEmitter } from "@maas/vue-equipment/plugins/MagicEmitter";
29
13
  import { useMagicError } from "@maas/vue-equipment/plugins/MagicError";
30
14
  import { useTraySnap } from "./useTraySnap.mjs";
31
- import { useTrayUtils } from "./useTrayUtils.mjs";
15
+ import { SIDES, useTrayUtils } from "./useTrayUtils.mjs";
32
16
  import { useTrayState } from "./useTrayState.mjs";
33
- const SIDES = ["top", "right", "bottom", "left"];
34
17
  export function useTrayDrag(args) {
35
18
  const { id, elRef } = args;
36
19
  const { logWarning } = useMagicError({
@@ -39,94 +22,27 @@ export function useTrayDrag(args) {
39
22
  });
40
23
  const { initializeState } = useTrayState(toValue(id));
41
24
  const state = initializeState();
42
- const { clampWithOvershoot, isVertical, flattenSnapPoints } = useTrayUtils();
25
+ const { flattenSnapPoints, isDraggableSide } = useTrayUtils();
43
26
  const emitter = useMagicEmitter();
44
27
  const {
45
28
  dimension,
46
29
  contentExtent,
47
- maxInset,
48
30
  mapSnapPoint,
49
31
  mappedSnapPoints,
50
- mappedRanges,
51
- rangeAt,
52
32
  snapPointAt,
53
- restingInset,
54
33
  isSnapTarget,
55
- findSnapTarget,
56
- interpolateDragged,
57
34
  snapTo
58
35
  } = useTraySnap({ id, state });
59
- function dragBounds(side) {
60
- const points = mappedSnapPoints(side);
61
- const geometricMax = maxInset(side);
62
- if (!points.length) {
63
- return { min: 0, max: geometricMax };
64
- }
65
- return {
66
- min: Math.max(0, points[0]),
67
- max: Math.min(points[points.length - 1], geometricMax)
68
- };
69
- }
70
36
  function openSnapPoint(side) {
71
37
  const points = mappedSnapPoints(side);
72
38
  return points.length ? snapPointAt(side, points[0]) : void 0;
73
39
  }
74
- let lastPendingTarget = void 0;
75
- let heldRangeSnap = false;
76
- let flicked = false;
77
- let suppressClick = false;
78
- let cancelPointerup = void 0;
79
- let cancelPointermove = void 0;
80
- let cancelPointercancel = void 0;
81
- let cancelTouchmove = void 0;
82
- let cancelTouchend = void 0;
83
- let cancelTouchcancel = void 0;
84
40
  let resizeObserverEl = null;
85
- let pointerdownTarget = void 0;
86
- let releaseSelection = void 0;
87
41
  const draggableSides = computed(
88
- () => SIDES.filter((side) => (state.options.snapPoints[side]?.length ?? 0) > 0)
89
- );
90
- const threshold = computed(() => state.options.threshold);
91
- const disabled = computed(() => state.options.disabled);
92
- const snapMode = computed(() => state.options.snap.mode);
93
- const dragMode = computed(() => state.options.drag.mode);
94
- const preventEdgeNavigation = computed(
95
- () => state.options.preventEdgeNavigation
42
+ () => SIDES.filter(
43
+ (side) => isDraggableSide({ snapPoints: state.options.snapPoints, side })
44
+ )
96
45
  );
97
- function snapDrag(side) {
98
- return {
99
- points: mappedSnapPoints(side),
100
- ranges: mappedRanges(side),
101
- mode: snapMode.value,
102
- rest: state.snapped[side],
103
- start: state.lastDragged[side],
104
- position: state.dragged[side]
105
- };
106
- }
107
- function settleTarget(side) {
108
- const target = snapRelease({
109
- ...snapDrag(side),
110
- committed: state.interpolateTo,
111
- flicked,
112
- tapped: !hasDragged.value
113
- });
114
- return restingInset(side, target);
115
- }
116
- function isSnapDrag(side) {
117
- return typeof dragMode.value === "string" ? dragMode.value === "snap" : (dragMode.value?.[side] ?? "free") === "snap";
118
- }
119
- const hasDragged = computed(() => {
120
- const side = state.draggingSide;
121
- if (!side) {
122
- return false;
123
- }
124
- return !isWithinRange({
125
- input: state.dragged[side],
126
- base: state.lastDragged[side],
127
- threshold: toValue(threshold).lock
128
- });
129
- });
130
46
  const clipPath = computed(() => {
131
47
  const top = Math.max(0, state.dragged.top + state.magnetic.top);
132
48
  const right = Math.max(0, state.dragged.right + state.magnetic.right);
@@ -199,315 +115,6 @@ export function useTrayDrag(args) {
199
115
  state.overshoot.inner = innerPixels ?? 0;
200
116
  await nextTick();
201
117
  }
202
- function computeInset(side, coord) {
203
- let newInset = 0;
204
- switch (side) {
205
- case "top":
206
- newInset = coord - state.origin;
207
- break;
208
- case "bottom":
209
- newInset = state.origin - coord;
210
- break;
211
- case "left":
212
- newInset = coord - state.origin;
213
- break;
214
- case "right":
215
- newInset = state.origin - coord;
216
- break;
217
- }
218
- const { min, max } = dragBounds(side);
219
- return clampWithOvershoot(
220
- newInset,
221
- min,
222
- max,
223
- state.overshoot.outer[side],
224
- state.overshoot.inner
225
- );
226
- }
227
- function setDragged(side, coord) {
228
- const newInset = computeInset(side, coord);
229
- if (newInset === state.dragged[side]) {
230
- return;
231
- }
232
- const prev = state.dragged[side];
233
- state.relDirection[side] = newInset < prev ? "below" : "above";
234
- state.dragged[side] = newInset;
235
- }
236
- function snapDragged(side, coord) {
237
- const inset = computeInset(side, coord);
238
- const target = findSnapTarget(side, inset);
239
- if (target === void 0 || target === state.snapped[side]) {
240
- return;
241
- }
242
- state.dragged[side] = target;
243
- state.snapped[side] = target;
244
- state.activeSnapPoint[side] = snapPointAt(side, target);
245
- heldRangeSnap = !mappedSnapPoints(side).includes(target);
246
- if (!heldRangeSnap) {
247
- emitSnap(side);
248
- }
249
- }
250
- function releaseSnapDrag(side) {
251
- if (heldRangeSnap) {
252
- emitSnap(side);
253
- }
254
- heldRangeSnap = false;
255
- }
256
- function emitSnap(side) {
257
- const point = state.activeSnapPoint[side];
258
- if (point === void 0) {
259
- return;
260
- }
261
- emitter.emit("beforeSnap", {
262
- id: toValue(id),
263
- snapPoint: { side, point }
264
- });
265
- emitter.emit("afterSnap", {
266
- id: toValue(id),
267
- snapPoint: { side, point }
268
- });
269
- }
270
- function checkPosition(side) {
271
- const direction = state.relDirection[side];
272
- state.interpolateTo = snapCommit({
273
- ...snapDrag(side),
274
- distance: toValue(threshold).distance,
275
- flicked,
276
- flickDirection: direction === "absolute" ? void 0 : direction
277
- });
278
- }
279
- function emitWillSnapTo(side) {
280
- const target = settleTarget(side);
281
- const isPoint = mappedSnapPoints(side).includes(target);
282
- const pending = !isPoint && rangeAt(side, target)?.range || target;
283
- if (pending === lastPendingTarget) {
284
- return;
285
- }
286
- lastPendingTarget = pending;
287
- const snapPoint = snapPointAt(side, target);
288
- if (snapPoint === void 0) {
289
- return;
290
- }
291
- emitter.emit("willSnapTo", {
292
- id: toValue(id),
293
- side,
294
- snapPoint
295
- });
296
- }
297
- function checkMomentum(side) {
298
- const elapsed = Date.now() - state.dragStart.getTime();
299
- const distance = Math.abs(state.dragged[side] - state.lastDragged[side]);
300
- const velocity = elapsed && distance ? distance / elapsed : 0;
301
- flicked = velocity > toValue(threshold).momentum;
302
- }
303
- function resetListeners() {
304
- cancelTouchmove?.();
305
- cancelTouchend?.();
306
- cancelTouchcancel?.();
307
- cancelPointerup?.();
308
- cancelPointermove?.();
309
- cancelPointercancel?.();
310
- }
311
- function resetDragState() {
312
- releaseSelection?.();
313
- releaseSelection = void 0;
314
- state.dragging = false;
315
- state.draggingSide = void 0;
316
- state.interpolateTo = void 0;
317
- }
318
- function settle(side) {
319
- const target = settleTarget(side);
320
- if (target !== state.snapped[side] || state.interpolateTo !== void 0) {
321
- state.snapped[side] = target;
322
- state.activeSnapPoint[side] = snapPointAt(side, target);
323
- }
324
- interpolateDragged({ side, to: target });
325
- }
326
- function onPointermove(e) {
327
- if (e.isTrusted && !e.isPrimary) {
328
- return;
329
- }
330
- const side = state.draggingSide;
331
- if (!side) {
332
- return;
333
- }
334
- e.stopImmediatePropagation();
335
- e.stopPropagation();
336
- const coord = isVertical(side) ? e.clientY : e.clientX;
337
- if (isSnapDrag(side)) {
338
- snapDragged(side, coord);
339
- } else {
340
- setDragged(side, coord);
341
- checkMomentum(side);
342
- checkPosition(side);
343
- emitWillSnapTo(side);
344
- }
345
- emitter.emit("drag", {
346
- id: toValue(id),
347
- side,
348
- value: state.dragged[side]
349
- });
350
- }
351
- function onPointerup(e) {
352
- const side = state.draggingSide;
353
- if (side) {
354
- suppressClick = hasDragged.value;
355
- if (isSnapDrag(side)) {
356
- releaseSnapDrag(side);
357
- } else {
358
- settle(side);
359
- }
360
- emitter.emit("afterDrag", {
361
- id: toValue(id),
362
- side,
363
- value: state.dragged[side]
364
- });
365
- }
366
- resetDragState();
367
- resetListeners();
368
- guardedReleasePointerCapture({ event: e, element: pointerdownTarget });
369
- }
370
- function onTouchmove(e) {
371
- const side = state.draggingSide;
372
- if (!side) {
373
- return;
374
- }
375
- const firstTouch = e.touches[0];
376
- if (!firstTouch) {
377
- return;
378
- }
379
- e.stopImmediatePropagation();
380
- e.stopPropagation();
381
- if (hasDragged.value) {
382
- e.preventDefault();
383
- }
384
- const coord = isVertical(side) ? firstTouch.clientY : firstTouch.clientX;
385
- if (isSnapDrag(side)) {
386
- snapDragged(side, coord);
387
- } else {
388
- setDragged(side, coord);
389
- checkMomentum(side);
390
- checkPosition(side);
391
- emitWillSnapTo(side);
392
- }
393
- emitter.emit("drag", {
394
- id: toValue(id),
395
- side,
396
- value: state.dragged[side]
397
- });
398
- }
399
- function onTouchend() {
400
- const side = state.draggingSide;
401
- if (side) {
402
- suppressClick = hasDragged.value;
403
- if (isSnapDrag(side)) {
404
- releaseSnapDrag(side);
405
- } else {
406
- settle(side);
407
- }
408
- emitter.emit("afterDrag", {
409
- id: toValue(id),
410
- side,
411
- value: state.dragged[side]
412
- });
413
- }
414
- resetDragState();
415
- resetListeners();
416
- }
417
- function beginDrag(side, coord, target) {
418
- state.dragging = true;
419
- state.draggingSide = side;
420
- state.interpolateTo = void 0;
421
- state.dragged[side] += state.magnetic[side];
422
- state.magnetic[side] = 0;
423
- state.lastDragged[side] = state.dragged[side];
424
- lastPendingTarget = void 0;
425
- heldRangeSnap = false;
426
- flicked = false;
427
- suppressClick = false;
428
- pointerdownTarget = target;
429
- releaseSelection = lockSelection();
430
- switch (side) {
431
- case "top":
432
- case "left":
433
- state.origin = coord - state.dragged[side];
434
- break;
435
- case "bottom":
436
- case "right":
437
- state.origin = coord + state.dragged[side];
438
- break;
439
- }
440
- state.dragStart = /* @__PURE__ */ new Date();
441
- emitter.emit("beforeDrag", {
442
- id: toValue(id),
443
- side,
444
- value: state.dragged[side]
445
- });
446
- }
447
- function onHandlePointerdown(side, e) {
448
- if (state.dragging || toValue(disabled)) {
449
- return;
450
- }
451
- const coord = isVertical(side) ? e.clientY : e.clientX;
452
- const target = e.target;
453
- beginDrag(side, coord, target);
454
- guardedSetPointerCapture({ event: e, element: target });
455
- resetListeners();
456
- cancelPointerup = useEventListener(document, "pointerup", onPointerup);
457
- cancelPointercancel = useEventListener(
458
- document,
459
- "pointercancel",
460
- onPointerup
461
- );
462
- cancelPointermove = useEventListener(
463
- document,
464
- "pointermove",
465
- onPointermove,
466
- {
467
- passive: false
468
- }
469
- );
470
- cancelTouchend = isIOS() || isAndroid() ? useEventListener(document, "touchend", onTouchend) : void 0;
471
- cancelTouchcancel = isIOS() || isAndroid() ? useEventListener(document, "touchcancel", onTouchend) : void 0;
472
- onPointermove(e);
473
- }
474
- function onHandleTouchstart(side, e) {
475
- if (toValue(disabled)) {
476
- return;
477
- }
478
- if (preventEdgeNavigation.value) {
479
- cancelEdgeNavigation({ event: e });
480
- }
481
- if (!isAndroid() || state.dragging) {
482
- return;
483
- }
484
- const firstTouch = e.touches[0];
485
- if (!firstTouch) {
486
- return;
487
- }
488
- e.stopImmediatePropagation();
489
- e.stopPropagation();
490
- const coord = isVertical(side) ? firstTouch.clientY : firstTouch.clientX;
491
- beginDrag(side, coord, e.target);
492
- cancelTouchmove?.();
493
- cancelTouchmove = useEventListener(document, "touchmove", onTouchmove, {
494
- passive: false
495
- });
496
- cancelTouchend?.();
497
- cancelTouchend = useEventListener(document, "touchend", onTouchend, {
498
- passive: false
499
- });
500
- cancelTouchcancel?.();
501
- cancelTouchcancel = useEventListener(document, "touchcancel", onTouchend);
502
- onTouchmove(e);
503
- }
504
- function onHandleClick(e) {
505
- if (suppressClick) {
506
- e.stopPropagation();
507
- e.preventDefault();
508
- }
509
- suppressClick = false;
510
- }
511
118
  async function snapToCallback(payload) {
512
119
  const { snapPoint } = payload;
513
120
  if (payload.id !== toValue(id) || typeof snapPoint !== "object" || Array.isArray(snapPoint)) {
@@ -584,8 +191,7 @@ export function useTrayDrag(args) {
584
191
  function destroy() {
585
192
  emitter.off("snapTo", snapToCallback);
586
193
  resizeObserverEl?.stop();
587
- resetDragState();
588
- resetListeners();
194
+ state.elRect = void 0;
589
195
  }
590
196
  onMounted(async () => {
591
197
  await initialize();
@@ -601,14 +207,6 @@ export function useTrayDrag(args) {
601
207
  await applyInitial();
602
208
  }
603
209
  );
604
- watch(disabled, (value) => {
605
- if (value && state.draggingSide) {
606
- const side = state.draggingSide;
607
- interpolateDragged({ side, to: state.snapped[side] });
608
- resetDragState();
609
- resetListeners();
610
- }
611
- });
612
210
  resizeObserverEl = useResizeObserver(elRef, () => {
613
211
  useThrottleFn(async () => {
614
212
  await getSizes();
@@ -630,10 +228,6 @@ export function useTrayDrag(args) {
630
228
  draggableSides,
631
229
  clipPath,
632
230
  handleStyle,
633
- hasDragged,
634
- dimension,
635
- onHandlePointerdown,
636
- onHandleTouchstart,
637
- onHandleClick
231
+ dimension
638
232
  };
639
233
  }
@@ -0,0 +1,16 @@
1
+ import type { MaybeRef, MaybeRefOrGetter } from 'vue';
2
+ import type { MagicTraySide, TrayState } from '../../types/index.js';
3
+ type UseTrayGestureArgs = {
4
+ id: MaybeRef<string>;
5
+ state: TrayState;
6
+ selectionLock?: 'press' | 'drag';
7
+ preventEdgeNavigation: MaybeRefOrGetter<boolean>;
8
+ };
9
+ export declare function useTrayGesture(args: UseTrayGestureArgs): {
10
+ active: Readonly<import("vue").Ref<boolean, boolean>>;
11
+ hasDragged: import("vue").ComputedRef<boolean>;
12
+ onPointerdown: (side: MagicTraySide, e: PointerEvent) => void;
13
+ onTouchstart: (side: MagicTraySide, e: TouchEvent) => void;
14
+ };
15
+ export type UseTrayGestureReturn = ReturnType<typeof useTrayGesture>;
16
+ export {};