@quantumwake/kgraph 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 QuantumWake
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.
package/README.md ADDED
@@ -0,0 +1,245 @@
1
+ # @quantumwake/kgraph
2
+
3
+ A lightweight, zero-dependency React graph canvas. Build node-based editors, pipelines, and diagrams with a familiar API — no Zustand, no d3, no CSS imports required.
4
+
5
+ If you've used ReactFlow, you'll feel right at home. If you haven't, you'll be up and running in 5 minutes.
6
+
7
+ ![kgraph example](example1.png)
8
+
9
+ ## Why KGraph?
10
+
11
+ | | ReactFlow | KGraph |
12
+ |---|---|---|
13
+ | Runtime deps | Zustand + d3-selection + d3-zoom + d3-drag | **None** |
14
+ | CSS import | Required | **Not needed** |
15
+ | Bundle size | ~150KB+ | **~42KB** |
16
+ | Source | 100+ files, monorepo | **12 files, ~2K LOC** |
17
+ | Mental model | Zustand store + d3 transforms | **React context + useState** |
18
+ | API surface | 19 hooks, 60+ types | **2 hooks, 15 types** |
19
+
20
+ ## Install
21
+
22
+ ```bash
23
+ npm install @quantumwake/kgraph
24
+ # or
25
+ yarn add @quantumwake/kgraph
26
+ # or
27
+ pnpm add @quantumwake/kgraph
28
+ ```
29
+
30
+ Requires React 17+. That's it — no CSS files to import, no provider wrappers to add.
31
+
32
+ ## Quick Start
33
+
34
+ ```tsx
35
+ import { useState } from 'react';
36
+ import {
37
+ KGraphCanvas,
38
+ applyNodeChanges,
39
+ applyEdgeChanges,
40
+ } from '@quantumwake/kgraph';
41
+ import type { KGraphNode, KGraphEdge, KGraphConnection } from '@quantumwake/kgraph';
42
+
43
+ function MyGraph() {
44
+ const [nodes, setNodes] = useState<KGraphNode[]>([
45
+ { id: '1', type: 'default', position: { x: 0, y: 0 }, data: { label: 'Hello' } },
46
+ { id: '2', type: 'default', position: { x: 200, y: 120 }, data: { label: 'World' } },
47
+ ]);
48
+ const [edges, setEdges] = useState<KGraphEdge[]>([
49
+ { id: 'e1', source: '1', target: '2' },
50
+ ]);
51
+
52
+ return (
53
+ <div style={{ width: '100%', height: 600 }}>
54
+ <KGraphCanvas
55
+ nodes={nodes}
56
+ edges={edges}
57
+ onNodesChange={c => setNodes(applyNodeChanges(c, nodes))}
58
+ onEdgesChange={c => setEdges(applyEdgeChanges(c, edges))}
59
+ onConnect={(conn: KGraphConnection) =>
60
+ setEdges(prev => [...prev, { id: `e-${Date.now()}`, ...conn }])
61
+ }
62
+ fitView
63
+ />
64
+ </div>
65
+ );
66
+ }
67
+ ```
68
+
69
+ That gives you pan, zoom, drag, snap-to-grid, selection, keyboard delete, a minimap, directed arrows, and a dot grid background — all out of the box.
70
+
71
+ ## Features
72
+
73
+ - **Zero dependencies** — peer dep on React, nothing else
74
+ - **ReactFlow-compatible API** — `applyNodeChanges`, `applyEdgeChanges`, `getBezierPath`
75
+ - **Custom nodes & edges** — bring your own React components
76
+ - **Connection drawing** — drag from source handle to target handle
77
+ - **Interactive handles** — visible dots with hover effects, crosshair cursor on sources
78
+ - **Directed arrows** — SVG markers on all edges by default
79
+ - **MiniMap** — click-to-navigate overview
80
+ - **Dot grid background** — configurable gap
81
+ - **Edge labels** — zoom-invariant HTML overlays
82
+ - **Viewport controls** — `useKGraph()` hook for `fitView`, `zoomIn`, `zoomOut`, `zoomTo`
83
+ - **Drag & drop** — `onDrop` callback with canvas-space coordinates
84
+ - **Multi-select** — Shift/Cmd+click
85
+ - **Keyboard shortcuts** — Delete/Backspace to remove selected elements
86
+ - **Snap-to-grid** — configurable grid size
87
+ - **Fully typed** — TypeScript declarations included
88
+
89
+ ## Custom Nodes
90
+
91
+ ```tsx
92
+ import { Handle } from '@quantumwake/kgraph';
93
+ import type { NodeComponentProps } from '@quantumwake/kgraph';
94
+
95
+ const MyNode: React.FC<NodeComponentProps> = ({ data, selected }) => (
96
+ <div style={{
97
+ padding: 16, borderRadius: 8,
98
+ border: `2px solid ${selected ? '#60a5fa' : '#333'}`,
99
+ background: '#1a1a2e', color: '#fff',
100
+ }}>
101
+ <Handle id="target-1" type="target" position="top" />
102
+ <h3>{data.title}</h3>
103
+ <p>{data.description}</p>
104
+ <Handle id="source-4" type="source" position="bottom" />
105
+ </div>
106
+ );
107
+
108
+ // Register it:
109
+ <KGraphCanvas nodeTypes={{ myNode: MyNode }} ... />
110
+ ```
111
+
112
+ **Handle IDs** map to positions: `*-1` = top, `*-2` = left, `*-3` = right, `*-4` = bottom.
113
+
114
+ Handles are visible by default (purple dots that grow on hover). Pass `style={{ background: '#22c55e', borderColor: '#4ade80' }}` to customize colors.
115
+
116
+ ## Custom Edges
117
+
118
+ ```tsx
119
+ import { getBezierPath } from '@quantumwake/kgraph';
120
+ import type { EdgeComponentProps } from '@quantumwake/kgraph';
121
+
122
+ const DashedEdge: React.FC<EdgeComponentProps> = (props) => {
123
+ const [path] = getBezierPath(props);
124
+ return (
125
+ <g>
126
+ <path d={path} fill="none" stroke="transparent" strokeWidth={20} />
127
+ <path d={path} fill="none" stroke="#7c3aed" strokeWidth={2}
128
+ strokeDasharray="8 4"
129
+ markerEnd="url(#kgraph-arrow)" />
130
+ </g>
131
+ );
132
+ };
133
+
134
+ <KGraphCanvas edgeTypes={{ dashed: DashedEdge }} ... />
135
+ ```
136
+
137
+ Arrow markers (`#kgraph-arrow` and `#kgraph-arrow-selected`) are defined automatically by KGraphCanvas.
138
+
139
+ ## Hooks
140
+
141
+ ### `useKGraph()`
142
+
143
+ Available inside any child of `<KGraphCanvas>`:
144
+
145
+ ```ts
146
+ const {
147
+ fitView, // (options?) => void
148
+ zoomIn, // () => void
149
+ zoomOut, // () => void
150
+ zoomTo, // (level: number) => void
151
+ getViewport, // () => { x, y, zoom }
152
+ setViewport, // (viewport | updater) => void
153
+ screenToCanvasPosition, // (clientX, clientY) => { x, y }
154
+ getNodes, // () => KGraphNode[]
155
+ getEdges, // () => KGraphEdge[]
156
+ } = useKGraph();
157
+ ```
158
+
159
+ ### `useKGraphContext()`
160
+
161
+ Full internal context — `containerRef`, handle registration, `canvasToScreenPosition`, etc. Use this for advanced integrations.
162
+
163
+ ## Props Reference
164
+
165
+ | Prop | Type | Default | Description |
166
+ |---|---|---|---|
167
+ | `nodes` | `KGraphNode[]` | required | Node array |
168
+ | `edges` | `KGraphEdge[]` | required | Edge array |
169
+ | `onNodesChange` | `(changes) => void` | — | Node change callback |
170
+ | `onEdgesChange` | `(changes) => void` | — | Edge change callback |
171
+ | `onConnect` | `(connection) => void` | — | New connection callback |
172
+ | `onNodeClick` | `(event, node) => void` | — | Node click handler |
173
+ | `onEdgeClick` | `(event, edge) => void` | — | Edge click handler |
174
+ | `onPaneClick` | `(event) => void` | — | Background click handler |
175
+ | `onDrop` | `(event, position) => void` | — | Drop with canvas coordinates |
176
+ | `nodeTypes` | `Record<string, Component>` | `{}` | Custom node components |
177
+ | `edgeTypes` | `Record<string, Component>` | `{}` | Custom edge components |
178
+ | `snapToGrid` | `boolean` | `true` | Snap node positions to grid |
179
+ | `snapGrid` | `[number, number]` | `[16, 16]` | Grid cell size in px |
180
+ | `panOnDrag` | `boolean` | `true` | Enable canvas panning |
181
+ | `zoomOnScroll` | `boolean` | `true` | Enable scroll/pinch zoom |
182
+ | `nodesDraggable` | `boolean` | `true` | Allow node dragging |
183
+ | `nodesConnectable` | `boolean` | `true` | Allow connection drawing |
184
+ | `elementsSelectable` | `boolean` | `true` | Allow click-to-select |
185
+ | `fitView` | `boolean` | `false` | Auto-fit viewport on mount |
186
+ | `showMiniMap` | `boolean` | `true` | Show minimap overlay |
187
+ | `showBackground` | `boolean` | `true` | Show dot grid |
188
+ | `backgroundGap` | `number` | `32` | Dot grid spacing |
189
+ | `minZoom` | `number` | `0.1` | Minimum zoom level |
190
+ | `maxZoom` | `number` | `4` | Maximum zoom level |
191
+
192
+ ## Examples
193
+
194
+ 9 interactive examples ship as a runnable Vite app:
195
+
196
+ ```bash
197
+ cd examples && npm install && npm run dev
198
+ ```
199
+
200
+ Open [localhost:5173](http://localhost:5173) — sidebar navigation across all demos:
201
+
202
+ | Example | What it shows |
203
+ |---|---|
204
+ | **Basic Graph** | Simplest usage — 3 nodes, 2 edges |
205
+ | **Custom Nodes** | Input/Processor/Output types with colored multi-handle |
206
+ | **Custom Edges** | Labeled, animated, and success edge styles |
207
+ | **Drag & Drop** | Palette panel, drag to create nodes |
208
+ | **Viewport Controls** | Programmatic zoom/fit toolbar via `useKGraph()` |
209
+ | **Interactive Callbacks** | Real-time event log for all interactions |
210
+ | **Canvas Options** | Runtime toggle of every canvas prop |
211
+ | **Large Graph** | 80-node grid for performance testing |
212
+ | **MiniMap & Background** | Category-colored pipeline with minimap |
213
+
214
+ All examples include drag & drop, right-click context menus, and connection drawing.
215
+
216
+ See [EXAMPLES.md](./EXAMPLES.md) for detailed docs on each one.
217
+
218
+ ## Migrating from ReactFlow
219
+
220
+ KGraph's API is designed for easy migration:
221
+
222
+ - `<ReactFlow>` → `<KGraphCanvas>`
223
+ - `<ReactFlowProvider>` → not needed (provider is built in)
224
+ - `useReactFlow()` → `useKGraph()`
225
+ - `applyNodeChanges` / `applyEdgeChanges` → same function names, same behavior
226
+ - `getBezierPath` → same function name, same return signature
227
+ - `Node<T>` → `KGraphNode`, `Edge<T>` → `KGraphEdge`
228
+ - Remove your ReactFlow CSS import — KGraph uses inline styles
229
+
230
+ See [COMPARISON.md](./COMPARISON.md) for a full feature matrix against ReactFlow, React Diagrams, Reaflow, and X6.
231
+
232
+ ## Contributing
233
+
234
+ ```bash
235
+ git clone https://github.com/quantumwake/kgraph.git
236
+ cd kgraph
237
+ npm install
238
+ npm run build # builds dist/
239
+ npm run dev # watch mode
240
+ npm run lint # type-check
241
+ ```
242
+
243
+ ## License
244
+
245
+ [MIT](./LICENSE)