@maas/vue-equipment 1.0.0-beta.72 → 1.0.0-beta.74

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@maas/vue-equipment/nuxt",
3
3
  "configKey": "vueEquipment",
4
- "version": "1.0.0-beta.71",
4
+ "version": "1.0.0-beta.73",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "unknown"
@@ -295,7 +295,7 @@ export function useDraggableDrag(args) {
295
295
  if (!e.isPrimary) {
296
296
  return;
297
297
  }
298
- setDragged({ x: e.screenX, y: e.screenY });
298
+ setDragged({ x: e.pageX, y: e.pageY });
299
299
  if (!distanceThresholdReached.value) {
300
300
  checkDistance();
301
301
  }
@@ -342,8 +342,8 @@ export function useDraggableDrag(args) {
342
342
  intermediateDraggedY.value = draggedY.value;
343
343
  lastDraggedX.value = draggedX.value;
344
344
  lastDraggedY.value = draggedY.value;
345
- originX.value = e.screenX - draggedX.value;
346
- originY.value = e.screenY - draggedY.value;
345
+ originX.value = e.pageX - draggedX.value;
346
+ originY.value = e.pageY - draggedY.value;
347
347
  cancelPointerup = useEventListener(document, "pointerup", onPointerup);
348
348
  cancelPointercancel = useEventListener(
349
349
  document,
@@ -372,7 +372,7 @@ export function useDrawerDrag(args) {
372
372
  e.stopImmediatePropagation();
373
373
  e.stopPropagation();
374
374
  shouldClose.value = false;
375
- checkDirection({ x: e.screenX, y: e.screenY });
375
+ checkDirection({ x: e.clientX, y: e.clientY });
376
376
  if (!scrollLock) {
377
377
  const scrollLockTarget = lockScroll(e.target);
378
378
  if (scrollLockTarget) {
@@ -384,7 +384,7 @@ export function useDrawerDrag(args) {
384
384
  if (!canDrag(dragTarget)) {
385
385
  return;
386
386
  }
387
- setDragged({ x: e.screenX, y: e.screenY });
387
+ setDragged({ x: e.clientX, y: e.clientY });
388
388
  checkMomentum();
389
389
  checkPosition();
390
390
  emitter.emit("drag", {
@@ -450,9 +450,9 @@ export function useDrawerDrag(args) {
450
450
  if (!firstTouch) {
451
451
  return;
452
452
  }
453
- checkDirection({ x: firstTouch.screenX, y: firstTouch.screenY });
453
+ checkDirection({ x: firstTouch.clientX, y: firstTouch.clientY });
454
454
  shouldClose.value = false;
455
- checkDirection({ x: firstTouch.screenX, y: firstTouch.screenY });
455
+ checkDirection({ x: firstTouch.clientX, y: firstTouch.clientY });
456
456
  if (!scrollLock) {
457
457
  const scrollLockTarget = lockScroll(firstTouch.target);
458
458
  if (scrollLockTarget) {
@@ -467,7 +467,7 @@ export function useDrawerDrag(args) {
467
467
  if (hasDragged.value) {
468
468
  e.preventDefault();
469
469
  }
470
- setDragged({ x: firstTouch.screenX, y: firstTouch.screenY });
470
+ setDragged({ x: firstTouch.clientX, y: firstTouch.clientY });
471
471
  checkMomentum();
472
472
  checkPosition();
473
473
  emitter.emit("drag", {
@@ -566,8 +566,8 @@ export function useDrawerDrag(args) {
566
566
  }) : void 0;
567
567
  cancelTouchend = isIOS() || isAndroid() ? useEventListener(document, "touchend", onTouchend) : void 0;
568
568
  cancelTouchcancel = isIOS() || isAndroid() ? useEventListener(document, "touchcancel", onTouchend) : void 0;
569
- originX.value = e.screenX - draggedX.value;
570
- originY.value = e.screenY - draggedY.value;
569
+ originX.value = e.clientX - draggedX.value;
570
+ originY.value = e.clientY - draggedY.value;
571
571
  dragStart.value = /* @__PURE__ */ new Date();
572
572
  onPointermove(e);
573
573
  }
@@ -608,8 +608,8 @@ export function useDrawerDrag(args) {
608
608
  if (!firstTouch) {
609
609
  return;
610
610
  }
611
- originX.value = firstTouch.screenX - draggedX.value;
612
- originY.value = firstTouch.screenY - draggedY.value;
611
+ originX.value = firstTouch.clientX - draggedX.value;
612
+ originY.value = firstTouch.clientY - draggedY.value;
613
613
  dragStart.value = /* @__PURE__ */ new Date();
614
614
  onTouchmove(e);
615
615
  }
@@ -1,6 +1,6 @@
1
1
  export declare function useMagicEmitter(): {
2
2
  on: {
3
- <Key extends "progress" | "acceptAll" | "acceptSelected" | "rejectAll" | "magnet" | "collision" | keyof import("../../../MagicPlayer/src/types/index.js").PlayerEvents | keyof import("../../../MagicDraggable/src/types/index.js").DraggableEvents | keyof import("../../../MagicAccordion/src/types/index.js").AccordionEvents>(type: Key, handler: import("mitt").Handler<({
3
+ <Key extends "progress" | "acceptAll" | "acceptSelected" | "rejectAll" | "magnet" | "willSnapTo" | "collision" | keyof import("../../../MagicPlayer/src/types/index.js").PlayerEvents | keyof import("../../../MagicDraggable/src/types/index.js").DraggableEvents | keyof import("../../../MagicAccordion/src/types/index.js").AccordionEvents>(type: Key, handler: import("mitt").Handler<({
4
4
  beforeEnter: string | {
5
5
  id: string;
6
6
  viewId: string;
@@ -329,6 +329,7 @@ export declare function useMagicEmitter(): {
329
329
  magnet: {
330
330
  id: string;
331
331
  } & import("../../../MagicTray/index.js").TraySidePayload;
332
+ willSnapTo: import("../../../MagicTray/src/types/index.js").TrayWillSnapToPayload;
332
333
  } & Omit<object, keyof import("../../../MagicTray/src/types/index.js").TrayEvents>, keyof import("../../../MagicToast/src/types/index.js").ToastEvents>, "collision">, keyof import("../../../MagicPlayer/src/types/index.js").PlayerEvents>, keyof import("../../../MagicMenu/src/types/index.js").MenuEvents>, keyof import("../../../MagicModal/src/types/index.js").ModalEvents>, keyof import("../../../MagicDrawer/src/types/index.js").DrawerEvents>, keyof import("../../../MagicDraggable/src/types/index.js").DraggableEvents>, keyof import("../../../MagicCookie/src/types/index.js").CookieEvents>, keyof import("../../../MagicAccordion/src/types/index.js").AccordionEvents>)[Key]>): void;
333
334
  (type: "*", handler: import("mitt").WildcardHandler<{
334
335
  beforeEnter: string | {
@@ -659,10 +660,11 @@ export declare function useMagicEmitter(): {
659
660
  magnet: {
660
661
  id: string;
661
662
  } & import("../../../MagicTray/index.js").TraySidePayload;
663
+ willSnapTo: import("../../../MagicTray/src/types/index.js").TrayWillSnapToPayload;
662
664
  } & Omit<object, keyof import("../../../MagicTray/src/types/index.js").TrayEvents>, keyof import("../../../MagicToast/src/types/index.js").ToastEvents>, "collision">, keyof import("../../../MagicPlayer/src/types/index.js").PlayerEvents>, keyof import("../../../MagicMenu/src/types/index.js").MenuEvents>, keyof import("../../../MagicModal/src/types/index.js").ModalEvents>, keyof import("../../../MagicDrawer/src/types/index.js").DrawerEvents>, keyof import("../../../MagicDraggable/src/types/index.js").DraggableEvents>, keyof import("../../../MagicCookie/src/types/index.js").CookieEvents>, keyof import("../../../MagicAccordion/src/types/index.js").AccordionEvents>>): void;
663
665
  };
664
666
  off: {
665
- <Key extends "progress" | "acceptAll" | "acceptSelected" | "rejectAll" | "magnet" | "collision" | keyof import("../../../MagicPlayer/src/types/index.js").PlayerEvents | keyof import("../../../MagicDraggable/src/types/index.js").DraggableEvents | keyof import("../../../MagicAccordion/src/types/index.js").AccordionEvents>(type: Key, handler?: import("mitt").Handler<({
667
+ <Key extends "progress" | "acceptAll" | "acceptSelected" | "rejectAll" | "magnet" | "willSnapTo" | "collision" | keyof import("../../../MagicPlayer/src/types/index.js").PlayerEvents | keyof import("../../../MagicDraggable/src/types/index.js").DraggableEvents | keyof import("../../../MagicAccordion/src/types/index.js").AccordionEvents>(type: Key, handler?: import("mitt").Handler<({
666
668
  beforeEnter: string | {
667
669
  id: string;
668
670
  viewId: string;
@@ -991,6 +993,7 @@ export declare function useMagicEmitter(): {
991
993
  magnet: {
992
994
  id: string;
993
995
  } & import("../../../MagicTray/index.js").TraySidePayload;
996
+ willSnapTo: import("../../../MagicTray/src/types/index.js").TrayWillSnapToPayload;
994
997
  } & Omit<object, keyof import("../../../MagicTray/src/types/index.js").TrayEvents>, keyof import("../../../MagicToast/src/types/index.js").ToastEvents>, "collision">, keyof import("../../../MagicPlayer/src/types/index.js").PlayerEvents>, keyof import("../../../MagicMenu/src/types/index.js").MenuEvents>, keyof import("../../../MagicModal/src/types/index.js").ModalEvents>, keyof import("../../../MagicDrawer/src/types/index.js").DrawerEvents>, keyof import("../../../MagicDraggable/src/types/index.js").DraggableEvents>, keyof import("../../../MagicCookie/src/types/index.js").CookieEvents>, keyof import("../../../MagicAccordion/src/types/index.js").AccordionEvents>)[Key]> | undefined): void;
995
998
  (type: "*", handler: import("mitt").WildcardHandler<{
996
999
  beforeEnter: string | {
@@ -1321,10 +1324,11 @@ export declare function useMagicEmitter(): {
1321
1324
  magnet: {
1322
1325
  id: string;
1323
1326
  } & import("../../../MagicTray/index.js").TraySidePayload;
1327
+ willSnapTo: import("../../../MagicTray/src/types/index.js").TrayWillSnapToPayload;
1324
1328
  } & Omit<object, keyof import("../../../MagicTray/src/types/index.js").TrayEvents>, keyof import("../../../MagicToast/src/types/index.js").ToastEvents>, "collision">, keyof import("../../../MagicPlayer/src/types/index.js").PlayerEvents>, keyof import("../../../MagicMenu/src/types/index.js").MenuEvents>, keyof import("../../../MagicModal/src/types/index.js").ModalEvents>, keyof import("../../../MagicDrawer/src/types/index.js").DrawerEvents>, keyof import("../../../MagicDraggable/src/types/index.js").DraggableEvents>, keyof import("../../../MagicCookie/src/types/index.js").CookieEvents>, keyof import("../../../MagicAccordion/src/types/index.js").AccordionEvents>>): void;
1325
1329
  };
1326
1330
  emit: {
1327
- <Key extends "progress" | "acceptAll" | "acceptSelected" | "rejectAll" | "magnet" | "collision" | keyof import("../../../MagicPlayer/src/types/index.js").PlayerEvents | keyof import("../../../MagicDraggable/src/types/index.js").DraggableEvents | keyof import("../../../MagicAccordion/src/types/index.js").AccordionEvents>(type: Key, event: ({
1331
+ <Key extends "progress" | "acceptAll" | "acceptSelected" | "rejectAll" | "magnet" | "willSnapTo" | "collision" | keyof import("../../../MagicPlayer/src/types/index.js").PlayerEvents | keyof import("../../../MagicDraggable/src/types/index.js").DraggableEvents | keyof import("../../../MagicAccordion/src/types/index.js").AccordionEvents>(type: Key, event: ({
1328
1332
  beforeEnter: string | {
1329
1333
  id: string;
1330
1334
  viewId: string;
@@ -1653,8 +1657,9 @@ export declare function useMagicEmitter(): {
1653
1657
  magnet: {
1654
1658
  id: string;
1655
1659
  } & import("../../../MagicTray/index.js").TraySidePayload;
1660
+ willSnapTo: import("../../../MagicTray/src/types/index.js").TrayWillSnapToPayload;
1656
1661
  } & Omit<object, keyof import("../../../MagicTray/src/types/index.js").TrayEvents>, keyof import("../../../MagicToast/src/types/index.js").ToastEvents>, "collision">, keyof import("../../../MagicPlayer/src/types/index.js").PlayerEvents>, keyof import("../../../MagicMenu/src/types/index.js").MenuEvents>, keyof import("../../../MagicModal/src/types/index.js").ModalEvents>, keyof import("../../../MagicDrawer/src/types/index.js").DrawerEvents>, keyof import("../../../MagicDraggable/src/types/index.js").DraggableEvents>, keyof import("../../../MagicCookie/src/types/index.js").CookieEvents>, keyof import("../../../MagicAccordion/src/types/index.js").AccordionEvents>)[Key]): void;
1657
- <Key extends "progress" | "acceptAll" | "acceptSelected" | "rejectAll" | "magnet" | "collision" | keyof import("../../../MagicPlayer/src/types/index.js").PlayerEvents | keyof import("../../../MagicDraggable/src/types/index.js").DraggableEvents | keyof import("../../../MagicAccordion/src/types/index.js").AccordionEvents>(type: undefined extends ({
1662
+ <Key extends "progress" | "acceptAll" | "acceptSelected" | "rejectAll" | "magnet" | "willSnapTo" | "collision" | keyof import("../../../MagicPlayer/src/types/index.js").PlayerEvents | keyof import("../../../MagicDraggable/src/types/index.js").DraggableEvents | keyof import("../../../MagicAccordion/src/types/index.js").AccordionEvents>(type: undefined extends ({
1658
1663
  beforeEnter: string | {
1659
1664
  id: string;
1660
1665
  viewId: string;
@@ -1983,6 +1988,7 @@ export declare function useMagicEmitter(): {
1983
1988
  magnet: {
1984
1989
  id: string;
1985
1990
  } & import("../../../MagicTray/index.js").TraySidePayload;
1991
+ willSnapTo: import("../../../MagicTray/src/types/index.js").TrayWillSnapToPayload;
1986
1992
  } & Omit<object, keyof import("../../../MagicTray/src/types/index.js").TrayEvents>, keyof import("../../../MagicToast/src/types/index.js").ToastEvents>, "collision">, keyof import("../../../MagicPlayer/src/types/index.js").PlayerEvents>, keyof import("../../../MagicMenu/src/types/index.js").MenuEvents>, keyof import("../../../MagicModal/src/types/index.js").ModalEvents>, keyof import("../../../MagicDrawer/src/types/index.js").DrawerEvents>, keyof import("../../../MagicDraggable/src/types/index.js").DraggableEvents>, keyof import("../../../MagicCookie/src/types/index.js").CookieEvents>, keyof import("../../../MagicAccordion/src/types/index.js").AccordionEvents>)[Key] ? Key : never): void;
1987
1993
  };
1988
1994
  };
@@ -246,7 +246,7 @@ export function useToastDrag(args) {
246
246
  e.stopImmediatePropagation();
247
247
  e.stopPropagation();
248
248
  shouldClose.value = false;
249
- setDragged({ x: e.screenX, y: e.screenY });
249
+ setDragged({ x: e.clientX, y: e.clientY });
250
250
  checkMomentum();
251
251
  checkPosition();
252
252
  emitter.emit("drag", {
@@ -294,8 +294,8 @@ export function useToastDrag(args) {
294
294
  { passive: false }
295
295
  );
296
296
  cancelTouchend = isIOS() ? useEventListener(document, "touchend", onPointerup) : void 0;
297
- originX.value = e.screenX - draggedX.value;
298
- originY.value = e.screenY - draggedY.value;
297
+ originX.value = e.clientX - draggedX.value;
298
+ originY.value = e.clientY - draggedY.value;
299
299
  dragStart.value = /* @__PURE__ */ new Date();
300
300
  onPointermove(e);
301
301
  }
@@ -8,4 +8,4 @@ import type { Plugin } from 'vue';
8
8
  import type { MagicTrayOptions, TraySide, TraySidePayload, TraySnapMode, TraySnapPoint, TraySnapPointPayload, TrayTransformAxis } from './src/types/index.js';
9
9
  declare const MagicTrayPlugin: Plugin;
10
10
  export { MagicTrayPlugin, MagicTray, MagicTrayProvider, MagicTrayContent, MagicTrayHandle, MagicTrayTransform, useMagicTray, };
11
- export type { MagicTrayOptions, TraySide, TraySidePayload, TraySnapMode, TraySnapPoint, TraySnapPointPayload, TrayTransformAxis, };
11
+ export type { MagicTrayOptions, TraySide, TraySidePayload, TraySnapMode, TraySnapPoint, TraySnapPointPayload, TrayWillSnapToPayload, TrayTransformAxis, };
@@ -24,10 +24,10 @@
24
24
  :data-drag-left="draggableSides.includes('left')"
25
25
  :style="{ clipPath }"
26
26
  >
27
- <div class="magic-tray-content__bg" v-if="slots.background">
27
+ <div v-if="slots.background" class="magic-tray-content__bg">
28
28
  <slot name="background" />
29
29
  </div>
30
- <div class="magic-tray-content__slot" v-if="slots.default">
30
+ <div v-if="slots.default" class="magic-tray-content__slot">
31
31
  <slot />
32
32
  </div>
33
33
  </component>
@@ -64,6 +64,7 @@ export function useTrayDrag(args) {
64
64
  const points = mappedSnapPoints(side);
65
65
  return points.length ? snapPointsMap(side)[points[0]] : void 0;
66
66
  }
67
+ let lastPendingTarget = void 0;
67
68
  let cancelPointerup = void 0;
68
69
  let cancelPointermove = void 0;
69
70
  let cancelPointercancel = void 0;
@@ -191,7 +192,8 @@ export function useTrayDrag(args) {
191
192
  if (newInset === state.dragged[side]) {
192
193
  return;
193
194
  }
194
- state.relDirection[side] = newInset < state.dragged[side] ? "below" : "above";
195
+ const prev = state.dragged[side];
196
+ state.relDirection[side] = newInset < prev ? "below" : "above";
195
197
  state.dragged[side] = newInset;
196
198
  }
197
199
  function checkPosition(side) {
@@ -202,8 +204,22 @@ export function useTrayDrag(args) {
202
204
  value: snapReference(side),
203
205
  direction: delta < 0 ? "below" : "above"
204
206
  });
207
+ } else {
208
+ state.interpolateTo = void 0;
205
209
  }
206
210
  }
211
+ function emitWillSnapTo(side) {
212
+ const target = state.interpolateTo ?? state.snapped[side];
213
+ if (target === lastPendingTarget) return;
214
+ lastPendingTarget = target;
215
+ const snapPoint = snapPointsMap(side)[target];
216
+ if (!snapPoint && snapPoint !== 0) return;
217
+ emitter.emit("willSnapTo", {
218
+ id: toValue(id),
219
+ side,
220
+ snapPoint
221
+ });
222
+ }
207
223
  function checkMomentum(side) {
208
224
  const elapsed = Date.now() - state.dragStart.getTime();
209
225
  const distance = Math.abs(state.dragged[side] - state.lastDragged[side]);
@@ -248,10 +264,11 @@ export function useTrayDrag(args) {
248
264
  }
249
265
  e.stopImmediatePropagation();
250
266
  e.stopPropagation();
251
- const coord = isVertical(side) ? e.screenY : e.screenX;
267
+ const coord = isVertical(side) ? e.clientY : e.clientX;
252
268
  setDragged(side, coord);
253
269
  checkMomentum(side);
254
270
  checkPosition(side);
271
+ emitWillSnapTo(side);
255
272
  emitter.emit("drag", {
256
273
  id: toValue(id),
257
274
  side,
@@ -286,10 +303,11 @@ export function useTrayDrag(args) {
286
303
  if (hasDragged.value) {
287
304
  e.preventDefault();
288
305
  }
289
- const coord = isVertical(side) ? firstTouch.screenY : firstTouch.screenX;
306
+ const coord = isVertical(side) ? firstTouch.clientY : firstTouch.clientX;
290
307
  setDragged(side, coord);
291
308
  checkMomentum(side);
292
309
  checkPosition(side);
310
+ emitWillSnapTo(side);
293
311
  emitter.emit("drag", {
294
312
  id: toValue(id),
295
313
  side,
@@ -316,6 +334,7 @@ export function useTrayDrag(args) {
316
334
  state.dragged[side] += state.magnetic[side];
317
335
  state.magnetic[side] = 0;
318
336
  state.lastDragged[side] = state.dragged[side];
337
+ lastPendingTarget = void 0;
319
338
  pointerdownTarget = target;
320
339
  switch (side) {
321
340
  case "top":
@@ -338,7 +357,7 @@ export function useTrayDrag(args) {
338
357
  if (state.dragging || toValue(disabled)) {
339
358
  return;
340
359
  }
341
- const coord = isVertical(side) ? e.screenY : e.screenX;
360
+ const coord = isVertical(side) ? e.clientY : e.clientX;
342
361
  const target = e.target;
343
362
  beginDrag(side, coord, target);
344
363
  guardedSetPointerCapture({ event: e, element: target });
@@ -371,7 +390,7 @@ export function useTrayDrag(args) {
371
390
  }
372
391
  e.stopImmediatePropagation();
373
392
  e.stopPropagation();
374
- const coord = isVertical(side) ? firstTouch.screenY : firstTouch.screenX;
393
+ const coord = isVertical(side) ? firstTouch.clientY : firstTouch.clientX;
375
394
  beginDrag(side, coord, e.target);
376
395
  cancelTouchmove?.();
377
396
  cancelTouchmove = useEventListener(document, "touchmove", onTouchmove, {
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  computed,
3
+ reactive,
3
4
  watch,
4
5
  toValue,
5
6
  onScopeDispose
@@ -28,10 +29,13 @@ export function useTrayMagnetism(args) {
28
29
  const easing = computed(() => easings[magnetism.value.easing]);
29
30
  const disabled = computed(() => state.options.disabled);
30
31
  const animation = computed(() => state.options.animation);
31
- function sideConfig(side) {
32
- const { sides } = magnetism.value;
33
- return sides ? sides[side] : void 0;
34
- }
32
+ const isVirtual = computed(() => magnetism.value.virtual);
33
+ const magneticOffset = reactive({
34
+ top: 0,
35
+ right: 0,
36
+ bottom: 0,
37
+ left: 0
38
+ });
35
39
  const magneticSides = computed(() => {
36
40
  return SIDES.filter((side) => {
37
41
  const draggable = (state.options.snapPoints[side]?.length ?? 0) > 0;
@@ -109,6 +113,10 @@ export function useTrayMagnetism(args) {
109
113
  let lastX = 0;
110
114
  let lastY = 0;
111
115
  let cancelPointermove = void 0;
116
+ function sideConfig(side) {
117
+ const { sides } = magnetism.value;
118
+ return sides ? sides[side] : void 0;
119
+ }
112
120
  function coercePoint(key) {
113
121
  return key.endsWith("px") ? key : Number(key);
114
122
  }
@@ -149,28 +157,37 @@ export function useTrayMagnetism(args) {
149
157
  }
150
158
  function resetSide(side) {
151
159
  cancelSettle(side);
152
- if (state.magnetic[side] !== 0) {
160
+ magneticOffset[side] = 0;
161
+ if (!isVirtual.value && state.magnetic[side] !== 0) {
153
162
  state.magnetic[side] = 0;
154
163
  }
155
164
  }
165
+ function disarm(side) {
166
+ armedDir[side] = null;
167
+ latched[side] = false;
168
+ resetSide(side);
169
+ }
156
170
  function settleSide(side) {
157
171
  if (settling[side]) {
158
172
  return;
159
173
  }
160
- if (Math.abs(state.magnetic[side]) <= EPSILON) {
174
+ if (Math.abs(magneticOffset[side]) <= EPSILON) {
161
175
  resetSide(side);
162
176
  return;
163
177
  }
164
178
  const { duration, easing: snapEasing } = animation.value.snap;
165
179
  settling[side] = true;
166
180
  settleId[side] = interpolate({
167
- from: state.magnetic[side],
181
+ from: magneticOffset[side],
168
182
  to: 0,
169
183
  duration,
170
184
  easing: snapEasing,
171
185
  interpolationIdCallback: (newId) => settleId[side] = newId,
172
186
  callback: (value) => {
173
- state.magnetic[side] = value;
187
+ magneticOffset[side] = value;
188
+ if (!isVirtual.value) {
189
+ state.magnetic[side] = value;
190
+ }
174
191
  if (value === 0) {
175
192
  settling[side] = false;
176
193
  settleId[side] = void 0;
@@ -180,9 +197,7 @@ export function useTrayMagnetism(args) {
180
197
  }
181
198
  function resetAll() {
182
199
  for (const side of SIDES) {
183
- armedDir[side] = null;
184
- latched[side] = false;
185
- resetSide(side);
200
+ disarm(side);
186
201
  }
187
202
  }
188
203
  function axisOverflow(value, min, max) {
@@ -195,6 +210,150 @@ export function useTrayMagnetism(args) {
195
210
  return 0;
196
211
  }
197
212
  }
213
+ function normalizeRadius(radius) {
214
+ if (typeof radius === "number") {
215
+ return radius > 0 ? { start: radius, stop: 0, configured: true } : { start: void 0, stop: void 0, configured: false };
216
+ }
217
+ const { start, stop } = radius;
218
+ return { start, stop, configured: start !== void 0 || stop !== void 0 };
219
+ }
220
+ function measureAxis(side, x, y, rect, hRect) {
221
+ let perp = 0;
222
+ let overflow = 0;
223
+ let center = 0;
224
+ switch (side) {
225
+ case "top": {
226
+ const edge = rect.top + state.snapped.top;
227
+ perp = y - edge;
228
+ overflow = axisOverflow(x, rect.left, rect.right);
229
+ if (hRect) {
230
+ center = hRect.top + hRect.height / 2 - edge - state.magnetic.top;
231
+ }
232
+ break;
233
+ }
234
+ case "bottom": {
235
+ const edge = rect.bottom - state.snapped.bottom;
236
+ perp = edge - y;
237
+ overflow = axisOverflow(x, rect.left, rect.right);
238
+ if (hRect) {
239
+ center = edge - (hRect.top + hRect.height / 2) - state.magnetic.bottom;
240
+ }
241
+ break;
242
+ }
243
+ case "left": {
244
+ const edge = rect.left + state.snapped.left;
245
+ perp = x - edge;
246
+ overflow = axisOverflow(y, rect.top, rect.bottom);
247
+ if (hRect) {
248
+ center = hRect.left + hRect.width / 2 - edge - state.magnetic.left;
249
+ }
250
+ break;
251
+ }
252
+ case "right": {
253
+ const edge = rect.right - state.snapped.right;
254
+ perp = edge - x;
255
+ overflow = axisOverflow(y, rect.top, rect.bottom);
256
+ if (hRect) {
257
+ center = edge - (hRect.left + hRect.width / 2) - state.magnetic.right;
258
+ }
259
+ break;
260
+ }
261
+ }
262
+ return { perp, overflow, center };
263
+ }
264
+ function resolveBand(band, geo) {
265
+ const { pull, thickness, center } = geo;
266
+ if (band.configured) {
267
+ const stop = band.stop ?? pull;
268
+ const start = band.start ?? stop + (thickness || pull);
269
+ return { innerEdge: start, outerEdge: -start, span: start - stop };
270
+ }
271
+ const anchorHalf = thickness / 2;
272
+ return {
273
+ innerEdge: center + anchorHalf,
274
+ outerEdge: center - anchorHalf,
275
+ span: anchorHalf / 2
276
+ };
277
+ }
278
+ function updateSide(side, x, y, rect, band) {
279
+ const direction = restDirection(side);
280
+ if (!direction) {
281
+ disarm(side);
282
+ return;
283
+ }
284
+ const allowInner = direction === "inner" || direction === "both";
285
+ const allowOuter = direction === "outer" || direction === "both";
286
+ const hRect = handleRect(side);
287
+ const thickness = hRect ? side === "top" || side === "bottom" ? hRect.height : hRect.width : 0;
288
+ const pull = magnetism.value.pull > 0 ? magnetism.value.pull : thickness / 4;
289
+ pullPx[side] = pull;
290
+ if (pull <= 0) {
291
+ disarm(side);
292
+ return;
293
+ }
294
+ const { perp, overflow, center } = measureAxis(side, x, y, rect, hRect);
295
+ const { innerEdge, outerEdge, span } = resolveBand(band, {
296
+ pull,
297
+ thickness,
298
+ center
299
+ });
300
+ if (span <= 0) {
301
+ disarm(side);
302
+ return;
303
+ }
304
+ if (overflow === 0) {
305
+ switch (true) {
306
+ case (allowInner && perp >= innerEdge):
307
+ armedDir[side] = "inner";
308
+ break;
309
+ case (allowOuter && perp <= outerEdge):
310
+ armedDir[side] = "outer";
311
+ break;
312
+ }
313
+ }
314
+ const dir = armedDir[side];
315
+ if (!dir) {
316
+ resetSide(side);
317
+ return;
318
+ }
319
+ let t = 0;
320
+ let sign = 0;
321
+ switch (dir) {
322
+ case "inner":
323
+ t = clampValue((innerEdge - perp) / span, 0, 1);
324
+ sign = 1;
325
+ break;
326
+ case "outer":
327
+ t = clampValue((perp - outerEdge) / span, 0, 1);
328
+ sign = -1;
329
+ break;
330
+ }
331
+ switch (true) {
332
+ case overflow === 0:
333
+ latched[side] = t >= 1;
334
+ break;
335
+ case !latched[side]:
336
+ armedDir[side] = null;
337
+ resetSide(side);
338
+ return;
339
+ }
340
+ const magnitude = overflow === 0 ? easing.value(t) : 1;
341
+ const offset = sign * pull * magnitude;
342
+ const target = clampValue(
343
+ offset,
344
+ -state.dragged[side],
345
+ maxInset(side) - state.dragged[side]
346
+ );
347
+ if (Math.abs(target) > EPSILON) {
348
+ cancelSettle(side);
349
+ magneticOffset[side] = target;
350
+ if (!isVirtual.value) {
351
+ state.magnetic[side] = target;
352
+ }
353
+ } else {
354
+ settleSide(side);
355
+ }
356
+ }
198
357
  function update(x, y) {
199
358
  if (state.dragging || disabled.value) {
200
359
  resetAll();
@@ -205,124 +364,10 @@ export function useTrayMagnetism(args) {
205
364
  resetAll();
206
365
  return;
207
366
  }
208
- const { pull: configuredPull, radius: configuredRadius } = magnetism.value;
367
+ const band = normalizeRadius(magnetism.value.radius);
209
368
  const rect = el.getBoundingClientRect();
210
369
  for (const side of magneticSides.value) {
211
- const direction = restDirection(side);
212
- if (!direction) {
213
- armedDir[side] = null;
214
- latched[side] = false;
215
- resetSide(side);
216
- continue;
217
- }
218
- const allowInner = direction === "inner" || direction === "both";
219
- const allowOuter = direction === "outer" || direction === "both";
220
- const hRect = handleRect(side);
221
- const thickness = hRect ? side === "top" || side === "bottom" ? hRect.height : hRect.width : 0;
222
- const anchorHalf = thickness / 2;
223
- const radius = configuredRadius > 0 ? configuredRadius : anchorHalf / 2;
224
- const pull = configuredPull > 0 ? configuredPull : anchorHalf / 2;
225
- pullPx[side] = pull;
226
- if (radius <= 0) {
227
- armedDir[side] = null;
228
- latched[side] = false;
229
- resetSide(side);
230
- continue;
231
- }
232
- let perp = 0;
233
- let overflow = 0;
234
- let center = 0;
235
- switch (side) {
236
- case "top": {
237
- const edge = rect.top + state.snapped.top;
238
- perp = y - edge;
239
- overflow = axisOverflow(x, rect.left, rect.right);
240
- if (hRect) {
241
- center = hRect.top + hRect.height / 2 - edge - state.magnetic.top;
242
- }
243
- break;
244
- }
245
- case "bottom": {
246
- const edge = rect.bottom - state.snapped.bottom;
247
- perp = edge - y;
248
- overflow = axisOverflow(x, rect.left, rect.right);
249
- if (hRect) {
250
- center = edge - (hRect.top + hRect.height / 2) - state.magnetic.bottom;
251
- }
252
- break;
253
- }
254
- case "left": {
255
- const edge = rect.left + state.snapped.left;
256
- perp = x - edge;
257
- overflow = axisOverflow(y, rect.top, rect.bottom);
258
- if (hRect) {
259
- center = hRect.left + hRect.width / 2 - edge - state.magnetic.left;
260
- }
261
- break;
262
- }
263
- case "right": {
264
- const edge = rect.right - state.snapped.right;
265
- perp = edge - x;
266
- overflow = axisOverflow(y, rect.top, rect.bottom);
267
- if (hRect) {
268
- center = edge - (hRect.left + hRect.width / 2) - state.magnetic.right;
269
- }
270
- break;
271
- }
272
- }
273
- const innerEdge = center + anchorHalf;
274
- const outerEdge = center - anchorHalf;
275
- if (overflow === 0) {
276
- switch (true) {
277
- case (allowInner && perp >= innerEdge):
278
- armedDir[side] = "inner";
279
- break;
280
- case (allowOuter && perp <= outerEdge):
281
- armedDir[side] = "outer";
282
- break;
283
- }
284
- }
285
- const dir = armedDir[side];
286
- if (!dir) {
287
- resetSide(side);
288
- continue;
289
- }
290
- let t = 0;
291
- let sign = 0;
292
- switch (dir) {
293
- case "inner":
294
- t = clampValue((innerEdge - perp) / radius, 0, 1);
295
- sign = 1;
296
- break;
297
- case "outer":
298
- t = clampValue((perp - outerEdge) / radius, 0, 1);
299
- sign = -1;
300
- break;
301
- }
302
- switch (true) {
303
- case overflow === 0:
304
- latched[side] = t >= 1;
305
- break;
306
- case !latched[side]:
307
- armedDir[side] = null;
308
- resetSide(side);
309
- continue;
310
- }
311
- const magnitude = overflow === 0 ? easing.value(t) : 1;
312
- const offset = sign * pull * magnitude;
313
- const target = clampValue(
314
- offset,
315
- -state.dragged[side],
316
- maxInset(side) - state.dragged[side]
317
- );
318
- switch (true) {
319
- case Math.abs(target) > EPSILON:
320
- cancelSettle(side);
321
- state.magnetic[side] = target;
322
- break;
323
- default:
324
- settleSide(side);
325
- }
370
+ updateSide(side, x, y, rect, band);
326
371
  }
327
372
  }
328
373
  function onPointermove(e) {
@@ -345,7 +390,7 @@ export function useTrayMagnetism(args) {
345
390
  resetAll();
346
391
  }
347
392
  watch(
348
- () => ({ ...state.magnetic }),
393
+ () => ({ ...magneticOffset }),
349
394
  (magnetic) => {
350
395
  for (const side of SIDES) {
351
396
  const max = pullPx[side];
@@ -362,6 +407,18 @@ export function useTrayMagnetism(args) {
362
407
  },
363
408
  { deep: true }
364
409
  );
410
+ watch(
411
+ () => ({ ...state.snapped }),
412
+ (next, prev) => {
413
+ for (const side of SIDES) {
414
+ if (next[side] !== prev[side]) {
415
+ armedDir[side] = null;
416
+ latched[side] = false;
417
+ settleSide(side);
418
+ }
419
+ }
420
+ }
421
+ );
365
422
  watch(
366
423
  () => [enabled.value, magnetism.value.sides, state.options.snapPoints],
367
424
  () => {
@@ -15,11 +15,16 @@ export type TraySnapPoints = Partial<Record<TraySide, TraySnapPoint[]>>;
15
15
  export type TrayMagneticDirection = 'inner' | 'outer' | 'both';
16
16
  export type TrayMagneticSide = Partial<Record<TraySnapPoint, TrayMagneticDirection>>;
17
17
  export type TrayMagneticSides = false | Partial<Record<TraySide, TrayMagneticSide>>;
18
+ export type TrayMagneticRadius = number | {
19
+ start?: number;
20
+ stop?: number;
21
+ };
18
22
  export interface TrayMagnetism {
19
23
  sides?: TrayMagneticSides;
20
- radius?: number;
24
+ radius?: TrayMagneticRadius;
21
25
  pull?: number;
22
26
  easing?: EasingKey;
27
+ virtual?: boolean;
23
28
  }
24
29
  export type TraySideRecord<T> = Record<TraySide, T>;
25
30
  export type TrayTransformAxis = 'both' | 'x' | 'y';
@@ -77,6 +82,11 @@ export interface TrayState {
77
82
  elRect: DOMRect | undefined;
78
83
  options: RequiredMagicTrayOptions;
79
84
  }
85
+ export interface TrayWillSnapToPayload {
86
+ id: string;
87
+ side: TraySide;
88
+ snapPoint: TraySnapPoint;
89
+ }
80
90
  export type TrayEvents = {
81
91
  beforeSnap: {
82
92
  id: string;
@@ -106,4 +116,5 @@ export type TrayEvents = {
106
116
  magnet: {
107
117
  id: string;
108
118
  } & TraySidePayload;
119
+ willSnapTo: TrayWillSnapToPayload;
109
120
  };
@@ -12,7 +12,8 @@ const defaultOptions = {
12
12
  sides: false,
13
13
  radius: 0,
14
14
  pull: 0,
15
- easing: "easeInOutQuad"
15
+ easing: "easeInOutQuad",
16
+ virtual: false
16
17
  },
17
18
  threshold: {
18
19
  lock: 0,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@maas/vue-equipment",
3
3
  "description": "Our Frontend Toolkit, Free and Open Source",
4
- "version": "1.0.0-beta.72",
4
+ "version": "1.0.0-beta.74",
5
5
  "contributors": [
6
6
  {
7
7
  "name": "Robin Scholz",