@luciole-sh/flow-graph 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/README.md +671 -2
- package/dist/Flow.d.ts +41 -0
- package/dist/Flow.d.ts.map +1 -0
- package/dist/Flow.js +489 -0
- package/dist/Flow.js.map +1 -0
- package/dist/components.d.ts +28 -0
- package/dist/components.d.ts.map +1 -0
- package/dist/components.js +100 -0
- package/dist/components.js.map +1 -0
- package/dist/frame.d.ts +68 -0
- package/dist/frame.d.ts.map +1 -0
- package/dist/frame.js +136 -0
- package/dist/frame.js.map +1 -0
- package/dist/geometry.d.ts +60 -0
- package/dist/geometry.d.ts.map +1 -0
- package/dist/geometry.js +205 -0
- package/dist/geometry.js.map +1 -0
- package/dist/hooks.d.ts +56 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +65 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/keymap.d.ts +11 -0
- package/dist/keymap.d.ts.map +1 -0
- package/dist/keymap.js +42 -0
- package/dist/keymap.js.map +1 -0
- package/dist/navigation.d.ts +32 -0
- package/dist/navigation.d.ts.map +1 -0
- package/dist/navigation.js +68 -0
- package/dist/navigation.js.map +1 -0
- package/dist/nodes.d.ts +18 -0
- package/dist/nodes.d.ts.map +1 -0
- package/dist/nodes.js +46 -0
- package/dist/nodes.js.map +1 -0
- package/dist/raster.d.ts +112 -0
- package/dist/raster.d.ts.map +1 -0
- package/dist/raster.js +370 -0
- package/dist/raster.js.map +1 -0
- package/dist/store.d.ts +104 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +186 -0
- package/dist/store.js.map +1 -0
- package/dist/theme.d.ts +25 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.js +39 -0
- package/dist/theme.js.map +1 -0
- package/dist/types.d.ts +140 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/vendor/xyflow/LICENSE +21 -0
- package/dist/vendor/xyflow/bezier.d.ts +26 -0
- package/dist/vendor/xyflow/bezier.d.ts.map +1 -0
- package/dist/vendor/xyflow/bezier.js +47 -0
- package/dist/vendor/xyflow/bezier.js.map +1 -0
- package/dist/vendor/xyflow/changes.d.ts +9 -0
- package/dist/vendor/xyflow/changes.d.ts.map +1 -0
- package/dist/vendor/xyflow/changes.js +133 -0
- package/dist/vendor/xyflow/changes.js.map +1 -0
- package/dist/vendor/xyflow/smoothstep.d.ts +17 -0
- package/dist/vendor/xyflow/smoothstep.d.ts.map +1 -0
- package/dist/vendor/xyflow/smoothstep.js +166 -0
- package/dist/vendor/xyflow/smoothstep.js.map +1 -0
- package/package.json +61 -4
- package/src/Flow.tsx +684 -0
- package/src/components.tsx +180 -0
- package/src/frame.ts +203 -0
- package/src/geometry.ts +274 -0
- package/src/hooks.tsx +121 -0
- package/src/index.ts +21 -0
- package/src/keymap.tsx +45 -0
- package/src/navigation.ts +86 -0
- package/src/nodes.tsx +86 -0
- package/src/raster.ts +453 -0
- package/src/store.ts +240 -0
- package/src/theme.ts +61 -0
- package/src/types.ts +130 -0
- package/src/vendor/xyflow/LICENSE +21 -0
- package/src/vendor/xyflow/README.md +20 -0
- package/src/vendor/xyflow/bezier.ts +102 -0
- package/src/vendor/xyflow/changes.ts +177 -0
- package/src/vendor/xyflow/smoothstep.ts +219 -0
- package/tsconfig.json +22 -0
package/dist/store.js
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What one canvas knows beyond its props: the viewport, the canvas size, each node's
|
|
3
|
+
* measured size and declared handles, the background, a connection under way, and what
|
|
4
|
+
* the last frame placed where (for hit tests). Framework-free: `<Flow>` and the hooks
|
|
5
|
+
* read it with `useSyncExternalStore`.
|
|
6
|
+
*/
|
|
7
|
+
import { anchorsOf, detailFor, fitViewport, flowBounds, panToShow, placeNodes, stepZoom, toFlow, zoomAround, } from "./geometry.js";
|
|
8
|
+
const DEFAULT_VIEWPORT = { x: 2, y: 1, zoom: 1 };
|
|
9
|
+
export class FlowStore {
|
|
10
|
+
viewport;
|
|
11
|
+
size = { width: 0, height: 0 };
|
|
12
|
+
nodes = [];
|
|
13
|
+
edges = [];
|
|
14
|
+
measured = new Map();
|
|
15
|
+
/** The last size each node had at full detail: the view fits it at any zoom. */
|
|
16
|
+
full = new Map();
|
|
17
|
+
handles = new Map();
|
|
18
|
+
background = null;
|
|
19
|
+
connecting = null;
|
|
20
|
+
callbacks = {};
|
|
21
|
+
/** Fit the view once the canvas has a size. */
|
|
22
|
+
pendingFit;
|
|
23
|
+
version = 0;
|
|
24
|
+
listeners = new Set();
|
|
25
|
+
constructor(options = {}) {
|
|
26
|
+
this.viewport = options.viewport ?? DEFAULT_VIEWPORT;
|
|
27
|
+
this.pendingFit = options.fitView ?? false;
|
|
28
|
+
}
|
|
29
|
+
subscribe = (listener) => {
|
|
30
|
+
this.listeners.add(listener);
|
|
31
|
+
return () => this.listeners.delete(listener);
|
|
32
|
+
};
|
|
33
|
+
getVersion = () => this.version;
|
|
34
|
+
changed() {
|
|
35
|
+
this.version++;
|
|
36
|
+
for (const listener of this.listeners)
|
|
37
|
+
listener();
|
|
38
|
+
}
|
|
39
|
+
get detail() {
|
|
40
|
+
return detailFor(this.viewport.zoom);
|
|
41
|
+
}
|
|
42
|
+
/** The latest props: served to hooks and event handlers, which run after the commit. */
|
|
43
|
+
sync(props) {
|
|
44
|
+
this.callbacks = props.callbacks;
|
|
45
|
+
if (props.nodes === this.nodes && props.edges === this.edges)
|
|
46
|
+
return;
|
|
47
|
+
this.nodes = props.nodes;
|
|
48
|
+
this.edges = props.edges;
|
|
49
|
+
this.changed();
|
|
50
|
+
}
|
|
51
|
+
setViewport(viewport) {
|
|
52
|
+
const { x, y, zoom } = this.viewport;
|
|
53
|
+
if (viewport.x === x && viewport.y === y && viewport.zoom === zoom)
|
|
54
|
+
return;
|
|
55
|
+
this.viewport = { x: Math.round(viewport.x), y: Math.round(viewport.y), zoom: viewport.zoom };
|
|
56
|
+
this.callbacks.onViewportChange?.(this.viewport);
|
|
57
|
+
this.changed();
|
|
58
|
+
}
|
|
59
|
+
panBy(dx, dy) {
|
|
60
|
+
this.setViewport({ ...this.viewport, x: this.viewport.x + dx, y: this.viewport.y + dy });
|
|
61
|
+
}
|
|
62
|
+
/** One zoom level in or out, around `anchor` (the canvas center by default). */
|
|
63
|
+
zoom(direction, anchor) {
|
|
64
|
+
const zoom = stepZoom(this.viewport.zoom, direction);
|
|
65
|
+
if (zoom === this.viewport.zoom)
|
|
66
|
+
return;
|
|
67
|
+
const center = anchor ?? {
|
|
68
|
+
x: Math.floor(this.size.width / 2),
|
|
69
|
+
y: Math.floor(this.size.height / 2),
|
|
70
|
+
};
|
|
71
|
+
this.setViewport(zoomAround(this.viewport, zoom, center));
|
|
72
|
+
}
|
|
73
|
+
fitView() {
|
|
74
|
+
if (this.size.width === 0 || this.size.height === 0) {
|
|
75
|
+
this.pendingFit = true;
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
this.pendingFit = false;
|
|
79
|
+
this.setViewport(fitViewport(flowBounds(this.nodes, this.full), this.size));
|
|
80
|
+
}
|
|
81
|
+
/** Centers the view on a flow point, at `zoom` or the current one. */
|
|
82
|
+
setCenter(point, zoom = this.viewport.zoom) {
|
|
83
|
+
this.setViewport({
|
|
84
|
+
x: Math.round(this.size.width / 2 - point.x * zoom),
|
|
85
|
+
y: Math.round(this.size.height / 2 - point.y * zoom),
|
|
86
|
+
zoom,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
/** Pans just enough for node `id` to be seen whole. */
|
|
90
|
+
reveal(id) {
|
|
91
|
+
const placed = this.place().find((p) => p.node.id === id);
|
|
92
|
+
if (placed)
|
|
93
|
+
this.setViewport(panToShow(this.viewport, placed.rect, this.size));
|
|
94
|
+
}
|
|
95
|
+
setSize(size) {
|
|
96
|
+
if (size.width === this.size.width && size.height === this.size.height)
|
|
97
|
+
return;
|
|
98
|
+
this.size = size;
|
|
99
|
+
if (this.pendingFit)
|
|
100
|
+
this.fitView();
|
|
101
|
+
this.changed();
|
|
102
|
+
}
|
|
103
|
+
measure(id, size) {
|
|
104
|
+
const known = this.measured.get(id);
|
|
105
|
+
if (known &&
|
|
106
|
+
known.width === size.width &&
|
|
107
|
+
known.height === size.height &&
|
|
108
|
+
known.detail === size.detail)
|
|
109
|
+
return;
|
|
110
|
+
this.measured.set(id, size);
|
|
111
|
+
if (size.detail === "full")
|
|
112
|
+
this.full.set(id, size);
|
|
113
|
+
this.changed();
|
|
114
|
+
}
|
|
115
|
+
addHandle(nodeId, key, spec) {
|
|
116
|
+
const handles = this.handles.get(nodeId) ?? new Map();
|
|
117
|
+
handles.set(key, spec);
|
|
118
|
+
this.handles.set(nodeId, handles);
|
|
119
|
+
this.changed();
|
|
120
|
+
}
|
|
121
|
+
removeHandle(nodeId, key) {
|
|
122
|
+
const handles = this.handles.get(nodeId);
|
|
123
|
+
if (!handles?.delete(key))
|
|
124
|
+
return;
|
|
125
|
+
if (handles.size === 0)
|
|
126
|
+
this.handles.delete(nodeId);
|
|
127
|
+
this.changed();
|
|
128
|
+
}
|
|
129
|
+
setBackground(background) {
|
|
130
|
+
this.background = background;
|
|
131
|
+
this.changed();
|
|
132
|
+
}
|
|
133
|
+
setConnecting(connecting) {
|
|
134
|
+
this.connecting = connecting;
|
|
135
|
+
this.changed();
|
|
136
|
+
}
|
|
137
|
+
/** The nodes on the canvas, in drawing order. */
|
|
138
|
+
place() {
|
|
139
|
+
return placeNodes(this.nodes, this.viewport, this.measured);
|
|
140
|
+
}
|
|
141
|
+
anchors(placed) {
|
|
142
|
+
return anchorsOf(placed, [...(this.handles.get(placed.node.id)?.values() ?? [])], this.detail);
|
|
143
|
+
}
|
|
144
|
+
/** A canvas cell as a flow point. */
|
|
145
|
+
toFlow(cell) {
|
|
146
|
+
return toFlow(cell, this.viewport);
|
|
147
|
+
}
|
|
148
|
+
// What an interaction proposes: the application applies it (or not) to its own state.
|
|
149
|
+
proposeNodes(changes) {
|
|
150
|
+
if (changes.length > 0)
|
|
151
|
+
this.callbacks.onNodesChange?.(changes);
|
|
152
|
+
}
|
|
153
|
+
proposeEdges(changes) {
|
|
154
|
+
if (changes.length > 0)
|
|
155
|
+
this.callbacks.onEdgesChange?.(changes);
|
|
156
|
+
}
|
|
157
|
+
/** Selects exactly `nodes` and `edges` (ids), deselecting the rest. */
|
|
158
|
+
select({ nodes = [], edges = [] }) {
|
|
159
|
+
const n = new Set(nodes);
|
|
160
|
+
const e = new Set(edges);
|
|
161
|
+
this.proposeNodes(this.nodes
|
|
162
|
+
.filter((node) => Boolean(node.selected) !== n.has(node.id))
|
|
163
|
+
.map((node) => ({ id: node.id, type: "select", selected: n.has(node.id) })));
|
|
164
|
+
this.proposeEdges(this.edges
|
|
165
|
+
.filter((edge) => Boolean(edge.selected) !== e.has(edge.id))
|
|
166
|
+
.map((edge) => ({ id: edge.id, type: "select", selected: e.has(edge.id) })));
|
|
167
|
+
}
|
|
168
|
+
/** Removes nodes (with their edges) and edges. */
|
|
169
|
+
deleteElements({ nodes = [], edges = [], }) {
|
|
170
|
+
const gone = new Set(nodes);
|
|
171
|
+
// A group's children go with it.
|
|
172
|
+
for (const node of this.nodes)
|
|
173
|
+
if (node.parentId && gone.has(node.parentId))
|
|
174
|
+
gone.add(node.id);
|
|
175
|
+
const edgeIds = new Set(edges);
|
|
176
|
+
for (const edge of this.edges)
|
|
177
|
+
if (gone.has(edge.source) || gone.has(edge.target))
|
|
178
|
+
edgeIds.add(edge.id);
|
|
179
|
+
this.proposeEdges([...edgeIds].map((id) => ({ id, type: "remove" })));
|
|
180
|
+
this.proposeNodes([...gone].map((id) => ({ id, type: "remove" })));
|
|
181
|
+
}
|
|
182
|
+
connect(connection) {
|
|
183
|
+
this.callbacks.onConnect?.(connection);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
|
package/dist/theme.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Role } from "./raster.ts";
|
|
2
|
+
/** The canvas's colors, as `#rrggbb`. `<Flow theme>` overrides any of them. */
|
|
3
|
+
export type FlowTheme = {
|
|
4
|
+
text: string;
|
|
5
|
+
muted: string;
|
|
6
|
+
border: string;
|
|
7
|
+
selected: string;
|
|
8
|
+
/** A node proposed as the target of a connection, and the connection's line. */
|
|
9
|
+
connect: string;
|
|
10
|
+
group: string;
|
|
11
|
+
edge: string;
|
|
12
|
+
animated: string;
|
|
13
|
+
label: string;
|
|
14
|
+
labelBg: string;
|
|
15
|
+
marker: string;
|
|
16
|
+
background: string;
|
|
17
|
+
handle: string;
|
|
18
|
+
panelBg: string;
|
|
19
|
+
};
|
|
20
|
+
export declare const defaultTheme: FlowTheme;
|
|
21
|
+
export declare const ThemeContext: import("react").Context<FlowTheme>;
|
|
22
|
+
export declare const useFlowTheme: () => FlowTheme;
|
|
23
|
+
/** The color a grid cell of `role` is drawn in. */
|
|
24
|
+
export declare function roleColor(theme: FlowTheme, role: Role): string;
|
|
25
|
+
//# sourceMappingURL=theme.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAExC,+EAA+E;AAC/E,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,gFAAgF;IAChF,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,SAe1B,CAAC;AAEF,eAAO,MAAM,YAAY,oCAAyC,CAAC;AACnE,eAAO,MAAM,YAAY,iBAAiC,CAAC;AAE3D,mDAAmD;AACnD,wBAAgB,SAAS,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,GAAG,MAAM,CAiB9D"}
|
package/dist/theme.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { createContext, useContext } from "react";
|
|
2
|
+
export const defaultTheme = {
|
|
3
|
+
text: "#e6edf3",
|
|
4
|
+
muted: "#8b98a5",
|
|
5
|
+
border: "#4d5966",
|
|
6
|
+
selected: "#67d9bc",
|
|
7
|
+
connect: "#f2cc60",
|
|
8
|
+
group: "#3b4450",
|
|
9
|
+
edge: "#6e7c8a",
|
|
10
|
+
animated: "#79c0ff",
|
|
11
|
+
label: "#c9d1d9",
|
|
12
|
+
labelBg: "#1f262e",
|
|
13
|
+
marker: "#8b98a5",
|
|
14
|
+
background: "#2d353e",
|
|
15
|
+
handle: "#f2cc60",
|
|
16
|
+
panelBg: "#161b22",
|
|
17
|
+
};
|
|
18
|
+
export const ThemeContext = createContext(defaultTheme);
|
|
19
|
+
export const useFlowTheme = () => useContext(ThemeContext);
|
|
20
|
+
/** The color a grid cell of `role` is drawn in. */
|
|
21
|
+
export function roleColor(theme, role) {
|
|
22
|
+
switch (role) {
|
|
23
|
+
case "edge":
|
|
24
|
+
return theme.edge;
|
|
25
|
+
case "selected":
|
|
26
|
+
return theme.selected;
|
|
27
|
+
case "animated":
|
|
28
|
+
return theme.animated;
|
|
29
|
+
case "label":
|
|
30
|
+
return theme.label;
|
|
31
|
+
case "marker":
|
|
32
|
+
return theme.marker;
|
|
33
|
+
case "background":
|
|
34
|
+
return theme.background;
|
|
35
|
+
case "handle":
|
|
36
|
+
return theme.handle;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=theme.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme.js","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAsBlD,MAAM,CAAC,MAAM,YAAY,GAAc;IACrC,IAAI,EAAE,SAAS;IACf,KAAK,EAAE,SAAS;IAChB,MAAM,EAAE,SAAS;IACjB,QAAQ,EAAE,SAAS;IACnB,OAAO,EAAE,SAAS;IAClB,KAAK,EAAE,SAAS;IAChB,IAAI,EAAE,SAAS;IACf,QAAQ,EAAE,SAAS;IACnB,KAAK,EAAE,SAAS;IAChB,OAAO,EAAE,SAAS;IAClB,MAAM,EAAE,SAAS;IACjB,UAAU,EAAE,SAAS;IACrB,MAAM,EAAE,SAAS;IACjB,OAAO,EAAE,SAAS;CACnB,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,aAAa,CAAY,YAAY,CAAC,CAAC;AACnE,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AAE3D,mDAAmD;AACnD,MAAM,UAAU,SAAS,CAAC,KAAgB,EAAE,IAAU;IACpD,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,MAAM;YACT,OAAO,KAAK,CAAC,IAAI,CAAC;QACpB,KAAK,UAAU;YACb,OAAO,KAAK,CAAC,QAAQ,CAAC;QACxB,KAAK,UAAU;YACb,OAAO,KAAK,CAAC,QAAQ,CAAC;QACxB,KAAK,OAAO;YACV,OAAO,KAAK,CAAC,KAAK,CAAC;QACrB,KAAK,QAAQ;YACX,OAAO,KAAK,CAAC,MAAM,CAAC;QACtB,KAAK,YAAY;YACf,OAAO,KAAK,CAAC,UAAU,CAAC;QAC1B,KAAK,QAAQ;YACX,OAAO,KAAK,CAAC,MAAM,CAAC;IACxB,CAAC;AACH,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* The graph's vocabulary, after React Flow's (`@xyflow/system` types): a node, an edge,
|
|
4
|
+
* the changes an interaction proposes, the viewport. Coordinates are terminal cells: `x`
|
|
5
|
+
* counts columns, `y` rows, and a row is about twice as tall as a column is wide.
|
|
6
|
+
*/
|
|
7
|
+
export type XY = {
|
|
8
|
+
x: number;
|
|
9
|
+
y: number;
|
|
10
|
+
};
|
|
11
|
+
export type Rect = {
|
|
12
|
+
x: number;
|
|
13
|
+
y: number;
|
|
14
|
+
width: number;
|
|
15
|
+
height: number;
|
|
16
|
+
};
|
|
17
|
+
/** Which side of a node a handle sits on. */
|
|
18
|
+
export type Position = "left" | "right" | "top" | "bottom";
|
|
19
|
+
/**
|
|
20
|
+
* Semantic zoom: the terminal cannot scale glyphs, so zooming out spaces nodes closer and
|
|
21
|
+
* draws less of each. `full` renders the node's component, `compact` its label on one
|
|
22
|
+
* row, `dot` a single cell.
|
|
23
|
+
*/
|
|
24
|
+
export type Detail = "full" | "compact" | "dot";
|
|
25
|
+
/** A node as the application keeps it. `position` is relative to `parentId`'s, if any. */
|
|
26
|
+
export type Node<Data extends Record<string, unknown> = Record<string, unknown>> = {
|
|
27
|
+
id: string;
|
|
28
|
+
position: XY;
|
|
29
|
+
data: Data;
|
|
30
|
+
/** A key of `nodeTypes`, or a built-in: `default`, `input`, `output`, `group`. */
|
|
31
|
+
type?: string;
|
|
32
|
+
selected?: boolean;
|
|
33
|
+
dragging?: boolean;
|
|
34
|
+
hidden?: boolean;
|
|
35
|
+
/** A group node this one sits in: its position is relative to the group's. */
|
|
36
|
+
parentId?: string;
|
|
37
|
+
/** Fixed size in cells (a group needs one); otherwise the rendered size is measured. */
|
|
38
|
+
width?: number;
|
|
39
|
+
height?: number;
|
|
40
|
+
/** Where edges leave (default `right`) and arrive (default `left`) without a `<Handle>`. */
|
|
41
|
+
sourcePosition?: Position;
|
|
42
|
+
targetPosition?: Position;
|
|
43
|
+
draggable?: boolean;
|
|
44
|
+
selectable?: boolean;
|
|
45
|
+
connectable?: boolean;
|
|
46
|
+
zIndex?: number;
|
|
47
|
+
/** The node's color where the canvas draws it itself: a dot when zoomed out, the minimap. */
|
|
48
|
+
color?: string;
|
|
49
|
+
};
|
|
50
|
+
export type MarkerType = "arrow" | "none";
|
|
51
|
+
export type Edge<Data extends Record<string, unknown> = Record<string, unknown>> = {
|
|
52
|
+
id: string;
|
|
53
|
+
source: string;
|
|
54
|
+
target: string;
|
|
55
|
+
sourceHandle?: string | null;
|
|
56
|
+
targetHandle?: string | null;
|
|
57
|
+
/** A key of `edgeTypes`, or a built-in: `smoothstep` (default), `step`, `straight`, `bezier`. */
|
|
58
|
+
type?: string;
|
|
59
|
+
label?: string;
|
|
60
|
+
/** Dashes that run from source to target. */
|
|
61
|
+
animated?: boolean;
|
|
62
|
+
selected?: boolean;
|
|
63
|
+
hidden?: boolean;
|
|
64
|
+
/** Default `arrow`. */
|
|
65
|
+
markerEnd?: MarkerType;
|
|
66
|
+
markerStart?: MarkerType;
|
|
67
|
+
/** A color for the line, as `#rrggbb`. */
|
|
68
|
+
color?: string;
|
|
69
|
+
data?: Data;
|
|
70
|
+
};
|
|
71
|
+
export type Connection = {
|
|
72
|
+
source: string;
|
|
73
|
+
target: string;
|
|
74
|
+
sourceHandle: string | null;
|
|
75
|
+
targetHandle: string | null;
|
|
76
|
+
};
|
|
77
|
+
export type Viewport = {
|
|
78
|
+
x: number;
|
|
79
|
+
y: number;
|
|
80
|
+
zoom: number;
|
|
81
|
+
};
|
|
82
|
+
export type NodePositionChange = {
|
|
83
|
+
id: string;
|
|
84
|
+
type: "position";
|
|
85
|
+
position?: XY;
|
|
86
|
+
dragging?: boolean;
|
|
87
|
+
};
|
|
88
|
+
export type NodeDimensionsChange = {
|
|
89
|
+
id: string;
|
|
90
|
+
type: "dimensions";
|
|
91
|
+
dimensions: {
|
|
92
|
+
width: number;
|
|
93
|
+
height: number;
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
export type SelectionChange = {
|
|
97
|
+
id: string;
|
|
98
|
+
type: "select";
|
|
99
|
+
selected: boolean;
|
|
100
|
+
};
|
|
101
|
+
export type RemoveChange = {
|
|
102
|
+
id: string;
|
|
103
|
+
type: "remove";
|
|
104
|
+
};
|
|
105
|
+
export type AddChange<T> = {
|
|
106
|
+
type: "add";
|
|
107
|
+
item: T;
|
|
108
|
+
index?: number;
|
|
109
|
+
};
|
|
110
|
+
export type ReplaceChange<T> = {
|
|
111
|
+
id: string;
|
|
112
|
+
type: "replace";
|
|
113
|
+
item: T;
|
|
114
|
+
};
|
|
115
|
+
export type NodeChange<N extends Node = Node> = NodePositionChange | NodeDimensionsChange | SelectionChange | RemoveChange | AddChange<N> | ReplaceChange<N>;
|
|
116
|
+
export type EdgeChange<E extends Edge = Edge> = SelectionChange | RemoveChange | AddChange<E> | ReplaceChange<E>;
|
|
117
|
+
export type HandleType = "source" | "target";
|
|
118
|
+
/** A handle a node declared with `<Handle>`. */
|
|
119
|
+
export type HandleSpec = {
|
|
120
|
+
id: string | null;
|
|
121
|
+
type: HandleType;
|
|
122
|
+
position: Position;
|
|
123
|
+
};
|
|
124
|
+
/** A node type: a function component of `NodeProps`. */
|
|
125
|
+
export type NodeComponent<N extends Node = Node> = (props: NodeProps<N>) => ReactNode;
|
|
126
|
+
/** What a node component receives. */
|
|
127
|
+
export type NodeProps<N extends Node = Node> = {
|
|
128
|
+
id: string;
|
|
129
|
+
data: N["data"];
|
|
130
|
+
type: string;
|
|
131
|
+
selected: boolean;
|
|
132
|
+
dragging: boolean;
|
|
133
|
+
/** `full` or `compact`: at `dot`, the canvas draws the node itself. */
|
|
134
|
+
detail: Detail;
|
|
135
|
+
/** Keyboard connection under way and this node is the proposed target. */
|
|
136
|
+
connectTarget: boolean;
|
|
137
|
+
width?: number;
|
|
138
|
+
height?: number;
|
|
139
|
+
};
|
|
140
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2019-2025 webkid GmbH
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Position } from "../../types.ts";
|
|
2
|
+
export declare function getEdgeCenter({ sourceX, sourceY, targetX, targetY, }: {
|
|
3
|
+
sourceX: number;
|
|
4
|
+
sourceY: number;
|
|
5
|
+
targetX: number;
|
|
6
|
+
targetY: number;
|
|
7
|
+
}): [number, number, number, number];
|
|
8
|
+
export declare function getBezierEdgeCenter({ sourceX, sourceY, targetX, targetY, sourceControlX, sourceControlY, targetControlX, targetControlY, }: {
|
|
9
|
+
sourceX: number;
|
|
10
|
+
sourceY: number;
|
|
11
|
+
targetX: number;
|
|
12
|
+
targetY: number;
|
|
13
|
+
sourceControlX: number;
|
|
14
|
+
sourceControlY: number;
|
|
15
|
+
targetControlX: number;
|
|
16
|
+
targetControlY: number;
|
|
17
|
+
}): [number, number];
|
|
18
|
+
export declare function getControlWithCurvature({ pos, x1, y1, x2, y2, c, }: {
|
|
19
|
+
pos: Position;
|
|
20
|
+
x1: number;
|
|
21
|
+
y1: number;
|
|
22
|
+
x2: number;
|
|
23
|
+
y2: number;
|
|
24
|
+
c: number;
|
|
25
|
+
}): [number, number];
|
|
26
|
+
//# sourceMappingURL=bezier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bezier.d.ts","sourceRoot":"","sources":["../../../src/vendor/xyflow/bezier.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAS/C,wBAAgB,aAAa,CAAC,EAC5B,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,GACR,EAAE;IACD,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAQnC;AAED,wBAAgB,mBAAmB,CAAC,EAClC,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,cAAc,EACd,cAAc,EACd,cAAc,EACd,cAAc,GACf,EAAE;IACD,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CACxB,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAgBnB;AAUD,wBAAgB,uBAAuB,CAAC,EACtC,GAAG,EACH,EAAE,EACF,EAAE,EACF,EAAE,EACF,EAAE,EACF,CAAC,GACF,EAAE;IACD,GAAG,EAAE,QAAQ,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,CAAC,EAAE,MAAM,CAAC;CACX,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAWnB"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
const HALF = 0.5;
|
|
2
|
+
// cubic bezier t=0.5 mid point weights: (1-t)^3, 3t(1-t)^2, 3t^2(1-t), t^3
|
|
3
|
+
const END_WEIGHT = 0.125;
|
|
4
|
+
const CONTROL_WEIGHT = 0.375;
|
|
5
|
+
const CURVATURE_SCALE = 25;
|
|
6
|
+
// this is used for straight edges and simple smoothstep edges (LTR, RTL, BTT, TTB)
|
|
7
|
+
export function getEdgeCenter({ sourceX, sourceY, targetX, targetY, }) {
|
|
8
|
+
const xOffset = Math.abs(targetX - sourceX) / 2;
|
|
9
|
+
const centerX = targetX < sourceX ? targetX + xOffset : targetX - xOffset;
|
|
10
|
+
const yOffset = Math.abs(targetY - sourceY) / 2;
|
|
11
|
+
const centerY = targetY < sourceY ? targetY + yOffset : targetY - yOffset;
|
|
12
|
+
return [centerX, centerY, xOffset, yOffset];
|
|
13
|
+
}
|
|
14
|
+
export function getBezierEdgeCenter({ sourceX, sourceY, targetX, targetY, sourceControlX, sourceControlY, targetControlX, targetControlY, }) {
|
|
15
|
+
/*
|
|
16
|
+
* cubic bezier t=0.5 mid point, not the actual mid point, but easy to calculate
|
|
17
|
+
* https://stackoverflow.com/questions/67516101/how-to-find-distance-mid-point-of-bezier-curve
|
|
18
|
+
*/
|
|
19
|
+
const centerX = sourceX * END_WEIGHT +
|
|
20
|
+
sourceControlX * CONTROL_WEIGHT +
|
|
21
|
+
targetControlX * CONTROL_WEIGHT +
|
|
22
|
+
targetX * END_WEIGHT;
|
|
23
|
+
const centerY = sourceY * END_WEIGHT +
|
|
24
|
+
sourceControlY * CONTROL_WEIGHT +
|
|
25
|
+
targetControlY * CONTROL_WEIGHT +
|
|
26
|
+
targetY * END_WEIGHT;
|
|
27
|
+
return [centerX, centerY];
|
|
28
|
+
}
|
|
29
|
+
function calculateControlOffset(distance, curvature) {
|
|
30
|
+
if (distance >= 0) {
|
|
31
|
+
return HALF * distance;
|
|
32
|
+
}
|
|
33
|
+
return curvature * CURVATURE_SCALE * Math.sqrt(-distance);
|
|
34
|
+
}
|
|
35
|
+
export function getControlWithCurvature({ pos, x1, y1, x2, y2, c, }) {
|
|
36
|
+
switch (pos) {
|
|
37
|
+
case "left":
|
|
38
|
+
return [x1 - calculateControlOffset(x1 - x2, c), y1];
|
|
39
|
+
case "right":
|
|
40
|
+
return [x1 + calculateControlOffset(x2 - x1, c), y1];
|
|
41
|
+
case "top":
|
|
42
|
+
return [x1, y1 - calculateControlOffset(y1 - y2, c)];
|
|
43
|
+
case "bottom":
|
|
44
|
+
return [x1, y1 + calculateControlOffset(y2 - y1, c)];
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=bezier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bezier.js","sourceRoot":"","sources":["../../../src/vendor/xyflow/bezier.ts"],"names":[],"mappings":"AAKA,MAAM,IAAI,GAAG,GAAG,CAAC;AACjB,2EAA2E;AAC3E,MAAM,UAAU,GAAG,KAAK,CAAC;AACzB,MAAM,cAAc,GAAG,KAAK,CAAC;AAC7B,MAAM,eAAe,GAAG,EAAE,CAAC;AAE3B,mFAAmF;AACnF,MAAM,UAAU,aAAa,CAAC,EAC5B,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,GAMR;IACC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAChD,MAAM,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,OAAO,GAAG,OAAO,CAAC;IAE1E,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAChD,MAAM,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,OAAO,GAAG,OAAO,CAAC;IAE1E,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,EAClC,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,cAAc,EACd,cAAc,EACd,cAAc,EACd,cAAc,GAUf;IACC;;;OAGG;IACH,MAAM,OAAO,GACX,OAAO,GAAG,UAAU;QACpB,cAAc,GAAG,cAAc;QAC/B,cAAc,GAAG,cAAc;QAC/B,OAAO,GAAG,UAAU,CAAC;IACvB,MAAM,OAAO,GACX,OAAO,GAAG,UAAU;QACpB,cAAc,GAAG,cAAc;QAC/B,cAAc,GAAG,cAAc;QAC/B,OAAO,GAAG,UAAU,CAAC;IACvB,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;AAC5B,CAAC;AAED,SAAS,sBAAsB,CAAC,QAAgB,EAAE,SAAiB;IACjE,IAAI,QAAQ,IAAI,CAAC,EAAE,CAAC;QAClB,OAAO,IAAI,GAAG,QAAQ,CAAC;IACzB,CAAC;IAED,OAAO,SAAS,GAAG,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,EACtC,GAAG,EACH,EAAE,EACF,EAAE,EACF,EAAE,EACF,EAAE,EACF,CAAC,GAQF;IACC,QAAQ,GAAG,EAAE,CAAC;QACZ,KAAK,MAAM;YACT,OAAO,CAAC,EAAE,GAAG,sBAAsB,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACvD,KAAK,OAAO;YACV,OAAO,CAAC,EAAE,GAAG,sBAAsB,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACvD,KAAK,KAAK;YACR,OAAO,CAAC,EAAE,EAAE,EAAE,GAAG,sBAAsB,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;QACvD,KAAK,QAAQ;YACX,OAAO,CAAC,EAAE,EAAE,EAAE,GAAG,sBAAsB,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IACzD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Connection, Edge, EdgeChange, Node, NodeChange } from "../../types.ts";
|
|
2
|
+
/** Applies what the canvas proposes (drag, selection, removal…) to the application's nodes. */
|
|
3
|
+
export declare function applyNodeChanges<N extends Node = Node>(changes: readonly NodeChange<N>[], nodes: readonly N[]): N[];
|
|
4
|
+
/** Applies what the canvas proposes to the application's edges. */
|
|
5
|
+
export declare function applyEdgeChanges<E extends Edge = Edge>(changes: readonly EdgeChange<E>[], edges: readonly E[]): E[];
|
|
6
|
+
export declare const getEdgeId: ({ source, sourceHandle, target, targetHandle }: Connection | Edge) => string;
|
|
7
|
+
/** `edges` with a new edge for `connection`, unless the same connection exists already. */
|
|
8
|
+
export declare function addEdge<E extends Edge = Edge>(connection: (Connection & Partial<Omit<E, keyof Connection>>) | E, edges: readonly E[], getId?: (connection: Connection | Edge) => string): E[];
|
|
9
|
+
//# sourceMappingURL=changes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"changes.d.ts","sourceRoot":"","sources":["../../../src/vendor/xyflow/changes.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAoIrF,+FAA+F;AAC/F,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,IAAI,GAAG,IAAI,EACpD,OAAO,EAAE,SAAS,UAAU,CAAC,CAAC,CAAC,EAAE,EACjC,KAAK,EAAE,SAAS,CAAC,EAAE,GAClB,CAAC,EAAE,CAEL;AAED,mEAAmE;AACnE,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,IAAI,GAAG,IAAI,EACpD,OAAO,EAAE,SAAS,UAAU,CAAC,CAAC,CAAC,EAAE,EACjC,KAAK,EAAE,SAAS,CAAC,EAAE,GAClB,CAAC,EAAE,CAEL;AAED,eAAO,MAAM,SAAS,mDAAoD,UAAU,GAAG,IAAI,WACjB,CAAC;AAW3E,2FAA2F;AAC3F,wBAAgB,OAAO,CAAC,CAAC,SAAS,IAAI,GAAG,IAAI,EAC3C,UAAU,EAAE,CAAC,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,EACjE,KAAK,EAAE,SAAS,CAAC,EAAE,EACnB,KAAK,GAAE,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,KAAK,MAAkB,GAC3D,CAAC,EAAE,CAQL"}
|