@witchcraft/layout 0.4.4 → 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 (99) 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 +44 -44
  15. package/dist/runtime/components/LayoutWindow.vue +27 -27
  16. package/dist/runtime/components/LayoutWindow.vue.d.ts +44 -44
  17. package/dist/runtime/composables/useFrames.d.ts +107 -109
  18. package/dist/runtime/composables/useFrames.js +103 -99
  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/helpers/createZoneSideClipPath.d.ts +2 -2
  24. package/dist/runtime/helpers/{findFrameDraggableEdges.d.ts → findFrameMoveableEdges.d.ts} +2 -2
  25. package/dist/runtime/helpers/{findFrameDraggableEdges.js → findFrameMoveableEdges.js} +3 -3
  26. package/dist/runtime/helpers/{findDraggableEdge.d.ts → findMoveableEdge.d.ts} +1 -1
  27. package/dist/runtime/helpers/{findDraggableEdge.js → findMoveableEdge.js} +1 -1
  28. package/dist/runtime/helpers/index.d.ts +2 -2
  29. package/dist/runtime/helpers/index.js +2 -2
  30. package/dist/runtime/layout/createSplitDecoFromDrag.d.ts +1 -1
  31. package/dist/runtime/layout/createSplitDecoFromDrag.js +2 -2
  32. package/dist/runtime/layout/findSafeSplitEdge.d.ts +1 -1
  33. package/dist/runtime/layout/findSafeSplitEdge.js +2 -2
  34. package/dist/runtime/layout/getCloseFrameInfo.js +4 -4
  35. package/dist/runtime/layout/getFrameRearrangeInfo.d.ts +2 -2
  36. package/dist/runtime/layout/getFrameRearrangeInfo.js +8 -8
  37. package/dist/runtime/layout/getFrameSplitInfo.d.ts +1 -1
  38. package/dist/runtime/layout/getFrameSplitInfo.js +2 -2
  39. package/dist/runtime/layout/{getFrameDragZones.d.ts → getFrameZones.d.ts} +3 -3
  40. package/dist/runtime/layout/{getFrameDragZones.js → getFrameZones.js} +1 -1
  41. package/dist/runtime/layout/{getWindowDragZones.d.ts → getWindowZones.d.ts} +1 -1
  42. package/dist/runtime/layout/{getWindowDragZones.js → getWindowZones.js} +1 -1
  43. package/dist/runtime/layout/getZones.d.ts +8 -0
  44. package/dist/runtime/layout/getZones.js +32 -0
  45. package/dist/runtime/layout/index.d.ts +3 -3
  46. package/dist/runtime/layout/index.js +3 -3
  47. package/dist/runtime/{drag/DragActionHandler.d.ts → move/ActionHandler.d.ts} +18 -21
  48. package/dist/runtime/{drag/DragActionHandler.js → move/ActionHandler.js} +17 -17
  49. package/dist/runtime/{drag → move}/CloseAction.d.ts +8 -8
  50. package/dist/runtime/{drag → move}/CloseAction.js +29 -26
  51. package/dist/runtime/{drag → move}/FrameDragAction.d.ts +8 -8
  52. package/dist/runtime/{drag → move}/FrameDragAction.js +23 -21
  53. package/dist/runtime/{drag/DragDirectionStore.d.ts → move/MoveDirectionStore.d.ts} +4 -4
  54. package/dist/runtime/{drag/DragDirectionStore.js → move/MoveDirectionStore.js} +9 -9
  55. package/dist/runtime/{drag → move}/SplitAction.d.ts +9 -9
  56. package/dist/runtime/{drag → move}/SplitAction.js +46 -43
  57. package/dist/runtime/{drag → move}/createDefaultHandlers.d.ts +2 -2
  58. package/dist/runtime/types/index.d.ts +185 -171
  59. package/dist/runtime/types/index.js +2 -2
  60. package/dist/runtime/types/vue.d.ts +14 -16
  61. package/dist/runtime/types/vue.js +1 -1
  62. package/package.json +1 -1
  63. package/src/runtime/components/FrameDragHandle.vue +3 -3
  64. package/src/runtime/components/LayoutDragEdgeGrabbed.vue +3 -3
  65. package/src/runtime/components/LayoutDragEdgeHandle.vue +4 -4
  66. package/src/runtime/components/LayoutDragEdges.vue +5 -5
  67. package/src/runtime/components/LayoutEdgesActiveFrame.vue +2 -2
  68. package/src/runtime/components/LayoutFrame.vue +2 -2
  69. package/src/runtime/components/LayoutIntersectionHandle.vue +4 -4
  70. package/src/runtime/components/LayoutIntersections.vue +4 -4
  71. package/src/runtime/components/LayoutWindow.vue +32 -32
  72. package/src/runtime/composables/useFrames.ts +108 -102
  73. package/src/runtime/demo/App.vue +18 -18
  74. package/src/runtime/demo/DemoControls.vue +5 -5
  75. package/src/runtime/helpers/createZoneSideClipPath.ts +2 -2
  76. package/src/runtime/helpers/{findFrameDraggableEdges.ts → findFrameMoveableEdges.ts} +4 -4
  77. package/src/runtime/helpers/{findDraggableEdge.ts → findMoveableEdge.ts} +1 -1
  78. package/src/runtime/helpers/index.ts +2 -2
  79. package/src/runtime/layout/createSplitDecoFromDrag.ts +2 -2
  80. package/src/runtime/layout/findSafeSplitEdge.ts +4 -4
  81. package/src/runtime/layout/getCloseFrameInfo.ts +4 -4
  82. package/src/runtime/layout/getFrameRearrangeInfo.ts +10 -10
  83. package/src/runtime/layout/getFrameSplitInfo.ts +5 -5
  84. package/src/runtime/layout/{getFrameDragZones.ts → getFrameZones.ts} +4 -4
  85. package/src/runtime/layout/{getWindowDragZones.ts → getWindowZones.ts} +1 -1
  86. package/src/runtime/layout/getZones.ts +48 -0
  87. package/src/runtime/layout/index.ts +3 -3
  88. package/src/runtime/{drag/DragActionHandler.ts → move/ActionHandler.ts} +42 -40
  89. package/src/runtime/{drag → move}/CloseAction.ts +39 -36
  90. package/src/runtime/{drag → move}/FrameDragAction.ts +36 -35
  91. package/src/runtime/{drag/DragDirectionStore.ts → move/MoveDirectionStore.ts} +10 -10
  92. package/src/runtime/{drag → move}/SplitAction.ts +56 -53
  93. package/src/runtime/{drag → move}/createDefaultHandlers.ts +2 -2
  94. package/src/runtime/types/index.ts +80 -69
  95. package/src/runtime/types/vue.ts +14 -14
  96. package/dist/runtime/layout/getDragZones.d.ts +0 -8
  97. package/dist/runtime/layout/getDragZones.js +0 -32
  98. package/src/runtime/layout/getDragZones.ts +0 -48
  99. /package/dist/runtime/{drag → move}/createDefaultHandlers.js +0 -0
@@ -7,7 +7,7 @@ import { getSideTouching } from "../helpers/getSideTouching.js"
7
7
  import { isEdgeEqual } from "../helpers/isEdgeEqual.js"
8
8
  import { oppositeSide } from "../helpers/oppositeSide.js"
9
9
  import { sideToDirection } from "../helpers/sideToDirection.js"
10
- import type { DragZone, LayoutChange, LayoutWindow } from "../types/index.js"
10
+ import type { LayoutChange, LayoutWindow, Zone } from "../types/index.js"
11
11
  import { LAYOUT_ERROR } from "../types/index.js"
12
12
  import { KnownError } from "../utils/KnownError.js"
13
13
 
@@ -150,9 +150,9 @@ import { KnownError } from "../utils/KnownError.js"
150
150
 
151
151
  export function getFrameRearrangeInfo(
152
152
  win: LayoutWindow,
153
- draggingFrameId: string,
153
+ movingFrameId: string,
154
154
  hoveredFrameId: string,
155
- zoneSide: DragZone["side"]
155
+ zoneSide: Zone["side"]
156
156
  ): LayoutChange<"split" | "swap" | "rearrange">
157
157
  | KnownError<typeof LAYOUT_ERROR.CANT_SWAP_WITH_SELF>
158
158
  | KnownError<typeof LAYOUT_ERROR.CANT_SPLIT_FRAME_TOO_SMALL>
@@ -161,10 +161,10 @@ export function getFrameRearrangeInfo(
161
161
  | KnownError<typeof LAYOUT_ERROR.CANT_REARRANGE_DOCKED_WITH_NON_DOCKED>
162
162
  | KnownError<typeof LAYOUT_ERROR.CANT_SPLIT_DOCKED_FRAME>
163
163
  | KnownError<typeof LAYOUT_ERROR.NO_FILL_CANDIDATES> {
164
- const draggingFrame = { ...win.frames[draggingFrameId] }
164
+ const draggingFrame = { ...win.frames[movingFrameId] }
165
165
  const hoveredFrame = { ...win.frames[hoveredFrameId] }
166
166
 
167
- if (draggingFrameId === hoveredFrameId) {
167
+ if (movingFrameId === hoveredFrameId) {
168
168
  if (zoneSide === "center") return new KnownError(LAYOUT_ERROR.CANT_SWAP_WITH_SELF, `Can't swap frame with self.`, { frame: hoveredFrame, zoneSide })
169
169
  }
170
170
 
@@ -180,12 +180,12 @@ export function getFrameRearrangeInfo(
180
180
  }
181
181
 
182
182
  if (draggingFrame.docked && !hoveredFrame.docked) { // center swapping IS allowed above
183
- return new KnownError(LAYOUT_ERROR.CANT_REARRANGE_DOCKED_WITH_NON_DOCKED, `Can't rearrange docked frame ${draggingFrameId} with non-docked frame ${hoveredFrameId}, can only swap.`, { draggingFrameId, hoveredFrameId, zoneSide })
183
+ return new KnownError(LAYOUT_ERROR.CANT_REARRANGE_DOCKED_WITH_NON_DOCKED, `Can't rearrange docked frame ${movingFrameId} with non-docked frame ${hoveredFrameId}, can only swap.`, { movingFrameId, hoveredFrameId, zoneSide })
184
184
  }
185
185
 
186
186
  // block edge rearrange on docked frames
187
187
  if (hoveredFrame.docked) { // again center swapping docked to undocked and vice versa is allowed
188
- return new KnownError(LAYOUT_ERROR.CANT_REARRANGE_WITH_DOCKED_EDGES, `Can't rearrange with docked frame ${hoveredFrameId} edge, can only swap.`, { draggingFrameId, hoveredFrameId, zoneSide })
188
+ return new KnownError(LAYOUT_ERROR.CANT_REARRANGE_WITH_DOCKED_EDGES, `Can't rearrange with docked frame ${hoveredFrameId} edge, can only swap.`, { movingFrameId, hoveredFrameId, zoneSide })
189
189
  }
190
190
 
191
191
  const touchingSide = getSideTouching(draggingFrame, hoveredFrame)
@@ -206,7 +206,7 @@ export function getFrameRearrangeInfo(
206
206
  }
207
207
  }
208
208
  if (hoverOppositeSide === zoneSide) {
209
- return new KnownError(LAYOUT_ERROR.CANT_REARRANGE_TO_SAME_RELATIVE_POSITION, `Frame ${draggingFrameId} is already on the ${zoneSide} of ${hoveredFrameId}`, { draggingFrameId, hoveredFrameId, zoneSide })
209
+ return new KnownError(LAYOUT_ERROR.CANT_REARRANGE_TO_SAME_RELATIVE_POSITION, `Frame ${movingFrameId} is already on the ${zoneSide} of ${hoveredFrameId}`, { movingFrameId, hoveredFrameId, zoneSide })
210
210
  }
211
211
  }
212
212
  }
@@ -224,7 +224,7 @@ export function getFrameRearrangeInfo(
224
224
  const splitFrame = splitResult.modified[0]
225
225
  const newFrame = splitResult.created[0]
226
226
 
227
- if (draggingFrameId === hoveredFrameId) {
227
+ if (movingFrameId === hoveredFrameId) {
228
228
  return { ...splitResult, deleted: [], info: "split" }
229
229
  }
230
230
 
@@ -249,7 +249,7 @@ export function getFrameRearrangeInfo(
249
249
  [draggingFrame.id]: draggingFrame
250
250
  }
251
251
  }
252
- const changes = getFillEmptySpaceInfo(winCopy, emptySpace, [hoveredFrameId, draggingFrameId])
252
+ const changes = getFillEmptySpaceInfo(winCopy, emptySpace, [hoveredFrameId, movingFrameId])
253
253
  if (changes instanceof KnownError) return changes
254
254
 
255
255
  // it will also be missing said changes unless it further moved the frames which is not alway
@@ -21,7 +21,7 @@ import { KnownError } from "../utils/KnownError.js"
21
21
  export function getFrameSplitInfo(
22
22
  frame: LayoutFrame,
23
23
  dir: Direction,
24
- dragPointOrPosition: Point | number | "midpoint" = "midpoint",
24
+ movePointOrPosition: Point | number | "midpoint" = "midpoint",
25
25
  minSize: Size = settings.minSizeScaled,
26
26
  snapAmount: Point = settings.snapPointScaled
27
27
  ): LayoutChange
@@ -42,11 +42,11 @@ export function getFrameSplitInfo(
42
42
  const sizeKey: "width" | "height" = isHorz ? "width" : "height"
43
43
  const posKey: "x" | "y" = isHorz ? "x" : "y"
44
44
 
45
- const position = dragPointOrPosition === "midpoint"
45
+ const position = movePointOrPosition === "midpoint"
46
46
  ? (isHorz ? frame.x + (frame.width / 2) : frame.y + (frame.height / 2))
47
- : typeof dragPointOrPosition === "number"
48
- ? dragPointOrPosition
49
- : dragPointOrPosition[isHorz ? "x" : "y"]
47
+ : typeof movePointOrPosition === "number"
48
+ ? movePointOrPosition
49
+ : movePointOrPosition[isHorz ? "x" : "y"]
50
50
 
51
51
  const safePosition = findSafeSplitEdgeAndPosition(
52
52
  frame,
@@ -1,5 +1,5 @@
1
1
  import { settings } from "../settings.js"
2
- import type { DragZone } from "../types/index.js"
2
+ import type { Zone } from "../types/index.js"
3
3
 
4
4
  /**
5
5
  * Returns frame drag zones (in **unrounded** scaled coordinate space).
@@ -10,12 +10,12 @@ import type { DragZone } from "../types/index.js"
10
10
  *
11
11
  * Unrounded because these are for display purposes only.
12
12
  */
13
- export function getFrameDragZones(
13
+ export function getFrameZones(
14
14
  frame: { x: number, y: number, width: number, height: number },
15
15
  thresholdPx: number,
16
16
  windowPxWidth: number,
17
17
  windowPxHeight: number
18
- ): DragZone[] {
18
+ ): Zone[] {
19
19
  // we do not round as we might undo this transform and drag along errors
20
20
  // plugs this is is for display purposes only
21
21
  const thX = thresholdPx / windowPxWidth * settings.maxInt
@@ -36,7 +36,7 @@ export function getFrameDragZones(
36
36
  }]
37
37
  }
38
38
 
39
- const zones: DragZone[] = []
39
+ const zones: Zone[] = []
40
40
 
41
41
  zones.push({
42
42
  type: "frame",
@@ -6,7 +6,7 @@ import type { LayoutWindow, WindowEdgeZone } from "../types/index.js"
6
6
  * Returns window edge drag zones (in scaled coordinates)
7
7
  *
8
8
  */
9
- export function getWindowDragZones(
9
+ export function getWindowZones(
10
10
  win: LayoutWindow,
11
11
  thresholdPx: number
12
12
  ): WindowEdgeZone[] {
@@ -0,0 +1,48 @@
1
+ import { getFrameZones } from "./getFrameZones.js"
2
+ import { getWindowZones } from "./getWindowZones.js"
3
+ import { isPointInRect } from "./isPointInRect.js"
4
+
5
+ import type { MoveState, WindowEdgeZone, Zone } from "../types/index.js"
6
+
7
+ /**
8
+ * Find the drag zone under the drag point.
9
+ */
10
+ export function getZones(
11
+ state: Pick<MoveState, "movePoint" | "moveHoveredFrame" | "frames" | "win">,
12
+ { frameEdgePx, windowEdgePx }: { frameEdgePx: number, windowEdgePx: number }
13
+ ): Zone | undefined {
14
+ const { movePoint, win } = state
15
+ const frameId = state.moveHoveredFrame?.id
16
+ if (!frameId) return
17
+
18
+ const frame = state.frames[frameId]
19
+ if (!frame || !movePoint) return
20
+
21
+ const frameZones = getFrameZones(frame, frameEdgePx, win.pxWidth, win.pxHeight)
22
+
23
+ const windowZones = getWindowZones(win, windowEdgePx)
24
+
25
+ let matchedZone: Zone | undefined
26
+ for (const zone of windowZones) {
27
+ if (isPointInRect(zone, movePoint)) {
28
+ matchedZone = {
29
+ ...zone,
30
+ type: "window"
31
+ } as WindowEdgeZone
32
+ break
33
+ }
34
+ }
35
+
36
+ if (!matchedZone) {
37
+ for (const zone of frameZones) {
38
+ if (isPointInRect(zone, movePoint)) {
39
+ matchedZone = zone
40
+ break
41
+ }
42
+ }
43
+ }
44
+
45
+ if (!matchedZone) return undefined
46
+
47
+ return matchedZone
48
+ }
@@ -9,11 +9,11 @@ export { findSafeSplitEdgeAndPosition } from "./findSafeSplitEdge.js"
9
9
  export { findVisualEdge } from "./findVisualEdge.js"
10
10
  export { frameCreate } from "./frameCreate.js"
11
11
  export { getCloseFrameInfo } from "./getCloseFrameInfo.js"
12
- export { getDragZones } from "./getDragZones.js"
12
+ export { getZones } from "./getZones.js"
13
13
  export { getFillEmptySpaceInfo } from "./getFillEmptySpaceInfo.js"
14
14
  export { getFrameCollapseInfo } from "./getFrameCollapseInfo.js"
15
15
  export { getFrameDockInfo } from "./getFrameDockInfo.js"
16
- export { getFrameDragZones } from "./getFrameDragZones.js"
16
+ export { getFrameZones } from "./getFrameZones.js"
17
17
  export { getFrameExpandInfo } from "./getFrameExpandInfo.js"
18
18
  export { getFrameRearrangeInfo } from "./getFrameRearrangeInfo.js"
19
19
  export { getFrameShrinkInfo } from "./getFrameShrinkInfo.js"
@@ -25,7 +25,7 @@ export { getFrameUncollapseInfo } from "./getFrameUncollapseInfo.js"
25
25
  export { getFrameUndockInfo } from "./getFrameUndockInfo.js"
26
26
  export { getRelaxFramesInfo } from "./getRelaxFramesInfo.js"
27
27
  export { getUpdateWindowSizeInfo } from "./getUpdateWindowSizeInfo.js"
28
- export { getWindowDragZones } from "./getWindowDragZones.js"
28
+ export { getWindowZones } from "./getWindowZones.js"
29
29
  export { isPointInRect } from "./isPointInRect.js"
30
30
  export { layoutAddWindow } from "./layoutAddWindow.js"
31
31
  export { layoutCreate } from "./layoutCreate.js"
@@ -2,36 +2,36 @@ import { get, type RecordFromArray } from "@alanscodelog/utils"
2
2
 
3
3
  import { isWindowEdge } from "../helpers/isWindowEdge.js"
4
4
  import { findFramesTouchingEdge } from "../layout/findFramesTouchingEdge.js"
5
- import type { DragChangeHandler, DragChangeResult, DragState, Edge, IDragAction, LayoutFrame, LayoutShape } from "../types/index.js"
5
+ import type { ActionHandlerApplyResult, Edge, IAction, LayoutFrame, LayoutShape, MoveChangeHandler, MoveChangeResult, MoveState } from "../types/index.js"
6
6
  import { LAYOUT_ERROR } from "../types/index.js"
7
7
  import { KnownError } from "../utils/KnownError.js"
8
8
 
9
9
  /**
10
- * Handles the lifecycle of a drag actions {@link IDragAction} and provides additional hooks.
10
+ * Handles the lifecycle of a drag actions {@link IAction} and provides additional hooks.
11
11
  *
12
12
  * The first action instance that can handle the request is passed control of the event handlers until the request changes.
13
13
  */
14
- export class DragActionHandler<
15
- TRawDragActions extends IDragAction[],
16
- TDragActions extends RecordFromArray<TRawDragActions, "name"> = RecordFromArray<TRawDragActions, "name">
14
+ export class ActionHandler<
15
+ TRawActions extends IAction[],
16
+ TActions extends RecordFromArray<TRawActions, "name"> = RecordFromArray<TRawActions, "name">
17
17
  > {
18
- activeAction?: keyof TDragActions
18
+ activeAction?: keyof TActions
19
19
 
20
- actions: TDragActions
20
+ actions: TActions
21
21
 
22
- eventCanceller: ((e: PointerEvent | KeyboardEvent | undefined, state: DragState) => void) | undefined = undefined
22
+ eventCanceller: ((e: PointerEvent | KeyboardEvent | undefined, state: MoveState) => void) | undefined = undefined
23
23
 
24
- boundCancel: (e: PointerEvent | KeyboardEvent | undefined, state: DragState) => void
24
+ boundCancel: (e: PointerEvent | KeyboardEvent | undefined, state: MoveState) => void
25
25
 
26
- defaultOnDragChange: DragChangeHandler = (type, _e, state, _forceRecalculateEdges, _cancel) => {
26
+ defaultOnMoveChange: MoveChangeHandler = (type, _e, state, _forceRecalculateEdges, _cancel) => {
27
27
  const isTouchingCollapsedFrameEdge = type === "move"
28
- && state.isDragging === "edge"
28
+ && state.isMoving === "edge"
29
29
  && state.touchingFramesArrays.some(frames =>
30
30
  // we check with a falsy check on PURPOSE, frames collapsed to 0 aren't an issue, they are ignored anyways
31
31
  Object.values(frames).some(f => f.collapsed)
32
32
  )
33
33
  return {
34
- updateEdges: type === "move" ? !(state.isDraggingFromWindowEdge || isTouchingCollapsedFrameEdge) : true,
34
+ updateEdges: type === "move" ? !(state.isMovingFromWindowEdge || isTouchingCollapsedFrameEdge) : true,
35
35
  shapes: []
36
36
  }
37
37
  }
@@ -46,7 +46,7 @@ export class DragActionHandler<
46
46
  */
47
47
  onEvent?: (e: PointerEvent | KeyboardEvent | undefined, cancel: () => void) => void
48
48
  /** Called when the action requested changes. */
49
- onRequestChange?: (type: keyof TDragActions | undefined) => void
49
+ onRequestChange?: (type: keyof TActions | undefined) => void
50
50
  /** Called when the drag action ends either because it was completed or cancelled. */
51
51
  onEnd?: (context: { cancelled: boolean, applied: boolean }) => void
52
52
  }
@@ -54,22 +54,22 @@ export class DragActionHandler<
54
54
  /** All action shapes merged into a single array. If using vue you can set this to a reactive array for reactivity. */
55
55
  shapes: LayoutShape[] = []
56
56
 
57
- /** All hint/error text from all actions, updated on every onDragChange. If using vue you can set this to a reactive object for reactivity. */
57
+ /** All hint/error text from all actions, updated on every onMoveChange. If using vue you can set this to a reactive object for reactivity. */
58
58
  textHints: { actions: string[], errors: string[] } = { actions: [], errors: [] }
59
59
 
60
60
  constructor(
61
- actions: TRawDragActions,
62
- hooks: DragActionHandler<TRawDragActions, TDragActions>["hooks"] = {},
61
+ actions: TRawActions,
62
+ hooks: ActionHandler<TRawActions, TActions>["hooks"] = {},
63
63
  /**
64
- * Default onDragChange handler for when no action can handle the request.
64
+ * Default onMoveChange handler for when no action can handle the request.
65
65
  *
66
66
  * Should return true to allow the edges to be moved, or false to prevent it.
67
67
  *
68
68
  * The default prevents movement when the edge is a window edge and when the edge is touching a collapsed frame.
69
69
  */
70
- defaultOnDragChange?: DragChangeHandler
70
+ defaultOnMoveChange?: MoveChangeHandler
71
71
  ) {
72
- if (defaultOnDragChange) this.defaultOnDragChange = defaultOnDragChange
72
+ if (defaultOnMoveChange) this.defaultOnMoveChange = defaultOnMoveChange
73
73
  this.hooks = hooks
74
74
  this.actions = {} as any
75
75
  for (const action of actions) {
@@ -80,10 +80,10 @@ export class DragActionHandler<
80
80
 
81
81
  eventHandler(
82
82
  e: KeyboardEvent | PointerEvent,
83
- state: DragState,
83
+ state: MoveState,
84
84
  forceRecalculateEdges: () => void
85
85
  ) {
86
- if (state.isDragging) {
86
+ if (state.isMoving) {
87
87
  e.preventDefault()
88
88
  }
89
89
  let cancelled = false
@@ -95,7 +95,7 @@ export class DragActionHandler<
95
95
 
96
96
  let found = false
97
97
  const oldActiveAction = this.activeAction
98
- for (const action of Object.values<TRawDragActions[number]>(this.actions)) {
98
+ for (const action of Object.values<TRawActions[number]>(this.actions)) {
99
99
  if (action.canHandleRequest(e, state, forceRecalculateEdges)) {
100
100
  // if (this.activeAction !== action.name) {
101
101
  // }
@@ -116,38 +116,40 @@ export class DragActionHandler<
116
116
  this.hooks.onRequestChange?.(this.activeAction)
117
117
  }
118
118
 
119
- if (state.isDragging) {
119
+ if (state.isMoving) {
120
120
  forceRecalculateEdges()
121
121
  this.hooks.onRecalculate?.()
122
122
  }
123
123
  return undefined
124
124
  }
125
125
 
126
- onDragChange<T extends "start" | "move" | "end">(
126
+ onMoveChange<T extends "start" | "move" | "end">(
127
127
  type: T,
128
128
  e: T extends "end" ? PointerEvent | undefined : PointerEvent,
129
- state: DragState,
129
+ state: MoveState,
130
130
  forceRecalculateEdges: () => void,
131
- cancel: (e: PointerEvent | KeyboardEvent | undefined, state: DragState) => void
132
- ): DragChangeResult {
131
+ cancel: T extends "end" ? undefined : (e: PointerEvent | KeyboardEvent | undefined, state: MoveState) => void,
132
+ resolve: T extends "end" ? undefined : (opts: ActionHandlerApplyResult) => void
133
+ ): MoveChangeResult {
133
134
  if (type === "start") {
134
135
  this.eventCanceller = cancel
135
136
  this.eventHandler(e!, state, forceRecalculateEdges)
136
137
  }
137
- if (type === "end") {
138
- this.activeAction = undefined
139
- }
140
138
 
141
139
  if (this.activeAction) {
142
- const res = this.actions[this.activeAction]!.onDragChange(type, e, state, forceRecalculateEdges, this.boundCancel)
140
+ const res = this.actions[this.activeAction]!.onMoveChange(type, e, state, forceRecalculateEdges, this.boundCancel as any, resolve as any)
143
141
  // in case it's a vue reactive array
144
142
  this.shapes.splice(0, this.shapes.length, ...res.shapes)
145
143
  this.setTextHints(type)
146
144
  return res
147
145
  }
148
146
  this.setTextHints(type)
149
- const res = this.defaultOnDragChange(type, e, state, forceRecalculateEdges, this.boundCancel)
147
+ const res = this.defaultOnMoveChange(type, e, state, forceRecalculateEdges, this.boundCancel as any, resolve as any)
150
148
  this.shapes.splice(0, this.shapes.length, ...res.shapes)
149
+
150
+ if (type === "end") {
151
+ this.activeAction = undefined
152
+ }
151
153
  return res
152
154
  }
153
155
 
@@ -155,7 +157,7 @@ export class DragActionHandler<
155
157
  // again in case it's a vue reactive object
156
158
  this.textHints.actions = []
157
159
  this.textHints.errors = []
158
- for (const action of Object.values<IDragAction>(this.actions)) {
160
+ for (const action of Object.values<IAction>(this.actions)) {
159
161
  const res = action.getTextHints?.(type)
160
162
  this.textHints.actions.push(...(res?.actions ?? []))
161
163
  this.textHints.errors.push(...(res?.errors ?? []))
@@ -166,7 +168,7 @@ export class DragActionHandler<
166
168
  for (const edge of edges) {
167
169
  // edge already has an error
168
170
  if (edge.error) continue
169
- for (const action of Object.values<IDragAction>(this.actions)) {
171
+ for (const action of Object.values<IAction>(this.actions)) {
170
172
  action.annotateEdge?.(edge, frames)
171
173
  if (edge.error) break
172
174
  }
@@ -188,12 +190,12 @@ export class DragActionHandler<
188
190
  }
189
191
  }
190
192
 
191
- onDragApply(
192
- state: DragState,
193
+ onMoveApply(
194
+ state: MoveState,
193
195
  forceRecalculateEdges: () => void
194
- ): { apply: boolean, result: any } {
196
+ ): ActionHandlerApplyResult {
195
197
  if (this.activeAction) {
196
- const res = this.actions[this.activeAction]!.onDragApply(state, forceRecalculateEdges)
198
+ const res = this.actions[this.activeAction]!.onMoveApply(state, forceRecalculateEdges)
197
199
  this.hooks.onEnd?.({ cancelled: false, applied: res })
198
200
  return { apply: res, result: undefined }
199
201
  }
@@ -201,7 +203,7 @@ export class DragActionHandler<
201
203
  return { apply: true, result: undefined }
202
204
  }
203
205
 
204
- cancel(e: PointerEvent | KeyboardEvent | undefined, state: DragState): void {
206
+ cancel(e: PointerEvent | KeyboardEvent | undefined, state: MoveState): void {
205
207
  if (this.activeAction) {
206
208
  this.actions[this.activeAction].cancel(e, state)
207
209
  }
@@ -213,7 +215,7 @@ export class DragActionHandler<
213
215
  static debugState(
214
216
  pluginName: string,
215
217
  type: "before" | "after" | string,
216
- state: DragState,
218
+ state: MoveState,
217
219
  pluginState: Record<string, any> = {},
218
220
  /** 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. */
219
221
  key?: string | boolean
@@ -1,4 +1,4 @@
1
- import { DragActionHandler } from "./DragActionHandler.js"
1
+ import { ActionHandler } from "./ActionHandler.js"
2
2
 
3
3
  import { dirToOrientation } from "../helpers/dirToOrientation.js"
4
4
  import { getEdgeOrientation } from "../helpers/getEdgeOrientation.js"
@@ -6,12 +6,12 @@ import { oppositeSide } from "../helpers/oppositeSide.js"
6
6
  import { applyFrameChanges } from "../layout/applyFrameChanges.js"
7
7
  import { findFramesTouchingEdge } from "../layout/findFramesTouchingEdge.js"
8
8
  import { getCloseFrameInfo } from "../layout/getCloseFrameInfo.js"
9
- import type { ActionDragChangeResult, CloseDeco, DragState, IDragAction } from "../types/index.js"
9
+ import type { ActionChangeResult, CloseDeco, IAction, MoveState } from "../types/index.js"
10
10
  import type { KnownError } from "../utils/KnownError.js"
11
11
 
12
12
  export type CloseInfo = Exclude<ReturnType<typeof getCloseFrameInfo>, KnownError>
13
13
 
14
- export class CloseAction implements IDragAction {
14
+ export class CloseAction implements IAction {
15
15
  name = "close" as const
16
16
  minDragDistance = 5
17
17
 
@@ -20,13 +20,13 @@ export class CloseAction implements IDragAction {
20
20
  force: boolean
21
21
  res: CloseInfo
22
22
  cacheKey: string | undefined
23
- lastReturn: ActionDragChangeResult
23
+ lastReturn: ActionChangeResult
24
24
  } | {
25
25
  allowed: false
26
26
  force: boolean
27
27
  res: CloseInfo | undefined
28
28
  cacheKey: string | undefined
29
- lastReturn: ActionDragChangeResult | undefined
29
+ lastReturn: ActionChangeResult | undefined
30
30
  } = {} as any // this is initialized by this.reset()
31
31
 
32
32
  debug: boolean | string = false
@@ -40,7 +40,7 @@ export class CloseAction implements IDragAction {
40
40
  transformError: e => e.message
41
41
  }
42
42
 
43
- handleEvent: (e: PointerEvent | KeyboardEvent, state: DragState) => boolean | "force" = (e: PointerEvent | KeyboardEvent) => {
43
+ handleEvent: (e: PointerEvent | KeyboardEvent, state: MoveState) => boolean | "force" = (e: PointerEvent | KeyboardEvent) => {
44
44
  if (e.ctrlKey && e.shiftKey) {
45
45
  return "force"
46
46
  }
@@ -86,10 +86,10 @@ export class CloseAction implements IDragAction {
86
86
  this.modifyDecos([])
87
87
  }
88
88
 
89
- private _getDecos(state: DragState): CloseDeco[] {
89
+ private _getDecos(state: MoveState): CloseDeco[] {
90
90
  let decos: CloseDeco[] = []
91
- const { isDragging } = state
92
- if (isDragging && this.state.allowed && this.state.res) {
91
+ const { isMoving } = state
92
+ if (isMoving && this.state.allowed && this.state.res) {
93
93
  const { force } = this.state
94
94
  decos = this.state.res.deleted.map(_ => ({
95
95
  id: _.id,
@@ -136,12 +136,12 @@ export class CloseAction implements IDragAction {
136
136
  }
137
137
 
138
138
 
139
- canHandleRequest(e: PointerEvent | KeyboardEvent, state: DragState): boolean {
140
- const { draggingEdges } = state
141
- if (draggingEdges.length !== 1) return false
139
+ canHandleRequest(e: PointerEvent | KeyboardEvent, state: MoveState): boolean {
140
+ const { movingEdges } = state
141
+ if (movingEdges.length !== 1) return false
142
142
  const res = this.handleEvent(e, state)
143
143
  this.state.force = res === "force"
144
- this.setTextHints(state.isDragging === "edge" ? true : undefined)
144
+ this.setTextHints(state.isMoving === "edge" ? true : undefined)
145
145
  if (res) {
146
146
  this.hooks.onStart?.(true)
147
147
  return true
@@ -150,47 +150,51 @@ export class CloseAction implements IDragAction {
150
150
  return false
151
151
  }
152
152
 
153
- onDragChange(
154
- _type: "start" | "end" | "move",
153
+ onMoveChange(
154
+ type: "start" | "end" | "move",
155
155
  _e: PointerEvent | undefined,
156
- state: DragState
157
- ): ActionDragChangeResult {
158
- if (state.dragDistance <= this.minDragDistance) {
156
+ state: MoveState
157
+ ): ActionChangeResult {
158
+ if (type === "end") {
159
+ this.reset()
160
+ return { shapes: [] }
161
+ }
162
+ if (state.moveDistance <= this.minDragDistance) {
159
163
  return { updateEdges: false, shapes: [] }
160
164
  }
161
165
  const {
162
166
  touchingFramesArrays,
163
- dragDirections,
164
- isDragging,
165
- draggingEdges,
167
+ moveDirections,
168
+ isMoving,
169
+ movingEdges,
166
170
  visualEdges,
167
171
  frames,
168
- isDraggingFromWindowEdge,
169
- dragPoint
172
+ isMovingFromWindowEdge,
173
+ movePoint
170
174
  } = state
171
- const oppositeOrientation = oppositeSide(getEdgeOrientation(draggingEdges[0]))
172
- const cacheKey = `${dragPoint?.x}-${dragPoint?.y}-${dragDirections[oppositeOrientation]!}-${this.state.force}`
175
+ const oppositeOrientation = oppositeSide(getEdgeOrientation(movingEdges[0]))
176
+ const cacheKey = `${movePoint?.x}-${movePoint?.y}-${moveDirections[oppositeOrientation]!}-${this.state.force}`
173
177
  if (this.state.allowed) {
174
178
  if (this.state.cacheKey === cacheKey) {
175
179
  return this.state.lastReturn
176
180
  }
177
181
  }
178
- if (isDragging && draggingEdges.length === 1) {
182
+ if (isMoving && movingEdges.length === 1) {
179
183
  const res = findFramesTouchingEdge(
180
- draggingEdges[0],
184
+ movingEdges[0],
181
185
  touchingFramesArrays[0],
182
186
  {
183
- // referencePoint: dragPoint.value, // if force pick smallest frame?
184
- searchDirections: [dragDirections[oppositeOrientation]!]
187
+ // referencePoint: movePoint.value, // if force pick smallest frame?
188
+ searchDirections: [moveDirections[oppositeOrientation]!]
185
189
  }
186
190
  )
187
191
  if (res.length > 0) {
188
- const orientation = dirToOrientation(dragDirections[oppositeOrientation]!)
192
+ const orientation = dirToOrientation(moveDirections[oppositeOrientation]!)
189
193
  const sizeKey = orientation === "horizontal" ? "width" : "height"
190
194
  const smallestFrameSize = Math.min(...res.map(_ => _.frame[sizeKey]))
191
195
  const frame = res.find(_ => _.frame[sizeKey] === smallestFrameSize)!.frame!
192
196
 
193
- const closeInfo = getCloseFrameInfo(Object.values(frames), visualEdges, frame, dragDirections[oppositeOrientation]!, "dir", this.state.force)
197
+ const closeInfo = getCloseFrameInfo(Object.values(frames), visualEdges, frame, moveDirections[oppositeOrientation]!, "dir", this.state.force)
194
198
  this.state.cacheKey = cacheKey
195
199
  this.setTextHints(closeInfo)
196
200
  if (!(closeInfo instanceof Error)) {
@@ -205,17 +209,16 @@ export class CloseAction implements IDragAction {
205
209
  }
206
210
  }
207
211
  const decos = this._getDecos(state)
208
- this.state.lastReturn = { updateEdges: !isDraggingFromWindowEdge, shapes: decos.flatMap(_ => _.shapes) }
212
+ this.state.lastReturn = { updateEdges: !isMovingFromWindowEdge, shapes: decos.flatMap(_ => _.shapes) }
209
213
  return this.state.lastReturn
210
214
  }
211
215
 
212
- onDragApply(state: DragState): boolean {
216
+ onMoveApply(state: MoveState): boolean {
213
217
  if (this.state.res) {
214
218
  const win = state.win
215
- if (this.debug) { DragActionHandler.debugState(this.name, "before", state, this.state, this.debug) }
219
+ if (this.debug) { ActionHandler.debugState(this.name, "before", state, this.state, this.debug) }
216
220
  applyFrameChanges(win, this.state.res)
217
- if (this.debug) { DragActionHandler.debugState(this.name, "after", state, this.state, this.debug) }
218
- this.reset()
221
+ if (this.debug) { ActionHandler.debugState(this.name, "after", state, this.state, this.debug) }
219
222
  return true
220
223
  }
221
224
  return false