@witchcraft/layout 0.5.1 → 0.5.2

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.
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@witchcraft/layout",
3
3
  "configKey": "witchcraftLayout",
4
- "version": "0.5.1",
4
+ "version": "0.5.2",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "unknown"
package/dist/module.mjs CHANGED
@@ -20,7 +20,7 @@ const module$1 = defineNuxtModule({
20
20
  getContents: () => [
21
21
  `@source "${resolve("runtime/components")}";`,
22
22
  // the drag actions handlers and utils they use add some styles
23
- `@source "${resolve("runtime/drag")}";`,
23
+ `@source "${resolve("runtime/move")}";`,
24
24
  `@source "${resolve("runtime/utils/createSplitDecoShapes")}";`
25
25
  ].join("\n")
26
26
  });
@@ -1,12 +1,14 @@
1
1
  import type { Ref } from "vue";
2
- import type { ActionHandler, ActionHandlerApplyResult, EdgeMoveStartData, FrameMoveStartData, IntersectionEntry, LayoutFrame, LayoutWindow } from "../types/index.js";
3
- export declare function useFrames(win: Ref<LayoutWindow>, handler: ActionHandler): {
2
+ import type { EdgeMoveStartData, FrameMoveStartData, IActionHandler, IntersectionEntry, LayoutFrame, LayoutWindow } from "../types/index.js";
3
+ export declare function useFrames(win: Ref<LayoutWindow>, handler: IActionHandler): {
4
4
  moveStart: <T extends "edge" | "frame">(e: PointerEvent, type: T, data: T extends "edge" ? EdgeMoveStartData : FrameMoveStartData, { moveEvent, endEvent, context }?: {
5
5
  moveEvent?: string;
6
6
  endEvent?: string;
7
7
  context?: Record<string, unknown>;
8
8
  }) => Promise<any>;
9
- moveEnd: (e?: PointerEvent, { apply }?: Partial<Pick<ActionHandlerApplyResult, "apply">>) => void;
9
+ moveEnd: (e?: PointerEvent, { apply }?: {
10
+ apply?: boolean;
11
+ }) => void;
10
12
  cancel: () => void;
11
13
  onMove: (e: PointerEvent) => void;
12
14
  moveDirections: Ref<{
@@ -1049,5 +1051,5 @@ export declare function useFrames(win: Ref<LayoutWindow>, handler: ActionHandler
1049
1051
  }>;
1050
1052
  showMoving: Ref<boolean, boolean>;
1051
1053
  movingFrameId: Ref<string | undefined, string | undefined>;
1052
- actionHandler: ActionHandler;
1054
+ actionHandler: IActionHandler;
1053
1055
  };
@@ -197,7 +197,7 @@ export function useFrames(win, handler) {
197
197
  if (apply) {
198
198
  const applyResult = handler.onMoveApply(state.value, forceRecalculateEdges);
199
199
  moveResult = applyResult.result;
200
- if (applyResult.apply) {
200
+ if (applyResult.updateEdges) {
201
201
  for (const frame of touchingFramesArrays.value.flat()) {
202
202
  win.value.frames[frame.id] = frame;
203
203
  }
@@ -1,16 +1,16 @@
1
1
  import { type RecordFromArray } from "@alanscodelog/utils";
2
- import type { ActionHandlerApplyResult, Edge, IAction, LayoutFrame, LayoutShape, MoveChangeHandler, MoveChangeResult, MoveState } from "../types/index.js";
2
+ import type { ActionHandlerApplyResult, ActionResolve, Edge, IAction, IActionHandler, LayoutFrame, LayoutShape, MoveChangeResult, MoveState } from "../types/index.js";
3
3
  /**
4
4
  * Handles the lifecycle of a drag actions {@link IAction} and provides additional hooks.
5
5
  *
6
6
  * The first action instance that can handle the request is passed control of the event handlers until the request changes.
7
7
  */
8
- export declare class ActionHandler<TRawActions extends IAction[], TActions extends RecordFromArray<TRawActions, "name"> = RecordFromArray<TRawActions, "name">> {
8
+ export declare class ActionHandler<TRawActions extends IAction[], TActions extends RecordFromArray<TRawActions, "name"> = RecordFromArray<TRawActions, "name">> implements IActionHandler {
9
9
  activeAction?: keyof TActions;
10
10
  actions: TActions;
11
11
  eventCanceller: ((e: PointerEvent | KeyboardEvent | undefined, state: MoveState) => void) | undefined;
12
12
  boundCancel: (e: PointerEvent | KeyboardEvent | undefined, state: MoveState) => void;
13
- defaultOnMoveChange: MoveChangeHandler;
13
+ defaultOnMoveChange: IAction["onMoveChange"];
14
14
  hooks: {
15
15
  /** Called while dragging during dragChange events. You can use this to update the dragging edges. */
16
16
  onRecalculate?: () => void;
@@ -25,7 +25,8 @@ export declare class ActionHandler<TRawActions extends IAction[], TActions exten
25
25
  /** Called when the drag action ends either because it was completed or cancelled. */
26
26
  onEnd?: (context: {
27
27
  cancelled: boolean;
28
- applied: boolean;
28
+ wasApplied: boolean;
29
+ result?: any;
29
30
  }) => void;
30
31
  };
31
32
  /** All action shapes merged into a single array. If using vue you can set this to a reactive array for reactivity. */
@@ -37,20 +38,18 @@ export declare class ActionHandler<TRawActions extends IAction[], TActions exten
37
38
  };
38
39
  constructor(actions: TRawActions, hooks?: ActionHandler<TRawActions, TActions>["hooks"],
39
40
  /**
40
- * Default onMoveChange handler for when no action can handle the request.
41
- *
42
- * Should return true to allow the edges to be moved, or false to prevent it.
41
+ * Default onMoveChange handler for when no action can handle the request. See {@link IAction.onMoveChange}.
43
42
  *
44
43
  * The default prevents movement when the edge is a window edge and when the edge is touching a collapsed frame.
45
44
  */
46
- defaultOnMoveChange?: MoveChangeHandler);
45
+ defaultOnMoveChange?: IAction["onMoveChange"]);
47
46
  eventHandler(e: KeyboardEvent | PointerEvent, state: MoveState, forceRecalculateEdges: () => void): undefined;
48
- onMoveChange<T extends "start" | "move" | "end">(type: T, e: T extends "end" ? PointerEvent | undefined : PointerEvent, state: MoveState, forceRecalculateEdges: () => void, cancel: (e: PointerEvent | KeyboardEvent | undefined, state: MoveState) => void, resolve: T extends "end" ? undefined : (opts: ActionHandlerApplyResult) => void): MoveChangeResult;
47
+ onMoveChange<T extends "start" | "move" | "end">(type: T, e: T extends "end" ? PointerEvent | undefined : PointerEvent, state: MoveState, forceRecalculateEdges: () => void, cancel: (e: PointerEvent | KeyboardEvent | undefined, state: MoveState) => void, resolve: T extends "end" ? undefined : ((opts: ActionResolve) => void)): MoveChangeResult;
48
+ onMoveApply(state: MoveState, forceRecalculateEdges: () => void): ActionHandlerApplyResult;
49
49
  onMoveEnded(): void;
50
+ cancel(e: PointerEvent | KeyboardEvent | undefined, state: MoveState): void;
50
51
  setTextHints(type: "start" | "move" | "end"): void;
51
52
  annotateEdges(edges: Edge[], frames: LayoutFrame[]): void;
52
- onMoveApply(state: MoveState, forceRecalculateEdges: () => void): ActionHandlerApplyResult;
53
- cancel(e: PointerEvent | KeyboardEvent | undefined, state: MoveState): void;
54
53
  static debugState(pluginName: string, type: "before" | "after" | string, state: MoveState, pluginState?: Record<string, any>,
55
54
  /** 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. */
56
55
  key?: string | boolean): void;
@@ -84,12 +84,29 @@ export class ActionHandler {
84
84
  this.shapes.splice(0, this.shapes.length, ...res.shapes);
85
85
  return res;
86
86
  }
87
+ onMoveApply(state, forceRecalculateEdges) {
88
+ if (this.activeAction) {
89
+ const res = this.actions[this.activeAction].onMoveApply(state, forceRecalculateEdges);
90
+ this.hooks.onEnd?.({ cancelled: false, wasApplied: res.wasApplied, result: res.result });
91
+ return res;
92
+ }
93
+ this.hooks.onEnd?.({ cancelled: false, wasApplied: false });
94
+ return { updateEdges: true, result: void 0 };
95
+ }
87
96
  onMoveEnded() {
88
97
  if (this.activeAction) {
89
98
  this.actions[this.activeAction].onMoveEnded();
90
99
  }
91
100
  this.activeAction = void 0;
92
101
  }
102
+ cancel(e, state) {
103
+ if (this.activeAction) {
104
+ this.actions[this.activeAction].cancel(e, state);
105
+ }
106
+ this.activeAction = void 0;
107
+ this.eventCanceller?.(e, state);
108
+ this.hooks.onEnd?.({ cancelled: true, wasApplied: false });
109
+ }
93
110
  setTextHints(type) {
94
111
  this.textHints.actions = [];
95
112
  this.textHints.errors = [];
@@ -121,23 +138,6 @@ export class ActionHandler {
121
138
  }
122
139
  }
123
140
  }
124
- onMoveApply(state, forceRecalculateEdges) {
125
- if (this.activeAction) {
126
- const res = this.actions[this.activeAction].onMoveApply(state, forceRecalculateEdges);
127
- this.hooks.onEnd?.({ cancelled: false, applied: res });
128
- return { apply: !res, result: void 0 };
129
- }
130
- this.hooks.onEnd?.({ cancelled: false, applied: false });
131
- return { apply: true, result: void 0 };
132
- }
133
- cancel(e, state) {
134
- if (this.activeAction) {
135
- this.actions[this.activeAction].cancel(e, state);
136
- }
137
- this.activeAction = void 0;
138
- this.eventCanceller?.(e, state);
139
- this.hooks.onEnd?.({ cancelled: true, applied: false });
140
- }
141
141
  static debugState(pluginName, type, state, pluginState = {}, key) {
142
142
  if (key === false) return;
143
143
  let res = { state, pluginState };
@@ -1,5 +1,5 @@
1
1
  import { getCloseFrameInfo } from "../layout/getCloseFrameInfo.js";
2
- import type { ActionChangeResult, CloseDeco, IAction, MoveState } from "../types/index.js";
2
+ import type { ActionApplyResult, ActionChangeResult, CloseDeco, IAction, MoveState } from "../types/index.js";
3
3
  import type { KnownError } from "../utils/KnownError.js";
4
4
  export type CloseInfo = Exclude<ReturnType<typeof getCloseFrameInfo>, KnownError>;
5
5
  export declare class CloseAction implements IAction {
@@ -53,7 +53,7 @@ export declare class CloseAction implements IAction {
53
53
  };
54
54
  canHandleRequest(e: PointerEvent | KeyboardEvent, state: MoveState): boolean;
55
55
  onMoveChange(type: "start" | "end" | "move", _e: PointerEvent | undefined, state: MoveState): ActionChangeResult;
56
- onMoveApply(state: MoveState): boolean;
56
+ onMoveApply(state: MoveState): ActionApplyResult;
57
57
  cancel(): void;
58
58
  onMoveEnded(): void;
59
59
  }
@@ -164,9 +164,9 @@ export class CloseAction {
164
164
  if (this.debug) {
165
165
  ActionHandler.debugState(this.name, "after", state, this.state, this.debug);
166
166
  }
167
- return true;
167
+ return { updateEdges: false, wasApplied: true };
168
168
  }
169
- return false;
169
+ return { updateEdges: true, wasApplied: false };
170
170
  }
171
171
  cancel() {
172
172
  this.hooks.onCancel?.();
@@ -1,4 +1,4 @@
1
- import type { ActionChangeResult, FrameDeco, IAction, LayoutChange, MoveState, Zone } from "../types/index.js";
1
+ import type { ActionApplyResult, ActionChangeResult, FrameDeco, IAction, LayoutChange, MoveState, Zone } from "../types/index.js";
2
2
  import type { KnownError } from "../utils/KnownError.js";
3
3
  export declare class FrameDragAction implements IAction {
4
4
  name: "frameDrag";
@@ -45,7 +45,7 @@ export declare class FrameDragAction implements IAction {
45
45
  getDecos(matchedZone: Zone | undefined, state: MoveState, result: LayoutChange<"split" | "swap" | "rearrange" | "dock"> | KnownError | undefined): FrameDeco[];
46
46
  canHandleRequest(e: PointerEvent | KeyboardEvent, state: MoveState): boolean;
47
47
  onMoveChange<T extends "start" | "move" | "end">(type: T, _e: PointerEvent | undefined, state: MoveState): ActionChangeResult;
48
- onMoveApply(state: MoveState): boolean;
48
+ onMoveApply(state: MoveState): ActionApplyResult;
49
49
  onMoveEnded(): void;
50
50
  cancel(): void;
51
51
  }
@@ -123,7 +123,7 @@ export class FrameDragAction {
123
123
  onMoveApply(state) {
124
124
  const result = this.state.lastReturn;
125
125
  if (!result || !state.moveHoveredFrame || !state.movingFrameId) {
126
- return true;
126
+ return { updateEdges: false, wasApplied: false };
127
127
  }
128
128
  if (result instanceof Error) {
129
129
  this.hooks.onError?.(result);
@@ -136,7 +136,7 @@ export class FrameDragAction {
136
136
  ActionHandler.debugState(this.name, "after", state, this.state, this.debug);
137
137
  }
138
138
  }
139
- return true;
139
+ return { updateEdges: false, wasApplied: true };
140
140
  }
141
141
  onMoveEnded() {
142
142
  this.reset();
@@ -1,5 +1,5 @@
1
1
  import { getFrameSplitInfo } from "../layout/getFrameSplitInfo.js";
2
- import type { ActionChangeResult, IAction, MoveState, Point, SplitDeco } from "../types/index.js";
2
+ import type { ActionApplyResult, ActionChangeResult, IAction, MoveState, Point, SplitDeco } from "../types/index.js";
3
3
  import type { KnownError } from "../utils/KnownError.js";
4
4
  export type SplitInfo = Exclude<ReturnType<typeof getFrameSplitInfo>, KnownError>;
5
5
  export type DragChangeType = "start" | "move" | "end";
@@ -51,7 +51,7 @@ export declare class SplitAction implements IAction {
51
51
  };
52
52
  calculateSplitRequest(state: MoveState): boolean;
53
53
  onMoveChange(type: "start" | "end" | "move", _e: PointerEvent | undefined, state: MoveState): ActionChangeResult;
54
- onMoveApply(state: MoveState): boolean;
54
+ onMoveApply(state: MoveState): ActionApplyResult;
55
55
  onMoveEnded(): void;
56
56
  cancel(): void;
57
57
  }
@@ -171,7 +171,7 @@ export class SplitAction {
171
171
  }
172
172
  }
173
173
  }
174
- return true;
174
+ return { updateEdges: false, wasApplied: true };
175
175
  }
176
176
  onMoveEnded() {
177
177
  this.reset();
@@ -1889,7 +1889,7 @@ export type MoveState = {
1889
1889
  */
1890
1890
  intersections: IntersectionEntry[];
1891
1891
  /**
1892
- * Whether the drag was initiated from a point along the window edge.
1892
+ * Whether the move was initiated from a point along the window edge.
1893
1893
  */
1894
1894
  isMovingFromWindowEdge: boolean;
1895
1895
  /** Custom context passed to moveStart, available to action handlers via state.eventContext. */
@@ -1897,7 +1897,7 @@ export type MoveState = {
1897
1897
  win: LayoutWindow;
1898
1898
  };
1899
1899
  export interface ActionChangeResult {
1900
- /** Whether the drag should update the edges. Defaults to false. */
1900
+ /** Whether the move should update the edges. Defaults to false. */
1901
1901
  updateEdges?: boolean;
1902
1902
  /** Deco shapes produced by this action during this drag step. */
1903
1903
  shapes: LayoutShape[];
@@ -1905,25 +1905,6 @@ export interface ActionChangeResult {
1905
1905
  showMoving?: boolean;
1906
1906
  }
1907
1907
  export type MoveChangeResult = Omit<ActionChangeResult, "shapes">;
1908
- /**
1909
- * Called when the drag coordinates change (during any event).
1910
- *
1911
- * Should return `{ allowed: true/false, shapes: LayoutShape[] }` to control whether the action is allowed and edges update and what deco shapes to render.
1912
- *
1913
- * Note that the allowed return type only affect the `move` event but is also typed as `boolean` for other events for ease of use.
1914
- *
1915
- * Use also to cleanup your action when type is "end".
1916
- *
1917
- * See also {@link ActionHandler.onMoveChange} to understand it's lifecycle as it is the extended version of.
1918
- */
1919
- export type MoveChangeHandler = <T extends "start" | "move" | "end">(type: T, e: T extends "end" ? PointerEvent | undefined : PointerEvent, state: MoveState, forceRecalculateEdges: () => void,
1920
- /** Calls moveEnd with apply: false. This can technically be called from "end", it should still work. */
1921
- cancel: (e: PointerEvent | KeyboardEvent | undefined, state: MoveState) => void,
1922
- /** Saves result to resolve moveStart promise with then calls moveEnd with given apply. Not available during "end" event. It's designed for resolving from other external evente (e.g. key events). */
1923
- resolve: T extends "end" ? undefined : ({ apply, result }: {
1924
- apply: boolean;
1925
- result: any;
1926
- }) => void) => ActionChangeResult;
1927
1908
  /**
1928
1909
  * A drag action describes when and how to handle a drag event.
1929
1910
  *
@@ -1934,18 +1915,30 @@ resolve: T extends "end" ? undefined : ({ apply, result }: {
1934
1915
  export interface IAction {
1935
1916
  /** A unique name for your action. */
1936
1917
  name: string;
1937
- onMoveChange: MoveChangeHandler;
1938
1918
  /**
1919
+ * Called when the drag coordinates change (during any event).
1939
1920
  *
1940
- * Is called before `onMoveChange("end")` with the same event. Might not be called if the request was cancelled.
1921
+ * Should return `{ allowed: true/false, shapes: LayoutShape[] }` to control whether the action is allowed and edges update and what deco shapes to render.
1941
1922
  *
1942
- * You should apply your action if possible and return whether it was applied.
1923
+ * Note that the allowed return type only affect the `move` event but is also typed as `boolean` for other events for ease of use.
1943
1924
  *
1944
- * Do not reset state here, use onMoveChange ("end").
1925
+ * Use also to cleanup your action when type is "end".
1945
1926
  *
1946
- * See also {@link ActionHandler.onMoveApply} which this is the extended version of.
1927
+ * See also {@link ActionHandler.onMoveChange} to understand it's lifecycle as it is the extended version of.
1947
1928
  */
1948
- onMoveApply: (state: MoveState, forceRecalculateEdges: () => void) => boolean;
1929
+ onMoveChange: <T extends "start" | "move" | "end">(type: T, e: T extends "end" ? PointerEvent | undefined : PointerEvent, state: MoveState, forceRecalculateEdges: () => void,
1930
+ /** Calls moveEnd with updateEdges: false. This can technically be called from "end", it should still work. */
1931
+ cancel: (e: PointerEvent | KeyboardEvent | undefined, state: MoveState) => void,
1932
+ /** Saves result to resolve moveStart promise with then calls moveEnd with given apply. Not available during "end" event. It's designed for resolving from other external evente (e.g. key events). */
1933
+ resolve: T extends "end" ? undefined : ((opts: ActionResolve) => void)) => ActionChangeResult;
1934
+ /**
1935
+ * Is called after `onMoveChange("end")` with the same event. Will not be called if the request was cancelled.
1936
+ *
1937
+ * You should apply your action if possible and return whether it was applied `wasApplied` as well as `updateEdges` and `result` (optional), see {@link ActionHandler.onMoveApply}, which this is the extended version of.
1938
+ *
1939
+ * Do not reset state here, use onMoveChange ("end").
1940
+ */
1941
+ onMoveApply: (state: MoveState, forceRecalculateEdges: () => void) => ActionApplyResult;
1949
1942
  /**
1950
1943
  * Should return true if it should handle the "request"/event (e.g. some modifier is being pressed => user is requesting x action).
1951
1944
  *
@@ -2010,18 +2003,24 @@ export type FrameMoveStartData = {
2010
2003
  frameId: FrameId;
2011
2004
  };
2012
2005
  export type ActionHandlerApplyResult = {
2013
- /** Whether to apply the regular drag end changes. Return false to reset to the position before dragging. */
2006
+ updateEdges: boolean;
2007
+ /** Value to resolve the drag promise with. Ignored if `updateEdges` is false. */
2008
+ result?: any;
2009
+ };
2010
+ export type ActionApplyResult = ActionHandlerApplyResult & {
2011
+ wasApplied: boolean;
2012
+ };
2013
+ export type ActionResolve = {
2014
2014
  apply: boolean;
2015
- /** Value to resolve the drag promise with. Ignored if `apply` is false. */
2016
- result: any;
2015
+ result?: any;
2017
2016
  };
2018
2017
  /**
2019
2018
  * Handler interface for drag actions.
2020
2019
  */
2021
- export interface ActionHandler {
2020
+ export interface IActionHandler {
2022
2021
  eventHandler: (e: KeyboardEvent, state: MoveState, forceRecalculateEdges: () => void) => void;
2023
2022
  /**
2024
- * 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. See also {@link MoveChangeHandler} for the built in action handler.
2023
+ * Called when the drag coordinates change (during any event). Should return updateEdges true to allow the edges to be updated/moved, or false to prevent it. See also {@link MoveChangeHandler} for the built in action handler.
2025
2024
  *
2026
2025
  * Can be used to save some context/info to later apply safely during onMoveApply.
2027
2026
  *
@@ -2030,12 +2029,19 @@ export interface ActionHandler {
2030
2029
  * - onMoveChange("move", ...)
2031
2030
  * - onMoveChange("end", ...)
2032
2031
  * - onMoveApply(...) (IF moveEnd was called with apply: true, otherwise this is skipped)
2032
+ * - If anything calls cancel or resolve they call onMoveApply (cancel with apply: false, resolve with whatever apply value you gave it).
2033
2033
  * - onMoveEnded() // do cleanup here
2034
+ *
2035
+ * Note also that resolve just resolves the promise value (after onMoveApply("end") and before onMoveEnded()). Depending on what you're doing you might still have to apply the result, remember onMoveApply will still be called if you do `resolve({ apply:true })`.
2034
2036
  */
2035
- onMoveChange: (...args: Parameters<MoveChangeHandler>) => MoveChangeResult;
2037
+ onMoveChange<T extends "start" | "move" | "end">(type: T, e: T extends "end" ? PointerEvent | undefined : PointerEvent, state: MoveState, forceRecalculateEdges: () => void,
2038
+ /** Calls moveEnd with apply: false. This can technically be called from "end", it should still work. */
2039
+ cancel: (e: PointerEvent | KeyboardEvent | undefined, state: MoveState) => void,
2040
+ /** Saves result to resolve moveStart promise with then calls moveEnd with given apply. Not available during "end" event. It's designed for resolving from other external evente (e.g. key events). */
2041
+ resolve: T extends "end" ? undefined : ((opts: ActionResolve) => void)): MoveChangeResult;
2036
2042
  /**
2037
2043
  * Called when drag will be applied. If moveEnd was called with apply false, it will not be called.
2038
- * Return false to not apply the regular drag end changes (i.e. return false to reset to the position before dragging).
2044
+ * Return `{updateEdges: false`} to not apply the regular drag end changes (i.e. return false to reset to the position before dragging). Optionally return a `result` value to resolve the promise with.
2039
2045
  *
2040
2046
  * Do not use for resetting handler state, use onMoveEnded for that.
2041
2047
  */
@@ -1,5 +1,5 @@
1
1
  import type { ComputedRef, InjectionKey, Ref } from "vue";
2
- import type { ActionHandler, ActionHandlerApplyResult, Direction, Edge, FrameId, IntersectionEntry, LayoutFrame, LayoutShape, LayoutWindow, MoveState, Orientation, Point } from "./index.js";
2
+ import type { Direction, Edge, FrameId, IActionHandler, IntersectionEntry, LayoutFrame, LayoutShape, LayoutWindow, MoveState, Orientation, Point } from "./index.js";
3
3
  export type LayoutContext = ComputedRef<{
4
4
  /** The owning window, needed so we can correctly scale coordinates. */
5
5
  win: LayoutWindow;
@@ -8,7 +8,7 @@ export type LayoutContext = ComputedRef<{
8
8
  }>;
9
9
  export declare const layoutContextInjectionKey: InjectionKey<LayoutContext>;
10
10
  export interface UseFramesContext {
11
- actionHandler: ActionHandler;
11
+ actionHandler: IActionHandler;
12
12
  moveStart: {
13
13
  (e: PointerEvent, type: "edge", data: {
14
14
  edge?: Edge;
@@ -27,7 +27,9 @@ export interface UseFramesContext {
27
27
  }): Promise<any>;
28
28
  };
29
29
  onMove: (e: PointerEvent) => void;
30
- moveEnd: (e?: PointerEvent, options?: Partial<Pick<ActionHandlerApplyResult, "apply">>) => void;
30
+ moveEnd: (e?: PointerEvent, options?: {
31
+ apply?: boolean;
32
+ }) => void;
31
33
  cancel: () => void;
32
34
  moveDirections: Ref<Record<Orientation, Direction | undefined>>;
33
35
  movePoint: Ref<Point | undefined>;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@witchcraft/layout",
3
3
  "description": "Headless layout manager.",
4
- "version": "0.5.1",
4
+ "version": "0.5.2",
5
5
  "main": "./dist/runtime/index.js",
6
6
  "type": "module",
7
7
  "sideEffects": false,
package/src/module.ts CHANGED
@@ -38,7 +38,7 @@ export default defineNuxtModule<ModuleOptions>({
38
38
  getContents: () => [
39
39
  `@source "${resolve("runtime/components")}";`,
40
40
  // the drag actions handlers and utils they use add some styles
41
- `@source "${resolve("runtime/drag")}";`,
41
+ `@source "${resolve("runtime/move")}";`,
42
42
  `@source "${resolve("runtime/utils/createSplitDecoShapes")}";`
43
43
  ].join("\n")
44
44
  })
@@ -12,11 +12,11 @@ import { toWindowCoord } from "../helpers/toWindowCoord.js"
12
12
  import { findFramesTouchingEdge } from "../layout/findFramesTouchingEdge.js"
13
13
  import { isPointInRect } from "../layout/isPointInRect.js"
14
14
  import { MoveDirectionStore } from "../move/MoveDirectionStore.js"
15
- import type { ActionHandler, ActionHandlerApplyResult, Direction, Edge, EdgeMoveStartData, FrameId, FrameMoveStartData, IntersectionEntry, LayoutFrame, LayoutWindow, MoveState, Orientation, Point } from "../types/index.js"
15
+ import type { ActionResolve, Direction, Edge, EdgeMoveStartData, FrameId, FrameMoveStartData, IActionHandler, IntersectionEntry, LayoutFrame, LayoutWindow, MoveState, Orientation, Point } from "../types/index.js"
16
16
 
17
17
  export function useFrames(
18
18
  win: Ref<LayoutWindow>,
19
- handler: ActionHandler
19
+ handler: IActionHandler
20
20
  ) {
21
21
  const movingEdges = ref<Edge[]>([])
22
22
 
@@ -255,7 +255,7 @@ export function useFrames(
255
255
  }
256
256
  }
257
257
 
258
- function moveEnd(e?: PointerEvent, { apply = true }: Partial<Pick<ActionHandlerApplyResult, "apply">> = {}): void {
258
+ function moveEnd(e?: PointerEvent, { apply = true }: { apply?: boolean } = {}) {
259
259
  if (e) {
260
260
  const point = toWindowCoord(win.value, e)
261
261
  movePoint.value = point
@@ -266,7 +266,7 @@ export function useFrames(
266
266
  if (apply) {
267
267
  const applyResult = handler.onMoveApply(state.value, forceRecalculateEdges)
268
268
  moveResult = applyResult.result
269
- if (applyResult.apply) {
269
+ if (applyResult.updateEdges) {
270
270
  for (const frame of touchingFramesArrays.value.flat()) {
271
271
  win!.value.frames[frame.id] = frame
272
272
  }
@@ -281,7 +281,8 @@ export function useFrames(
281
281
  function cancel(): void {
282
282
  moveEnd(undefined, { apply: false })
283
283
  }
284
- function resolve({ apply, result: value }: ActionHandlerApplyResult): void {
284
+ // we use apply not updateEdges, updateEdges needs to be returned by onMoveApply
285
+ function resolve({ apply, result: value }: ActionResolve): void {
285
286
  moveResult = value
286
287
  moveEnd(undefined, { apply })
287
288
  }
@@ -2,7 +2,7 @@ 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 { ActionHandlerApplyResult, Edge, IAction, LayoutFrame, LayoutShape, MoveChangeHandler, MoveChangeResult, MoveState } from "../types/index.js"
5
+ import type { ActionHandlerApplyResult, ActionResolve, Edge, IAction, IActionHandler, LayoutFrame, LayoutShape, 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
 
@@ -14,7 +14,7 @@ import { KnownError } from "../utils/KnownError.js"
14
14
  export class ActionHandler<
15
15
  TRawActions extends IAction[],
16
16
  TActions extends RecordFromArray<TRawActions, "name"> = RecordFromArray<TRawActions, "name">
17
- > {
17
+ > implements IActionHandler {
18
18
  activeAction?: keyof TActions
19
19
 
20
20
  actions: TActions
@@ -23,7 +23,7 @@ export class ActionHandler<
23
23
 
24
24
  boundCancel: (e: PointerEvent | KeyboardEvent | undefined, state: MoveState) => void
25
25
 
26
- defaultOnMoveChange: MoveChangeHandler = (type, _e, state, _forceRecalculateEdges, _cancel) => {
26
+ defaultOnMoveChange: IAction["onMoveChange"] = (type, _e, state, _forceRecalculateEdges, _cancel) => {
27
27
  const isTouchingCollapsedFrameEdge = type === "move"
28
28
  && state.isMoving === "edge"
29
29
  && state.touchingFramesArrays.some(frames =>
@@ -48,7 +48,7 @@ export class ActionHandler<
48
48
  /** Called when the action requested changes. */
49
49
  onRequestChange?: (type: keyof TActions | undefined) => void
50
50
  /** Called when the drag action ends either because it was completed or cancelled. */
51
- onEnd?: (context: { cancelled: boolean, applied: boolean }) => void
51
+ onEnd?: (context: { cancelled: boolean, wasApplied: boolean, result?: any }) => void
52
52
  }
53
53
 
54
54
  /** All action shapes merged into a single array. If using vue you can set this to a reactive array for reactivity. */
@@ -61,13 +61,11 @@ export class ActionHandler<
61
61
  actions: TRawActions,
62
62
  hooks: ActionHandler<TRawActions, TActions>["hooks"] = {},
63
63
  /**
64
- * Default onMoveChange handler for when no action can handle the request.
65
- *
66
- * Should return true to allow the edges to be moved, or false to prevent it.
64
+ * Default onMoveChange handler for when no action can handle the request. See {@link IAction.onMoveChange}.
67
65
  *
68
66
  * The default prevents movement when the edge is a window edge and when the edge is touching a collapsed frame.
69
67
  */
70
- defaultOnMoveChange?: MoveChangeHandler
68
+ defaultOnMoveChange?: IAction["onMoveChange"]
71
69
  ) {
72
70
  if (defaultOnMoveChange) this.defaultOnMoveChange = defaultOnMoveChange
73
71
  this.hooks = hooks
@@ -129,7 +127,7 @@ export class ActionHandler<
129
127
  state: MoveState,
130
128
  forceRecalculateEdges: () => void,
131
129
  cancel: (e: PointerEvent | KeyboardEvent | undefined, state: MoveState) => void,
132
- resolve: T extends "end" ? undefined : (opts: ActionHandlerApplyResult) => void
130
+ resolve: T extends "end" ? undefined : ((opts: ActionResolve) => void)
133
131
  ): MoveChangeResult {
134
132
  if (type === "start") {
135
133
  this.eventCanceller = cancel
@@ -150,6 +148,19 @@ export class ActionHandler<
150
148
  return res
151
149
  }
152
150
 
151
+ onMoveApply(
152
+ state: MoveState,
153
+ forceRecalculateEdges: () => void
154
+ ): ActionHandlerApplyResult {
155
+ if (this.activeAction) {
156
+ const res = this.actions[this.activeAction]!.onMoveApply(state, forceRecalculateEdges)
157
+ this.hooks.onEnd?.({ cancelled: false, wasApplied: res.wasApplied, result: res.result })
158
+ return res
159
+ }
160
+ this.hooks.onEnd?.({ cancelled: false, wasApplied: false })
161
+ return { updateEdges: true, result: undefined }
162
+ }
163
+
153
164
  onMoveEnded() {
154
165
  if (this.activeAction) {
155
166
  this.actions[this.activeAction]!.onMoveEnded()
@@ -158,6 +169,16 @@ export class ActionHandler<
158
169
  this.activeAction = undefined
159
170
  }
160
171
 
172
+ cancel(e: PointerEvent | KeyboardEvent | undefined, state: MoveState): void {
173
+ if (this.activeAction) {
174
+ this.actions[this.activeAction].cancel(e, state)
175
+ }
176
+ this.activeAction = undefined
177
+ this.eventCanceller?.(e, state)
178
+ this.hooks.onEnd?.({ cancelled: true, wasApplied: false })
179
+ }
180
+
181
+
161
182
  setTextHints(type: "start" | "move" | "end") {
162
183
  // again in case it's a vue reactive object
163
184
  this.textHints.actions = []
@@ -195,28 +216,6 @@ export class ActionHandler<
195
216
  }
196
217
  }
197
218
 
198
- onMoveApply(
199
- state: MoveState,
200
- forceRecalculateEdges: () => void
201
- ): ActionHandlerApplyResult {
202
- if (this.activeAction) {
203
- const res = this.actions[this.activeAction]!.onMoveApply(state, forceRecalculateEdges)
204
- this.hooks.onEnd?.({ cancelled: false, applied: res })
205
- return { apply: !res, result: undefined }
206
- }
207
- this.hooks.onEnd?.({ cancelled: false, applied: false })
208
- return { apply: true, result: undefined }
209
- }
210
-
211
- cancel(e: PointerEvent | KeyboardEvent | undefined, state: MoveState): void {
212
- if (this.activeAction) {
213
- this.actions[this.activeAction].cancel(e, state)
214
- }
215
- this.activeAction = undefined
216
- this.eventCanceller?.(e, state)
217
- this.hooks.onEnd?.({ cancelled: true, applied: false })
218
- }
219
-
220
219
  static debugState(
221
220
  pluginName: string,
222
221
  type: "before" | "after" | string,
@@ -6,7 +6,7 @@ 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 { ActionChangeResult, CloseDeco, IAction, MoveState } from "../types/index.js"
9
+ import type { ActionApplyResult, 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>
@@ -212,15 +212,15 @@ export class CloseAction implements IAction {
212
212
  return this.state.lastReturn
213
213
  }
214
214
 
215
- onMoveApply(state: MoveState): boolean {
215
+ onMoveApply(state: MoveState): ActionApplyResult {
216
216
  if (this.state.res) {
217
217
  const win = state.win
218
218
  if (this.debug) { ActionHandler.debugState(this.name, "before", state, this.state, this.debug) }
219
219
  applyFrameChanges(win, this.state.res)
220
220
  if (this.debug) { ActionHandler.debugState(this.name, "after", state, this.state, this.debug) }
221
- return true
221
+ return { updateEdges: false, wasApplied: true }
222
222
  }
223
- return false
223
+ return { updateEdges: true, wasApplied: false }
224
224
  }
225
225
 
226
226
  cancel(): void {
@@ -7,7 +7,7 @@ import { getFrameRearrangeInfo } from "../layout/getFrameRearrangeInfo.js"
7
7
  import { getFrameSwapInfo } from "../layout/getFrameSwapInfo.js"
8
8
  import { getZones } from "../layout/getZones.js"
9
9
  import { settings } from "../settings.js"
10
- import type { ActionChangeResult, FrameDeco, IAction, LayoutChange, MoveState, Zone } from "../types/index.js"
10
+ import type { ActionApplyResult, ActionChangeResult, FrameDeco, IAction, LayoutChange, MoveState, Zone } from "../types/index.js"
11
11
  import type { KnownError } from "../utils/KnownError.js"
12
12
 
13
13
 
@@ -187,10 +187,10 @@ export class FrameDragAction implements IAction {
187
187
  }
188
188
  }
189
189
 
190
- onMoveApply(state: MoveState): boolean {
190
+ onMoveApply(state: MoveState): ActionApplyResult {
191
191
  const result = this.state.lastReturn
192
192
  if (!result || !state.moveHoveredFrame || !state.movingFrameId) {
193
- return true
193
+ return { updateEdges: false, wasApplied: false }
194
194
  }
195
195
 
196
196
  if (result instanceof Error) {
@@ -201,7 +201,7 @@ export class FrameDragAction implements IAction {
201
201
  if (this.debug) { ActionHandler.debugState(this.name, "after", state, this.state, this.debug) }
202
202
  }
203
203
 
204
- return true
204
+ return { updateEdges: false, wasApplied: true }
205
205
  }
206
206
 
207
207
  onMoveEnded() {
@@ -5,7 +5,7 @@ import { oppositeSide } from "../helpers/oppositeSide.js"
5
5
  import { applyFrameChanges } from "../layout/applyFrameChanges.js"
6
6
  import { createSplitDecoFromDrag } from "../layout/createSplitDecoFromDrag.js"
7
7
  import { getFrameSplitInfo } from "../layout/getFrameSplitInfo.js"
8
- import type { ActionChangeResult, IAction, LayoutShape, MoveState, Point, SplitDeco } from "../types/index.js"
8
+ import type { ActionApplyResult, ActionChangeResult, IAction, LayoutShape, MoveState, Point, SplitDeco } from "../types/index.js"
9
9
  import type { KnownError } from "../utils/KnownError.js"
10
10
 
11
11
  export type SplitInfo = Exclude<ReturnType<typeof getFrameSplitInfo>, KnownError>
@@ -219,7 +219,7 @@ export class SplitAction implements IAction {
219
219
  return this.state.lastReturn
220
220
  }
221
221
 
222
- onMoveApply(state: MoveState): boolean {
222
+ onMoveApply(state: MoveState): ActionApplyResult {
223
223
  if (this.state.res && state.moveHoveredFrame) {
224
224
  // this only caches once per frame hovered over
225
225
  // so the drag position is outdated, we must recalculate
@@ -230,7 +230,7 @@ export class SplitAction implements IAction {
230
230
  if (this.debug) { ActionHandler.debugState(this.name, "after", state, this.state, this.debug) }
231
231
  }
232
232
  }
233
- return true
233
+ return { updateEdges: false, wasApplied: true }
234
234
  }
235
235
 
236
236
  onMoveEnded() {
@@ -487,7 +487,7 @@ export type MoveState = {
487
487
  */
488
488
  intersections: IntersectionEntry[]
489
489
  /**
490
- * Whether the drag was initiated from a point along the window edge.
490
+ * Whether the move was initiated from a point along the window edge.
491
491
  */
492
492
  isMovingFromWindowEdge: boolean
493
493
  /** Custom context passed to moveStart, available to action handlers via state.eventContext. */
@@ -497,7 +497,7 @@ export type MoveState = {
497
497
 
498
498
 
499
499
  export interface ActionChangeResult {
500
- /** Whether the drag should update the edges. Defaults to false. */
500
+ /** Whether the move should update the edges. Defaults to false. */
501
501
  updateEdges?: boolean
502
502
  /** Deco shapes produced by this action during this drag step. */
503
503
  shapes: LayoutShape[]
@@ -506,27 +506,6 @@ export interface ActionChangeResult {
506
506
  }
507
507
  export type MoveChangeResult = Omit<ActionChangeResult, "shapes">
508
508
 
509
- /**
510
- * Called when the drag coordinates change (during any event).
511
- *
512
- * Should return `{ allowed: true/false, shapes: LayoutShape[] }` to control whether the action is allowed and edges update and what deco shapes to render.
513
- *
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.
519
- */
520
- export type MoveChangeHandler = <T extends "start" | "move" | "end">(
521
- type: T,
522
- e: T extends "end" ? PointerEvent | undefined : PointerEvent,
523
- state: MoveState,
524
- forceRecalculateEdges: () => void,
525
- /** Calls moveEnd with apply: false. This can technically be called from "end", it should still work. */
526
- cancel: (e: PointerEvent | KeyboardEvent | undefined, state: MoveState) => void,
527
- /** Saves result to resolve moveStart promise with then calls moveEnd with given apply. Not available during "end" event. It's designed for resolving from other external evente (e.g. key events). */
528
- resolve: T extends "end" ? undefined : ({ apply, result }: { apply: boolean, result: any }) => void
529
- ) => ActionChangeResult
530
509
 
531
510
  /**
532
511
  * A drag action describes when and how to handle a drag event.
@@ -539,18 +518,35 @@ export type MoveChangeHandler = <T extends "start" | "move" | "end">(
539
518
  export interface IAction {
540
519
  /** A unique name for your action. */
541
520
  name: string
542
- onMoveChange: MoveChangeHandler
543
521
  /**
522
+ * Called when the drag coordinates change (during any event).
544
523
  *
545
- * Is called before `onMoveChange("end")` with the same event. Might not be called if the request was cancelled.
524
+ * Should return `{ allowed: true/false, shapes: LayoutShape[] }` to control whether the action is allowed and edges update and what deco shapes to render.
546
525
  *
547
- * You should apply your action if possible and return whether it was applied.
526
+ * Note that the allowed return type only affect the `move` event but is also typed as `boolean` for other events for ease of use.
548
527
  *
549
- * Do not reset state here, use onMoveChange ("end").
528
+ * Use also to cleanup your action when type is "end".
550
529
  *
551
- * See also {@link ActionHandler.onMoveApply} which this is the extended version of.
530
+ * See also {@link ActionHandler.onMoveChange} to understand it's lifecycle as it is the extended version of.
552
531
  */
553
- onMoveApply: (state: MoveState, forceRecalculateEdges: () => void) => boolean
532
+ onMoveChange: <T extends "start" | "move" | "end">(
533
+ type: T,
534
+ e: T extends "end" ? PointerEvent | undefined : PointerEvent,
535
+ state: MoveState,
536
+ forceRecalculateEdges: () => void,
537
+ /** Calls moveEnd with updateEdges: false. This can technically be called from "end", it should still work. */
538
+ cancel: (e: PointerEvent | KeyboardEvent | undefined, state: MoveState) => void,
539
+ /** Saves result to resolve moveStart promise with then calls moveEnd with given apply. Not available during "end" event. It's designed for resolving from other external evente (e.g. key events). */
540
+ resolve: T extends "end" ? undefined : ((opts: ActionResolve) => void)
541
+ ) => ActionChangeResult
542
+ /**
543
+ * Is called after `onMoveChange("end")` with the same event. Will not be called if the request was cancelled.
544
+ *
545
+ * You should apply your action if possible and return whether it was applied `wasApplied` as well as `updateEdges` and `result` (optional), see {@link ActionHandler.onMoveApply}, which this is the extended version of.
546
+ *
547
+ * Do not reset state here, use onMoveChange ("end").
548
+ */
549
+ onMoveApply: (state: MoveState, forceRecalculateEdges: () => void) => ActionApplyResult
554
550
  /**
555
551
  * Should return true if it should handle the "request"/event (e.g. some modifier is being pressed => user is requesting x action).
556
552
  *
@@ -617,19 +613,25 @@ export type EdgeMoveStartData = { edge?: Edge, intersection?: IntersectionEntry
617
613
  export type FrameMoveStartData = { frameId: FrameId }
618
614
 
619
615
  export type ActionHandlerApplyResult = {
620
- /** Whether to apply the regular drag end changes. Return false to reset to the position before dragging. */
621
- apply: boolean
622
- /** Value to resolve the drag promise with. Ignored if `apply` is false. */
623
- result: any
616
+ // /** Whether the move should update the edges. Defaults to false which resets to the position before moving started.*/
617
+ updateEdges: boolean
618
+ /** Value to resolve the drag promise with. Ignored if `updateEdges` is false. */
619
+ result?: any
624
620
  }
625
621
 
622
+ export type ActionApplyResult = ActionHandlerApplyResult & { wasApplied: boolean }
623
+
624
+ export type ActionResolve = { apply: boolean, result?: any }
625
+
626
626
  /**
627
627
  * Handler interface for drag actions.
628
628
  */
629
- export interface ActionHandler {
629
+ // eslint-disable-next-line @typescript-eslint/naming-convention
630
+ export interface IActionHandler {
630
631
  eventHandler: (e: KeyboardEvent, state: MoveState, forceRecalculateEdges: () => void) => void
632
+
631
633
  /**
632
- * 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. See also {@link MoveChangeHandler} for the built in action handler.
634
+ * Called when the drag coordinates change (during any event). Should return updateEdges true to allow the edges to be updated/moved, or false to prevent it. See also {@link MoveChangeHandler} for the built in action handler.
633
635
  *
634
636
  * Can be used to save some context/info to later apply safely during onMoveApply.
635
637
  *
@@ -638,12 +640,24 @@ export interface ActionHandler {
638
640
  * - onMoveChange("move", ...)
639
641
  * - onMoveChange("end", ...)
640
642
  * - onMoveApply(...) (IF moveEnd was called with apply: true, otherwise this is skipped)
643
+ * - If anything calls cancel or resolve they call onMoveApply (cancel with apply: false, resolve with whatever apply value you gave it).
641
644
  * - onMoveEnded() // do cleanup here
645
+ *
646
+ * Note also that resolve just resolves the promise value (after onMoveApply("end") and before onMoveEnded()). Depending on what you're doing you might still have to apply the result, remember onMoveApply will still be called if you do `resolve({ apply:true })`.
642
647
  */
643
- onMoveChange: (...args: Parameters<MoveChangeHandler>) => MoveChangeResult
648
+ onMoveChange<T extends "start" | "move" | "end">(
649
+ type: T,
650
+ e: T extends "end" ? PointerEvent | undefined : PointerEvent,
651
+ state: MoveState,
652
+ forceRecalculateEdges: () => void,
653
+ /** Calls moveEnd with apply: false. This can technically be called from "end", it should still work. */
654
+ cancel: (e: PointerEvent | KeyboardEvent | undefined, state: MoveState) => void,
655
+ /** Saves result to resolve moveStart promise with then calls moveEnd with given apply. Not available during "end" event. It's designed for resolving from other external evente (e.g. key events). */
656
+ resolve: T extends "end" ? undefined : ((opts: ActionResolve) => void)
657
+ ): MoveChangeResult
644
658
  /**
645
659
  * Called when drag will be applied. If moveEnd was called with apply false, it will not be called.
646
- * Return false to not apply the regular drag end changes (i.e. return false to reset to the position before dragging).
660
+ * Return `{updateEdges: false`} to not apply the regular drag end changes (i.e. return false to reset to the position before dragging). Optionally return a `result` value to resolve the promise with.
647
661
  *
648
662
  * Do not use for resetting handler state, use onMoveEnded for that.
649
663
  */
@@ -1,7 +1,7 @@
1
1
  import type { ComputedRef, InjectionKey, Ref } from "vue"
2
2
 
3
3
  // eslint-disable-next-line no-restricted-imports
4
- import type { ActionHandler, ActionHandlerApplyResult, Direction, Edge, FrameId, IntersectionEntry, LayoutFrame, LayoutShape, LayoutWindow, MoveState, Orientation, Point } from "./index.js"
4
+ import type { Direction, Edge, FrameId, IActionHandler, IntersectionEntry, LayoutFrame, LayoutShape, LayoutWindow, MoveState, Orientation, Point } from "./index.js"
5
5
 
6
6
  export type LayoutContext = ComputedRef<
7
7
  & {
@@ -15,13 +15,13 @@ export type LayoutContext = ComputedRef<
15
15
  export const layoutContextInjectionKey = Symbol.for("@witchcraft/layout:context") as InjectionKey<LayoutContext>
16
16
 
17
17
  export interface UseFramesContext {
18
- actionHandler: ActionHandler
18
+ actionHandler: IActionHandler
19
19
  moveStart: {
20
20
  (e: PointerEvent, type: "edge", data: { edge?: Edge, intersection?: IntersectionEntry }, opts?: { moveEvent?: string, endEvent?: string, context?: Record<string, unknown> }): Promise<any>
21
21
  (e: PointerEvent, type: "frame", data: { frameId: FrameId }, opts?: { moveEvent?: string, endEvent?: string, context?: Record<string, unknown> }): Promise<any>
22
22
  }
23
23
  onMove: (e: PointerEvent) => void
24
- moveEnd: (e?: PointerEvent, options?: Partial<Pick<ActionHandlerApplyResult, "apply">>) => void
24
+ moveEnd: (e?: PointerEvent, options?: { apply?: boolean }) => void
25
25
  cancel: () => void
26
26
  moveDirections: Ref<Record<Orientation, Direction | undefined>>
27
27
  movePoint: Ref<Point | undefined>