@bavuchoko/edge-node 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 +437 -2
- package/dist/components/ConnectionLine.d.ts +9 -0
- package/dist/components/EdgeEditor.d.ts +16 -0
- package/dist/components/GraphCanvas.d.ts +42 -0
- package/dist/components/GraphEdge.d.ts +22 -0
- package/dist/components/GraphNode.d.ts +59 -0
- package/dist/dependencies.d.ts +32 -0
- package/dist/geometry.d.ts +26 -0
- package/dist/hooks/useColorMode.d.ts +21 -0
- package/dist/hooks/useConnectionDrag.d.ts +12 -0
- package/dist/hooks/useGraphPersistence.d.ts +42 -0
- package/dist/hooks/useViewport.d.ts +15 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +1639 -0
- package/dist/layout.d.ts +20 -0
- package/dist/store.d.ts +46 -0
- package/dist/style.css +628 -0
- package/dist/theme.d.ts +108 -0
- package/dist/types.d.ts +86 -0
- package/package.json +68 -4
package/dist/theme.d.ts
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import type { CSSProperties } from 'react';
|
|
2
|
+
export type GraphColorMode = 'dark' | 'light';
|
|
3
|
+
export type GraphTheme = {
|
|
4
|
+
background?: string;
|
|
5
|
+
/** Dot grid overlay color. Set to 'transparent' to hide. */
|
|
6
|
+
gridColor?: string;
|
|
7
|
+
gridSize?: number;
|
|
8
|
+
node?: {
|
|
9
|
+
background?: string;
|
|
10
|
+
border?: string;
|
|
11
|
+
borderHover?: string;
|
|
12
|
+
borderSelected?: string;
|
|
13
|
+
title?: string;
|
|
14
|
+
subtitle?: string;
|
|
15
|
+
shadow?: string;
|
|
16
|
+
radius?: number;
|
|
17
|
+
handle?: string;
|
|
18
|
+
handleActive?: string;
|
|
19
|
+
badgeBackground?: string;
|
|
20
|
+
badgeText?: string;
|
|
21
|
+
statusSuccess?: string;
|
|
22
|
+
statusError?: string;
|
|
23
|
+
statusIdle?: string;
|
|
24
|
+
};
|
|
25
|
+
edge?: {
|
|
26
|
+
color?: string;
|
|
27
|
+
hoverColor?: string;
|
|
28
|
+
selectedColor?: string;
|
|
29
|
+
width?: number;
|
|
30
|
+
hoverWidth?: number;
|
|
31
|
+
selectedWidth?: number;
|
|
32
|
+
/** Invisible hit area width in screen px */
|
|
33
|
+
hitWidth?: number;
|
|
34
|
+
draftColor?: string;
|
|
35
|
+
draftWidth?: number;
|
|
36
|
+
draftDash?: string;
|
|
37
|
+
/** Arrowhead length in screen px. 0 hides arrows. */
|
|
38
|
+
arrowSize?: number;
|
|
39
|
+
/** Dash pattern for `kind: 'optional'` edges. */
|
|
40
|
+
optionalDash?: string;
|
|
41
|
+
labelColor?: string;
|
|
42
|
+
};
|
|
43
|
+
hud?: {
|
|
44
|
+
color?: string;
|
|
45
|
+
};
|
|
46
|
+
/** Colors used when a node is hovered to show its dependency chain. */
|
|
47
|
+
dependency?: {
|
|
48
|
+
/** Nodes the hovered node depends on (incoming side). */
|
|
49
|
+
upstreamColor?: string;
|
|
50
|
+
/** Nodes that depend on the hovered node (outgoing side). */
|
|
51
|
+
downstreamColor?: string;
|
|
52
|
+
/** Opacity of nodes/edges outside the chain. */
|
|
53
|
+
dimOpacity?: number;
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
export type ResolvedGraphTheme = {
|
|
57
|
+
background: string;
|
|
58
|
+
gridColor: string;
|
|
59
|
+
gridSize: number;
|
|
60
|
+
node: {
|
|
61
|
+
background: string;
|
|
62
|
+
border: string;
|
|
63
|
+
borderHover: string;
|
|
64
|
+
borderSelected: string;
|
|
65
|
+
title: string;
|
|
66
|
+
subtitle: string;
|
|
67
|
+
shadow: string;
|
|
68
|
+
radius: number;
|
|
69
|
+
handle: string;
|
|
70
|
+
handleActive: string;
|
|
71
|
+
badgeBackground: string;
|
|
72
|
+
badgeText: string;
|
|
73
|
+
statusSuccess: string;
|
|
74
|
+
statusError: string;
|
|
75
|
+
statusIdle: string;
|
|
76
|
+
};
|
|
77
|
+
edge: {
|
|
78
|
+
color: string;
|
|
79
|
+
hoverColor: string;
|
|
80
|
+
selectedColor: string;
|
|
81
|
+
width: number;
|
|
82
|
+
hoverWidth: number;
|
|
83
|
+
selectedWidth: number;
|
|
84
|
+
hitWidth: number;
|
|
85
|
+
draftColor: string;
|
|
86
|
+
draftWidth: number;
|
|
87
|
+
draftDash: string;
|
|
88
|
+
arrowSize: number;
|
|
89
|
+
optionalDash: string;
|
|
90
|
+
labelColor: string;
|
|
91
|
+
};
|
|
92
|
+
hud: {
|
|
93
|
+
color: string;
|
|
94
|
+
};
|
|
95
|
+
dependency: {
|
|
96
|
+
upstreamColor: string;
|
|
97
|
+
downstreamColor: string;
|
|
98
|
+
dimOpacity: number;
|
|
99
|
+
};
|
|
100
|
+
};
|
|
101
|
+
export declare const darkGraphTheme: ResolvedGraphTheme;
|
|
102
|
+
export declare const lightGraphTheme: ResolvedGraphTheme;
|
|
103
|
+
/** Alias of `darkGraphTheme`, the theme used when no color mode is given. */
|
|
104
|
+
export declare const defaultGraphTheme: ResolvedGraphTheme;
|
|
105
|
+
export declare const graphThemes: Record<GraphColorMode, ResolvedGraphTheme>;
|
|
106
|
+
/** Fills a partial theme from the preset for `mode`. */
|
|
107
|
+
export declare function resolveGraphTheme(partial?: GraphTheme, mode?: GraphColorMode): ResolvedGraphTheme;
|
|
108
|
+
export declare function themeToCssVars(theme: ResolvedGraphTheme): CSSProperties;
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
export type NodeId = string;
|
|
2
|
+
export type EdgeId = string;
|
|
3
|
+
export type Point = {
|
|
4
|
+
x: number;
|
|
5
|
+
y: number;
|
|
6
|
+
};
|
|
7
|
+
export type NodeStatus = 'success' | 'error' | 'idle';
|
|
8
|
+
export type NodeDetail = {
|
|
9
|
+
label: string;
|
|
10
|
+
value: string | number;
|
|
11
|
+
};
|
|
12
|
+
export type NodeData = {
|
|
13
|
+
title: string;
|
|
14
|
+
subtitle?: string;
|
|
15
|
+
status: NodeStatus;
|
|
16
|
+
stats?: string;
|
|
17
|
+
badge?: string;
|
|
18
|
+
/** Rows shown when the node is expanded (click its content area). */
|
|
19
|
+
details?: NodeDetail[];
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* `TData` is free-form when you draw cards yourself with `renderNode`; the
|
|
23
|
+
* built-in card reads the `NodeData` fields.
|
|
24
|
+
*/
|
|
25
|
+
export type GraphNode<TData = NodeData> = {
|
|
26
|
+
id: NodeId;
|
|
27
|
+
position: Point;
|
|
28
|
+
width: number;
|
|
29
|
+
height: number;
|
|
30
|
+
data: TData;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* - `required`: target cannot run without source (solid line)
|
|
34
|
+
* - `optional`: soft / ordering-only dependency (dashed line)
|
|
35
|
+
*/
|
|
36
|
+
export type EdgeKind = 'required' | 'optional';
|
|
37
|
+
/** Directed edge: `target` depends on `source`. */
|
|
38
|
+
export type GraphEdge = {
|
|
39
|
+
id: EdgeId;
|
|
40
|
+
source: NodeId;
|
|
41
|
+
target: NodeId;
|
|
42
|
+
/** Defaults to `'required'`. */
|
|
43
|
+
kind?: EdgeKind;
|
|
44
|
+
/** Short text drawn at the middle of the edge. */
|
|
45
|
+
label?: string;
|
|
46
|
+
/**
|
|
47
|
+
* The target's relation to the source, read as "target <relation> source"
|
|
48
|
+
* (e.g. `'runs on'`). Shown on the target's card while the source is hovered.
|
|
49
|
+
*/
|
|
50
|
+
relation?: string;
|
|
51
|
+
/**
|
|
52
|
+
* The source's relation to the target, read as "source <inverseRelation> target"
|
|
53
|
+
* (e.g. `'hosts'`). Shown on the source's card while the target is hovered.
|
|
54
|
+
*/
|
|
55
|
+
inverseRelation?: string;
|
|
56
|
+
};
|
|
57
|
+
/** Edge fields the user can edit after drawing a connection. */
|
|
58
|
+
export type EdgePatch = Partial<Pick<GraphEdge, 'kind' | 'label' | 'relation' | 'inverseRelation'>>;
|
|
59
|
+
export type GraphEdgeInput = Omit<GraphEdge, 'id'>;
|
|
60
|
+
export type Viewport = {
|
|
61
|
+
x: number;
|
|
62
|
+
y: number;
|
|
63
|
+
zoom: number;
|
|
64
|
+
};
|
|
65
|
+
export type HandleSide = 'left' | 'right';
|
|
66
|
+
export type Selection = {
|
|
67
|
+
type: 'node';
|
|
68
|
+
id: NodeId;
|
|
69
|
+
}
|
|
70
|
+
/** `created` is set right after the edge was drawn, so its editor can grab focus. */
|
|
71
|
+
| {
|
|
72
|
+
type: 'edge';
|
|
73
|
+
id: EdgeId;
|
|
74
|
+
created?: boolean;
|
|
75
|
+
} | null;
|
|
76
|
+
export type ConnectionDraft = {
|
|
77
|
+
sourceId: NodeId;
|
|
78
|
+
pointer: Point;
|
|
79
|
+
};
|
|
80
|
+
export type GraphState<TData = NodeData> = {
|
|
81
|
+
nodes: Record<NodeId, GraphNode<TData>>;
|
|
82
|
+
edges: Record<EdgeId, GraphEdge>;
|
|
83
|
+
viewport: Viewport;
|
|
84
|
+
selection: Selection;
|
|
85
|
+
connectionDraft: ConnectionDraft | null;
|
|
86
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,70 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bavuchoko/edge-node",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "React node-graph editor with pannable canvas, draggable nodes and connectable edges.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"react",
|
|
7
|
+
"node-editor",
|
|
8
|
+
"graph",
|
|
9
|
+
"dag",
|
|
10
|
+
"pipeline",
|
|
11
|
+
"dependency-graph",
|
|
12
|
+
"diagram",
|
|
13
|
+
"edges"
|
|
14
|
+
],
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"author": "bavuchoko",
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/bavuchoko/edge-node.git"
|
|
20
|
+
},
|
|
21
|
+
"homepage": "https://github.com/bavuchoko/edge-node#readme",
|
|
22
|
+
"bugs": {
|
|
23
|
+
"url": "https://github.com/bavuchoko/edge-node/issues"
|
|
24
|
+
},
|
|
25
|
+
"type": "module",
|
|
26
|
+
"main": "./dist/index.js",
|
|
27
|
+
"module": "./dist/index.js",
|
|
28
|
+
"types": "./dist/index.d.ts",
|
|
29
|
+
"exports": {
|
|
30
|
+
".": {
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
32
|
+
"import": "./dist/index.js",
|
|
33
|
+
"default": "./dist/index.js"
|
|
34
|
+
},
|
|
35
|
+
"./style.css": "./dist/style.css",
|
|
36
|
+
"./package.json": "./package.json"
|
|
37
|
+
},
|
|
38
|
+
"files": [
|
|
39
|
+
"dist"
|
|
40
|
+
],
|
|
41
|
+
"sideEffects": [
|
|
42
|
+
"**/*.css"
|
|
43
|
+
],
|
|
44
|
+
"scripts": {
|
|
45
|
+
"dev": "vite",
|
|
46
|
+
"build": "tsc -b && vite build",
|
|
47
|
+
"build:lib": "vite build --mode lib && tsc -p tsconfig.lib.json && node -e \"require('node:fs').copyFileSync('src/graph/graph.css','dist/style.css')\"",
|
|
48
|
+
"prepack": "npm run build:lib",
|
|
49
|
+
"lint": "oxlint",
|
|
50
|
+
"preview": "vite preview"
|
|
51
|
+
},
|
|
52
|
+
"peerDependencies": {
|
|
53
|
+
"react": ">=18",
|
|
54
|
+
"react-dom": ">=18"
|
|
55
|
+
},
|
|
56
|
+
"devDependencies": {
|
|
57
|
+
"@types/node": "^24.13.2",
|
|
58
|
+
"@types/react": "^19.2.17",
|
|
59
|
+
"@types/react-dom": "^19.2.3",
|
|
60
|
+
"@vitejs/plugin-react": "^6.0.3",
|
|
61
|
+
"oxlint": "^1.71.0",
|
|
62
|
+
"react": "^19.2.7",
|
|
63
|
+
"react-dom": "^19.2.7",
|
|
64
|
+
"typescript": "~6.0.2",
|
|
65
|
+
"vite": "^8.1.1"
|
|
66
|
+
},
|
|
67
|
+
"publishConfig": {
|
|
68
|
+
"access": "public"
|
|
69
|
+
}
|
|
70
|
+
}
|