@witchcraft/layout 0.4.3 → 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 (50) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/runtime/components/LayoutWindow.d.vue.ts +10 -1
  3. package/dist/runtime/components/LayoutWindow.vue +4 -4
  4. package/dist/runtime/components/LayoutWindow.vue.d.ts +10 -1
  5. package/dist/runtime/composables/useFrames.d.ts +37 -22
  6. package/dist/runtime/composables/useFrames.js +32 -8
  7. package/dist/runtime/demo/tailwind.css +1 -1
  8. package/dist/runtime/drag/DragActionHandler.d.ts +4 -1
  9. package/dist/runtime/drag/DragActionHandler.js +2 -2
  10. package/dist/runtime/helpers/findEdgesTouchingWindow.d.ts +7 -0
  11. package/dist/runtime/helpers/findEdgesTouchingWindow.js +20 -0
  12. package/dist/runtime/helpers/index.d.ts +8 -1
  13. package/dist/runtime/helpers/index.js +8 -1
  14. package/dist/runtime/layout/debugFrame.js +5 -1
  15. package/dist/runtime/layout/getFrameCollapseInfo.d.ts +1 -1
  16. package/dist/runtime/layout/getFrameCollapseInfo.js +9 -29
  17. package/dist/runtime/layout/getFrameDockInfo.d.ts +1 -1
  18. package/dist/runtime/layout/getFrameDockInfo.js +61 -44
  19. package/dist/runtime/layout/getFrameExpandInfo.d.ts +11 -0
  20. package/dist/runtime/layout/getFrameExpandInfo.js +49 -0
  21. package/dist/runtime/layout/getFrameShrinkInfo.d.ts +14 -0
  22. package/dist/runtime/layout/getFrameShrinkInfo.js +48 -0
  23. package/dist/runtime/layout/getFrameUncollapseInfo.d.ts +1 -1
  24. package/dist/runtime/layout/getFrameUncollapseInfo.js +6 -20
  25. package/dist/runtime/layout/getUpdateWindowSizeInfo.js +10 -12
  26. package/dist/runtime/layout/index.d.ts +3 -0
  27. package/dist/runtime/layout/index.js +3 -0
  28. package/dist/runtime/types/index.d.ts +70 -0
  29. package/dist/runtime/types/index.js +2 -1
  30. package/dist/runtime/types/vue.d.ts +12 -3
  31. package/package.json +3 -2
  32. package/src/runtime/components/LayoutWindow.vue +5 -5
  33. package/src/runtime/composables/useFrames.ts +46 -32
  34. package/src/runtime/demo/tailwind.css +4 -0
  35. package/src/runtime/drag/DragActionHandler.ts +3 -3
  36. package/src/runtime/helpers/findEdgesTouchingWindow.ts +30 -0
  37. package/src/runtime/helpers/index.ts +8 -1
  38. package/src/runtime/layout/debugFrame.ts +6 -1
  39. package/src/runtime/layout/getFrameCollapseInfo.ts +12 -41
  40. package/src/runtime/layout/getFrameDockInfo.ts +77 -57
  41. package/src/runtime/layout/getFrameExpandInfo.ts +84 -0
  42. package/src/runtime/layout/getFrameShrinkInfo.ts +87 -0
  43. package/src/runtime/layout/getFrameUncollapseInfo.ts +8 -30
  44. package/src/runtime/layout/getUpdateWindowSizeInfo.ts +16 -22
  45. package/src/runtime/layout/index.ts +3 -0
  46. package/src/runtime/types/index.ts +39 -1
  47. package/src/runtime/types/vue.ts +5 -3
  48. package/dist/runtime/drag/defaultDragActions.d.ts +0 -9
  49. package/dist/runtime/drag/defaultDragActions.js +0 -10
  50. 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.3",
4
+ "version": "0.4.4",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "unknown"
@@ -3,7 +3,7 @@ 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, note the actionHandler's prop will no longer have any effect.*/
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
7
  dragActionHandler?: DragActionHandler<any, any>;
8
8
  /** Custom drag action handlers. Falls back to default split/close/frame handlers if not provided. */
9
9
  actionHandlers?: IDragAction[];
@@ -109,6 +109,8 @@ declare const __VLS_component: import("vue").DefineComponent<__VLS_PublicProps,
109
109
  frame: import("../types/index.js").LayoutFrame;
110
110
  } | {
111
111
  frame: import("../types/index.js").LayoutFrame;
112
+ } | {
113
+ frame: import("../types/index.js").LayoutFrame;
112
114
  }> | {
113
115
  code: string;
114
116
  message: string;
@@ -184,6 +186,8 @@ declare const __VLS_component: import("vue").DefineComponent<__VLS_PublicProps,
184
186
  frame: import("../types/index.js").LayoutFrame;
185
187
  } | {
186
188
  frame: import("../types/index.js").LayoutFrame;
189
+ } | {
190
+ frame: import("../types/index.js").LayoutFrame;
187
191
  }> | {
188
192
  code: string;
189
193
  message: string;
@@ -251,6 +255,8 @@ declare const __VLS_component: import("vue").DefineComponent<__VLS_PublicProps,
251
255
  frame: import("../types/index.js").LayoutFrame;
252
256
  } | {
253
257
  frame: import("../types/index.js").LayoutFrame;
258
+ } | {
259
+ frame: import("../types/index.js").LayoutFrame;
254
260
  }> | {
255
261
  code: string;
256
262
  message: string;
@@ -321,6 +327,8 @@ declare const __VLS_component: import("vue").DefineComponent<__VLS_PublicProps,
321
327
  frame: import("../types/index.js").LayoutFrame;
322
328
  } | {
323
329
  frame: import("../types/index.js").LayoutFrame;
330
+ } | {
331
+ frame: import("../types/index.js").LayoutFrame;
324
332
  }> | {
325
333
  code: string;
326
334
  message: string;
@@ -332,6 +340,7 @@ declare const __VLS_component: import("vue").DefineComponent<__VLS_PublicProps,
332
340
  dragHoveredFrame: import("../types/index.js").LayoutFrame | undefined;
333
341
  intersections: import("../types/index.js").IntersectionEntry[];
334
342
  isDraggingFromWindowEdge: boolean;
343
+ eventContext: Record<string, unknown> | undefined;
335
344
  win: import("../types/index.js").BaseLayoutWindow;
336
345
  }>;
337
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 user-select-none`,
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";
@@ -92,7 +92,7 @@ const props = defineProps({
92
92
  const emit = defineEmits(["isShowingDrag", "dragState"]);
93
93
  const windowEl = ref(null);
94
94
  const requestType = ref();
95
- const dragActionHandler = props.dragActionHandler ?? new DragActionHandler(
95
+ const dragActionHandler = props.dragActionHandler ?? markRaw(new DragActionHandler(
96
96
  [
97
97
  ...props.actionHandlers ?? createDefaultHandlers()
98
98
  ],
@@ -111,7 +111,7 @@ const dragActionHandler = props.dragActionHandler ?? new DragActionHandler(
111
111
  showDragging.value = true;
112
112
  }
113
113
  }
114
- );
114
+ ));
115
115
  dragActionHandler.shapes = reactive([]);
116
116
  dragActionHandler.textHints = reactive({ actions: [], errors: [] });
117
117
  const shapes = dragActionHandler.shapes;
@@ -3,7 +3,7 @@ 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, note the actionHandler's prop will no longer have any effect.*/
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
7
  dragActionHandler?: DragActionHandler<any, any>;
8
8
  /** Custom drag action handlers. Falls back to default split/close/frame handlers if not provided. */
9
9
  actionHandlers?: IDragAction[];
@@ -109,6 +109,8 @@ declare const __VLS_component: import("vue").DefineComponent<__VLS_PublicProps,
109
109
  frame: import("../types/index.js").LayoutFrame;
110
110
  } | {
111
111
  frame: import("../types/index.js").LayoutFrame;
112
+ } | {
113
+ frame: import("../types/index.js").LayoutFrame;
112
114
  }> | {
113
115
  code: string;
114
116
  message: string;
@@ -184,6 +186,8 @@ declare const __VLS_component: import("vue").DefineComponent<__VLS_PublicProps,
184
186
  frame: import("../types/index.js").LayoutFrame;
185
187
  } | {
186
188
  frame: import("../types/index.js").LayoutFrame;
189
+ } | {
190
+ frame: import("../types/index.js").LayoutFrame;
187
191
  }> | {
188
192
  code: string;
189
193
  message: string;
@@ -251,6 +255,8 @@ declare const __VLS_component: import("vue").DefineComponent<__VLS_PublicProps,
251
255
  frame: import("../types/index.js").LayoutFrame;
252
256
  } | {
253
257
  frame: import("../types/index.js").LayoutFrame;
258
+ } | {
259
+ frame: import("../types/index.js").LayoutFrame;
254
260
  }> | {
255
261
  code: string;
256
262
  message: string;
@@ -321,6 +327,8 @@ declare const __VLS_component: import("vue").DefineComponent<__VLS_PublicProps,
321
327
  frame: import("../types/index.js").LayoutFrame;
322
328
  } | {
323
329
  frame: import("../types/index.js").LayoutFrame;
330
+ } | {
331
+ frame: import("../types/index.js").LayoutFrame;
324
332
  }> | {
325
333
  code: string;
326
334
  message: string;
@@ -332,6 +340,7 @@ declare const __VLS_component: import("vue").DefineComponent<__VLS_PublicProps,
332
340
  dragHoveredFrame: import("../types/index.js").LayoutFrame | undefined;
333
341
  intersections: import("../types/index.js").IntersectionEntry[];
334
342
  isDraggingFromWindowEdge: boolean;
343
+ eventContext: Record<string, unknown> | undefined;
335
344
  win: import("../types/index.js").BaseLayoutWindow;
336
345
  }>;
337
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;
@@ -810,6 +815,8 @@ export declare function useFrames(win: Ref<LayoutWindow>, handler: {
810
815
  frame: LayoutFrame;
811
816
  } | {
812
817
  frame: LayoutFrame;
818
+ } | {
819
+ frame: LayoutFrame;
813
820
  }> | {
814
821
  code: string;
815
822
  message: string;
@@ -885,6 +892,8 @@ export declare function useFrames(win: Ref<LayoutWindow>, handler: {
885
892
  frame: LayoutFrame;
886
893
  } | {
887
894
  frame: LayoutFrame;
895
+ } | {
896
+ frame: LayoutFrame;
888
897
  }> | {
889
898
  code: string;
890
899
  message: string;
@@ -952,6 +961,8 @@ export declare function useFrames(win: Ref<LayoutWindow>, handler: {
952
961
  frame: LayoutFrame;
953
962
  } | {
954
963
  frame: LayoutFrame;
964
+ } | {
965
+ frame: LayoutFrame;
955
966
  }> | {
956
967
  code: string;
957
968
  message: string;
@@ -1022,6 +1033,8 @@ export declare function useFrames(win: Ref<LayoutWindow>, handler: {
1022
1033
  frame: LayoutFrame;
1023
1034
  } | {
1024
1035
  frame: LayoutFrame;
1036
+ } | {
1037
+ frame: LayoutFrame;
1025
1038
  }> | {
1026
1039
  code: string;
1027
1040
  message: string;
@@ -1033,8 +1046,10 @@ export declare function useFrames(win: Ref<LayoutWindow>, handler: {
1033
1046
  dragHoveredFrame: LayoutFrame | undefined;
1034
1047
  intersections: IntersectionEntry[];
1035
1048
  isDraggingFromWindowEdge: boolean;
1049
+ eventContext: Record<string, unknown> | undefined;
1036
1050
  win: import("../types/index.js").BaseLayoutWindow;
1037
1051
  }>;
1038
1052
  showDragging: Ref<boolean, boolean>;
1039
1053
  frameDragFrameId: Ref<string | undefined, string | undefined>;
1054
+ actionHandler: ActionHandler;
1040
1055
  };
@@ -32,6 +32,7 @@ export function useFrames(win, handler) {
32
32
  const draggingIntersection = ref(void 0);
33
33
  const isDraggingFromWindowEdge = ref(false);
34
34
  const frameDragFrameId = ref();
35
+ const eventContext = ref();
35
36
  const frames = computed(
36
37
  () => isDragging.value && showDragging.value ? { ...win.value.frames, ...allTouchingFrames.value } : win.value.frames
37
38
  );
@@ -79,11 +80,17 @@ export function useFrames(win, handler) {
79
80
  dragHoveredFrame: dragHoveredFrame.value,
80
81
  intersections: intersections.value,
81
82
  isDraggingFromWindowEdge: isDraggingFromWindowEdge.value,
83
+ eventContext: eventContext.value,
82
84
  win: win.value
83
85
  }));
84
86
  let controller;
87
+ let dragResolve;
88
+ let dragResult;
85
89
  function resetState() {
86
90
  dragStartPoint = void 0;
91
+ dragResolve?.(dragResult);
92
+ dragResolve = void 0;
93
+ dragResult = void 0;
87
94
  draggingEdges.value = [];
88
95
  draggingIntersection.value = void 0;
89
96
  isDragging.value = false;
@@ -91,20 +98,32 @@ export function useFrames(win, handler) {
91
98
  dragDistance.value = -1;
92
99
  touchingFrames.value = [];
93
100
  frameDragFrameId.value = void 0;
101
+ eventContext.value = void 0;
94
102
  dragDirStore.reset();
95
103
  showDragging.value = false;
96
104
  forceRecalculateEdges();
97
105
  }
98
- 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
+ });
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, dragMove, { signal: controller.signal });
121
+ window.addEventListener(endEvent, dragEnd, { signal: controller.signal });
104
122
  const point = toWindowCoord(win.value, e);
105
123
  dragPoint.value = point;
106
124
  dragStartPoint = { ...point };
107
125
  dragDirStore.update(point);
126
+ eventContext.value = context;
108
127
  isDragging.value = type;
109
128
  showDragging.value = true;
110
129
  if (type === "frame") {
@@ -136,6 +155,7 @@ export function useFrames(win, handler) {
136
155
  }
137
156
  const res = handler.onDragChange("start", e, state.value, forceRecalculateEdges, cancel);
138
157
  showDragging.value = res.showDragging ?? true;
158
+ return promise;
139
159
  }
140
160
  function dragMove(e) {
141
161
  e.preventDefault();
@@ -169,10 +189,13 @@ export function useFrames(win, handler) {
169
189
  const point = toWindowCoord(win.value, e);
170
190
  dragPoint.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.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
+ }
176
199
  }
177
200
  }
178
201
  handler.onDragChange("end", e, state.value, forceRecalculateEdges, cancel);
@@ -213,6 +236,7 @@ export function useFrames(win, handler) {
213
236
  forceRecalculateEdges,
214
237
  state,
215
238
  showDragging,
216
- frameDragFrameId
239
+ frameDragFrameId,
240
+ actionHandler: handler
217
241
  };
218
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}
@@ -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) {
@@ -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
+ }
@@ -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";
@@ -21,17 +22,21 @@ export { doesEdgeContinueEdge } from "./doesEdgeContinueEdge.js";
21
22
  export { edgeToPoints } from "./edgeToPoints.js";
22
23
  export { findDraggableEdge } from "./findDraggableEdge.js";
23
24
  export { findFrameDraggableEdges } from "./findFrameDraggableEdges.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";
@@ -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";
@@ -21,17 +22,21 @@ export { doesEdgeContinueEdge } from "./doesEdgeContinueEdge.js";
21
22
  export { edgeToPoints } from "./edgeToPoints.js";
22
23
  export { findDraggableEdge } from "./findDraggableEdge.js";
23
24
  export { findFrameDraggableEdges } from "./findFrameDraggableEdges.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";
@@ -1,5 +1,9 @@
1
+ import { keys } from "@alanscodelog/utils/keys";
2
+ const builtinProperties = ["id", "x", "y", "width", "height", "docked", "collapsed"];
1
3
  export function debugFrame(frame) {
2
4
  const f = frame;
5
+ const otherProperties = keys(f).filter((k) => !builtinProperties.includes(k)).map((k) => `${k}: ${f[k]}`);
6
+ const otherPropertiesString = otherProperties.length > 0 ? `, ${otherProperties.join(", ")}` : "";
3
7
  return `id: ${f.id.slice(0, 4)}, x: ${f.x}, y: ${f.y}, w: ${f.width}, h: ${f.height}
4
- docked: ${f.docked}, collapsed: ${f.collapsed}`;
8
+ docked: ${f.docked}, collapsed: ${f.collapsed}${otherPropertiesString}`;
5
9
  }
@@ -13,4 +13,4 @@ import { KnownError } from "../utils/KnownError.js";
13
13
  export declare function getFrameCollapseInfo(win: LayoutWindow, frameId: string, { collapseSizeScaled }?: {
14
14
  /** Override the target collapse size. If provided, the frame will collapse to this size instead of settings.collapseSizeScaled. */
15
15
  collapseSizeScaled?: Size;
16
- }): LayoutChange | KnownError<typeof LAYOUT_ERROR.CANT_COLLAPSE_NOT_DOCKED> | KnownError<typeof LAYOUT_ERROR.REDISTRIBUTE_WOULD_RESULT_IN_INVALID_FRAMES>;
16
+ }): LayoutChange | KnownError<typeof LAYOUT_ERROR.CANT_COLLAPSE_NOT_DOCKED> | KnownError<typeof LAYOUT_ERROR.REDISTRIBUTE_WOULD_RESULT_IN_INVALID_FRAMES> | KnownError<typeof LAYOUT_ERROR.CANT_RESIZE_SINGLE_FRAME>;
@@ -1,10 +1,7 @@
1
1
  import { pushIfNotIn } from "@alanscodelog/utils/pushIfNotIn";
2
2
  import { walk } from "@alanscodelog/utils/walk";
3
3
  import { applyFrameChanges } from "./applyFrameChanges.js";
4
- import { getFramesRedistributeInfo } from "./getFramesRedistributeInfo.js";
5
- import { framesRedistributeFix } from "../helpers/framesRedistributeFix.js";
6
- import { getPinnedEdgesForCollapsedFrames } from "../helpers/getPinnedEdgesForCollapsedFrames.js";
7
- import { oppositeSide } from "../helpers/oppositeSide.js";
4
+ import { getFrameShrinkInfo } from "./getFrameShrinkInfo.js";
8
5
  import { settings } from "../settings.js";
9
6
  import { LAYOUT_ERROR } from "../types/index.js";
10
7
  import { KnownError } from "../utils/KnownError.js";
@@ -27,35 +24,18 @@ export function getFrameCollapseInfo(win, frameId, {
27
24
  }
28
25
  const isVertical = frame.docked === "left" || frame.docked === "right";
29
26
  const sizeKey = isVertical ? "width" : "height";
30
- const posKey = isVertical ? "x" : "y";
31
- const oppositePosKey = isVertical ? "y" : "x";
32
- const oppositeSizeKey = isVertical ? "height" : "width";
33
27
  const currentSize = frame[sizeKey];
34
- const collapseAmount = collapseSizeScaled[sizeKey];
35
- const shrinkAmount = currentSize - collapseAmount;
36
- const dockedSide = frame.docked;
37
- const { applyFixes, toFix } = framesRedistributeFix(win, frame, dockedSide, posKey, sizeKey, "shrink");
38
- const otherFrameIds = Object.keys(win.frames).filter((id) => id !== frameId);
39
- const redistributeSide = oppositeSide(dockedSide);
40
- const pinnedEdgeCoordinates = getPinnedEdgesForCollapsedFrames(win, frame, dockedSide, posKey, sizeKey);
41
- const changes = getFramesRedistributeInfo(win, redistributeSide, otherFrameIds, -shrinkAmount, { allowOutOfBounds: true, pinnedEdgeCoordinates });
42
- if (changes instanceof KnownError) {
43
- if (changes.code === LAYOUT_ERROR.REDISTRIBUTE_OUT_OF_BOUNDS || changes.code === LAYOUT_ERROR.NO_SPACE_TO_REDISTRIBUTE) {
44
- changes.message = `This error should never happen, please file a bug report: ${changes.message}`;
45
- throw changes;
46
- }
47
- return changes;
28
+ const shrinkAmount = currentSize - collapseSizeScaled[sizeKey];
29
+ const shrinkResult = getFrameShrinkInfo(win, frameId, shrinkAmount, frame.docked, { allowOutOfBounds: true });
30
+ if (shrinkResult instanceof KnownError) {
31
+ return shrinkResult;
48
32
  }
49
- applyFrameChanges(win, changes);
50
- pushIfNotIn(toExtract, changes.modified.map((_) => _.id));
51
- applyFixes();
52
- pushIfNotIn(toExtract, toFix);
53
- if (frame.docked === "right" || frame.docked === "bottom") {
54
- frame[posKey] = frame[posKey] + (frame[sizeKey] - collapseSizeScaled[sizeKey]);
55
- }
56
- frame[sizeKey] = collapseSizeScaled[sizeKey];
33
+ applyFrameChanges(win, shrinkResult);
34
+ pushIfNotIn(toExtract, shrinkResult.modified.map((_) => _.id));
57
35
  frame.collapsed = currentSize;
58
36
  if (collapseSizeScaled[sizeKey] === 0) {
37
+ const oppositePosKey = isVertical ? "y" : "x";
38
+ const oppositeSizeKey = isVertical ? "height" : "width";
59
39
  frame[oppositePosKey] = 0;
60
40
  frame[oppositeSizeKey] = settings.maxInt;
61
41
  }