@pixerate/editor 0.142.1 → 0.143.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.
- package/dist/agent/index.cjs +74 -34
- package/dist/agent/index.js +52 -12
- package/dist/agent/planner.d.cts +7 -2
- package/dist/agent/planner.d.ts +7 -2
- package/dist/canvas/index.cjs +103 -101
- package/dist/canvas/index.js +3 -1
- package/dist/canvas/layout.d.cts +15 -2
- package/dist/canvas/layout.d.ts +15 -2
- package/dist/{chunk-UBRYHNRU.cjs → chunk-EL4PSKFT.cjs} +46 -4
- package/dist/{chunk-DW4CV5H4.js → chunk-U4VE4UI2.js} +45 -3
- package/package.json +1 -1
package/dist/canvas/index.js
CHANGED
|
@@ -88,12 +88,13 @@ import {
|
|
|
88
88
|
matchSize,
|
|
89
89
|
overlaps,
|
|
90
90
|
placeBeside,
|
|
91
|
+
placeInView,
|
|
91
92
|
readStyleSize,
|
|
92
93
|
reorderNodes,
|
|
93
94
|
toggleLockNodes,
|
|
94
95
|
unlockNodes,
|
|
95
96
|
withStyleSize
|
|
96
|
-
} from "../chunk-
|
|
97
|
+
} from "../chunk-U4VE4UI2.js";
|
|
97
98
|
import {
|
|
98
99
|
DEFAULT_ARRANGE_SHORTCUTS,
|
|
99
100
|
matchArrangeShortcut
|
|
@@ -12057,6 +12058,7 @@ export {
|
|
|
12057
12058
|
pathfinder,
|
|
12058
12059
|
pieScene,
|
|
12059
12060
|
placeBeside,
|
|
12061
|
+
placeInView,
|
|
12060
12062
|
planarSplit,
|
|
12061
12063
|
playCanvasSceneTransition,
|
|
12062
12064
|
playWebAnimations,
|
package/dist/canvas/layout.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CanvasEdge, CanvasLayoutOptions, CanvasNode, IncrementalLayoutOptions, PlaceBesideOptions, Rect, Side, XYPosition } from
|
|
1
|
+
import type { CanvasEdge, CanvasLayoutOptions, CanvasNode, IncrementalLayoutOptions, PlaceBesideOptions, Rect, Side, XYPosition } from "./types.cjs";
|
|
2
2
|
export declare const DEFAULT_NODE_WIDTH = 200;
|
|
3
3
|
export declare const DEFAULT_NODE_HEIGHT = 60;
|
|
4
4
|
export declare const DEFAULT_PLACEMENT_GAP = 48;
|
|
@@ -42,7 +42,7 @@ export declare function overlaps(a: Rect, b: Rect, pad?: number): boolean;
|
|
|
42
42
|
/**
|
|
43
43
|
* Maps directed layout flow to its natural forward growth side.
|
|
44
44
|
*/
|
|
45
|
-
export declare function flowSide(direction?:
|
|
45
|
+
export declare function flowSide(direction?: "LR" | "TB" | "RL" | "BT"): Side;
|
|
46
46
|
/**
|
|
47
47
|
* Incremental layout blending:
|
|
48
48
|
* Keeps established/manual node positions intact. Runs Dagre on the entire graph,
|
|
@@ -58,3 +58,16 @@ export declare function placeBeside(rects: Record<string, Rect>, size: {
|
|
|
58
58
|
width: number;
|
|
59
59
|
height: number;
|
|
60
60
|
}, side: Side, nearNodeId?: string, options?: PlaceBesideOptions): XYPosition;
|
|
61
|
+
/**
|
|
62
|
+
* Where a node of `size` goes when nothing anchors it: centred in `view` (the visible part of
|
|
63
|
+
* the canvas, in flow coordinates) when that is free, else the nearest free spot in rings
|
|
64
|
+
* around the centre, so new work appears where the user is looking and never on top of
|
|
65
|
+
* `rects`.
|
|
66
|
+
*/
|
|
67
|
+
export declare function placeInView(rects: Record<string, Rect>, size: {
|
|
68
|
+
width: number;
|
|
69
|
+
height: number;
|
|
70
|
+
}, view: Rect, options?: {
|
|
71
|
+
gap?: number;
|
|
72
|
+
maxRings?: number;
|
|
73
|
+
}): XYPosition;
|
package/dist/canvas/layout.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CanvasEdge, CanvasLayoutOptions, CanvasNode, IncrementalLayoutOptions, PlaceBesideOptions, Rect, Side, XYPosition } from
|
|
1
|
+
import type { CanvasEdge, CanvasLayoutOptions, CanvasNode, IncrementalLayoutOptions, PlaceBesideOptions, Rect, Side, XYPosition } from "./types.js";
|
|
2
2
|
export declare const DEFAULT_NODE_WIDTH = 200;
|
|
3
3
|
export declare const DEFAULT_NODE_HEIGHT = 60;
|
|
4
4
|
export declare const DEFAULT_PLACEMENT_GAP = 48;
|
|
@@ -42,7 +42,7 @@ export declare function overlaps(a: Rect, b: Rect, pad?: number): boolean;
|
|
|
42
42
|
/**
|
|
43
43
|
* Maps directed layout flow to its natural forward growth side.
|
|
44
44
|
*/
|
|
45
|
-
export declare function flowSide(direction?:
|
|
45
|
+
export declare function flowSide(direction?: "LR" | "TB" | "RL" | "BT"): Side;
|
|
46
46
|
/**
|
|
47
47
|
* Incremental layout blending:
|
|
48
48
|
* Keeps established/manual node positions intact. Runs Dagre on the entire graph,
|
|
@@ -58,3 +58,16 @@ export declare function placeBeside(rects: Record<string, Rect>, size: {
|
|
|
58
58
|
width: number;
|
|
59
59
|
height: number;
|
|
60
60
|
}, side: Side, nearNodeId?: string, options?: PlaceBesideOptions): XYPosition;
|
|
61
|
+
/**
|
|
62
|
+
* Where a node of `size` goes when nothing anchors it: centred in `view` (the visible part of
|
|
63
|
+
* the canvas, in flow coordinates) when that is free, else the nearest free spot in rings
|
|
64
|
+
* around the centre, so new work appears where the user is looking and never on top of
|
|
65
|
+
* `rects`.
|
|
66
|
+
*/
|
|
67
|
+
export declare function placeInView(rects: Record<string, Rect>, size: {
|
|
68
|
+
width: number;
|
|
69
|
+
height: number;
|
|
70
|
+
}, view: Rect, options?: {
|
|
71
|
+
gap?: number;
|
|
72
|
+
maxRings?: number;
|
|
73
|
+
}): XYPosition;
|
|
@@ -4,8 +4,14 @@ var DEFAULT_NODE_WIDTH = 200;
|
|
|
4
4
|
var DEFAULT_NODE_HEIGHT = 60;
|
|
5
5
|
var DEFAULT_PLACEMENT_GAP = 48;
|
|
6
6
|
function getCenteredNodePosition(width = 0, height = 0, screenToFlowPosition, screenDimensions) {
|
|
7
|
-
const rect = _nullishCoalesce(screenDimensions, () => ( (typeof document !== "undefined" ? {
|
|
8
|
-
|
|
7
|
+
const rect = _nullishCoalesce(screenDimensions, () => ( (typeof document !== "undefined" ? {
|
|
8
|
+
width: document.documentElement.clientWidth,
|
|
9
|
+
height: document.documentElement.clientHeight
|
|
10
|
+
} : { width: 1920, height: 1080 })));
|
|
11
|
+
const flowPos = screenToFlowPosition({
|
|
12
|
+
x: rect.width / 2,
|
|
13
|
+
y: rect.height / 2
|
|
14
|
+
});
|
|
9
15
|
return {
|
|
10
16
|
x: flowPos.x - width / 2,
|
|
11
17
|
y: flowPos.y - height / 2
|
|
@@ -73,7 +79,10 @@ function getLayoutedNodes(nodes, edges, getNodesBounds, options = {}) {
|
|
|
73
79
|
function estimateNodeSize(node, defaultWidth = DEFAULT_NODE_WIDTH, defaultHeight = DEFAULT_NODE_HEIGHT) {
|
|
74
80
|
const label = String(_nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_optionalChain([node, 'access', _10 => _10.data, 'optionalAccess', _11 => _11.label]), () => ( _optionalChain([node, 'access', _12 => _12.data, 'optionalAccess', _13 => _13.title]))), () => ( node.id)), () => ( "")));
|
|
75
81
|
const lines = label.split(/\n|<br\s*\/?>/);
|
|
76
|
-
const longest = Math.max(
|
|
82
|
+
const longest = Math.max(
|
|
83
|
+
...lines.map((l) => l.replace(/<[^>]+>/g, "").length),
|
|
84
|
+
1
|
|
85
|
+
);
|
|
77
86
|
const width = Math.min(480, Math.max(defaultWidth, longest * 8 + 48));
|
|
78
87
|
const height = Math.max(defaultHeight, lines.length * 20 + 24);
|
|
79
88
|
return { width, height };
|
|
@@ -203,6 +212,38 @@ function placeBeside(rects, size, side, nearNodeId, options = {}) {
|
|
|
203
212
|
y: Math.round(baseY)
|
|
204
213
|
};
|
|
205
214
|
}
|
|
215
|
+
function placeInView(rects, size, view, options = {}) {
|
|
216
|
+
const gap = _nullishCoalesce(options.gap, () => ( DEFAULT_PLACEMENT_GAP));
|
|
217
|
+
const maxRings = _nullishCoalesce(options.maxRings, () => ( 24));
|
|
218
|
+
const obstacles = Object.values(rects);
|
|
219
|
+
const start = {
|
|
220
|
+
x: view.x + view.width / 2 - size.width / 2,
|
|
221
|
+
y: view.y + view.height / 2 - size.height / 2
|
|
222
|
+
};
|
|
223
|
+
const free = (p) => !obstacles.some(
|
|
224
|
+
(o) => overlaps({ ...p, width: size.width, height: size.height }, o, gap / 2)
|
|
225
|
+
);
|
|
226
|
+
if (free(start)) return { x: Math.round(start.x), y: Math.round(start.y) };
|
|
227
|
+
const stepX = size.width + gap;
|
|
228
|
+
const stepY = size.height + gap;
|
|
229
|
+
for (let ring = 1; ring <= maxRings; ring++) {
|
|
230
|
+
const candidates = [];
|
|
231
|
+
for (let i = -ring; i <= ring; i++) {
|
|
232
|
+
candidates.push(
|
|
233
|
+
{ x: start.x + ring * stepX, y: start.y + i * stepY },
|
|
234
|
+
{ x: start.x - ring * stepX, y: start.y + i * stepY },
|
|
235
|
+
{ x: start.x + i * stepX, y: start.y + ring * stepY },
|
|
236
|
+
{ x: start.x + i * stepX, y: start.y - ring * stepY }
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
candidates.sort(
|
|
240
|
+
(a, b) => Math.hypot(a.x - start.x, a.y - start.y) - Math.hypot(b.x - start.x, b.y - start.y)
|
|
241
|
+
);
|
|
242
|
+
const spot = candidates.find(free);
|
|
243
|
+
if (spot) return { x: Math.round(spot.x), y: Math.round(spot.y) };
|
|
244
|
+
}
|
|
245
|
+
return { x: Math.round(start.x), y: Math.round(start.y) };
|
|
246
|
+
}
|
|
206
247
|
|
|
207
248
|
// src/canvas/arrange.ts
|
|
208
249
|
var LOCKED_DATA_KEY = "locked";
|
|
@@ -588,4 +629,5 @@ function invertNodeUpdates(nodes, updates) {
|
|
|
588
629
|
|
|
589
630
|
|
|
590
631
|
|
|
591
|
-
|
|
632
|
+
|
|
633
|
+
exports.DEFAULT_NODE_WIDTH = DEFAULT_NODE_WIDTH; exports.DEFAULT_NODE_HEIGHT = DEFAULT_NODE_HEIGHT; exports.DEFAULT_PLACEMENT_GAP = DEFAULT_PLACEMENT_GAP; exports.getCenteredNodePosition = getCenteredNodePosition; exports.centerNodes = centerNodes; exports.getLayoutedNodes = getLayoutedNodes; exports.estimateNodeSize = estimateNodeSize; exports.boundsOf = boundsOf; exports.centre = centre; exports.overlaps = overlaps; exports.flowSide = flowSide; exports.ensureLayout = ensureLayout; exports.placeBeside = placeBeside; exports.placeInView = placeInView; exports.LOCKED_DATA_KEY = LOCKED_DATA_KEY; exports.LOCKED_PREVIOUS_FLAGS_KEY = LOCKED_PREVIOUS_FLAGS_KEY; exports.readStyleSize = readStyleSize; exports.withStyleSize = withStyleSize; exports.getNodeSize = getNodeSize; exports.getAbsolutePosition = getAbsolutePosition; exports.createNodeLookup = createNodeLookup; exports.getNodeRect = getNodeRect; exports.isLocked = isLocked; exports.lockNodes = lockNodes; exports.unlockNodes = unlockNodes; exports.toggleLockNodes = toggleLockNodes; exports.alignNodes = alignNodes; exports.distributeNodes = distributeNodes; exports.matchSize = matchSize; exports.reorderNodes = reorderNodes; exports.applyNodeUpdates = applyNodeUpdates; exports.invertNodeUpdates = invertNodeUpdates;
|
|
@@ -4,8 +4,14 @@ var DEFAULT_NODE_WIDTH = 200;
|
|
|
4
4
|
var DEFAULT_NODE_HEIGHT = 60;
|
|
5
5
|
var DEFAULT_PLACEMENT_GAP = 48;
|
|
6
6
|
function getCenteredNodePosition(width = 0, height = 0, screenToFlowPosition, screenDimensions) {
|
|
7
|
-
const rect = screenDimensions ?? (typeof document !== "undefined" ? {
|
|
8
|
-
|
|
7
|
+
const rect = screenDimensions ?? (typeof document !== "undefined" ? {
|
|
8
|
+
width: document.documentElement.clientWidth,
|
|
9
|
+
height: document.documentElement.clientHeight
|
|
10
|
+
} : { width: 1920, height: 1080 });
|
|
11
|
+
const flowPos = screenToFlowPosition({
|
|
12
|
+
x: rect.width / 2,
|
|
13
|
+
y: rect.height / 2
|
|
14
|
+
});
|
|
9
15
|
return {
|
|
10
16
|
x: flowPos.x - width / 2,
|
|
11
17
|
y: flowPos.y - height / 2
|
|
@@ -73,7 +79,10 @@ function getLayoutedNodes(nodes, edges, getNodesBounds, options = {}) {
|
|
|
73
79
|
function estimateNodeSize(node, defaultWidth = DEFAULT_NODE_WIDTH, defaultHeight = DEFAULT_NODE_HEIGHT) {
|
|
74
80
|
const label = String(node.data?.label ?? node.data?.title ?? node.id ?? "");
|
|
75
81
|
const lines = label.split(/\n|<br\s*\/?>/);
|
|
76
|
-
const longest = Math.max(
|
|
82
|
+
const longest = Math.max(
|
|
83
|
+
...lines.map((l) => l.replace(/<[^>]+>/g, "").length),
|
|
84
|
+
1
|
|
85
|
+
);
|
|
77
86
|
const width = Math.min(480, Math.max(defaultWidth, longest * 8 + 48));
|
|
78
87
|
const height = Math.max(defaultHeight, lines.length * 20 + 24);
|
|
79
88
|
return { width, height };
|
|
@@ -203,6 +212,38 @@ function placeBeside(rects, size, side, nearNodeId, options = {}) {
|
|
|
203
212
|
y: Math.round(baseY)
|
|
204
213
|
};
|
|
205
214
|
}
|
|
215
|
+
function placeInView(rects, size, view, options = {}) {
|
|
216
|
+
const gap = options.gap ?? DEFAULT_PLACEMENT_GAP;
|
|
217
|
+
const maxRings = options.maxRings ?? 24;
|
|
218
|
+
const obstacles = Object.values(rects);
|
|
219
|
+
const start = {
|
|
220
|
+
x: view.x + view.width / 2 - size.width / 2,
|
|
221
|
+
y: view.y + view.height / 2 - size.height / 2
|
|
222
|
+
};
|
|
223
|
+
const free = (p) => !obstacles.some(
|
|
224
|
+
(o) => overlaps({ ...p, width: size.width, height: size.height }, o, gap / 2)
|
|
225
|
+
);
|
|
226
|
+
if (free(start)) return { x: Math.round(start.x), y: Math.round(start.y) };
|
|
227
|
+
const stepX = size.width + gap;
|
|
228
|
+
const stepY = size.height + gap;
|
|
229
|
+
for (let ring = 1; ring <= maxRings; ring++) {
|
|
230
|
+
const candidates = [];
|
|
231
|
+
for (let i = -ring; i <= ring; i++) {
|
|
232
|
+
candidates.push(
|
|
233
|
+
{ x: start.x + ring * stepX, y: start.y + i * stepY },
|
|
234
|
+
{ x: start.x - ring * stepX, y: start.y + i * stepY },
|
|
235
|
+
{ x: start.x + i * stepX, y: start.y + ring * stepY },
|
|
236
|
+
{ x: start.x + i * stepX, y: start.y - ring * stepY }
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
candidates.sort(
|
|
240
|
+
(a, b) => Math.hypot(a.x - start.x, a.y - start.y) - Math.hypot(b.x - start.x, b.y - start.y)
|
|
241
|
+
);
|
|
242
|
+
const spot = candidates.find(free);
|
|
243
|
+
if (spot) return { x: Math.round(spot.x), y: Math.round(spot.y) };
|
|
244
|
+
}
|
|
245
|
+
return { x: Math.round(start.x), y: Math.round(start.y) };
|
|
246
|
+
}
|
|
206
247
|
|
|
207
248
|
// src/canvas/arrange.ts
|
|
208
249
|
var LOCKED_DATA_KEY = "locked";
|
|
@@ -570,6 +611,7 @@ export {
|
|
|
570
611
|
flowSide,
|
|
571
612
|
ensureLayout,
|
|
572
613
|
placeBeside,
|
|
614
|
+
placeInView,
|
|
573
615
|
LOCKED_DATA_KEY,
|
|
574
616
|
LOCKED_PREVIOUS_FLAGS_KEY,
|
|
575
617
|
readStyleSize,
|