@witchcraft/layout 0.4.2 → 0.4.4

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 (65) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/runtime/components/LayoutDragEdgeGrabbed.vue +1 -1
  3. package/dist/runtime/components/LayoutDragEdgeHandle.vue +1 -2
  4. package/dist/runtime/components/LayoutWindow.d.vue.ts +12 -0
  5. package/dist/runtime/components/LayoutWindow.vue +5 -4
  6. package/dist/runtime/components/LayoutWindow.vue.d.ts +12 -0
  7. package/dist/runtime/composables/useFrames.d.ts +38 -22
  8. package/dist/runtime/composables/useFrames.js +44 -8
  9. package/dist/runtime/demo/tailwind.css +1 -1
  10. package/dist/runtime/drag/CloseAction.d.ts +3 -0
  11. package/dist/runtime/drag/CloseAction.js +5 -0
  12. package/dist/runtime/drag/DragActionHandler.d.ts +4 -1
  13. package/dist/runtime/drag/DragActionHandler.js +2 -2
  14. package/dist/runtime/drag/FrameDragAction.d.ts +3 -0
  15. package/dist/runtime/drag/FrameDragAction.js +5 -0
  16. package/dist/runtime/drag/SplitAction.d.ts +3 -0
  17. package/dist/runtime/drag/SplitAction.js +8 -3
  18. package/dist/runtime/helpers/findEdgesTouchingWindow.d.ts +7 -0
  19. package/dist/runtime/helpers/findEdgesTouchingWindow.js +20 -0
  20. package/dist/runtime/helpers/index.d.ts +8 -1
  21. package/dist/runtime/helpers/index.js +8 -1
  22. package/dist/runtime/layout/debugFrame.js +5 -1
  23. package/dist/runtime/layout/getFrameCollapseInfo.d.ts +1 -1
  24. package/dist/runtime/layout/getFrameCollapseInfo.js +9 -29
  25. package/dist/runtime/layout/getFrameDockInfo.d.ts +1 -1
  26. package/dist/runtime/layout/getFrameDockInfo.js +61 -44
  27. package/dist/runtime/layout/getFrameExpandInfo.d.ts +11 -0
  28. package/dist/runtime/layout/getFrameExpandInfo.js +49 -0
  29. package/dist/runtime/layout/getFrameShrinkInfo.d.ts +14 -0
  30. package/dist/runtime/layout/getFrameShrinkInfo.js +48 -0
  31. package/dist/runtime/layout/getFrameUncollapseInfo.d.ts +1 -1
  32. package/dist/runtime/layout/getFrameUncollapseInfo.js +6 -20
  33. package/dist/runtime/layout/getUpdateWindowSizeInfo.js +10 -12
  34. package/dist/runtime/layout/index.d.ts +3 -0
  35. package/dist/runtime/layout/index.js +3 -0
  36. package/dist/runtime/settings.js +1 -1
  37. package/dist/runtime/types/index.d.ts +72 -0
  38. package/dist/runtime/types/index.js +2 -1
  39. package/dist/runtime/types/vue.d.ts +12 -3
  40. package/package.json +3 -2
  41. package/src/runtime/components/LayoutDragEdgeGrabbed.vue +1 -1
  42. package/src/runtime/components/LayoutDragEdgeHandle.vue +1 -2
  43. package/src/runtime/components/LayoutWindow.vue +8 -6
  44. package/src/runtime/composables/useFrames.ts +61 -32
  45. package/src/runtime/demo/tailwind.css +4 -0
  46. package/src/runtime/drag/CloseAction.ts +7 -0
  47. package/src/runtime/drag/DragActionHandler.ts +3 -3
  48. package/src/runtime/drag/FrameDragAction.ts +9 -0
  49. package/src/runtime/drag/SplitAction.ts +11 -3
  50. package/src/runtime/helpers/findEdgesTouchingWindow.ts +30 -0
  51. package/src/runtime/helpers/index.ts +8 -1
  52. package/src/runtime/layout/debugFrame.ts +6 -1
  53. package/src/runtime/layout/getFrameCollapseInfo.ts +12 -41
  54. package/src/runtime/layout/getFrameDockInfo.ts +77 -57
  55. package/src/runtime/layout/getFrameExpandInfo.ts +84 -0
  56. package/src/runtime/layout/getFrameShrinkInfo.ts +87 -0
  57. package/src/runtime/layout/getFrameUncollapseInfo.ts +8 -30
  58. package/src/runtime/layout/getUpdateWindowSizeInfo.ts +16 -22
  59. package/src/runtime/layout/index.ts +3 -0
  60. package/src/runtime/settings.ts +1 -1
  61. package/src/runtime/types/index.ts +41 -1
  62. package/src/runtime/types/vue.ts +5 -3
  63. package/dist/runtime/drag/defaultDragActions.d.ts +0 -9
  64. package/dist/runtime/drag/defaultDragActions.js +0 -10
  65. package/src/runtime/drag/defaultDragActions.ts +0 -20
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@witchcraft/layout",
3
3
  "configKey": "witchcraftLayout",
4
- "version": "0.4.2",
4
+ "version": "0.4.4",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "unknown"
@@ -7,7 +7,7 @@
7
7
  z-20
8
8
  bg-accent-500
9
9
  cursor-pointer
10
- [&.request-split]:hidden
10
+ [.request-split_&]:hidden
11
11
  `,
12
12
  $attrs.class
13
13
  )"
@@ -7,8 +7,7 @@
7
7
  drag-edge
8
8
  z-20
9
9
  hover:cursor-pointer
10
-
11
- [&.request-split]:hidden
10
+ [.request-split_&]:hidden
12
11
  `,
13
12
  edge.error && `
14
13
  drag-edge-errored
@@ -3,6 +3,8 @@ import { type DragState, type IDragAction } from "../types/index.js";
3
3
  import { getUpdateWindowSizeInfo } from "../layout/getUpdateWindowSizeInfo.js";
4
4
  import { type LayoutWindow } from "../types/index.js";
5
5
  type __VLS_Props = {
6
+ /** If you really need it, you can provide your own drag action handler (remember to markRaw it), note the actionHandler's prop will no longer have any effect.*/
7
+ dragActionHandler?: DragActionHandler<any, any>;
6
8
  /** Custom drag action handlers. Falls back to default split/close/frame handlers if not provided. */
7
9
  actionHandlers?: IDragAction[];
8
10
  textHints?: {
@@ -41,6 +43,7 @@ declare const __VLS_component: import("vue").DefineComponent<__VLS_PublicProps,
41
43
  x: number;
42
44
  y: number;
43
45
  } | undefined;
46
+ dragDistance: number;
44
47
  isDragging: false | "edge" | "frame";
45
48
  showDragging: boolean;
46
49
  draggingFrameId: string | undefined;
@@ -106,6 +109,8 @@ declare const __VLS_component: import("vue").DefineComponent<__VLS_PublicProps,
106
109
  frame: import("../types/index.js").LayoutFrame;
107
110
  } | {
108
111
  frame: import("../types/index.js").LayoutFrame;
112
+ } | {
113
+ frame: import("../types/index.js").LayoutFrame;
109
114
  }> | {
110
115
  code: string;
111
116
  message: string;
@@ -181,6 +186,8 @@ declare const __VLS_component: import("vue").DefineComponent<__VLS_PublicProps,
181
186
  frame: import("../types/index.js").LayoutFrame;
182
187
  } | {
183
188
  frame: import("../types/index.js").LayoutFrame;
189
+ } | {
190
+ frame: import("../types/index.js").LayoutFrame;
184
191
  }> | {
185
192
  code: string;
186
193
  message: string;
@@ -248,6 +255,8 @@ declare const __VLS_component: import("vue").DefineComponent<__VLS_PublicProps,
248
255
  frame: import("../types/index.js").LayoutFrame;
249
256
  } | {
250
257
  frame: import("../types/index.js").LayoutFrame;
258
+ } | {
259
+ frame: import("../types/index.js").LayoutFrame;
251
260
  }> | {
252
261
  code: string;
253
262
  message: string;
@@ -318,6 +327,8 @@ declare const __VLS_component: import("vue").DefineComponent<__VLS_PublicProps,
318
327
  frame: import("../types/index.js").LayoutFrame;
319
328
  } | {
320
329
  frame: import("../types/index.js").LayoutFrame;
330
+ } | {
331
+ frame: import("../types/index.js").LayoutFrame;
321
332
  }> | {
322
333
  code: string;
323
334
  message: string;
@@ -329,6 +340,7 @@ declare const __VLS_component: import("vue").DefineComponent<__VLS_PublicProps,
329
340
  dragHoveredFrame: import("../types/index.js").LayoutFrame | undefined;
330
341
  intersections: import("../types/index.js").IntersectionEntry[];
331
342
  isDraggingFromWindowEdge: boolean;
343
+ eventContext: Record<string, unknown> | undefined;
332
344
  win: import("../types/index.js").BaseLayoutWindow;
333
345
  }>;
334
346
  win: import("vue").ModelRef<import("../types/index.js").BaseLayoutWindow, string, import("../types/index.js").BaseLayoutWindow, import("../types/index.js").BaseLayoutWindow>;
@@ -7,7 +7,7 @@
7
7
  flex
8
8
  flex-col
9
9
  `,
10
- isDragging && `dragging cursor-pointer`,
10
+ isDragging && `dragging cursor-pointer user-select-none pointer-events-none`,
11
11
  requestType && `request-${requestType}`,
12
12
  $attrs.class
13
13
  )"
@@ -67,7 +67,7 @@
67
67
  <script setup>
68
68
  import { useGlobalResizeObserver } from "@witchcraft/ui/composables/useGlobalResizeObserver";
69
69
  import { twMerge } from "@witchcraft/ui/utils/twMerge";
70
- import { computed, provide, reactive, ref, useAttrs, watch } from "vue";
70
+ import { computed, markRaw, provide, reactive, ref, useAttrs, watch } from "vue";
71
71
  import { useFrames } from "../composables/useFrames.js";
72
72
  import { createDefaultHandlers } from "../drag/createDefaultHandlers.js";
73
73
  import { DragActionHandler } from "../drag/DragActionHandler";
@@ -82,6 +82,7 @@ import { applyFrameChanges } from "../layout/applyFrameChanges.js";
82
82
  const $attrs = useAttrs();
83
83
  const win = defineModel("win", { type: Object, ...{ required: true } });
84
84
  const props = defineProps({
85
+ dragActionHandler: { type: Object, required: false },
85
86
  actionHandlers: { type: Array, required: false, default: void 0 },
86
87
  textHints: { type: Array, required: false, default: () => [] },
87
88
  textHintsTeleportTo: { type: null, required: true, default: void 0 },
@@ -91,7 +92,7 @@ const props = defineProps({
91
92
  const emit = defineEmits(["isShowingDrag", "dragState"]);
92
93
  const windowEl = ref(null);
93
94
  const requestType = ref();
94
- const dragActionHandler = new DragActionHandler(
95
+ const dragActionHandler = props.dragActionHandler ?? markRaw(new DragActionHandler(
95
96
  [
96
97
  ...props.actionHandlers ?? createDefaultHandlers()
97
98
  ],
@@ -110,7 +111,7 @@ const dragActionHandler = new DragActionHandler(
110
111
  showDragging.value = true;
111
112
  }
112
113
  }
113
- );
114
+ ));
114
115
  dragActionHandler.shapes = reactive([]);
115
116
  dragActionHandler.textHints = reactive({ actions: [], errors: [] });
116
117
  const shapes = dragActionHandler.shapes;
@@ -3,6 +3,8 @@ import { type DragState, type IDragAction } from "../types/index.js";
3
3
  import { getUpdateWindowSizeInfo } from "../layout/getUpdateWindowSizeInfo.js";
4
4
  import { type LayoutWindow } from "../types/index.js";
5
5
  type __VLS_Props = {
6
+ /** If you really need it, you can provide your own drag action handler (remember to markRaw it), note the actionHandler's prop will no longer have any effect.*/
7
+ dragActionHandler?: DragActionHandler<any, any>;
6
8
  /** Custom drag action handlers. Falls back to default split/close/frame handlers if not provided. */
7
9
  actionHandlers?: IDragAction[];
8
10
  textHints?: {
@@ -41,6 +43,7 @@ declare const __VLS_component: import("vue").DefineComponent<__VLS_PublicProps,
41
43
  x: number;
42
44
  y: number;
43
45
  } | undefined;
46
+ dragDistance: number;
44
47
  isDragging: false | "edge" | "frame";
45
48
  showDragging: boolean;
46
49
  draggingFrameId: string | undefined;
@@ -106,6 +109,8 @@ declare const __VLS_component: import("vue").DefineComponent<__VLS_PublicProps,
106
109
  frame: import("../types/index.js").LayoutFrame;
107
110
  } | {
108
111
  frame: import("../types/index.js").LayoutFrame;
112
+ } | {
113
+ frame: import("../types/index.js").LayoutFrame;
109
114
  }> | {
110
115
  code: string;
111
116
  message: string;
@@ -181,6 +186,8 @@ declare const __VLS_component: import("vue").DefineComponent<__VLS_PublicProps,
181
186
  frame: import("../types/index.js").LayoutFrame;
182
187
  } | {
183
188
  frame: import("../types/index.js").LayoutFrame;
189
+ } | {
190
+ frame: import("../types/index.js").LayoutFrame;
184
191
  }> | {
185
192
  code: string;
186
193
  message: string;
@@ -248,6 +255,8 @@ declare const __VLS_component: import("vue").DefineComponent<__VLS_PublicProps,
248
255
  frame: import("../types/index.js").LayoutFrame;
249
256
  } | {
250
257
  frame: import("../types/index.js").LayoutFrame;
258
+ } | {
259
+ frame: import("../types/index.js").LayoutFrame;
251
260
  }> | {
252
261
  code: string;
253
262
  message: string;
@@ -318,6 +327,8 @@ declare const __VLS_component: import("vue").DefineComponent<__VLS_PublicProps,
318
327
  frame: import("../types/index.js").LayoutFrame;
319
328
  } | {
320
329
  frame: import("../types/index.js").LayoutFrame;
330
+ } | {
331
+ frame: import("../types/index.js").LayoutFrame;
321
332
  }> | {
322
333
  code: string;
323
334
  message: string;
@@ -329,6 +340,7 @@ declare const __VLS_component: import("vue").DefineComponent<__VLS_PublicProps,
329
340
  dragHoveredFrame: import("../types/index.js").LayoutFrame | undefined;
330
341
  intersections: import("../types/index.js").IntersectionEntry[];
331
342
  isDraggingFromWindowEdge: boolean;
343
+ eventContext: Record<string, unknown> | undefined;
332
344
  win: import("../types/index.js").BaseLayoutWindow;
333
345
  }>;
334
346
  win: import("vue").ModelRef<import("../types/index.js").BaseLayoutWindow, string, import("../types/index.js").BaseLayoutWindow, import("../types/index.js").BaseLayoutWindow>;
@@ -1,26 +1,11 @@
1
1
  import type { Ref } from "vue";
2
- import type { DragChangeHandler, DragChangeResult, DragState, Edge, EdgeDragStartData, FrameDragStartData, IntersectionEntry, LayoutFrame, LayoutWindow } from "../types/index.js";
3
- export declare function useFrames(win: Ref<LayoutWindow>, handler: {
4
- eventHandler: (e: KeyboardEvent, state: DragState, forceRecalculateEdges: () => void) => void;
5
- /**
6
- * Called when the drag coordinates change (during any event). Should return true to allow the edges to be updated/moved, or false to prevent it.
7
- *
8
- * Can return anything for the end event as it's ignored.
9
- *
10
- * Can be used to save some context/info to later apply safely during onDragApply.
11
- */
12
- onDragChange: (...args: Parameters<DragChangeHandler>) => DragChangeResult;
13
- /**
14
- * Called when drag will be applied. If dragEnd was called with apply false, it will not be called.
15
- * Return false to not apply the regular drag end changes (i.e. return false to reset to the position before dragging).
16
- */
17
- onDragApply: ((state: DragState, forceRecalculateEdges: () => void) => boolean);
18
- /**
19
- * Called after visual edges are recalculated. Action handlers can annotate edges with error info.
20
- */
21
- annotateEdges?: (edges: Edge[], frames: LayoutFrame[]) => void;
22
- }): {
23
- dragStart: <T extends "edge" | "frame">(e: PointerEvent, type: T, data: T extends "edge" ? EdgeDragStartData : FrameDragStartData) => void;
2
+ import type { ActionHandler, EdgeDragStartData, FrameDragStartData, IntersectionEntry, LayoutFrame, LayoutWindow } from "../types/index.js";
3
+ export declare function useFrames(win: Ref<LayoutWindow>, handler: ActionHandler): {
4
+ dragStart: <T extends "edge" | "frame">(e: PointerEvent, type: T, data: T extends "edge" ? EdgeDragStartData : FrameDragStartData, { moveEvent, endEvent, context }?: {
5
+ moveEvent?: string;
6
+ endEvent?: string;
7
+ context?: Record<string, unknown>;
8
+ }) => Promise<any>;
24
9
  dragEnd: (e?: PointerEvent, { apply }?: {
25
10
  apply?: boolean;
26
11
  }) => void;
@@ -103,6 +88,8 @@ export declare function useFrames(win: Ref<LayoutWindow>, handler: {
103
88
  frame: LayoutFrame;
104
89
  } | {
105
90
  frame: LayoutFrame;
91
+ } | {
92
+ frame: LayoutFrame;
106
93
  }> | {
107
94
  code: string;
108
95
  message: string;
@@ -169,6 +156,8 @@ export declare function useFrames(win: Ref<LayoutWindow>, handler: {
169
156
  frame: LayoutFrame;
170
157
  } | {
171
158
  frame: LayoutFrame;
159
+ } | {
160
+ frame: LayoutFrame;
172
161
  }> | {
173
162
  code: string;
174
163
  message: string;
@@ -235,6 +224,8 @@ export declare function useFrames(win: Ref<LayoutWindow>, handler: {
235
224
  frame: LayoutFrame;
236
225
  } | {
237
226
  frame: LayoutFrame;
227
+ } | {
228
+ frame: LayoutFrame;
238
229
  }> | {
239
230
  code: string;
240
231
  message: string;
@@ -310,6 +301,8 @@ export declare function useFrames(win: Ref<LayoutWindow>, handler: {
310
301
  frame: LayoutFrame;
311
302
  } | {
312
303
  frame: LayoutFrame;
304
+ } | {
305
+ frame: LayoutFrame;
313
306
  }> | {
314
307
  code: string;
315
308
  message: string;
@@ -377,6 +370,8 @@ export declare function useFrames(win: Ref<LayoutWindow>, handler: {
377
370
  frame: LayoutFrame;
378
371
  } | {
379
372
  frame: LayoutFrame;
373
+ } | {
374
+ frame: LayoutFrame;
380
375
  }> | {
381
376
  code: string;
382
377
  message: string;
@@ -454,6 +449,8 @@ export declare function useFrames(win: Ref<LayoutWindow>, handler: {
454
449
  frame: LayoutFrame;
455
450
  } | {
456
451
  frame: LayoutFrame;
452
+ } | {
453
+ frame: LayoutFrame;
457
454
  }> | {
458
455
  code: string;
459
456
  message: string;
@@ -521,6 +518,8 @@ export declare function useFrames(win: Ref<LayoutWindow>, handler: {
521
518
  frame: LayoutFrame;
522
519
  } | {
523
520
  frame: LayoutFrame;
521
+ } | {
522
+ frame: LayoutFrame;
524
523
  }> | {
525
524
  code: string;
526
525
  message: string;
@@ -591,6 +590,8 @@ export declare function useFrames(win: Ref<LayoutWindow>, handler: {
591
590
  frame: LayoutFrame;
592
591
  } | {
593
592
  frame: LayoutFrame;
593
+ } | {
594
+ frame: LayoutFrame;
594
595
  }> | {
595
596
  code: string;
596
597
  message: string;
@@ -657,6 +658,8 @@ export declare function useFrames(win: Ref<LayoutWindow>, handler: {
657
658
  frame: LayoutFrame;
658
659
  } | {
659
660
  frame: LayoutFrame;
661
+ } | {
662
+ frame: LayoutFrame;
660
663
  }> | {
661
664
  code: string;
662
665
  message: string;
@@ -723,6 +726,8 @@ export declare function useFrames(win: Ref<LayoutWindow>, handler: {
723
726
  frame: LayoutFrame;
724
727
  } | {
725
728
  frame: LayoutFrame;
729
+ } | {
730
+ frame: LayoutFrame;
726
731
  }> | {
727
732
  code: string;
728
733
  message: string;
@@ -744,6 +749,7 @@ export declare function useFrames(win: Ref<LayoutWindow>, handler: {
744
749
  x: number;
745
750
  y: number;
746
751
  } | undefined;
752
+ dragDistance: number;
747
753
  isDragging: false | "edge" | "frame";
748
754
  showDragging: boolean;
749
755
  draggingFrameId: string | undefined;
@@ -809,6 +815,8 @@ export declare function useFrames(win: Ref<LayoutWindow>, handler: {
809
815
  frame: LayoutFrame;
810
816
  } | {
811
817
  frame: LayoutFrame;
818
+ } | {
819
+ frame: LayoutFrame;
812
820
  }> | {
813
821
  code: string;
814
822
  message: string;
@@ -884,6 +892,8 @@ export declare function useFrames(win: Ref<LayoutWindow>, handler: {
884
892
  frame: LayoutFrame;
885
893
  } | {
886
894
  frame: LayoutFrame;
895
+ } | {
896
+ frame: LayoutFrame;
887
897
  }> | {
888
898
  code: string;
889
899
  message: string;
@@ -951,6 +961,8 @@ export declare function useFrames(win: Ref<LayoutWindow>, handler: {
951
961
  frame: LayoutFrame;
952
962
  } | {
953
963
  frame: LayoutFrame;
964
+ } | {
965
+ frame: LayoutFrame;
954
966
  }> | {
955
967
  code: string;
956
968
  message: string;
@@ -1021,6 +1033,8 @@ export declare function useFrames(win: Ref<LayoutWindow>, handler: {
1021
1033
  frame: LayoutFrame;
1022
1034
  } | {
1023
1035
  frame: LayoutFrame;
1036
+ } | {
1037
+ frame: LayoutFrame;
1024
1038
  }> | {
1025
1039
  code: string;
1026
1040
  message: string;
@@ -1032,8 +1046,10 @@ export declare function useFrames(win: Ref<LayoutWindow>, handler: {
1032
1046
  dragHoveredFrame: LayoutFrame | undefined;
1033
1047
  intersections: IntersectionEntry[];
1034
1048
  isDraggingFromWindowEdge: boolean;
1049
+ eventContext: Record<string, unknown> | undefined;
1035
1050
  win: import("../types/index.js").BaseLayoutWindow;
1036
1051
  }>;
1037
1052
  showDragging: Ref<boolean, boolean>;
1038
1053
  frameDragFrameId: Ref<string | undefined, string | undefined>;
1054
+ actionHandler: ActionHandler;
1039
1055
  };
@@ -27,9 +27,12 @@ export function useFrames(win, handler) {
27
27
  const showDragging = ref(false);
28
28
  const dragPoint = ref();
29
29
  const dragDirections = ref({});
30
+ let dragStartPoint;
31
+ const dragDistance = ref(-1);
30
32
  const draggingIntersection = ref(void 0);
31
33
  const isDraggingFromWindowEdge = ref(false);
32
34
  const frameDragFrameId = ref();
35
+ const eventContext = ref();
33
36
  const frames = computed(
34
37
  () => isDragging.value && showDragging.value ? { ...win.value.frames, ...allTouchingFrames.value } : win.value.frames
35
38
  );
@@ -64,6 +67,7 @@ export function useFrames(win, handler) {
64
67
  const state = computed(() => ({
65
68
  dragDirections: dragDirections.value,
66
69
  dragPoint: dragPoint.value,
70
+ dragDistance: dragDistance.value,
67
71
  isDragging: isDragging.value,
68
72
  showDragging: showDragging.value,
69
73
  draggingFrameId: frameDragFrameId.value,
@@ -76,29 +80,50 @@ export function useFrames(win, handler) {
76
80
  dragHoveredFrame: dragHoveredFrame.value,
77
81
  intersections: intersections.value,
78
82
  isDraggingFromWindowEdge: isDraggingFromWindowEdge.value,
83
+ eventContext: eventContext.value,
79
84
  win: win.value
80
85
  }));
81
86
  let controller;
87
+ let dragResolve;
88
+ let dragResult;
82
89
  function resetState() {
90
+ dragStartPoint = void 0;
91
+ dragResolve?.(dragResult);
92
+ dragResolve = void 0;
93
+ dragResult = void 0;
83
94
  draggingEdges.value = [];
84
95
  draggingIntersection.value = void 0;
85
96
  isDragging.value = false;
86
97
  dragPoint.value = void 0;
98
+ dragDistance.value = -1;
87
99
  touchingFrames.value = [];
88
100
  frameDragFrameId.value = void 0;
101
+ eventContext.value = void 0;
89
102
  dragDirStore.reset();
90
103
  showDragging.value = false;
91
104
  forceRecalculateEdges();
92
105
  }
93
- function dragStart(e, type, data) {
106
+ function dragStart(e, type, data, {
107
+ moveEvent = "pointermove",
108
+ endEvent = "pointerup",
109
+ context
110
+ } = {}) {
111
+ if (controller) {
112
+ controller.abort();
113
+ }
114
+ const promise = new Promise((resolve) => {
115
+ dragResolve = resolve;
116
+ });
94
117
  controller = new AbortController();
95
118
  controller.signal.addEventListener("abort", () => resetState());
96
119
  e.preventDefault();
97
- window.addEventListener("pointermove", dragMove, { signal: controller.signal });
98
- window.addEventListener("pointerup", dragEnd, { signal: controller.signal });
120
+ window.addEventListener(moveEvent, dragMove, { signal: controller.signal });
121
+ window.addEventListener(endEvent, dragEnd, { signal: controller.signal });
99
122
  const point = toWindowCoord(win.value, e);
100
123
  dragPoint.value = point;
124
+ dragStartPoint = { ...point };
101
125
  dragDirStore.update(point);
126
+ eventContext.value = context;
102
127
  isDragging.value = type;
103
128
  showDragging.value = true;
104
129
  if (type === "frame") {
@@ -130,12 +155,19 @@ export function useFrames(win, handler) {
130
155
  }
131
156
  const res = handler.onDragChange("start", e, state.value, forceRecalculateEdges, cancel);
132
157
  showDragging.value = res.showDragging ?? true;
158
+ return promise;
133
159
  }
134
160
  function dragMove(e) {
135
161
  e.preventDefault();
136
162
  const point = toWindowCoord(win.value, e);
137
163
  const didChange = dragDirStore.update(point);
138
164
  dragPoint.value = point;
165
+ dragDistance.value = 0;
166
+ if (dragStartPoint) {
167
+ dragDistance.value = Math.sqrt(
168
+ Math.pow(point.x - dragStartPoint.x, 2) + Math.pow(point.y - dragStartPoint.y, 2)
169
+ );
170
+ }
139
171
  if (!didChange) return;
140
172
  const res = handler.onDragChange("move", e, state.value, forceRecalculateEdges, cancel);
141
173
  showDragging.value = res.showDragging ?? true;
@@ -157,10 +189,13 @@ export function useFrames(win, handler) {
157
189
  const point = toWindowCoord(win.value, e);
158
190
  dragPoint.value = point;
159
191
  }
160
- const doApply = apply && handler.onDragApply(state.value, forceRecalculateEdges);
161
- if (doApply) {
162
- for (const frame of touchingFramesArrays.value.flat()) {
163
- win.value.frames[frame.id] = frame;
192
+ if (apply) {
193
+ const applyResult = handler.onDragApply(state.value, forceRecalculateEdges);
194
+ dragResult = applyResult.result;
195
+ if (applyResult.apply) {
196
+ for (const frame of touchingFramesArrays.value.flat()) {
197
+ win.value.frames[frame.id] = frame;
198
+ }
164
199
  }
165
200
  }
166
201
  handler.onDragChange("end", e, state.value, forceRecalculateEdges, cancel);
@@ -201,6 +236,7 @@ export function useFrames(win, handler) {
201
236
  forceRecalculateEdges,
202
237
  state,
203
238
  showDragging,
204
- frameDragFrameId
239
+ frameDragFrameId,
240
+ actionHandler: handler
205
241
  };
206
242
  }
@@ -1 +1 @@
1
- @import "tailwindcss";@import "../../../playground/.nuxt/witchcraft-ui.css";@import "../../../playground/.nuxt/witchcraft-layout.css";@source "../../../src/runtime/demo";
1
+ @import "tailwindcss";@import "../../../playground/.nuxt/witchcraft-ui.css";@import "../../../playground/.nuxt/witchcraft-layout.css";@source "../../../src/runtime/demo";button{cursor:pointer}
@@ -4,6 +4,7 @@ import type { KnownError } from "../utils/KnownError.js";
4
4
  export type CloseInfo = Exclude<ReturnType<typeof getCloseFrameInfo>, KnownError>;
5
5
  export declare class CloseAction implements IDragAction {
6
6
  name: "close";
7
+ minDragDistance: number;
7
8
  state: {
8
9
  allowed: true;
9
10
  force: boolean;
@@ -40,6 +41,8 @@ export declare class CloseAction implements IDragAction {
40
41
  modifyDecos?: CloseAction["modifyDecos"], hooks?: CloseAction["hooks"], config?: {
41
42
  debug?: boolean | string;
42
43
  closeHints?: Partial<CloseAction["closeHints"]>;
44
+ /** Minimum pixel distance the user must drag before the action is allowed (decos shown and action applied). Defaults to 5. */
45
+ minDragDistance?: number;
43
46
  });
44
47
  reset(): void;
45
48
  private _getDecos;
@@ -7,6 +7,7 @@ import { findFramesTouchingEdge } from "../layout/findFramesTouchingEdge.js";
7
7
  import { getCloseFrameInfo } from "../layout/getCloseFrameInfo.js";
8
8
  export class CloseAction {
9
9
  name = "close";
10
+ minDragDistance = 5;
10
11
  state = {};
11
12
  // this is initialized by this.reset()
12
13
  debug = false;
@@ -30,6 +31,7 @@ export class CloseAction {
30
31
  if (modifyDecos !== void 0) this.modifyDecos = modifyDecos;
31
32
  this.hooks = hooks;
32
33
  if (config?.debug) this.debug = true;
34
+ if (config?.minDragDistance !== void 0) this.minDragDistance = config.minDragDistance;
33
35
  this.reset();
34
36
  }
35
37
  reset() {
@@ -97,6 +99,9 @@ export class CloseAction {
97
99
  return false;
98
100
  }
99
101
  onDragChange(_type, _e, state) {
102
+ if (state.dragDistance <= this.minDragDistance) {
103
+ return { updateEdges: false, shapes: [] };
104
+ }
100
105
  const {
101
106
  touchingFramesArrays,
102
107
  dragDirections,
@@ -48,7 +48,10 @@ export declare class DragActionHandler<TRawDragActions extends IDragAction[], TD
48
48
  onDragChange<T extends "start" | "move" | "end">(type: T, e: T extends "end" ? PointerEvent | undefined : PointerEvent, state: DragState, forceRecalculateEdges: () => void, cancel: (e: PointerEvent | KeyboardEvent | undefined, state: DragState) => void): DragChangeResult;
49
49
  setTextHints(type: "start" | "move" | "end"): void;
50
50
  annotateEdges(edges: Edge[], frames: LayoutFrame[]): void;
51
- onDragApply(state: DragState, forceRecalculateEdges: () => void): boolean;
51
+ onDragApply(state: DragState, forceRecalculateEdges: () => void): {
52
+ apply: boolean;
53
+ result: any;
54
+ };
52
55
  cancel(e: PointerEvent | KeyboardEvent | undefined, state: DragState): void;
53
56
  static debugState(pluginName: string, type: "before" | "after" | string, state: DragState, pluginState?: Record<string, any>,
54
57
  /** Object key to filter the state by, e.g. state.win.frames. If false is ignored. The idea is you pass this.debug and users can set this.debug to a string to filter. */
@@ -122,10 +122,10 @@ export class DragActionHandler {
122
122
  if (this.activeAction) {
123
123
  const res = this.actions[this.activeAction].onDragApply(state, forceRecalculateEdges);
124
124
  this.hooks.onEnd?.({ cancelled: false, applied: res });
125
- return false;
125
+ return { apply: res, result: void 0 };
126
126
  }
127
127
  this.hooks.onEnd?.({ cancelled: false, applied: false });
128
- return true;
128
+ return { apply: true, result: void 0 };
129
129
  }
130
130
  cancel(e, state) {
131
131
  if (this.activeAction) {
@@ -2,6 +2,7 @@ import type { ActionDragChangeResult, DragState, DragZone, FrameDragDeco, IDragA
2
2
  import type { KnownError } from "../utils/KnownError.js";
3
3
  export declare class FrameDragAction implements IDragAction {
4
4
  name: "frameDrag";
5
+ minDragDistance: number;
5
6
  state: {
6
7
  lastReturn?: LayoutChange<"split" | "swap" | "rearrange" | "dock"> | KnownError;
7
8
  };
@@ -32,6 +33,8 @@ export declare class FrameDragAction implements IDragAction {
32
33
  /** Modify the created decos before they are rendered. */
33
34
  modifyDecos?: FrameDragAction["modifyDecos"], hooks?: FrameDragAction["hooks"], config?: {
34
35
  debug?: boolean | string;
36
+ /** Minimum pixel distance the user must drag before the action is allowed (decos shown and action applied). Defaults to 5. */
37
+ minDragDistance?: number;
35
38
  });
36
39
  reset(): void;
37
40
  setTextHints(result: LayoutChange<"split" | "swap" | "rearrange" | "dock"> | KnownError | undefined): void;
@@ -8,6 +8,7 @@ import { getFrameSwapInfo } from "../layout/getFrameSwapInfo.js";
8
8
  import { settings } from "../settings.js";
9
9
  export class FrameDragAction {
10
10
  name = "frameDrag";
11
+ minDragDistance = 5;
11
12
  state = {
12
13
  lastReturn: void 0
13
14
  };
@@ -31,6 +32,7 @@ export class FrameDragAction {
31
32
  if (modifyDecos !== void 0) this.modifyDecos = modifyDecos;
32
33
  this.hooks = hooks;
33
34
  if (config?.debug) this.debug = true;
35
+ if (config?.minDragDistance !== void 0) this.minDragDistance = config.minDragDistance;
34
36
  this.reset();
35
37
  }
36
38
  reset() {
@@ -92,6 +94,9 @@ export class FrameDragAction {
92
94
  return false;
93
95
  }
94
96
  onDragChange(_type, _e, state) {
97
+ if (state.dragDistance <= this.minDragDistance) {
98
+ return { updateEdges: false, shapes: [], showDragging: false };
99
+ }
95
100
  const { win, draggingFrameId, dragHoveredFrame } = state;
96
101
  const matchedZone = getDragZones(state, settings.zoneSizes);
97
102
  if (!matchedZone) {
@@ -5,6 +5,7 @@ export type SplitInfo = Exclude<ReturnType<typeof getFrameSplitInfo>, KnownError
5
5
  export type DragChangeType = "start" | "move" | "end";
6
6
  export declare class SplitAction implements IDragAction {
7
7
  name: "split";
8
+ minDragDistance: number;
8
9
  state: {
9
10
  allowed: true;
10
11
  res: SplitInfo;
@@ -37,6 +38,8 @@ export declare class SplitAction implements IDragAction {
37
38
  modifyDecos?: SplitAction["modifyDecos"], hooks?: SplitAction["hooks"], config?: {
38
39
  debug?: boolean | string;
39
40
  splitHints?: Partial<SplitAction["splitHints"]>;
41
+ /** Minimum pixel distance the user must drag before the action is allowed (decos shown and action applied). Defaults to 5. */
42
+ minDragDistance?: number;
40
43
  });
41
44
  reset(): void;
42
45
  getDecos(state: DragState): SplitDeco[];