@witchcraft/layout 0.4.3 → 0.5.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 (126) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/runtime/components/FrameDragHandle.vue +3 -3
  3. package/dist/runtime/components/LayoutDragEdgeGrabbed.vue +3 -3
  4. package/dist/runtime/components/LayoutDragEdgeHandle.d.vue.ts +2 -2
  5. package/dist/runtime/components/LayoutDragEdgeHandle.vue +2 -2
  6. package/dist/runtime/components/LayoutDragEdgeHandle.vue.d.ts +2 -2
  7. package/dist/runtime/components/LayoutDragEdges.vue +5 -5
  8. package/dist/runtime/components/LayoutEdgesActiveFrame.vue +2 -2
  9. package/dist/runtime/components/LayoutFrame.vue +2 -2
  10. package/dist/runtime/components/LayoutIntersectionHandle.d.vue.ts +2 -2
  11. package/dist/runtime/components/LayoutIntersectionHandle.vue +2 -2
  12. package/dist/runtime/components/LayoutIntersectionHandle.vue.d.ts +2 -2
  13. package/dist/runtime/components/LayoutIntersections.vue +4 -4
  14. package/dist/runtime/components/LayoutWindow.d.vue.ts +54 -45
  15. package/dist/runtime/components/LayoutWindow.vue +29 -29
  16. package/dist/runtime/components/LayoutWindow.vue.d.ts +54 -45
  17. package/dist/runtime/composables/useFrames.d.ts +142 -129
  18. package/dist/runtime/composables/useFrames.js +122 -94
  19. package/dist/runtime/demo/App.vue +16 -16
  20. package/dist/runtime/demo/DemoControls.d.vue.ts +2 -2
  21. package/dist/runtime/demo/DemoControls.vue +4 -4
  22. package/dist/runtime/demo/DemoControls.vue.d.ts +2 -2
  23. package/dist/runtime/demo/tailwind.css +1 -1
  24. package/dist/runtime/helpers/createZoneSideClipPath.d.ts +2 -2
  25. package/dist/runtime/helpers/findEdgesTouchingWindow.d.ts +7 -0
  26. package/dist/runtime/helpers/findEdgesTouchingWindow.js +20 -0
  27. package/dist/runtime/helpers/{findFrameDraggableEdges.d.ts → findFrameMoveableEdges.d.ts} +2 -2
  28. package/dist/runtime/helpers/{findFrameDraggableEdges.js → findFrameMoveableEdges.js} +3 -3
  29. package/dist/runtime/helpers/{findDraggableEdge.d.ts → findMoveableEdge.d.ts} +1 -1
  30. package/dist/runtime/helpers/{findDraggableEdge.js → findMoveableEdge.js} +1 -1
  31. package/dist/runtime/helpers/index.d.ts +10 -3
  32. package/dist/runtime/helpers/index.js +10 -3
  33. package/dist/runtime/layout/createSplitDecoFromDrag.d.ts +1 -1
  34. package/dist/runtime/layout/createSplitDecoFromDrag.js +2 -2
  35. package/dist/runtime/layout/debugFrame.js +5 -1
  36. package/dist/runtime/layout/findSafeSplitEdge.d.ts +1 -1
  37. package/dist/runtime/layout/findSafeSplitEdge.js +2 -2
  38. package/dist/runtime/layout/getCloseFrameInfo.js +4 -4
  39. package/dist/runtime/layout/getFrameCollapseInfo.d.ts +1 -1
  40. package/dist/runtime/layout/getFrameCollapseInfo.js +9 -29
  41. package/dist/runtime/layout/getFrameDockInfo.d.ts +1 -1
  42. package/dist/runtime/layout/getFrameDockInfo.js +61 -44
  43. package/dist/runtime/layout/getFrameExpandInfo.d.ts +11 -0
  44. package/dist/runtime/layout/getFrameExpandInfo.js +49 -0
  45. package/dist/runtime/layout/getFrameRearrangeInfo.d.ts +2 -2
  46. package/dist/runtime/layout/getFrameRearrangeInfo.js +8 -8
  47. package/dist/runtime/layout/getFrameShrinkInfo.d.ts +14 -0
  48. package/dist/runtime/layout/getFrameShrinkInfo.js +48 -0
  49. package/dist/runtime/layout/getFrameSplitInfo.d.ts +1 -1
  50. package/dist/runtime/layout/getFrameSplitInfo.js +2 -2
  51. package/dist/runtime/layout/getFrameUncollapseInfo.d.ts +1 -1
  52. package/dist/runtime/layout/getFrameUncollapseInfo.js +6 -20
  53. package/dist/runtime/layout/{getFrameDragZones.d.ts → getFrameZones.d.ts} +3 -3
  54. package/dist/runtime/layout/{getFrameDragZones.js → getFrameZones.js} +1 -1
  55. package/dist/runtime/layout/getUpdateWindowSizeInfo.js +10 -12
  56. package/dist/runtime/layout/{getWindowDragZones.d.ts → getWindowZones.d.ts} +1 -1
  57. package/dist/runtime/layout/{getWindowDragZones.js → getWindowZones.js} +1 -1
  58. package/dist/runtime/layout/getZones.d.ts +8 -0
  59. package/dist/runtime/layout/getZones.js +32 -0
  60. package/dist/runtime/layout/index.d.ts +6 -3
  61. package/dist/runtime/layout/index.js +6 -3
  62. package/dist/runtime/{drag/DragActionHandler.d.ts → move/ActionHandler.d.ts} +18 -18
  63. package/dist/runtime/{drag/DragActionHandler.js → move/ActionHandler.js} +19 -19
  64. package/dist/runtime/{drag → move}/CloseAction.d.ts +8 -8
  65. package/dist/runtime/{drag → move}/CloseAction.js +29 -26
  66. package/dist/runtime/{drag → move}/FrameDragAction.d.ts +8 -8
  67. package/dist/runtime/{drag → move}/FrameDragAction.js +23 -21
  68. package/dist/runtime/{drag/DragDirectionStore.d.ts → move/MoveDirectionStore.d.ts} +4 -4
  69. package/dist/runtime/{drag/DragDirectionStore.js → move/MoveDirectionStore.js} +9 -9
  70. package/dist/runtime/{drag → move}/SplitAction.d.ts +9 -9
  71. package/dist/runtime/{drag → move}/SplitAction.js +46 -43
  72. package/dist/runtime/{drag → move}/createDefaultHandlers.d.ts +2 -2
  73. package/dist/runtime/types/index.d.ts +242 -158
  74. package/dist/runtime/types/index.js +4 -3
  75. package/dist/runtime/types/vue.d.ts +25 -18
  76. package/dist/runtime/types/vue.js +1 -1
  77. package/package.json +3 -2
  78. package/src/runtime/components/FrameDragHandle.vue +3 -3
  79. package/src/runtime/components/LayoutDragEdgeGrabbed.vue +3 -3
  80. package/src/runtime/components/LayoutDragEdgeHandle.vue +4 -4
  81. package/src/runtime/components/LayoutDragEdges.vue +5 -5
  82. package/src/runtime/components/LayoutEdgesActiveFrame.vue +2 -2
  83. package/src/runtime/components/LayoutFrame.vue +2 -2
  84. package/src/runtime/components/LayoutIntersectionHandle.vue +4 -4
  85. package/src/runtime/components/LayoutIntersections.vue +4 -4
  86. package/src/runtime/components/LayoutWindow.vue +35 -35
  87. package/src/runtime/composables/useFrames.ts +141 -121
  88. package/src/runtime/demo/App.vue +18 -18
  89. package/src/runtime/demo/DemoControls.vue +5 -5
  90. package/src/runtime/demo/tailwind.css +4 -0
  91. package/src/runtime/helpers/createZoneSideClipPath.ts +2 -2
  92. package/src/runtime/helpers/findEdgesTouchingWindow.ts +30 -0
  93. package/src/runtime/helpers/{findFrameDraggableEdges.ts → findFrameMoveableEdges.ts} +4 -4
  94. package/src/runtime/helpers/{findDraggableEdge.ts → findMoveableEdge.ts} +1 -1
  95. package/src/runtime/helpers/index.ts +10 -3
  96. package/src/runtime/layout/createSplitDecoFromDrag.ts +2 -2
  97. package/src/runtime/layout/debugFrame.ts +6 -1
  98. package/src/runtime/layout/findSafeSplitEdge.ts +4 -4
  99. package/src/runtime/layout/getCloseFrameInfo.ts +4 -4
  100. package/src/runtime/layout/getFrameCollapseInfo.ts +12 -41
  101. package/src/runtime/layout/getFrameDockInfo.ts +77 -57
  102. package/src/runtime/layout/getFrameExpandInfo.ts +84 -0
  103. package/src/runtime/layout/getFrameRearrangeInfo.ts +10 -10
  104. package/src/runtime/layout/getFrameShrinkInfo.ts +87 -0
  105. package/src/runtime/layout/getFrameSplitInfo.ts +5 -5
  106. package/src/runtime/layout/getFrameUncollapseInfo.ts +8 -30
  107. package/src/runtime/layout/{getFrameDragZones.ts → getFrameZones.ts} +4 -4
  108. package/src/runtime/layout/getUpdateWindowSizeInfo.ts +16 -22
  109. package/src/runtime/layout/{getWindowDragZones.ts → getWindowZones.ts} +1 -1
  110. package/src/runtime/layout/getZones.ts +48 -0
  111. package/src/runtime/layout/index.ts +6 -3
  112. package/src/runtime/{drag/DragActionHandler.ts → move/ActionHandler.ts} +44 -42
  113. package/src/runtime/{drag → move}/CloseAction.ts +39 -36
  114. package/src/runtime/{drag → move}/FrameDragAction.ts +36 -35
  115. package/src/runtime/{drag/DragDirectionStore.ts → move/MoveDirectionStore.ts} +10 -10
  116. package/src/runtime/{drag → move}/SplitAction.ts +56 -53
  117. package/src/runtime/{drag/defaultDragActions.ts → move/createDefaultHandlers.ts} +2 -2
  118. package/src/runtime/types/index.ts +104 -55
  119. package/src/runtime/types/vue.ts +18 -16
  120. package/dist/runtime/drag/defaultDragActions.d.ts +0 -9
  121. package/dist/runtime/drag/defaultDragActions.js +0 -10
  122. package/dist/runtime/layout/getDragZones.d.ts +0 -8
  123. package/dist/runtime/layout/getDragZones.js +0 -32
  124. package/src/runtime/drag/createDefaultHandlers.ts +0 -20
  125. package/src/runtime/layout/getDragZones.ts +0 -48
  126. /package/dist/runtime/{drag → move}/createDefaultHandlers.js +0 -0
@@ -1,7 +1,6 @@
1
1
  import { debounce } from "@alanscodelog/utils/debounce";
2
2
  import { keys } from "@alanscodelog/utils/keys";
3
3
  import { computed, onBeforeUnmount, onMounted, ref, watch } from "vue";
4
- import { DragDirectionStore } from "../drag/DragDirectionStore.js";
5
4
  import { cloneFrame } from "../helpers/cloneFrame.js";
6
5
  import { getIntersections } from "../helpers/getIntersections.js";
7
6
  import { getVisualEdges } from "../helpers/getVisualEdges.js";
@@ -10,8 +9,9 @@ import { moveEdge } from "../helpers/moveEdge.js";
10
9
  import { toWindowCoord } from "../helpers/toWindowCoord.js";
11
10
  import { findFramesTouchingEdge } from "../layout/findFramesTouchingEdge.js";
12
11
  import { isPointInRect } from "../layout/isPointInRect.js";
12
+ import { MoveDirectionStore } from "../move/MoveDirectionStore.js";
13
13
  export function useFrames(win, handler) {
14
- const draggingEdges = ref([]);
14
+ const movingEdges = ref([]);
15
15
  const touchingFrames = ref([]);
16
16
  const allTouchingFrames = computed(() => {
17
17
  const result = {};
@@ -23,22 +23,23 @@ export function useFrames(win, handler) {
23
23
  return result;
24
24
  });
25
25
  const touchingFramesArrays = computed(() => touchingFrames.value.map((entry) => Object.values(entry)));
26
- const isDragging = ref(false);
27
- const showDragging = ref(false);
28
- const dragPoint = ref();
29
- const dragDirections = ref({});
30
- let dragStartPoint;
31
- const dragDistance = ref(-1);
32
- const draggingIntersection = ref(void 0);
33
- const isDraggingFromWindowEdge = ref(false);
34
- const frameDragFrameId = ref();
26
+ const isMoving = ref(false);
27
+ const showMoving = ref(false);
28
+ const movePoint = ref();
29
+ const moveDirections = ref({});
30
+ let moveStartPoint;
31
+ const moveDistance = ref(-1);
32
+ const movingIntersection = ref(void 0);
33
+ const isMovingFromWindowEdge = ref(false);
34
+ const movingFrameId = ref();
35
+ const eventContext = ref();
35
36
  const frames = computed(
36
- () => isDragging.value && showDragging.value ? { ...win.value.frames, ...allTouchingFrames.value } : win.value.frames
37
+ () => isMoving.value && showMoving.value ? { ...win.value.frames, ...allTouchingFrames.value } : win.value.frames
37
38
  );
38
- const dragHoveredFrame = computed(() => {
39
- if (isDragging.value) {
39
+ const moveHoveredFrame = computed(() => {
40
+ if (isMoving.value) {
40
41
  for (const id of keys(frames.value)) {
41
- if (isPointInRect(frames.value[id], dragPoint.value)) {
42
+ if (isPointInRect(frames.value[id], movePoint.value)) {
42
43
  return frames.value[id];
43
44
  }
44
45
  }
@@ -47,83 +48,101 @@ export function useFrames(win, handler) {
47
48
  });
48
49
  const visualEdges = ref([]);
49
50
  const intersections = computed(() => getIntersections(visualEdges.value));
50
- const debounceGetDraggableEdges = debounce((f) => {
51
+ const debounceGetMoveableEdges = debounce((f) => {
51
52
  visualEdges.value = getVisualEdges(f, { includeWindowEdges: true });
52
53
  handler.annotateEdges?.(visualEdges.value, f);
53
54
  }, 50, {});
54
- watch([isDragging, frames], () => {
55
- if (isDragging.value) return;
56
- debounceGetDraggableEdges(Object.values(frames.value));
55
+ watch([isMoving, frames], () => {
56
+ if (isMoving.value) return;
57
+ debounceGetMoveableEdges(Object.values(frames.value));
57
58
  }, { deep: true });
58
- debounceGetDraggableEdges(Object.values(frames.value));
59
+ debounceGetMoveableEdges(Object.values(frames.value));
59
60
  function forceRecalculateEdges() {
60
61
  visualEdges.value = getVisualEdges(Object.values(frames.value), { includeWindowEdges: true });
61
62
  handler.annotateEdges?.(visualEdges.value, Object.values(frames.value));
62
63
  }
63
- const dragDirStore = new DragDirectionStore({
64
- onUpdate: (dir) => dragDirections.value = dir
64
+ const moveDirStore = new MoveDirectionStore({
65
+ onUpdate: (dir) => moveDirections.value = dir
65
66
  });
66
67
  const state = computed(() => ({
67
- dragDirections: dragDirections.value,
68
- dragPoint: dragPoint.value,
69
- dragDistance: dragDistance.value,
70
- isDragging: isDragging.value,
71
- showDragging: showDragging.value,
72
- draggingFrameId: frameDragFrameId.value,
73
- draggingEdges: draggingEdges.value,
74
- draggingIntersection: draggingIntersection.value,
68
+ moveDirections: moveDirections.value,
69
+ movePoint: movePoint.value,
70
+ moveDistance: moveDistance.value,
71
+ isMoving: isMoving.value,
72
+ showMoving: showMoving.value,
73
+ movingFrameId: movingFrameId.value,
74
+ movingEdges: movingEdges.value,
75
+ movingIntersection: movingIntersection.value,
75
76
  visualEdges: visualEdges.value,
76
77
  touchingFrames: touchingFrames.value,
77
78
  touchingFramesArrays: touchingFramesArrays.value,
78
79
  frames: frames.value,
79
- dragHoveredFrame: dragHoveredFrame.value,
80
+ moveHoveredFrame: moveHoveredFrame.value,
80
81
  intersections: intersections.value,
81
- isDraggingFromWindowEdge: isDraggingFromWindowEdge.value,
82
+ isMovingFromWindowEdge: isMovingFromWindowEdge.value,
83
+ eventContext: eventContext.value,
82
84
  win: win.value
83
85
  }));
84
86
  let controller;
87
+ let moveResolve;
88
+ let moveResult;
85
89
  function resetState() {
86
- dragStartPoint = void 0;
87
- draggingEdges.value = [];
88
- draggingIntersection.value = void 0;
89
- isDragging.value = false;
90
- dragPoint.value = void 0;
91
- dragDistance.value = -1;
90
+ moveStartPoint = void 0;
91
+ moveResolve?.(moveResult);
92
+ moveResolve = void 0;
93
+ moveResult = void 0;
94
+ movingEdges.value = [];
95
+ movingIntersection.value = void 0;
96
+ isMoving.value = false;
97
+ movePoint.value = void 0;
98
+ moveDistance.value = -1;
92
99
  touchingFrames.value = [];
93
- frameDragFrameId.value = void 0;
94
- dragDirStore.reset();
95
- showDragging.value = false;
100
+ movingFrameId.value = void 0;
101
+ eventContext.value = void 0;
102
+ moveDirStore.reset();
103
+ showMoving.value = false;
96
104
  forceRecalculateEdges();
97
105
  }
98
- function dragStart(e, type, data) {
106
+ function moveStart(e, type, data, {
107
+ moveEvent = "pointermove",
108
+ endEvent = "pointerup",
109
+ context
110
+ } = {}) {
111
+ if (controller) {
112
+ controller.abort();
113
+ }
114
+ const promise = new Promise((resolve2) => {
115
+ moveResolve = resolve2;
116
+ });
99
117
  controller = new AbortController();
100
118
  controller.signal.addEventListener("abort", () => resetState());
101
119
  e.preventDefault();
102
- window.addEventListener("pointermove", dragMove, { signal: controller.signal });
103
- window.addEventListener("pointerup", dragEnd, { signal: controller.signal });
120
+ window.addEventListener(moveEvent, onMove, { signal: controller.signal });
121
+ window.addEventListener(endEvent, moveEnd, { signal: controller.signal });
104
122
  const point = toWindowCoord(win.value, e);
105
- dragPoint.value = point;
106
- dragStartPoint = { ...point };
107
- dragDirStore.update(point);
108
- isDragging.value = type;
109
- showDragging.value = true;
123
+ movePoint.value = point;
124
+ moveStartPoint = { ...point };
125
+ moveDirStore.update(point);
126
+ eventContext.value = context;
127
+ isMoving.value = type;
128
+ showMoving.value = true;
110
129
  if (type === "frame") {
111
- frameDragFrameId.value = data.frameId;
130
+ movingFrameId.value = data.frameId;
112
131
  } else {
113
132
  const { edge, intersection } = data;
114
- draggingIntersection.value = intersection;
115
- draggingEdges.value = edge ? [edge] : [
116
- ...draggingIntersection.value?.sharedEdges.horizontal ?? [],
117
- ...draggingIntersection.value?.sharedEdges.vertical ?? []
133
+ movingIntersection.value = intersection;
134
+ movingEdges.value = edge ? [edge] : [
135
+ ...movingIntersection.value?.sharedEdges.horizontal ?? [],
136
+ ...movingIntersection.value?.sharedEdges.vertical ?? []
118
137
  ];
119
- isDraggingFromWindowEdge.value = draggingEdges.value.some((_) => isWindowEdge(_));
138
+ isMovingFromWindowEdge.value = movingEdges.value.some((_) => isWindowEdge(_));
120
139
  const framesArray = Object.values(win.value.frames);
121
140
  touchingFrames.value = [];
122
141
  const clones = /* @__PURE__ */ new Map();
123
- for (let i = 0; i < draggingEdges.value.length; i++) {
124
- const draggingEdge = draggingEdges.value[i];
142
+ for (let i = 0; i < movingEdges.value.length; i++) {
143
+ const movingEdge = movingEdges.value[i];
125
144
  touchingFrames.value[i] = {};
126
- for (const { frame } of findFramesTouchingEdge(draggingEdge, framesArray)) {
145
+ for (const { frame } of findFramesTouchingEdge(movingEdge, framesArray)) {
127
146
  if (!clones.has(frame.id)) {
128
147
  const clone = cloneFrame(frame);
129
148
  touchingFrames.value[i][frame.id] = clone;
@@ -134,52 +153,60 @@ export function useFrames(win, handler) {
134
153
  }
135
154
  }
136
155
  }
137
- const res = handler.onDragChange("start", e, state.value, forceRecalculateEdges, cancel);
138
- showDragging.value = res.showDragging ?? true;
156
+ const res = handler.onMoveChange("start", e, state.value, forceRecalculateEdges, cancel, resolve);
157
+ showMoving.value = res.showMoving ?? true;
158
+ return promise;
139
159
  }
140
- function dragMove(e) {
160
+ function onMove(e) {
141
161
  e.preventDefault();
142
162
  const point = toWindowCoord(win.value, e);
143
- const didChange = dragDirStore.update(point);
144
- dragPoint.value = point;
145
- dragDistance.value = 0;
146
- if (dragStartPoint) {
147
- dragDistance.value = Math.sqrt(
148
- Math.pow(point.x - dragStartPoint.x, 2) + Math.pow(point.y - dragStartPoint.y, 2)
163
+ const didChange = moveDirStore.update(point);
164
+ movePoint.value = point;
165
+ moveDistance.value = 0;
166
+ if (moveStartPoint) {
167
+ moveDistance.value = Math.sqrt(
168
+ Math.pow(point.x - moveStartPoint.x, 2) + Math.pow(point.y - moveStartPoint.y, 2)
149
169
  );
150
170
  }
151
171
  if (!didChange) return;
152
- const res = handler.onDragChange("move", e, state.value, forceRecalculateEdges, cancel);
153
- showDragging.value = res.showDragging ?? true;
172
+ const res = handler.onMoveChange("move", e, state.value, forceRecalculateEdges, cancel, resolve);
173
+ showMoving.value = res.showMoving ?? true;
154
174
  if (!res.updateEdges) return;
155
- if (isDragging.value === "edge") {
175
+ if (isMoving.value === "edge") {
156
176
  requestAnimationFrame(() => {
157
- for (let i = 0; i < draggingEdges.value.length; i++) {
158
- const draggingEdge = draggingEdges.value[i];
159
- if (draggingEdge) {
160
- moveEdge(touchingFramesArrays.value[i], draggingEdge, point);
177
+ for (let i = 0; i < movingEdges.value.length; i++) {
178
+ const movingEdge = movingEdges.value[i];
179
+ if (movingEdge) {
180
+ moveEdge(touchingFramesArrays.value[i], movingEdge, point);
161
181
  }
162
182
  }
163
183
  forceRecalculateEdges();
164
184
  });
165
185
  }
166
186
  }
167
- function dragEnd(e, { apply = true } = {}) {
187
+ function moveEnd(e, { apply = true } = {}) {
168
188
  if (e) {
169
189
  const point = toWindowCoord(win.value, e);
170
- dragPoint.value = point;
190
+ movePoint.value = point;
171
191
  }
172
- const doApply = apply && handler.onDragApply(state.value, forceRecalculateEdges);
173
- if (doApply) {
174
- for (const frame of touchingFramesArrays.value.flat()) {
175
- win.value.frames[frame.id] = frame;
192
+ if (apply) {
193
+ const applyResult = handler.onMoveApply(state.value, forceRecalculateEdges);
194
+ moveResult = applyResult.result;
195
+ if (applyResult.apply) {
196
+ for (const frame of touchingFramesArrays.value.flat()) {
197
+ win.value.frames[frame.id] = frame;
198
+ }
176
199
  }
177
200
  }
178
- handler.onDragChange("end", e, state.value, forceRecalculateEdges, cancel);
201
+ handler.onMoveChange("end", e, state.value, forceRecalculateEdges, void 0, void 0);
179
202
  controller?.abort();
180
203
  }
181
204
  function cancel() {
182
- dragEnd(void 0, { apply: false });
205
+ moveEnd(void 0, { apply: false });
206
+ }
207
+ function resolve({ apply, result: value }) {
208
+ moveResult = value;
209
+ moveEnd(void 0, { apply });
183
210
  }
184
211
  const keydownController = new AbortController();
185
212
  const wrappedKeydownHandler = (e) => {
@@ -194,25 +221,26 @@ export function useFrames(win, handler) {
194
221
  keydownController?.abort();
195
222
  });
196
223
  return {
197
- dragStart,
198
- dragEnd,
224
+ moveStart,
225
+ moveEnd,
199
226
  cancel,
200
- dragMove,
201
- dragDirections,
202
- dragPoint,
203
- isDragging,
204
- draggingEdges,
205
- draggingIntersection,
227
+ onMove,
228
+ moveDirections,
229
+ movePoint,
230
+ isMoving,
231
+ movingEdges,
232
+ movingIntersection,
206
233
  visualEdges,
207
234
  touchingFrames,
208
235
  touchingFramesArrays,
209
236
  frames,
210
- dragHoveredFrame,
237
+ moveHoveredFrame,
211
238
  intersections,
212
- isDraggingFromWindowEdge,
239
+ isMovingFromWindowEdge,
213
240
  forceRecalculateEdges,
214
241
  state,
215
- showDragging,
216
- frameDragFrameId
242
+ showMoving,
243
+ movingFrameId,
244
+ actionHandler: handler
217
245
  };
218
246
  }
@@ -10,7 +10,7 @@
10
10
  v-if="win"
11
11
  :frames="frames"
12
12
  :win="win"
13
- :dragActionHandler="dragActionHandler"
13
+ :actionHandler="actionHandler"
14
14
  />
15
15
 
16
16
  <LayoutWindow
@@ -34,8 +34,8 @@
34
34
  :textHints="textHints"
35
35
  textHintsTeleportTo="#status-bar"
36
36
  v-model:win="win"
37
- @is-showing-drag="isShowingDrag = $event"
38
- @drag-state="dragState = $event"
37
+ @is-showing-move="isShowingMove = $event"
38
+ @move-state="moveState = $event"
39
39
  >
40
40
  <LayoutFrame class="
41
41
  flex
@@ -175,7 +175,7 @@ import {
175
175
  import { settings } from "../settings.js";
176
176
  import { throwIfError } from "@alanscodelog/utils/throwIfError";
177
177
  import { useTemplateRef } from "vue";
178
- import { DragActionHandler } from "../drag/DragActionHandler.js";
178
+ import { ActionHandler } from "../move/ActionHandler.js";
179
179
  import LayoutDragEdgeHandle from "../components/LayoutDragEdgeHandle.vue";
180
180
  import LayoutDragEdgeVisible from "../components/LayoutDragEdgeVisible.vue";
181
181
  import LayoutIntersectionVisible from "../components/LayoutIntersectionVisible.vue";
@@ -213,25 +213,25 @@ function layoutInitialize(layout, { defaultPos, defaultSize } = {
213
213
  }));
214
214
  w.activeFrame = frame.id;
215
215
  }
216
- const isShowingDrag = ref(false);
217
- const dragState = ref(void 0);
216
+ const isShowingMove = ref(false);
217
+ const moveState = ref(void 0);
218
218
  function handleUndock(frameId) {
219
219
  const changes = throwIfError(getFrameUndockInfo(win.value, frameId));
220
- DragActionHandler.debugState("undock", "before", dragState.value, {}, void 0);
220
+ ActionHandler.debugState("undock", "before", moveState.value, {}, void 0);
221
221
  applyFrameChanges(win.value, changes);
222
- DragActionHandler.debugState("undock", "after", dragState.value, {}, void 0);
222
+ ActionHandler.debugState("undock", "after", moveState.value, {}, void 0);
223
223
  }
224
224
  function handleCollapse(frameId) {
225
225
  const changes = throwIfError(getFrameCollapseInfo(win.value, frameId));
226
- DragActionHandler.debugState("collapse", "before", dragState.value, {}, void 0);
226
+ ActionHandler.debugState("collapse", "before", moveState.value, {}, void 0);
227
227
  applyFrameChanges(win.value, changes);
228
- DragActionHandler.debugState("collapse", "after", dragState.value, {}, void 0);
228
+ ActionHandler.debugState("collapse", "after", moveState.value, {}, void 0);
229
229
  }
230
230
  function handleUncollapse(frameId) {
231
231
  const changes = throwIfError(getFrameUncollapseInfo(win.value, frameId));
232
- DragActionHandler.debugState("uncollapse", "before", dragState.value, {}, void 0);
232
+ ActionHandler.debugState("uncollapse", "before", moveState.value, {}, void 0);
233
233
  applyFrameChanges(win.value, changes);
234
- DragActionHandler.debugState("uncollapse", "after", dragState.value, {}, void 0);
234
+ ActionHandler.debugState("uncollapse", "after", moveState.value, {}, void 0);
235
235
  }
236
236
  const collapsedDocks = computed(() => {
237
237
  const sides = {};
@@ -242,12 +242,12 @@ const collapsedDocks = computed(() => {
242
242
  }
243
243
  return sides;
244
244
  });
245
- const dragActionHandler = computed(() => layoutComponent.value?.dragActionHandler);
245
+ const actionHandler = computed(() => layoutComponent.value?.actionHandler);
246
246
  const textHints = computed(() => {
247
- const isDragging = dragState.value?.isDragging;
248
- const textHints2 = dragActionHandler.value?.textHints ?? { actions: [], errors: [] };
247
+ const isMoving = moveState.value?.isMoving;
248
+ const textHints2 = actionHandler.value?.textHints ?? { actions: [], errors: [] };
249
249
  return [
250
- ...!isDragging ? [{ classes: "", text: "Drag from an edge to create a new frame." }] : [],
250
+ ...!isMoving ? [{ classes: "", text: "Drag from an edge to create a new frame." }] : [],
251
251
  ...textHints2.errors.map((_) => ({ classes: "text-red-500", text: _ })),
252
252
  ...textHints2.actions.map((_) => ({ text: _ }))
253
253
  ];
@@ -1,9 +1,9 @@
1
1
  import type { LayoutFrame, LayoutWindow } from "../types/index.js";
2
- import type { DragActionHandler } from "../drag/DragActionHandler.js";
2
+ import type { ActionHandler } from "../move/ActionHandler.js";
3
3
  type __VLS_Props = {
4
4
  win: LayoutWindow;
5
5
  frames: LayoutFrame[];
6
- dragActionHandler?: DragActionHandler<any>;
6
+ actionHandler?: ActionHandler<any>;
7
7
  };
8
8
  declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
9
9
  export default _default;
@@ -26,7 +26,7 @@
26
26
  <WButton class="flex-1" @click="copyState">Copy State</WButton>
27
27
  <WCheckbox v-model="renameFrames">Easy Ids</WCheckbox>
28
28
  </div>
29
- <label class="flex flex-col gap-2 text-sm" v-if="dragActionHandler">
29
+ <label class="flex flex-col gap-2 text-sm" v-if="actionHandler">
30
30
  <span>Plugin Debug Logs (true | debug path):</span>
31
31
  <WSimpleInput v-model="debugKey" />
32
32
  </label>
@@ -55,7 +55,7 @@ import { rotateLayout } from "../helpers/rotateFrames.js";
55
55
  const props = defineProps({
56
56
  win: { type: Object, required: true },
57
57
  frames: { type: Array, required: true },
58
- dragActionHandler: { type: Object, required: false }
58
+ actionHandler: { type: Object, required: false }
59
59
  });
60
60
  const showDevActions = ref(false);
61
61
  const collapseSizeValue = ref(settings.collapseSizePx.width);
@@ -101,9 +101,9 @@ function copyState() {
101
101
  }
102
102
  const debugKey = ref(import.meta.dev ? "state.win.frames" : "false");
103
103
  watch(debugKey, () => {
104
- if (!props.dragActionHandler) return;
104
+ if (!props.actionHandler) return;
105
105
  const value = debugKey.value === "true" ? true : debugKey.value === "false" ? false : debugKey.value;
106
- for (const plugin of Object.values(props.dragActionHandler.actions)) {
106
+ for (const plugin of Object.values(props.actionHandler.actions)) {
107
107
  plugin.debug = value;
108
108
  }
109
109
  });
@@ -1,9 +1,9 @@
1
1
  import type { LayoutFrame, LayoutWindow } from "../types/index.js";
2
- import type { DragActionHandler } from "../drag/DragActionHandler.js";
2
+ import type { ActionHandler } from "../move/ActionHandler.js";
3
3
  type __VLS_Props = {
4
4
  win: LayoutWindow;
5
5
  frames: LayoutFrame[];
6
- dragActionHandler?: DragActionHandler<any>;
6
+ actionHandler?: ActionHandler<any>;
7
7
  };
8
8
  declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
9
9
  export default _default;
@@ -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}
@@ -5,8 +5,8 @@
5
5
  *
6
6
  * Accepts scaled coordinates.
7
7
  */
8
- import type { DragZone } from "../types/index.js";
9
- export declare function createZoneSideClipPath(zone: DragZone, { frameEdgePx, windowEdgePx }: {
8
+ import type { Zone } from "../types/index.js";
9
+ export declare function createZoneSideClipPath(zone: Zone, { frameEdgePx, windowEdgePx }: {
10
10
  frameEdgePx: number;
11
11
  windowEdgePx: number;
12
12
  }): string | undefined;
@@ -0,0 +1,7 @@
1
+ import type { EdgeSide, LayoutFrame } from "../types/index.js";
2
+ /**
3
+ * Checks which window edges a frame touches and how.
4
+ *
5
+ * @returns Record mapping touched sides to `"full"` (spans the entire edge) or `"partial"` (touches but doesn't span fully). Only touched sides are included as keys.
6
+ */
7
+ export declare function findEdgesTouchingWindow(frame: LayoutFrame): Partial<Record<EdgeSide, "full" | "partial">>;
@@ -0,0 +1,20 @@
1
+ import { settings } from "../settings.js";
2
+ export function findEdgesTouchingWindow(frame) {
3
+ const maxInt = settings.maxInt;
4
+ const result = {};
5
+ const spansVertical = frame.y === 0 && frame.y + frame.height === maxInt;
6
+ const spansHorizontal = frame.x === 0 && frame.x + frame.width === maxInt;
7
+ if (frame.x === 0) {
8
+ result.left = spansVertical ? "full" : "partial";
9
+ }
10
+ if (frame.x + frame.width === maxInt) {
11
+ result.right = spansVertical ? "full" : "partial";
12
+ }
13
+ if (frame.y === 0) {
14
+ result.top = spansHorizontal ? "full" : "partial";
15
+ }
16
+ if (frame.y + frame.height === maxInt) {
17
+ result.bottom = spansHorizontal ? "full" : "partial";
18
+ }
19
+ return result;
20
+ }
@@ -1,6 +1,6 @@
1
1
  import type { Edge, EdgeSide, LayoutFrame } from "../types/index.js";
2
- export declare function findFrameDraggableEdges(frame: LayoutFrame, edges: Edge[],
3
- /** See {@link findDraggableEdge} */
2
+ export declare function findFrameMoveableEdges(frame: LayoutFrame, edges: Edge[],
3
+ /** See {@link findMoveableEdge} */
4
4
  exact?: boolean, sides?: EdgeSide[]): {
5
5
  edge: Edge;
6
6
  side: EdgeSide;
@@ -1,8 +1,8 @@
1
- import { findDraggableEdge } from "./findDraggableEdge.js";
1
+ import { findMoveableEdge } from "./findMoveableEdge.js";
2
2
  import { frameToEdges } from "./frameToEdges.js";
3
3
  import { isWindowEdge } from "./isWindowEdge.js";
4
4
  import { sideToOrientation } from "./sideToOrientation.js";
5
- export function findFrameDraggableEdges(frame, edges, exact = true, sides = ["left", "right", "top", "bottom"]) {
5
+ export function findFrameMoveableEdges(frame, edges, exact = true, sides = ["left", "right", "top", "bottom"]) {
6
6
  const frameEdges = frameToEdges(frame);
7
7
  const res = [];
8
8
  for (const side of sides) {
@@ -10,7 +10,7 @@ export function findFrameDraggableEdges(frame, edges, exact = true, sides = ["le
10
10
  const edgeDirection = sideToOrientation(side);
11
11
  const isWinEdge = isWindowEdge(edge, edgeDirection);
12
12
  if (isWinEdge) continue;
13
- const maybeEdge = findDraggableEdge(edge, edges, exact, edgeDirection);
13
+ const maybeEdge = findMoveableEdge(edge, edges, exact, edgeDirection);
14
14
  if (maybeEdge) res.push({ edge: maybeEdge, side });
15
15
  }
16
16
  if (res.length > 0) return res;
@@ -1,4 +1,4 @@
1
1
  import type { Edge, Orientation } from "../types/index.js";
2
- export declare function findDraggableEdge(edge: Edge, edges: Edge[],
2
+ export declare function findMoveableEdge(edge: Edge, edges: Edge[],
3
3
  /** Whether the edge must match exactly and does not "contain/touch" another frame. */
4
4
  exact?: boolean, edgeOrientation?: Orientation): Edge | undefined;
@@ -1,7 +1,7 @@
1
1
  import { containsEdge } from "./containsEdge.js";
2
2
  import { getEdgeOrientation } from "./getEdgeOrientation.js";
3
3
  import { isEdgeEqual } from "./isEdgeEqual.js";
4
- export function findDraggableEdge(edge, edges, exact = true, edgeOrientation) {
4
+ export function findMoveableEdge(edge, edges, exact = true, edgeOrientation) {
5
5
  edgeOrientation ??= getEdgeOrientation(edge);
6
6
  for (const otherEdge of edges) {
7
7
  const didFindEdge = exact ? isEdgeEqual(edge, otherEdge, edgeOrientation) : containsEdge(edge, otherEdge, edgeOrientation);
@@ -9,6 +9,7 @@ export { assertValidWinAndFrameIds } from "./assertValidWinAndFrameIds.js";
9
9
  export { assertWindowHasActiveFrame } from "./assertWindowHasActiveFrame.js";
10
10
  export { cloneFrame } from "./cloneFrame.js";
11
11
  export { cloneFrames } from "./cloneFrames.js";
12
+ export { consoleDebugWindow } from "./consoleDebugWindow.js";
12
13
  export { containsEdge } from "./containsEdge.js";
13
14
  export { convertLayoutWindowToWorkspace } from "./convertLayoutWindowToWorkspace.js";
14
15
  export { copySize } from "./copySize.js";
@@ -19,19 +20,23 @@ export { dirToSide } from "./dirToSide.js";
19
20
  export { doEdgesOverlap } from "./doEdgesOverlap.js";
20
21
  export { doesEdgeContinueEdge } from "./doesEdgeContinueEdge.js";
21
22
  export { edgeToPoints } from "./edgeToPoints.js";
22
- export { findDraggableEdge } from "./findDraggableEdge.js";
23
- export { findFrameDraggableEdges } from "./findFrameDraggableEdges.js";
23
+ export { findMoveableEdge } from "./findMoveableEdge.js";
24
+ export { findFrameMoveableEdges } from "./findFrameMoveableEdges.js";
25
+ export { framesRedistributeFix } from "./framesRedistributeFix.js";
24
26
  export { frameToEdges } from "./frameToEdges.js";
25
27
  export { frameToPoints } from "./frameToPoints.js";
28
+ export { getDockBoundaries } from "./getDockBoundaries.js";
26
29
  export { getEdgeLength } from "./getEdgeLength.js";
27
30
  export { getEdgeOrientation } from "./getEdgeOrientation.js";
28
31
  export { getEdgeSharedDirection } from "./getEdgeSharedDirection.js";
29
32
  export { getEdgeSide } from "./getEdgeSide.js";
30
33
  export { getFrameById } from "./getFrameById.js";
31
34
  export { getFrameConstant } from "./getFrameConstant.js";
35
+ export { findEdgesTouchingWindow } from "./findEdgesTouchingWindow.js";
32
36
  export { getIntersections } from "./getIntersections.js";
33
37
  export { getIntersectionsCss } from "./getIntersectionsCss.js";
34
38
  export { getMoveEdgeInfo } from "./getMoveEdgeInfo.js";
39
+ export { getPinnedEdgesForCollapsedFrames } from "./getPinnedEdgesForCollapsedFrames.js";
35
40
  export { getResizeLimit } from "./getResizeLimit.js";
36
41
  export { getShapeRectCss } from "./getShapeRectCss.js";
37
42
  export { getSideTouching } from "./getSideTouching.js";
@@ -52,9 +57,10 @@ export { isWindowEdge } from "./isWindowEdge.js";
52
57
  export { isWindowEdgePoint } from "./isWindowEdgePoint.js";
53
58
  export { moveEdge } from "./moveEdge.js";
54
59
  export { numberToScaledPercent } from "./numberToScaledPercent.js";
55
- export { pxSizeToScaledSize } from "./pxSizeToScaledSize.js";
56
60
  export { oppositeSide } from "./oppositeSide.js";
61
+ export { pxSizeToScaledSize } from "./pxSizeToScaledSize.js";
57
62
  export { resizeByEdge } from "./resizeByEdge.js";
63
+ export { rotateLayout } from "./rotateFrames.js";
58
64
  export { scaledPointToPx } from "./scaledPointToPx.js";
59
65
  export { sideToDirection } from "./sideToDirection.js";
60
66
  export { sideToOrientation } from "./sideToOrientation.js";
@@ -64,3 +70,4 @@ export { toId } from "./toId.js";
64
70
  export { toWindowCoord } from "./toWindowCoord.js";
65
71
  export { unionEdges } from "./unionEdges.js";
66
72
  export { updateWindowWithEvent } from "./updateWindowSizeWithEvent.js";
73
+ export { validateLayoutShape } from "./validateLayoutShape.js";