@maas/vue-equipment 1.0.1 → 1.1.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 (24) hide show
  1. package/dist/nuxt/module.json +1 -1
  2. package/dist/nuxt/module.mjs +2 -2
  3. package/dist/plugins/MagicDrawer/index.d.ts +2 -2
  4. package/dist/plugins/MagicDrawer/src/composables/private/useDrawerDrag.mjs +127 -168
  5. package/dist/plugins/MagicDrawer/src/composables/private/useDrawerSnap.d.ts +16 -11
  6. package/dist/plugins/MagicDrawer/src/composables/private/useDrawerSnap.mjs +178 -175
  7. package/dist/plugins/MagicDrawer/src/composables/private/useDrawerState.mjs +2 -1
  8. package/dist/plugins/MagicDrawer/src/composables/private/useDrawerUtils.d.ts +3 -0
  9. package/dist/plugins/MagicDrawer/src/composables/private/useDrawerUtils.mjs +11 -1
  10. package/dist/plugins/MagicDrawer/src/composables/useMagicDrawer.d.ts +1 -0
  11. package/dist/plugins/MagicDrawer/src/composables/useMagicDrawer.mjs +2 -1
  12. package/dist/plugins/MagicDrawer/src/types/index.d.ts +8 -1
  13. package/dist/plugins/MagicTray/index.d.ts +2 -2
  14. package/dist/plugins/MagicTray/src/composables/private/useTrayDrag.mjs +99 -51
  15. package/dist/plugins/MagicTray/src/composables/private/useTrayMagnetism.mjs +3 -1
  16. package/dist/plugins/MagicTray/src/composables/private/useTraySnap.d.ts +12 -7
  17. package/dist/plugins/MagicTray/src/composables/private/useTraySnap.mjs +89 -39
  18. package/dist/plugins/MagicTray/src/composables/private/useTrayUtils.d.ts +3 -1
  19. package/dist/plugins/MagicTray/src/composables/private/useTrayUtils.mjs +11 -1
  20. package/dist/plugins/MagicTray/src/types/index.d.ts +7 -1
  21. package/dist/utils/index.d.ts +46 -1
  22. package/dist/utils/index.js +75 -0
  23. package/dist/utils/index.js.map +1 -1
  24. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@maas/vue-equipment/nuxt",
3
3
  "configKey": "vueEquipment",
4
- "version": "1.0.0",
4
+ "version": "1.0.1",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.3",
7
7
  "unbuild": "unknown"
@@ -45,7 +45,7 @@ const functions$1 = [
45
45
  {
46
46
  name: "MagicDrawer",
47
47
  "package": "plugins",
48
- lastUpdated: 1784033815000,
48
+ lastUpdated: 1792678394000,
49
49
  docs: "https://vue.equipment/plugins/MagicDrawer",
50
50
  description: "MagicDrawer is a flexible"
51
51
  },
@@ -122,7 +122,7 @@ const functions$1 = [
122
122
  {
123
123
  name: "MagicTray",
124
124
  "package": "plugins",
125
- lastUpdated: 1787844782000,
125
+ lastUpdated: 1792675743000,
126
126
  docs: "https://vue.equipment/plugins/MagicTray",
127
127
  description: "MagicTray is a flexible"
128
128
  },
@@ -6,7 +6,7 @@ import MagicDrawerContent from './src/components/MagicDrawerContent.vue.js';
6
6
  import MagicDrawerTrigger from './src/components/MagicDrawerTrigger.vue.js';
7
7
  import { useMagicDrawer } from './src/composables/useMagicDrawer.js';
8
8
  import type { Plugin } from 'vue';
9
- import type { MagicDrawerOptions, MagicDrawerSnapPoint, MagicDrawerWillSnapToPayload } from './src/types/index.js';
9
+ import type { MagicDrawerOptions, MagicDrawerSnapPoint, MagicDrawerSnapRange, MagicDrawerSnapEntry, MagicDrawerWillSnapToPayload } from './src/types/index.js';
10
10
  declare const MagicDrawerPlugin: Plugin;
11
11
  export { MagicDrawerPlugin, MagicDrawer, MagicDrawerProvider, MagicDrawerTeleport, MagicDrawerBackdrop, MagicDrawerContent, MagicDrawerTrigger, useMagicDrawer, };
12
- export type { MagicDrawerOptions, MagicDrawerSnapPoint, MagicDrawerWillSnapToPayload, };
12
+ export type { MagicDrawerOptions, MagicDrawerSnapPoint, MagicDrawerSnapRange, MagicDrawerSnapEntry, MagicDrawerWillSnapToPayload, };
@@ -21,7 +21,9 @@ import {
21
21
  guardedSetPointerCapture,
22
22
  isAndroid,
23
23
  isIOS,
24
- isWithinRange
24
+ isWithinRange,
25
+ snapCommit,
26
+ snapRelease
25
27
  } from "@maas/vue-equipment/utils";
26
28
  import { useMagicEmitter } from "@maas/vue-equipment/plugins/MagicEmitter";
27
29
  import { useMagicError } from "@maas/vue-equipment/plugins/MagicError";
@@ -69,10 +71,12 @@ export function useDrawerDrag(args) {
69
71
  absDirectionX,
70
72
  absDirectionY,
71
73
  elRect,
72
- wrapperRect
74
+ wrapperRect,
75
+ activeSnapPoint
73
76
  } = toRefs(state);
74
77
  const { isActive, close } = useMagicDrawer(id);
75
78
  let lastPendingTarget = void 0;
79
+ let flicked = false;
76
80
  let pointerdownTarget = void 0;
77
81
  let cancelPointerup = void 0;
78
82
  let cancelPointermove = void 0;
@@ -99,22 +103,23 @@ export function useDrawerDrag(args) {
99
103
  () => `transform: translate(${draggedX.value}px, ${draggedY.value}px)`
100
104
  );
101
105
  const snapMode = computed(() => toValue(snap).mode);
102
- const draggedRefX = computed(
103
- () => snapMode.value === "step" ? lastDraggedX.value : draggedX.value
104
- );
105
- const draggedRefY = computed(
106
- () => snapMode.value === "step" ? lastDraggedY.value : draggedY.value
107
- );
106
+ const isVertical = computed(() => {
107
+ const side = toValue(position);
108
+ return side === "top" || side === "bottom";
109
+ });
108
110
  const {
109
111
  snappedY,
110
112
  snappedX,
111
- activeSnapPoint,
112
- snapTo,
113
- snapPointsMap,
114
- interpolateDragged,
115
- findClosestSnapPoint,
116
113
  drawerHeight,
117
- drawerWidth
114
+ drawerWidth,
115
+ mappedSnapPoints,
116
+ mappedRanges,
117
+ rangeAt,
118
+ snapPointAt,
119
+ restingOffset,
120
+ isSnapTarget,
121
+ snapTo,
122
+ interpolateDragged
118
123
  } = useDrawerSnap({
119
124
  id,
120
125
  wrapperRect,
@@ -124,7 +129,8 @@ export function useDrawerDrag(args) {
124
129
  position,
125
130
  overshoot,
126
131
  draggedY,
127
- draggedX
132
+ draggedX,
133
+ activeSnapPoint
128
134
  });
129
135
  const { canDrag, canInterpolate, lockScroll } = useDrawerGuards({
130
136
  elRef,
@@ -142,96 +148,79 @@ export function useDrawerDrag(args) {
142
148
  wrapperRect.value = wrapper ? markRaw(wrapper.getBoundingClientRect()) : void 0;
143
149
  await nextTick();
144
150
  }
145
- function checkPosition() {
146
- const distanceX = Math.abs(draggedX.value - lastDraggedX.value);
147
- const distanceY = Math.abs(draggedY.value - lastDraggedY.value);
148
- switch (position) {
149
- case "bottom":
150
- case "top": {
151
- if (distanceY > toValue(threshold).distance) {
152
- const snapPointY = findClosestSnapPoint({
153
- draggedX: 0,
154
- draggedY: draggedRefY.value,
155
- direction: relDirectionY.value
156
- });
157
- if (Math.abs(snapPointY ?? 0) === drawerHeight.value) {
158
- shouldClose.value = true;
159
- } else {
160
- interpolateTo.value = snapPointY;
161
- }
162
- }
163
- break;
164
- }
165
- case "right":
166
- case "left": {
167
- if (distanceX > toValue(threshold).distance) {
168
- const snapPointX = findClosestSnapPoint({
169
- draggedX: draggedRefX.value,
170
- draggedY: 0,
171
- direction: relDirectionX.value
172
- });
173
- if (Math.abs(snapPointX ?? 0) === drawerWidth.value) {
174
- shouldClose.value = true;
175
- } else {
176
- interpolateTo.value = snapPointX;
177
- }
178
- }
179
- break;
180
- }
151
+ function snapDrag() {
152
+ const layout = {
153
+ points: mappedSnapPoints.value,
154
+ ranges: mappedRanges.value,
155
+ mode: snapMode.value
156
+ };
157
+ return isVertical.value ? {
158
+ ...layout,
159
+ rest: snappedY.value,
160
+ start: lastDraggedY.value,
161
+ position: draggedY.value
162
+ } : {
163
+ ...layout,
164
+ rest: snappedX.value,
165
+ start: lastDraggedX.value,
166
+ position: draggedX.value
167
+ };
168
+ }
169
+ function isClosing(offset) {
170
+ const extent = isVertical.value ? drawerHeight.value : drawerWidth.value;
171
+ if (extent <= 0) {
172
+ return false;
173
+ }
174
+ if (Math.abs(offset) === extent) {
175
+ return true;
181
176
  }
177
+ const side = toValue(position);
178
+ const closed = side === "bottom" || side === "right" ? extent : -extent;
179
+ const rest = isVertical.value ? snappedY.value : snappedX.value;
180
+ const range = rangeAt(offset);
181
+ const reachesClosed = range?.min === closed || range?.max === closed;
182
+ const towardClosed = Math.abs(closed - offset) < Math.abs(closed - rest);
183
+ return hasDragged.value && reachesClosed && towardClosed && Math.abs(closed - offset) <= toValue(threshold).distance;
184
+ }
185
+ function settleTarget() {
186
+ const target = snapRelease({
187
+ ...snapDrag(),
188
+ committed: interpolateTo.value,
189
+ flicked,
190
+ tapped: !hasDragged.value
191
+ });
192
+ return restingOffset(target);
182
193
  }
183
194
  function checkMomentum() {
184
195
  const elapsed = Date.now() - dragStart.value.getTime();
185
- const distanceX = Math.abs(draggedX.value - lastDraggedX.value);
186
- const distanceY = Math.abs(draggedY.value - lastDraggedY.value);
187
- const velocityX = elapsed && distanceX ? distanceX / elapsed : 0;
188
- const velocityY = elapsed && distanceY ? distanceY / elapsed : 0;
189
- switch (position) {
190
- case "bottom":
191
- case "top": {
192
- if (velocityY > toValue(threshold).momentum) {
193
- const snapPointY = findClosestSnapPoint({
194
- draggedX: 0,
195
- draggedY: draggedRefY.value,
196
- direction: relDirectionY.value
197
- });
198
- if (Math.abs(snapPointY ?? 0) === drawerHeight.value) {
199
- shouldClose.value = true;
200
- } else {
201
- interpolateTo.value = snapPointY;
202
- }
203
- }
204
- break;
205
- }
206
- case "right":
207
- case "left": {
208
- if (velocityX > toValue(threshold).momentum) {
209
- const snapPointX = findClosestSnapPoint({
210
- draggedX: draggedRefX.value,
211
- draggedY,
212
- direction: relDirectionX.value
213
- });
214
- if (Math.abs(snapPointX ?? 0) === drawerWidth.value) {
215
- shouldClose.value = true;
216
- } else {
217
- interpolateTo.value = snapPointX;
218
- }
219
- }
220
- break;
221
- }
222
- }
196
+ const { position: dragged, start } = snapDrag();
197
+ const distance = Math.abs(dragged - start);
198
+ const velocity = elapsed && distance ? distance / elapsed : 0;
199
+ flicked = velocity > toValue(threshold).momentum;
200
+ }
201
+ function checkPosition() {
202
+ const direction = isVertical.value ? relDirectionY.value : relDirectionX.value;
203
+ interpolateTo.value = snapCommit({
204
+ ...snapDrag(),
205
+ distance: toValue(threshold).distance,
206
+ flicked,
207
+ flickDirection: direction === "absolute" ? void 0 : direction
208
+ });
209
+ shouldClose.value = isClosing(settleTarget());
223
210
  }
224
211
  function emitWillSnapTo() {
225
- const target = interpolateTo.value || interpolateTo.value === 0 ? interpolateTo.value : position === "top" || position === "bottom" ? snappedY.value : snappedX.value;
226
212
  if (shouldClose.value) {
227
213
  return;
228
214
  }
229
- if (target === lastPendingTarget) {
215
+ const target = settleTarget();
216
+ const isPoint = mappedSnapPoints.value.includes(target);
217
+ const pending = !isPoint && rangeAt(target)?.range || target;
218
+ if (pending === lastPendingTarget) {
230
219
  return;
231
220
  }
232
- lastPendingTarget = target;
233
- const snapPoint = snapPointsMap.value[target];
234
- if (!snapPoint && snapPoint !== 0) {
221
+ lastPendingTarget = pending;
222
+ const snapPoint = snapPointAt(target);
223
+ if (snapPoint === void 0) {
235
224
  return;
236
225
  }
237
226
  emitter.emit("willSnapTo", {
@@ -239,6 +228,27 @@ export function useDrawerDrag(args) {
239
228
  snapPoint
240
229
  });
241
230
  }
231
+ function settle(target) {
232
+ if (shouldClose.value) {
233
+ close();
234
+ return;
235
+ }
236
+ const destination = settleTarget();
237
+ const snapped = isVertical.value ? snappedY.value : snappedX.value;
238
+ if (destination === snapped && interpolateTo.value === void 0) {
239
+ interpolateDragged({ to: snapped });
240
+ return;
241
+ }
242
+ activeSnapPoint.value = snapPointAt(destination);
243
+ if (isVertical.value) {
244
+ snappedY.value = destination;
245
+ } else {
246
+ snappedX.value = destination;
247
+ }
248
+ if (scrollLock && scrollLock.value || canInterpolate(target)) {
249
+ interpolateDragged({ to: destination });
250
+ }
251
+ }
242
252
  function setDragged({ x, y }) {
243
253
  const os = toValue(overshoot);
244
254
  switch (position) {
@@ -336,14 +346,23 @@ export function useDrawerDrag(args) {
336
346
  resetSnapState();
337
347
  }
338
348
  }
349
+ function isUnknownSnapPoint(snapPoint) {
350
+ return !!wrapperRect.value && !isSnapTarget(snapPoint);
351
+ }
339
352
  function snapToCallback(payload) {
340
353
  if (payload.id === toValue(id)) {
354
+ const snapPoint = payload.snapPoint;
341
355
  if (!toValue(isActive)) {
342
356
  logWarning("Cannot snap to point when drawer is not open");
343
357
  return;
358
+ } else if (isUnknownSnapPoint(snapPoint)) {
359
+ logWarning(
360
+ `Cannot snap to ${snapPoint}, which is neither a snap point nor inside a range`
361
+ );
362
+ return;
344
363
  } else {
345
364
  snapTo({
346
- snapPoint: payload.snapPoint,
365
+ snapPoint,
347
366
  interpolate: true,
348
367
  duration: payload.duration
349
368
  });
@@ -414,41 +433,7 @@ export function useDrawerDrag(args) {
414
433
  });
415
434
  }
416
435
  function onPointerup(e) {
417
- if (shouldClose.value) {
418
- close();
419
- } else if (interpolateTo.value || interpolateTo.value === 0) {
420
- if (scrollLock && scrollLock.value || canInterpolate(e.target)) {
421
- interpolateDragged({
422
- to: interpolateTo.value
423
- });
424
- }
425
- activeSnapPoint.value = snapPointsMap.value[interpolateTo.value];
426
- switch (position) {
427
- case "bottom":
428
- case "top":
429
- snappedY.value = interpolateTo.value;
430
- break;
431
- case "right":
432
- case "left":
433
- snappedX.value = interpolateTo.value;
434
- break;
435
- }
436
- } else {
437
- switch (position) {
438
- case "bottom":
439
- case "top":
440
- interpolateDragged({
441
- to: snappedY.value
442
- });
443
- break;
444
- case "right":
445
- case "left":
446
- interpolateDragged({
447
- to: snappedX.value
448
- });
449
- break;
450
- }
451
- }
436
+ settle(e.target);
452
437
  emitter.emit("afterDrag", {
453
438
  id: toValue(id),
454
439
  x: draggedX.value,
@@ -498,41 +483,7 @@ export function useDrawerDrag(args) {
498
483
  });
499
484
  }
500
485
  function onTouchend(e) {
501
- if (shouldClose.value) {
502
- close();
503
- } else if (interpolateTo.value || interpolateTo.value === 0) {
504
- if (scrollLock && scrollLock.value || canInterpolate(e.target)) {
505
- interpolateDragged({
506
- to: interpolateTo.value
507
- });
508
- }
509
- activeSnapPoint.value = snapPointsMap.value[interpolateTo.value];
510
- switch (position) {
511
- case "bottom":
512
- case "top":
513
- snappedY.value = interpolateTo.value;
514
- break;
515
- case "right":
516
- case "left":
517
- snappedX.value = interpolateTo.value;
518
- break;
519
- }
520
- } else {
521
- switch (position) {
522
- case "bottom":
523
- case "top":
524
- interpolateDragged({
525
- to: snappedY.value
526
- });
527
- break;
528
- case "right":
529
- case "left":
530
- interpolateDragged({
531
- to: snappedX.value
532
- });
533
- break;
534
- }
535
- }
486
+ settle(e.target);
536
487
  emitter.emit("afterDrag", {
537
488
  id: toValue(id),
538
489
  x: draggedX.value,
@@ -557,6 +508,7 @@ export function useDrawerDrag(args) {
557
508
  }
558
509
  dragging.value = true;
559
510
  lastPendingTarget = void 0;
511
+ flicked = false;
560
512
  pointerdownTarget = e.target;
561
513
  guardedSetPointerCapture({
562
514
  event: e,
@@ -618,6 +570,7 @@ export function useDrawerDrag(args) {
618
570
  e.stopPropagation();
619
571
  dragging.value = true;
620
572
  lastPendingTarget = void 0;
573
+ flicked = false;
621
574
  pointerdownTarget = e.target;
622
575
  emitter.emit("beforeDrag", {
623
576
  id: toValue(id),
@@ -657,9 +610,16 @@ export function useDrawerDrag(args) {
657
610
  async () => {
658
611
  await getSizes();
659
612
  const snapPoint = toValue(initial)?.snapPoint;
660
- if (snapPoint) {
661
- snapTo({ snapPoint, interpolate: false });
613
+ if (!snapPoint) {
614
+ return;
615
+ }
616
+ if (isUnknownSnapPoint(snapPoint)) {
617
+ logWarning(
618
+ `initial.snapPoint (${snapPoint}) is neither a snap point nor inside a range and is ignored`
619
+ );
620
+ return;
662
621
  }
622
+ snapTo({ snapPoint, interpolate: false });
663
623
  }
664
624
  );
665
625
  watch([snappedX, snappedY], ([x, y]) => {
@@ -679,7 +639,6 @@ export function useDrawerDrag(args) {
679
639
  await getSizes();
680
640
  if (activeSnapPoint.value) {
681
641
  await snapTo({ snapPoint: activeSnapPoint.value, interpolate: false });
682
- snapPointsMap.trigger();
683
642
  }
684
643
  }, 100)();
685
644
  });
@@ -1,21 +1,17 @@
1
1
  import type { MaybeRef, Ref } from 'vue';
2
- import type { MagicDrawerSnapPoint, RequiredMagicDrawerOptions } from '../../types/index.js';
2
+ import type { MagicDrawerSnapPoint, MagicDrawerSnapRange, RequiredMagicDrawerOptions } from '../../types/index.js';
3
3
  type UseDrawerSnapArgs = {
4
4
  id: MaybeRef<string>;
5
5
  wrapperRect: Ref<DOMRect | undefined>;
6
6
  draggedY: Ref<number>;
7
7
  draggedX: Ref<number>;
8
+ activeSnapPoint: Ref<MagicDrawerSnapPoint | undefined>;
8
9
  position: MaybeRef<RequiredMagicDrawerOptions['position']>;
9
10
  animation: MaybeRef<RequiredMagicDrawerOptions['animation']>;
10
11
  snapPoints: MaybeRef<RequiredMagicDrawerOptions['snapPoints']>;
11
12
  preventDragClose: MaybeRef<RequiredMagicDrawerOptions['preventDragClose']>;
12
13
  overshoot: MaybeRef<number>;
13
14
  };
14
- type FindClosestSnapPointArgs = {
15
- draggedY: MaybeRef<number>;
16
- draggedX: MaybeRef<number>;
17
- direction?: 'below' | 'above' | 'absolute';
18
- };
19
15
  type SnapToArgs = {
20
16
  snapPoint: MagicDrawerSnapPoint;
21
17
  interpolate: boolean;
@@ -26,15 +22,24 @@ type InterpolateDraggedArgs = {
26
22
  duration?: number;
27
23
  easing?: (t: number) => number;
28
24
  };
25
+ type MappedSnapRange = {
26
+ min: number;
27
+ max: number;
28
+ momentum?: boolean;
29
+ range: MagicDrawerSnapRange;
30
+ };
29
31
  export declare function useDrawerSnap(args: UseDrawerSnapArgs): {
30
32
  snappedY: import("vue").ShallowRef<number, number>;
31
33
  snappedX: import("vue").ShallowRef<number, number>;
32
- activeSnapPoint: import("vue").ShallowRef<MagicDrawerSnapPoint | undefined, MagicDrawerSnapPoint | undefined>;
33
- snapTo: (args: SnapToArgs) => Promise<void>;
34
- findClosestSnapPoint: (args: FindClosestSnapPointArgs) => number | undefined;
35
- interpolateDragged: (args: InterpolateDraggedArgs) => void;
36
- snapPointsMap: import("@vueuse/core").ComputedRefWithControl<Record<number, MagicDrawerSnapPoint>>;
37
34
  drawerHeight: import("vue").ComputedRef<number>;
38
35
  drawerWidth: import("vue").ComputedRef<number>;
36
+ mappedSnapPoints: import("vue").ComputedRef<any[]>;
37
+ mappedRanges: import("vue").ComputedRef<MappedSnapRange[]>;
38
+ rangeAt: (offset: number) => any;
39
+ snapPointAt: (offset: number) => MagicDrawerSnapPoint | undefined;
40
+ restingOffset: (offset: number) => any;
41
+ isSnapTarget: (snapPoint: MagicDrawerSnapPoint) => boolean;
42
+ snapTo: (args: SnapToArgs) => Promise<void>;
43
+ interpolateDragged: (args: InterpolateDraggedArgs) => void;
39
44
  };
40
45
  export {};