@witchcraft/layout 0.4.0 → 0.4.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.4.0",
4
+ "version": "0.4.2",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "unknown"
@@ -2,14 +2,14 @@ declare var __VLS_1: {
2
2
  css: any;
3
3
  edge: any;
4
4
  onPointerDown: any;
5
- }, __VLS_10: {
5
+ }, __VLS_6: {
6
6
  css: any;
7
7
  edge: any;
8
8
  };
9
9
  type __VLS_Slots = {} & {
10
10
  handle?: (props: typeof __VLS_1) => any;
11
11
  } & {
12
- indicator?: (props: typeof __VLS_10) => any;
12
+ indicator?: (props: typeof __VLS_6) => any;
13
13
  };
14
14
  declare const __VLS_component: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
15
15
  declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
@@ -11,7 +11,7 @@
11
11
  <LayoutDragEdgeHandle
12
12
  :css="css.handle"
13
13
  :edge="visualEdges[i]"
14
- @pointerdown="dragCtx.dragStart"
14
+ :on-pointer-down="dragCtx.dragStart"
15
15
  />
16
16
  </slot>
17
17
  <slot name="indicator" v-bind="{
@@ -2,14 +2,14 @@ declare var __VLS_1: {
2
2
  css: any;
3
3
  edge: any;
4
4
  onPointerDown: any;
5
- }, __VLS_10: {
5
+ }, __VLS_6: {
6
6
  css: any;
7
7
  edge: any;
8
8
  };
9
9
  type __VLS_Slots = {} & {
10
10
  handle?: (props: typeof __VLS_1) => any;
11
11
  } & {
12
- indicator?: (props: typeof __VLS_10) => any;
12
+ indicator?: (props: typeof __VLS_6) => any;
13
13
  };
14
14
  declare const __VLS_component: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
15
15
  declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
@@ -11,6 +11,7 @@
11
11
  <LayoutIntersectionHandle
12
12
  :css="css.handle"
13
13
  :intersection="draggableIntersections[i]"
14
+ :on-pointer-down="dragCtx.dragStart"
14
15
  />
15
16
  </slot>
16
17
  <slot name="indicator" v-bind="{ css: css.visible, intersection: draggableIntersections[i] }">
@@ -23,7 +23,9 @@ export declare class CloseAction implements IDragAction {
23
23
  errors: string[];
24
24
  };
25
25
  closeHints: {
26
- actions: string[];
26
+ actions: string[] | ((state: {
27
+ force: boolean;
28
+ }) => string[]);
27
29
  transformError: (e: KnownError) => string;
28
30
  };
29
31
  handleEvent: (e: PointerEvent | KeyboardEvent, state: DragState) => boolean | "force";
@@ -73,7 +73,7 @@ export class CloseAction {
73
73
  this.textHints.actions = [];
74
74
  this.textHints.errors = [this.closeHints.transformError(result)];
75
75
  } else {
76
- this.textHints.actions = this.closeHints.actions;
76
+ this.textHints.actions = typeof this.closeHints.actions === "function" ? this.closeHints.actions({ force: this.state.force }) : this.closeHints.actions;
77
77
  this.textHints.errors = [];
78
78
  }
79
79
  }
@@ -13,11 +13,13 @@ export declare class FrameDragAction implements IDragAction {
13
13
  handleEvent: (e: PointerEvent | KeyboardEvent, state: DragState) => boolean;
14
14
  dragHints: {
15
15
  actions: {
16
- split: string;
17
- swap: string;
18
- rearrange: string;
19
- dock: string;
20
- };
16
+ split?: string;
17
+ swap?: string;
18
+ rearrange?: string;
19
+ dock?: string;
20
+ } | ((state: {
21
+ type: "split" | "swap" | "rearrange" | "dock";
22
+ }) => string[]);
21
23
  transformError: (e: KnownError) => string;
22
24
  };
23
25
  modifyDecos: (shapes: FrameDragDeco[]) => void;
@@ -46,8 +46,7 @@ export class FrameDragAction {
46
46
  this.textHints.actions = [];
47
47
  this.textHints.errors = [this.dragHints.transformError(result)];
48
48
  } else {
49
- const text = this.dragHints.actions[result.info];
50
- this.textHints.actions = [text];
49
+ this.textHints.actions = typeof this.dragHints.actions === "function" ? this.dragHints.actions({ type: result.info }) : this.dragHints.actions[result.info] !== void 0 ? [this.dragHints.actions[result.info]] : [];
51
50
  this.textHints.errors = [];
52
51
  }
53
52
  }
@@ -2,6 +2,7 @@ import { getFrameSplitInfo } from "../layout/getFrameSplitInfo.js";
2
2
  import type { ActionDragChangeResult, DragState, IDragAction, 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
+ export type DragChangeType = "start" | "move" | "end";
5
6
  export declare class SplitAction implements IDragAction {
6
7
  name: "split";
7
8
  state: {
@@ -21,7 +22,7 @@ export declare class SplitAction implements IDragAction {
21
22
  errors: string[];
22
23
  };
23
24
  splitHints: {
24
- action: string;
25
+ actions: string[] | ((type: DragChangeType) => string[]);
25
26
  transformError: (e: KnownError) => string;
26
27
  };
27
28
  handleEvent: (e: PointerEvent | KeyboardEvent, state: DragState) => boolean;
@@ -11,7 +11,7 @@ export class SplitAction {
11
11
  debug = false;
12
12
  textHints = { actions: [], errors: [] };
13
13
  splitHints = {
14
- action: "Hold Alt to Split",
14
+ actions: ["Hold Alt to Split"],
15
15
  transformError: (e) => e.message
16
16
  };
17
17
  handleEvent = (e, state) => e.altKey || state.isDraggingFromWindowEdge;
@@ -24,7 +24,7 @@ export class SplitAction {
24
24
  this.hooks = hooks;
25
25
  this.reset();
26
26
  if (config?.debug) this.debug = true;
27
- if (config?.splitHints?.action) this.splitHints.action = config.splitHints.action;
27
+ if (config?.splitHints?.actions) this.splitHints.actions = config.splitHints.actions;
28
28
  if (config?.splitHints?.transformError) this.splitHints.transformError = config.splitHints.transformError;
29
29
  }
30
30
  reset() {
@@ -78,7 +78,7 @@ export class SplitAction {
78
78
  this.textHints.actions = [];
79
79
  this.textHints.errors = [this.splitHints.transformError(result)];
80
80
  } else {
81
- this.textHints.actions = [this.splitHints.action];
81
+ this.textHints.actions = typeof this.splitHints.actions === "function" ? this.splitHints.actions("move") : this.splitHints.actions;
82
82
  this.textHints.errors = [];
83
83
  }
84
84
  }
@@ -217,6 +217,6 @@ export function createDebugLabeler({
217
217
  const size = showSize ? ` ${f.width}x${f.height}` : "";
218
218
  const pos = showPos ? ` ${f.x},${f.y}` : "";
219
219
  const pxSize = showPxSize ? ` ${widthPx}x${heightPx}px` : "";
220
- return `${isCollapsed}${isDocked}${size}${pos}${pxSize}`;
220
+ return `${isCollapsed}${isDocked}${pos}${size}${pxSize}`;
221
221
  };
222
222
  }
@@ -34,6 +34,7 @@ export function getFrameUndockInfo(win, frameId) {
34
34
  const adjustmentKey = frameSide === "left" ? "x" : frameSide === "top" ? "y" : frameSide === "right" ? "width" : "height";
35
35
  const secondaryAdjustmentKey = frameSide === "left" ? "width" : frameSide === "top" ? "height" : frameSide === "right" ? "x" : "y";
36
36
  const adjustmentValue = frameSide === "left" || frameSide === "top" ? 0 : maxInt;
37
+ const perpendicularSizeKey = isVertical ? "width" : "height";
37
38
  const otherChanges = otherDockedFramesToResize.map((other) => {
38
39
  if (other.docked === shrinkStartKey) {
39
40
  frameClone[posKey] += other[sizeKey];
@@ -41,10 +42,12 @@ export function getFrameUndockInfo(win, frameId) {
41
42
  } else if (other.docked === shrinkEndKey) {
42
43
  frameClone[sizeKey] -= other[sizeKey];
43
44
  }
45
+ const otherIsVertical = other.docked === "left" || other.docked === "right";
46
+ const isSameAxis = isVertical === otherIsVertical;
44
47
  return {
45
48
  ...other,
46
49
  [adjustmentKey]: adjustmentValue,
47
- [secondaryAdjustmentKey]: other[secondaryAdjustmentKey] + other[adjustmentKey]
50
+ ...isSameAxis ? { [secondaryAdjustmentKey]: other[secondaryAdjustmentKey] + other[adjustmentKey] } : { [perpendicularSizeKey]: maxInt }
48
51
  };
49
52
  });
50
53
  return { modified: [frameClone, ...otherChanges], created: [], deleted: [] };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@witchcraft/layout",
3
3
  "description": "Headless layout manager.",
4
- "version": "0.4.0",
4
+ "version": "0.4.2",
5
5
  "main": "./dist/runtime/index.js",
6
6
  "type": "module",
7
7
  "sideEffects": false,
@@ -11,7 +11,7 @@
11
11
  <LayoutDragEdgeHandle
12
12
  :css="css.handle"
13
13
  :edge="visualEdges[i]"
14
- @pointerdown="dragCtx.dragStart"
14
+ :on-pointer-down="dragCtx.dragStart"
15
15
  />
16
16
  </slot>
17
17
  <slot name="indicator" v-bind="{
@@ -11,6 +11,7 @@
11
11
  <LayoutIntersectionHandle
12
12
  :css="css.handle"
13
13
  :intersection="draggableIntersections[i]"
14
+ :on-pointer-down="dragCtx.dragStart"
14
15
  />
15
16
  </slot>
16
17
  <slot name="indicator" v-bind="{ css: css.visible, intersection: draggableIntersections[i] }">
@@ -32,7 +32,7 @@ export class CloseAction implements IDragAction {
32
32
  textHints: { actions: string[], errors: string[] } = { actions: [], errors: [] }
33
33
 
34
34
  closeHints: {
35
- actions: string[]
35
+ actions: string[] | ((state: { force: boolean }) => string[])
36
36
  transformError: (e: KnownError) => string
37
37
  } = {
38
38
  actions: ["Hold Shift to Close", "Hold Ctrl+Shift to Force Close"],
@@ -116,7 +116,9 @@ export class CloseAction implements IDragAction {
116
116
  this.textHints.actions = []
117
117
  this.textHints.errors = [this.closeHints.transformError(result)]
118
118
  } else {
119
- this.textHints.actions = this.closeHints.actions
119
+ this.textHints.actions = typeof this.closeHints.actions === "function"
120
+ ? this.closeHints.actions({ force: this.state.force })
121
+ : this.closeHints.actions
120
122
  this.textHints.errors = []
121
123
  }
122
124
  }
@@ -26,7 +26,7 @@ export class FrameDragAction implements IDragAction {
26
26
  = (_e: PointerEvent | KeyboardEvent, state: DragState) => state.isDragging === "frame"
27
27
 
28
28
  dragHints: {
29
- actions: { split: string, swap: string, rearrange: string, dock: string }
29
+ actions: { split?: string, swap?: string, rearrange?: string, dock?: string } | ((state: { type: "split" | "swap" | "rearrange" | "dock" }) => string[])
30
30
  transformError: (e: KnownError) => string
31
31
  } = {
32
32
  actions: {
@@ -76,8 +76,11 @@ export class FrameDragAction implements IDragAction {
76
76
  this.textHints.actions = []
77
77
  this.textHints.errors = [this.dragHints.transformError(result)]
78
78
  } else {
79
- const text = this.dragHints.actions[result.info]
80
- this.textHints.actions = [text]
79
+ this.textHints.actions = typeof this.dragHints.actions === "function"
80
+ ? this.dragHints.actions({ type: result.info })
81
+ : this.dragHints.actions[result.info] !== undefined
82
+ ? [this.dragHints.actions[result.info]!]
83
+ : []
81
84
  this.textHints.errors = []
82
85
  }
83
86
  }
@@ -12,6 +12,8 @@ export type SplitInfo = Exclude<ReturnType<typeof getFrameSplitInfo>, KnownError
12
12
 
13
13
  // note that we dont annotateEdges because is possible to forexample drag from a window edge to a frame that can be split, moving over a collapsed frame that was sharing the edge but can't be split
14
14
 
15
+ export type DragChangeType = "start" | "move" | "end"
16
+
15
17
  export class SplitAction implements IDragAction {
16
18
  name = "split" as const
17
19
 
@@ -30,10 +32,10 @@ export class SplitAction implements IDragAction {
30
32
  debug: boolean | string = false
31
33
  textHints: { actions: string[], errors: string[] } = { actions: [], errors: [] }
32
34
  splitHints: {
33
- action: string
35
+ actions: string[] | ((type: DragChangeType) => string[])
34
36
  transformError: (e: KnownError) => string
35
37
  } = {
36
- action: "Hold Alt to Split",
38
+ actions: ["Hold Alt to Split"],
37
39
  transformError: e => e.message
38
40
  }
39
41
 
@@ -63,7 +65,7 @@ export class SplitAction implements IDragAction {
63
65
  this.hooks = hooks
64
66
  this.reset()
65
67
  if (config?.debug) this.debug = true
66
- if (config?.splitHints?.action) this.splitHints.action = config.splitHints.action
68
+ if (config?.splitHints?.actions) this.splitHints.actions = config.splitHints.actions
67
69
  if (config?.splitHints?.transformError) this.splitHints.transformError = config.splitHints.transformError
68
70
  }
69
71
 
@@ -121,7 +123,10 @@ export class SplitAction implements IDragAction {
121
123
  this.textHints.actions = []
122
124
  this.textHints.errors = [this.splitHints.transformError(result)]
123
125
  } else {
124
- this.textHints.actions = [this.splitHints.action]
126
+ this.textHints.actions = typeof this.splitHints.actions === "function"
127
+ ? this.splitHints.actions("move")
128
+ : this.splitHints.actions
129
+
125
130
  this.textHints.errors = []
126
131
  }
127
132
  }
@@ -325,7 +325,7 @@ export function createDebugLabeler({
325
325
  const pos = showPos ? ` ${f.x},${f.y}` : ""
326
326
  const pxSize = showPxSize ? ` ${widthPx}x${heightPx}px` : ""
327
327
 
328
- return `${isCollapsed}${isDocked}${size}${pos}${pxSize}`
328
+ return `${isCollapsed}${isDocked}${pos}${size}${pxSize}`
329
329
  }
330
330
  }
331
331
 
@@ -78,6 +78,9 @@ export function getFrameUndockInfo(
78
78
  : "y"
79
79
 
80
80
  const adjustmentValue = frameSide === "left" || frameSide === "top" ? 0 : maxInt
81
+ // for perpendicular frames (e.g. top/bottom when undocking left/right),
82
+ // expand along the dimension perpendicular to the undock axis
83
+ const perpendicularSizeKey = isVertical ? "width" : "height" as const
81
84
  const otherChanges = otherDockedFramesToResize.map(other => {
82
85
  // shrink the ends of the undocking frame
83
86
  if (other.docked === shrinkStartKey) {
@@ -86,10 +89,13 @@ export function getFrameUndockInfo(
86
89
  } else if (other.docked === shrinkEndKey) {
87
90
  frameClone[sizeKey] -= other[sizeKey]
88
91
  }
92
+ // same-axis frames shift their position; perpendicular frames expand their dimension to fill the space
93
+ const otherIsVertical = other.docked === "left" || other.docked === "right"
94
+ const isSameAxis = isVertical === otherIsVertical
89
95
  return {
90
96
  ...other,
91
97
  [adjustmentKey]: adjustmentValue,
92
- [secondaryAdjustmentKey]: other[secondaryAdjustmentKey] + other[adjustmentKey]
98
+ ...(isSameAxis ? { [secondaryAdjustmentKey]: other[secondaryAdjustmentKey] + other[adjustmentKey] } : { [perpendicularSizeKey]: maxInt })
93
99
  }
94
100
  })
95
101