@witchcraft/layout 0.5.4 → 0.5.6

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.
@@ -1,11 +1,19 @@
1
1
  import type { Ref } from "vue";
2
- import type { EdgeMoveStartData, FrameMoveStartData, IActionHandler, IntersectionEntry, LayoutFrame, LayoutWindow } from "../types/index.js";
2
+ import type { EdgeMoveStartData, ExtendedMoveTypes, FrameMoveStartData, IActionHandler, IntersectionEntry, LayoutFrame, LayoutWindow } from "../types/index.js";
3
3
  export declare function useFrames(win: Ref<LayoutWindow>, handler: IActionHandler): {
4
- moveStart: <T extends "edge" | "frame">(e: PointerEvent, type: T, data: T extends "edge" ? EdgeMoveStartData : FrameMoveStartData, { moveEvent, endEvent, context }?: {
4
+ moveStart: <T extends "edge" | "frame" | "other", TContextType extends keyof ExtendedMoveTypes, TContext extends ExtendedMoveTypes[TContextType], TContextReturn extends TContext extends {
5
+ resolve: infer R;
6
+ } ? R : never, TContextMoveType extends TContext extends {
7
+ moveType: infer M;
8
+ } ? M : never, TContextContext extends TContext extends {
9
+ context: infer C;
10
+ } ? C : never>(e: PointerEvent, type: TContextMoveType extends never ? T : TContextMoveType, data: T extends "edge" ? EdgeMoveStartData : T extends "frame" ? FrameMoveStartData : undefined, { moveEvent, endEvent, context }?: {
5
11
  moveEvent?: string;
6
12
  endEvent?: string;
7
- context?: Record<string, unknown>;
8
- }) => Promise<any>;
13
+ context?: {
14
+ type: TContextType;
15
+ } & TContextContext;
16
+ }) => TContext extends never ? Promise<void> : Promise<TContextReturn>;
9
17
  moveEnd: (e?: PointerEvent, { apply }?: {
10
18
  apply?: boolean;
11
19
  }) => void;
@@ -25,7 +33,7 @@ export declare function useFrames(win: Ref<LayoutWindow>, handler: IActionHandle
25
33
  x: number;
26
34
  y: number;
27
35
  } | undefined>;
28
- isMoving: Ref<false | "edge" | "frame", false | "edge" | "frame">;
36
+ isMoving: Ref<false | "edge" | "frame" | "other", false | "edge" | "frame" | "other">;
29
37
  movingEdges: Ref<{
30
38
  startX: number;
31
39
  startY: number;
@@ -750,7 +758,7 @@ export declare function useFrames(win: Ref<LayoutWindow>, handler: IActionHandle
750
758
  y: number;
751
759
  } | undefined;
752
760
  moveDistance: number;
753
- isMoving: false | "edge" | "frame";
761
+ isMoving: false | "edge" | "frame" | "other";
754
762
  showMoving: boolean;
755
763
  movingFrameId: string | undefined;
756
764
  movingEdges: {
@@ -129,7 +129,7 @@ export function useFrames(win, handler) {
129
129
  showMoving.value = true;
130
130
  if (type === "frame") {
131
131
  movingFrameId.value = data.frameId;
132
- } else {
132
+ } else if (type === "edge") {
133
133
  const { edge, intersection } = data;
134
134
  movingIntersection.value = intersection;
135
135
  movingEdges.value = edge ? [edge] : [
@@ -1,4 +1,5 @@
1
1
  import type { EnumLike } from "@alanscodelog/utils";
2
+ import type { Flatten, OrToAnd } from "@alanscodelog/utils/types";
2
3
  import { z } from "zod";
3
4
  import { KnownError } from "../utils/KnownError.js";
4
5
  export declare const zUuid: z.ZodUUID;
@@ -1843,6 +1844,12 @@ export type LayoutChange<TInfo = never> = {
1843
1844
  window?: Partial<LayoutWindow>;
1844
1845
  info?: TInfo;
1845
1846
  };
1847
+ export type ExtendedMoveTypes = Flatten<OrToAnd<keyof Register extends `LayoutMove${infer T}` ? Register extends Record<`LayoutMove${T}`, infer U> ? U extends {
1848
+ type: string;
1849
+ context: any;
1850
+ resolve: any;
1851
+ moveType: "edge" | "frame" | "other";
1852
+ } ? Record<U["type"], U> : never : never : never>>;
1846
1853
  export type MoveState = {
1847
1854
  /** The current directions in the corresponding orientations that the user is dragging in. */
1848
1855
  moveDirections: Record<Orientation, Direction | undefined>;
@@ -1850,8 +1857,12 @@ export type MoveState = {
1850
1857
  movePoint?: Point;
1851
1858
  /** Cumulative pixel distance the user has dragged from the initial click point. 0 on start, increases on each move. */
1852
1859
  moveDistance: number;
1853
- /** Whether the user is currently dragging and what type of drag. Is truthy string during all drag events. */
1854
- isMoving: boolean | "frame" | "edge";
1860
+ /**
1861
+ * Whether the user is currently moving and what type of move. Is truthy string during all move events. The actions decide what they need to set it to as "frame" and "edge" have custom behavior.
1862
+ *
1863
+ * Other is for actions that do things other than drag frames/edges which include built in behavior (e.g. frames get a frame dragging indicator at the cursor)
1864
+ */
1865
+ isMoving: boolean | "frame" | "edge" | "other";
1855
1866
  /** Whether to show the moved frames while dragging. */
1856
1867
  showMoving: boolean;
1857
1868
  /** The frame being dragged during a frame drag. Only set when isMoving is "frame". */
@@ -33,7 +33,7 @@ export interface UseFramesContext {
33
33
  cancel: () => void;
34
34
  moveDirections: Ref<Record<Orientation, Direction | undefined>>;
35
35
  movePoint: Ref<Point | undefined>;
36
- isMoving: Ref<false | "frame" | "edge">;
36
+ isMoving: Ref<false | "frame" | "edge" | "other">;
37
37
  movingEdges: Ref<Edge[]>;
38
38
  movingIntersection: Ref<IntersectionEntry | undefined>;
39
39
  visualEdges: Ref<Edge[]>;
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.4",
4
+ "version": "0.5.6",
5
5
  "main": "./dist/runtime/index.js",
6
6
  "type": "module",
7
7
  "sideEffects": false,
@@ -146,7 +146,7 @@ actionHandler.shapes = reactive([])
146
146
  actionHandler.textHints = reactive({ actions: [], errors: [] })
147
147
  const shapes = actionHandler.shapes
148
148
 
149
- const dragContext = useFrames(
149
+ const moveContext = useFrames(
150
150
  win,
151
151
  actionHandler
152
152
  )
@@ -158,9 +158,9 @@ const {
158
158
  state,
159
159
  movingFrameId,
160
160
  showMoving,
161
- } = dragContext
161
+ } = moveContext
162
162
 
163
- provide(moveContextInjectionKey, dragContext)
163
+ provide(moveContextInjectionKey, moveContext)
164
164
 
165
165
  function getWindowOffset() {
166
166
  const windowElRect = windowEl.value!.getBoundingClientRect()
@@ -209,6 +209,7 @@ defineExpose({
209
209
  win,
210
210
  getUpdateWindowSizeInfo,
211
211
  actionHandler: actionHandler as ActionHandler<any, any>,
212
+ moveContext
212
213
  })
213
214
  </script>
214
215
 
@@ -12,7 +12,23 @@ 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 { ActionResolve, Direction, Edge, EdgeMoveStartData, FrameId, FrameMoveStartData, IActionHandler, IntersectionEntry, LayoutFrame, LayoutWindow, MoveState, Orientation, Point } from "../types/index.js"
15
+ import type {
16
+ ActionResolve,
17
+ Direction,
18
+ Edge,
19
+ EdgeMoveStartData,
20
+ ExtendedMoveTypes,
21
+ FrameId,
22
+ FrameMoveStartData,
23
+ IActionHandler,
24
+ IntersectionEntry,
25
+ LayoutFrame,
26
+ LayoutWindow,
27
+ MoveState,
28
+ Orientation,
29
+ Point
30
+ } from "../types/index.js"
31
+
16
32
 
17
33
  export function useFrames(
18
34
  win: Ref<LayoutWindow>,
@@ -34,7 +50,7 @@ export function useFrames(
34
50
 
35
51
  const touchingFramesArrays = computed(() => touchingFrames.value.map(entry => Object.values(entry)))
36
52
 
37
- const isMoving = ref<false | "frame" | "edge">(false)
53
+ const isMoving = ref<false | "frame" | "edge" | "other">(false)
38
54
  const showMoving = ref(false)
39
55
  const movePoint = ref<Point | undefined>()
40
56
 
@@ -137,11 +153,18 @@ export function useFrames(
137
153
  handler.onMoveEnded()
138
154
  }
139
155
 
140
- function moveStart<T extends "edge" | "frame">(
156
+ function moveStart<
157
+ T extends "edge" | "frame" | "other",
158
+ TContextType extends keyof ExtendedMoveTypes,
159
+ TContext extends ExtendedMoveTypes[TContextType],
160
+ TContextReturn extends TContext extends { resolve: infer R } ? R : never,
161
+ TContextMoveType extends TContext extends { moveType: infer M } ? M : never,
162
+ TContextContext extends TContext extends { context: infer C } ? C : never
163
+ >(
141
164
  e: PointerEvent,
142
- type: T,
165
+ type: TContextMoveType extends never ? T : TContextMoveType,
143
166
  // someday this will work
144
- data: T extends "edge" ? EdgeMoveStartData : FrameMoveStartData,
167
+ data: T extends "edge" ? EdgeMoveStartData : T extends "frame" ? FrameMoveStartData : undefined,
145
168
  {
146
169
  moveEvent = "pointermove",
147
170
  endEvent = "pointerup",
@@ -149,9 +172,11 @@ export function useFrames(
149
172
  }: {
150
173
  moveEvent?: string
151
174
  endEvent?: string
152
- context?: Record<string, unknown>
175
+ context?: { type: TContextType } & TContextContext
153
176
  } = {}
154
- ): Promise<any> {
177
+ ): TContext extends never
178
+ ? Promise<void>
179
+ : Promise<TContextReturn> {
155
180
  // if already dragging, abort previous (resetState resolves the old promise)
156
181
  if (controller) {
157
182
  controller.abort()
@@ -174,12 +199,12 @@ export function useFrames(
174
199
  moveDirStore.update(point)
175
200
  eventContext.value = context
176
201
 
177
- isMoving.value = type
202
+ isMoving.value = type as any
178
203
  showMoving.value = true
179
204
 
180
205
  if (type === "frame") {
181
206
  movingFrameId.value = (data as FrameMoveStartData).frameId
182
- } else {
207
+ } else if (type === "edge") {
183
208
  const { edge, intersection } = data as EdgeMoveStartData
184
209
  movingIntersection.value = intersection
185
210
 
@@ -216,7 +241,7 @@ export function useFrames(
216
241
 
217
242
  const res = handler.onMoveChange("start", e, state.value, forceRecalculateEdges, cancel, resolve)
218
243
  showMoving.value = res.showMoving ?? true
219
- return promise
244
+ return promise as any
220
245
  }
221
246
 
222
247
  function onMove(e: PointerEvent): void {
@@ -1,5 +1,6 @@
1
1
  import type { EnumLike } from "@alanscodelog/utils"
2
2
  import { enumFromArray } from "@alanscodelog/utils/enumFromArray"
3
+ import type { Flatten, OrToAnd } from "@alanscodelog/utils/types"
3
4
  import { z } from "zod"
4
5
 
5
6
  import { KnownError } from "../utils/KnownError.js"
@@ -441,6 +442,22 @@ export type LayoutChange<TInfo = never> = {
441
442
  window?: Partial<LayoutWindow>
442
443
  info?: TInfo
443
444
  }
445
+
446
+
447
+ // #todo we also need to change how the normal types are extended to this pattern
448
+ export type ExtendedMoveTypes = Flatten<OrToAnd<keyof Register extends `LayoutMove${infer T}`
449
+ ? Register extends Record<`LayoutMove${T}`, infer U>
450
+ ? U extends {
451
+ type: string
452
+ context: any
453
+ resolve: any
454
+ moveType: "edge" | "frame" | "other"
455
+ }
456
+ ? Record<U["type"], U>
457
+ : never
458
+ : never
459
+ : never>>
460
+
444
461
  export type MoveState = {
445
462
  /** The current directions in the corresponding orientations that the user is dragging in. */
446
463
  moveDirections: Record<Orientation, Direction | undefined>
@@ -448,8 +465,12 @@ export type MoveState = {
448
465
  movePoint?: Point
449
466
  /** Cumulative pixel distance the user has dragged from the initial click point. 0 on start, increases on each move. */
450
467
  moveDistance: number
451
- /** Whether the user is currently dragging and what type of drag. Is truthy string during all drag events. */
452
- isMoving: boolean | "frame" | "edge"
468
+ /**
469
+ * Whether the user is currently moving and what type of move. Is truthy string during all move events. The actions decide what they need to set it to as "frame" and "edge" have custom behavior.
470
+ *
471
+ * Other is for actions that do things other than drag frames/edges which include built in behavior (e.g. frames get a frame dragging indicator at the cursor)
472
+ */
473
+ isMoving: boolean | "frame" | "edge" | "other"
453
474
  /** Whether to show the moved frames while dragging. */
454
475
  showMoving: boolean
455
476
  /** The frame being dragged during a frame drag. Only set when isMoving is "frame". */
@@ -25,7 +25,7 @@ export interface UseFramesContext {
25
25
  cancel: () => void
26
26
  moveDirections: Ref<Record<Orientation, Direction | undefined>>
27
27
  movePoint: Ref<Point | undefined>
28
- isMoving: Ref<false | "frame" | "edge">
28
+ isMoving: Ref<false | "frame" | "edge" | "other">
29
29
  movingEdges: Ref<Edge[]>
30
30
  movingIntersection: Ref<IntersectionEntry | undefined>
31
31
  visualEdges: Ref<Edge[]>
@@ -41,3 +41,4 @@ export interface UseFramesContext {
41
41
  }
42
42
 
43
43
  export const moveContextInjectionKey = Symbol.for("@witchcraft/layout:moveContext") as InjectionKey<UseFramesContext>
44
+