@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
@@ -246,18 +246,18 @@ const zCloseDeco = zBaseDeco.extend({
246
246
  export type CloseDeco = z.infer<typeof zCloseDeco>
247
247
 
248
248
 
249
- const zFrameDragDeco = zBaseDeco.extend({
249
+ const zFrameDeco = zBaseDeco.extend({
250
250
  id: z.uuid(),
251
251
  type: z.literal("drop"),
252
252
  position: zSide.or(z.enum(["center"]))
253
253
  })
254
254
 
255
- export type FrameDragDeco = z.infer<typeof zFrameDragDeco>
255
+ export type FrameDeco = z.infer<typeof zFrameDeco>
256
256
 
257
257
  export const zDeco = z.union([
258
258
  zSplitDeco,
259
259
  zCloseDeco,
260
- zFrameDragDeco
260
+ zFrameDeco
261
261
  ])
262
262
 
263
263
  export type Deco = z.infer<typeof zDeco>
@@ -287,7 +287,8 @@ export const LAYOUT_ERROR = enumFromArray([
287
287
  "CANT_COLLAPSE_NOT_DOCKED",
288
288
  "CANT_UNCOLLAPSE_NOT_COLLAPSED",
289
289
  "NO_FILL_CANDIDATES",
290
- "CANT_RESIZE_COLLAPSED_FRAME"
290
+ "CANT_RESIZE_COLLAPSED_FRAME",
291
+ "CANT_RESIZE_SINGLE_FRAME"
291
292
  ])
292
293
 
293
294
  export type LayoutError = EnumLike<typeof LAYOUT_ERROR>
@@ -330,19 +331,19 @@ export type LayoutErrorsInfo = {
330
331
  frame: LayoutFrame
331
332
  }
332
333
  [LAYOUT_ERROR.CANT_REARRANGE_TO_SAME_RELATIVE_POSITION]: {
333
- draggingFrameId: string
334
+ movingFrameId: string
334
335
  hoveredFrameId: string
335
- zoneSide: DragZone["side"]
336
+ zoneSide: Zone["side"]
336
337
  }
337
338
  [LAYOUT_ERROR.CANT_REARRANGE_WITH_DOCKED_EDGES]: {
338
- draggingFrameId: string
339
+ movingFrameId: string
339
340
  hoveredFrameId: string
340
- zoneSide: DragZone["side"]
341
+ zoneSide: Zone["side"]
341
342
  }
342
343
  [LAYOUT_ERROR.CANT_REARRANGE_DOCKED_WITH_NON_DOCKED]: {
343
- draggingFrameId: string
344
+ movingFrameId: string
344
345
  hoveredFrameId: string
345
- zoneSide: DragZone["side"]
346
+ zoneSide: Zone["side"]
346
347
  }
347
348
  [LAYOUT_ERROR.CANT_SPLIT_DOCKED_FRAME]: {
348
349
  frame: LayoutFrame
@@ -376,6 +377,9 @@ export type LayoutErrorsInfo = {
376
377
  [LAYOUT_ERROR.CANT_RESIZE_COLLAPSED_FRAME]: {
377
378
  frame: LayoutFrame
378
379
  }
380
+ [LAYOUT_ERROR.CANT_RESIZE_SINGLE_FRAME]: {
381
+ frame: LayoutFrame
382
+ }
379
383
  [LAYOUT_ERROR.REDISTRIBUTE_WOULD_RESULT_IN_INVALID_FRAMES]: {
380
384
  problemEdgeCoordinates: number[]
381
385
  }
@@ -385,7 +389,7 @@ export type LayoutErrorsInfo = {
385
389
  export type HasOpposite = Direction | EdgeSide | ExtendedDirection | ExtendedEdgeSide | keyof Point | keyof Size
386
390
 
387
391
 
388
- export type BaseDragZone = {
392
+ export type BaseZone = {
389
393
  x: number
390
394
  y: number
391
395
  width: number
@@ -394,17 +398,17 @@ export type BaseDragZone = {
394
398
  pxHeight: number
395
399
  }
396
400
 
397
- export type FrameDragZone = BaseDragZone & {
401
+ export type FrameZone = BaseZone & {
398
402
  type: "frame"
399
403
  side: EdgeSide | "center"
400
404
  }
401
405
 
402
- export type WindowEdgeZone = BaseDragZone & {
406
+ export type WindowEdgeZone = BaseZone & {
403
407
  type: "window"
404
408
  side: EdgeSide
405
409
  }
406
410
 
407
- export type DragZone = FrameDragZone | WindowEdgeZone
411
+ export type Zone = FrameZone | WindowEdgeZone
408
412
 
409
413
  export const zWindowCreate = zLayoutWindowLoose
410
414
  .partial({ id: true, pxWidth: true, pxHeight: true, pxX: true, pxY: true })
@@ -437,33 +441,33 @@ export type LayoutChange<TInfo = never> = {
437
441
  window?: Partial<LayoutWindow>
438
442
  info?: TInfo
439
443
  }
440
- export type DragState = {
444
+ export type MoveState = {
441
445
  /** The current directions in the corresponding orientations that the user is dragging in. */
442
- dragDirections: Record<Orientation, Direction | undefined>
446
+ moveDirections: Record<Orientation, Direction | undefined>
443
447
  /** The curren point (in scaled window coordinates) the user is dragging at. */
444
- dragPoint?: Point
448
+ movePoint?: Point
445
449
  /** Cumulative pixel distance the user has dragged from the initial click point. 0 on start, increases on each move. */
446
- dragDistance: number
450
+ moveDistance: number
447
451
  /** Whether the user is currently dragging and what type of drag. Is truthy string during all drag events. */
448
- isDragging: boolean | "frame" | "edge"
452
+ isMoving: boolean | "frame" | "edge"
449
453
  /** Whether to show the moved frames while dragging. */
450
- showDragging: boolean
451
- /** The frame being dragged during a frame drag. Only set when isDragging is "frame". */
452
- draggingFrameId?: FrameId
454
+ showMoving: boolean
455
+ /** The frame being dragged during a frame drag. Only set when isMoving is "frame". */
456
+ movingFrameId?: FrameId
453
457
  /**
454
458
  * The edges that are currently being dragged. There are multiple edges if they drag an intersection since what's actually happening is we're just dragging the closest horizontal and vertical edges.
455
459
  */
456
- draggingEdges: Edge[]
460
+ movingEdges: Edge[]
457
461
  /**
458
462
  * The intersection that is currently being dragged.
459
463
  */
460
- draggingIntersection?: IntersectionEntry
464
+ movingIntersection?: IntersectionEntry
461
465
  /** The "visual" edges that can be displayed for dragging. See {@link getVisualEdges} */
462
466
  visualEdges: Edge[]
463
467
  /**
464
468
  * The frames touching the currently dragged edges. Each entry corresponds to the frames touching the corresponding dragging edge.
465
469
  *
466
- * So you can use the index in draggingEdges to get the corresponding frames.
470
+ * So you can use the index in movingEdges to get the corresponding frames.
467
471
  */
468
472
  touchingFrames: Record<string, LayoutFrame>[]
469
473
  /**
@@ -471,13 +475,13 @@ export type DragState = {
471
475
  */
472
476
  touchingFramesArrays: LayoutFrame[][]
473
477
  /**
474
- * All the frames, with/without the currently dragged frames depending on if `showDragging` is true.
478
+ * All the frames, with/without the currently dragged frames depending on if `showMoving` is true.
475
479
  */
476
480
  frames: Record<string, LayoutFrame>
477
481
  /**
478
- * The frame that is currently being hovered over (according to whether `dragPoint` in in the frame or not).
482
+ * The frame that is currently being hovered over (according to whether `movePoint` in in the frame or not).
479
483
  */
480
- dragHoveredFrame: LayoutFrame | undefined
484
+ moveHoveredFrame: LayoutFrame | undefined
481
485
  /**
482
486
  * A list of corner intersections. Frames can also be dragged by these.
483
487
  */
@@ -485,20 +489,22 @@ export type DragState = {
485
489
  /**
486
490
  * Whether the drag was initiated from a point along the window edge.
487
491
  */
488
- isDraggingFromWindowEdge: boolean
492
+ isMovingFromWindowEdge: boolean
493
+ /** Custom context passed to moveStart, available to action handlers via state.eventContext. */
494
+ eventContext?: Record<string, unknown>
489
495
  win: LayoutWindow
490
496
  }
491
497
 
492
498
 
493
- export interface ActionDragChangeResult {
499
+ export interface ActionChangeResult {
494
500
  /** Whether the drag should update the edges. Defaults to false. */
495
501
  updateEdges?: boolean
496
502
  /** Deco shapes produced by this action during this drag step. */
497
503
  shapes: LayoutShape[]
498
504
  /** Whether to show the moved edges while dragging. Defaults to true. */
499
- showDragging?: boolean
505
+ showMoving?: boolean
500
506
  }
501
- export type DragChangeResult = Omit<ActionDragChangeResult, "shapes">
507
+ export type MoveChangeResult = Omit<ActionChangeResult, "shapes">
502
508
 
503
509
  /**
504
510
  * Called when the drag coordinates change (during any event).
@@ -506,14 +512,21 @@ export type DragChangeResult = Omit<ActionDragChangeResult, "shapes">
506
512
  * Should return `{ allowed: true/false, shapes: LayoutShape[] }` to control whether the action is allowed and edges update and what deco shapes to render.
507
513
  *
508
514
  * Note that the allowed return type only affect the `move` event but is also typed as `boolean` for other events for ease of use.
515
+ *
516
+ * Use also to cleanup your action when type is "end".
517
+ *
518
+ * See also {@link ActionHandler.onMoveChange} to understand it's lifecycle as it is the extended version of.
509
519
  */
510
- export type DragChangeHandler = <T extends "start" | "move" | "end">(
520
+ export type MoveChangeHandler = <T extends "start" | "move" | "end">(
511
521
  type: T,
512
522
  e: T extends "end" ? PointerEvent | undefined : PointerEvent,
513
- state: DragState,
523
+ state: MoveState,
514
524
  forceRecalculateEdges: () => void,
515
- cancel: (e: PointerEvent | KeyboardEvent | undefined, state: DragState) => void
516
- ) => ActionDragChangeResult
525
+ /** Calls moveEnd with apply: false */
526
+ cancel: T extends "end" ? undefined : (e: PointerEvent | KeyboardEvent | undefined, state: MoveState) => void,
527
+ /** Saves result to resolve moveStart promise with then calls moveEnd with given apply. */
528
+ resolve: T extends "end" ? undefined : ({ apply, result }: { apply: boolean, result: any }) => void
529
+ ) => ActionChangeResult
517
530
 
518
531
  /**
519
532
  * A drag action describes when and how to handle a drag event.
@@ -523,19 +536,21 @@ export type DragChangeHandler = <T extends "start" | "move" | "end">(
523
536
  * Each action should handle it's configuration and saving/caching any state it needs. See {@link SplitAction} and {@link CloseAction} for examples.
524
537
  */
525
538
  // eslint-disable-next-line @typescript-eslint/naming-convention
526
- export interface IDragAction {
539
+ export interface IAction {
527
540
  /** A unique name for your action. */
528
541
  name: string
529
- onDragChange: DragChangeHandler
542
+ onMoveChange: MoveChangeHandler
530
543
  /**
531
544
  *
532
- * Is called after `onDragChange("end")` with the same event. Might not be called if the request was cancelled.
545
+ * Is called before `onMoveChange("end")` with the same event. Might not be called if the request was cancelled.
533
546
  *
534
547
  * You should apply your action if possible and return whether it was applied.
535
548
  *
536
- * This is also a good place to reset your state.
549
+ * Do not reset state here, use onMoveChange ("end").
550
+ *
551
+ * See also {@link ActionHandler.onMoveApply} which this is the extended version of.
537
552
  */
538
- onDragApply: (state: DragState, forceRecalculateEdges: () => void) => boolean
553
+ onMoveApply: (state: MoveState, forceRecalculateEdges: () => void) => boolean
539
554
  /**
540
555
  * Should return true if it should handle the "request"/event (e.g. some modifier is being pressed => user is requesting x action).
541
556
  *
@@ -545,22 +560,16 @@ export interface IDragAction {
545
560
  */
546
561
  canHandleRequest(
547
562
  e: KeyboardEvent | PointerEvent,
548
- state: DragState,
563
+ state: MoveState,
549
564
  forceRecalculateEdges: () => void
550
565
  ): boolean
551
566
  /**
552
- * Called when a user cancels the drag action.
553
- *
554
- * You should reset your state here.
555
- */
556
- cancel(e: PointerEvent | KeyboardEvent | undefined, state: DragState): void
557
- /**
558
- * Plugins should implement some basic debug logs by calling {@link DragActionHandler.debugState } at least before and after applying actions in onDragApply. Debug can be a string because it can be an object key to filter on (see the debugState function).
567
+ * Plugins should implement some basic debug logs by calling {@link ActionHandler.debugState } at least before and after applying actions in onMoveApply. Debug can be a string because it can be an object key to filter on (see the debugState function).
559
568
  *
560
569
  *
561
570
  * Calls look like this usually, where this.state is the plugin state:
562
571
  * ```ts
563
- * DragActionHandler.debugState(this.name, "before", state, this.state, this.debug)
572
+ * ActionHandler.debugState(this.name, "before", state, this.state, this.debug)
564
573
  * ```
565
574
  */
566
575
  debug: boolean | string
@@ -599,13 +608,53 @@ export interface IDragAction {
599
608
  */
600
609
  annotateEdge?(edge: Edge, frames: LayoutFrame[]): void
601
610
  }
602
- export type EdgeDragStartData = { edge?: Edge, intersection?: IntersectionEntry }
603
- export type FrameDragStartData = { frameId: FrameId }
611
+ export type EdgeMoveStartData = { edge?: Edge, intersection?: IntersectionEntry }
612
+ export type FrameMoveStartData = { frameId: FrameId }
613
+
614
+ export type ActionHandlerApplyResult = {
615
+ /** Whether to apply the regular drag end changes. Return false to reset to the position before dragging. */
616
+ apply: boolean
617
+ /** Value to resolve the drag promise with. Ignored if `apply` is false. */
618
+ result: any
619
+ }
620
+
621
+ /**
622
+ * Handler interface for drag actions.
623
+ */
624
+ export interface ActionHandler {
625
+ eventHandler: (e: KeyboardEvent, state: MoveState, forceRecalculateEdges: () => void) => void
626
+ /**
627
+ * 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. Note that the return only affects the move event but it's typed like this for ease of use. See also {@link MoveChangeHandler}.
628
+ *
629
+ * Can be used to save some context/info to later apply safely during onMoveApply.
630
+ *
631
+ * The call order is:
632
+ * - onMoveChange("start", ...)
633
+ * - onMoveChange("move", ...)
634
+ * - onMoveApply(...) (IF moveEnd was called with apply: true, otherwise this is skipped)
635
+ * - onMoveChange("end", ...) // always called last, do cleanup here
636
+ */
637
+ onMoveChange: (...args: Parameters<MoveChangeHandler>) => MoveChangeResult
638
+ /**
639
+ * Called when drag will be applied. If moveEnd was called with apply false, it will not be called.
640
+ * Return false to not apply the regular drag end changes (i.e. return false to reset to the position before dragging).
641
+ *
642
+ * Do not use for resetting handler state, use onMoveChange("end", ...) for that.
643
+ */
644
+ onMoveApply: (
645
+ state: MoveState,
646
+ forceRecalculateEdges: () => void
647
+ ) => ActionHandlerApplyResult
648
+ /**
649
+ * Called after visual edges are recalculated. Action handlers can annotate edges with error info.
650
+ */
651
+ annotateEdges?: (edges: Edge[], frames: LayoutFrame[]) => void
652
+ }
604
653
 
605
654
  // drag start overloads for triggering dragsj
606
- export type DragStartFn = {
607
- (e: PointerEvent, type: "edge", data: EdgeDragStartData): void
608
- (e: PointerEvent, type: "frame", data: FrameDragStartData): void
655
+ export type MoveStartFn = {
656
+ (e: PointerEvent, type: "edge", data: EdgeMoveStartData): void
657
+ (e: PointerEvent, type: "frame", data: FrameMoveStartData): void
609
658
  }
610
659
 
611
660
  export type * from "./vue.js"
@@ -1,10 +1,11 @@
1
1
  import type { ComputedRef, InjectionKey, Ref } from "vue"
2
2
 
3
3
  // eslint-disable-next-line no-restricted-imports
4
- import type { Direction, DragState, Edge, FrameId, IntersectionEntry, LayoutFrame, LayoutShape, LayoutWindow, Orientation, Point } from "./index.js"
4
+ import type { ActionHandler, ActionHandlerApplyResult, Direction, Edge, FrameId, IntersectionEntry, LayoutFrame, LayoutShape, LayoutWindow, MoveState, Orientation, Point } from "./index.js"
5
5
 
6
6
  export type LayoutContext = ComputedRef<
7
7
  & {
8
+
8
9
  /** The owning window, needed so we can correctly scale coordinates. */
9
10
  win: LayoutWindow
10
11
  onFocus: (frameId: string) => void
@@ -14,28 +15,29 @@ export type LayoutContext = ComputedRef<
14
15
  export const layoutContextInjectionKey = Symbol.for("@witchcraft/layout:context") as InjectionKey<LayoutContext>
15
16
 
16
17
  export interface UseFramesContext {
17
- dragStart: {
18
- (e: PointerEvent, type: "edge", data: { edge?: Edge, intersection?: IntersectionEntry }): void
19
- (e: PointerEvent, type: "frame", data: { frameId: FrameId }): void
18
+ actionHandler: ActionHandler
19
+ moveStart: {
20
+ (e: PointerEvent, type: "edge", data: { edge?: Edge, intersection?: IntersectionEntry }, opts?: { moveEvent?: string, endEvent?: string, context?: Record<string, unknown> }): Promise<any>
21
+ (e: PointerEvent, type: "frame", data: { frameId: FrameId }, opts?: { moveEvent?: string, endEvent?: string, context?: Record<string, unknown> }): Promise<any>
20
22
  }
21
- dragMove: (e: PointerEvent) => void
22
- dragEnd: (e?: PointerEvent, options?: { apply?: boolean }) => void
23
+ onMove: (e: PointerEvent) => void
24
+ moveEnd: (e?: PointerEvent, options?: Partial<Pick<ActionHandlerApplyResult, "apply">>) => void
23
25
  cancel: () => void
24
- dragDirections: Ref<Record<Orientation, Direction | undefined>>
25
- dragPoint: Ref<Point | undefined>
26
- isDragging: Ref<false | "frame" | "edge">
27
- draggingEdges: Ref<Edge[]>
28
- draggingIntersection: Ref<IntersectionEntry | undefined>
26
+ moveDirections: Ref<Record<Orientation, Direction | undefined>>
27
+ movePoint: Ref<Point | undefined>
28
+ isMoving: Ref<false | "frame" | "edge">
29
+ movingEdges: Ref<Edge[]>
30
+ movingIntersection: Ref<IntersectionEntry | undefined>
29
31
  visualEdges: Ref<Edge[]>
30
32
  touchingFrames: Ref<Record<string, LayoutFrame>[]>
31
33
  touchingFramesArrays: Ref<LayoutFrame[][]>
32
34
  frames: ComputedRef<Record<string, LayoutFrame>>
33
- dragHoveredFrame: ComputedRef<LayoutFrame | undefined>
35
+ moveHoveredFrame: ComputedRef<LayoutFrame | undefined>
34
36
  intersections: ComputedRef<IntersectionEntry[]>
35
- isDraggingFromWindowEdge: Ref<boolean>
37
+ isMovingFromWindowEdge: Ref<boolean>
36
38
  forceRecalculateEdges: () => void
37
- state: ComputedRef<DragState>
38
- frameDragFrameId: Ref<FrameId | undefined>
39
+ state: ComputedRef<MoveState>
40
+ movingFrameId: Ref<FrameId | undefined>
39
41
  }
40
42
 
41
- export const dragContextInjectionKey = Symbol.for("@witchcraft/layout:dragContext") as InjectionKey<UseFramesContext>
43
+ export const moveContextInjectionKey = Symbol.for("@witchcraft/layout:moveContext") as InjectionKey<UseFramesContext>
@@ -1,9 +0,0 @@
1
- import type { IDragAction } from "../types/index.js";
2
- /**
3
- * Creates the default drag actions (Split, Close, FrameDrag).
4
- */
5
- export declare function createDefaultHandlers(config: {
6
- debugSplit?: boolean;
7
- debugClose?: boolean;
8
- debugFrameDrag?: boolean;
9
- }): IDragAction[];
@@ -1,10 +0,0 @@
1
- import { CloseAction } from "./CloseAction.js";
2
- import { FrameDragAction } from "./FrameDragAction.js";
3
- import { SplitAction } from "./SplitAction.js";
4
- export function createDefaultHandlers(config) {
5
- return [
6
- new SplitAction(void 0, void 0, void 0, { debug: config.debugSplit }),
7
- new CloseAction(void 0, void 0, void 0, { debug: config.debugClose }),
8
- new FrameDragAction(void 0, void 0, void 0, { debug: config.debugFrameDrag })
9
- ];
10
- }
@@ -1,8 +0,0 @@
1
- import type { DragState, DragZone } from "../types/index.js";
2
- /**
3
- * Find the drag zone under the drag point.
4
- */
5
- export declare function getDragZones(state: Pick<DragState, "dragPoint" | "dragHoveredFrame" | "frames" | "win">, { frameEdgePx, windowEdgePx }: {
6
- frameEdgePx: number;
7
- windowEdgePx: number;
8
- }): DragZone | undefined;
@@ -1,32 +0,0 @@
1
- import { getFrameDragZones } from "./getFrameDragZones.js";
2
- import { getWindowDragZones } from "./getWindowDragZones.js";
3
- import { isPointInRect } from "./isPointInRect.js";
4
- export function getDragZones(state, { frameEdgePx, windowEdgePx }) {
5
- const { dragPoint, win } = state;
6
- const frameId = state.dragHoveredFrame?.id;
7
- if (!frameId) return;
8
- const frame = state.frames[frameId];
9
- if (!frame || !dragPoint) return;
10
- const frameZones = getFrameDragZones(frame, frameEdgePx, win.pxWidth, win.pxHeight);
11
- const windowZones = getWindowDragZones(win, windowEdgePx);
12
- let matchedZone;
13
- for (const zone of windowZones) {
14
- if (isPointInRect(zone, dragPoint)) {
15
- matchedZone = {
16
- ...zone,
17
- type: "window"
18
- };
19
- break;
20
- }
21
- }
22
- if (!matchedZone) {
23
- for (const zone of frameZones) {
24
- if (isPointInRect(zone, dragPoint)) {
25
- matchedZone = zone;
26
- break;
27
- }
28
- }
29
- }
30
- if (!matchedZone) return void 0;
31
- return matchedZone;
32
- }
@@ -1,20 +0,0 @@
1
- import { CloseAction } from "./CloseAction"
2
- import { FrameDragAction } from "./FrameDragAction.js"
3
- import { SplitAction } from "./SplitAction.js"
4
-
5
- import type { IDragAction } from "../types/index.js"
6
-
7
- /**
8
- * Creates the default drag actions (Split, Close, FrameDrag).
9
- */
10
- export function createDefaultHandlers(config: {
11
- debugSplit?: boolean
12
- debugClose?: boolean
13
- debugFrameDrag?: boolean
14
- } = {}): IDragAction[] {
15
- return [
16
- new SplitAction(undefined, undefined, undefined, { debug: config.debugSplit }),
17
- new CloseAction(undefined, undefined, undefined, { debug: config.debugClose }),
18
- new FrameDragAction(undefined, undefined, undefined, { debug: config.debugFrameDrag })
19
- ]
20
- }
@@ -1,48 +0,0 @@
1
- import { getFrameDragZones } from "./getFrameDragZones.js"
2
- import { getWindowDragZones } from "./getWindowDragZones.js"
3
- import { isPointInRect } from "./isPointInRect.js"
4
-
5
- import type { DragState, DragZone, WindowEdgeZone } from "../types/index.js"
6
-
7
- /**
8
- * Find the drag zone under the drag point.
9
- */
10
- export function getDragZones(
11
- state: Pick<DragState, "dragPoint" | "dragHoveredFrame" | "frames" | "win">,
12
- { frameEdgePx, windowEdgePx }: { frameEdgePx: number, windowEdgePx: number }
13
- ): DragZone | undefined {
14
- const { dragPoint, win } = state
15
- const frameId = state.dragHoveredFrame?.id
16
- if (!frameId) return
17
-
18
- const frame = state.frames[frameId]
19
- if (!frame || !dragPoint) return
20
-
21
- const frameZones = getFrameDragZones(frame, frameEdgePx, win.pxWidth, win.pxHeight)
22
-
23
- const windowZones = getWindowDragZones(win, windowEdgePx)
24
-
25
- let matchedZone: DragZone | undefined
26
- for (const zone of windowZones) {
27
- if (isPointInRect(zone, dragPoint)) {
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, dragPoint)) {
39
- matchedZone = zone
40
- break
41
- }
42
- }
43
- }
44
-
45
- if (!matchedZone) return undefined
46
-
47
- return matchedZone
48
- }