@og-mcp/reactflow-mcp 1.0.5 → 1.0.6
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 -21
- package/README.md +74 -74
- package/dist/data/api-types.js +69 -69
- package/dist/data/components.js +217 -217
- package/dist/data/hooks.js +106 -106
- package/dist/data/migration.js +44 -44
- package/dist/data/patterns.js +582 -582
- package/dist/data/templates.js +126 -126
- package/dist/data/utilities.js +29 -29
- package/dist/index.js +0 -0
- package/dist/tools/cheatsheet.js +84 -84
- package/dist/tools/generate-flow.js +89 -89
- package/package.json +54 -54
package/dist/data/components.js
CHANGED
|
@@ -64,65 +64,65 @@ const reactFlowComponent = {
|
|
|
64
64
|
{ name: "autoPanOnConnect", type: "boolean", description: "Pan viewport when creating connections near edge.", default: "true" },
|
|
65
65
|
{ name: "autoPanOnNodeDrag", type: "boolean", description: "Pan viewport when dragging nodes near edge.", default: "true" },
|
|
66
66
|
],
|
|
67
|
-
usage: `import { ReactFlow, Background, Controls } from '@xyflow/react';
|
|
68
|
-
import '@xyflow/react/dist/style.css';
|
|
69
|
-
|
|
70
|
-
const nodes = [
|
|
71
|
-
{ id: '1', position: { x: 0, y: 0 }, data: { label: 'Node 1' } },
|
|
72
|
-
{ id: '2', position: { x: 200, y: 100 }, data: { label: 'Node 2' } },
|
|
73
|
-
];
|
|
74
|
-
const edges = [{ id: 'e1-2', source: '1', target: '2' }];
|
|
75
|
-
|
|
76
|
-
export default function Flow() {
|
|
77
|
-
return (
|
|
78
|
-
<div style={{ width: '100%', height: '100vh' }}>
|
|
79
|
-
<ReactFlow nodes={nodes} edges={edges} fitView>
|
|
80
|
-
<Background />
|
|
81
|
-
<Controls />
|
|
82
|
-
</ReactFlow>
|
|
83
|
-
</div>
|
|
84
|
-
);
|
|
67
|
+
usage: `import { ReactFlow, Background, Controls } from '@xyflow/react';
|
|
68
|
+
import '@xyflow/react/dist/style.css';
|
|
69
|
+
|
|
70
|
+
const nodes = [
|
|
71
|
+
{ id: '1', position: { x: 0, y: 0 }, data: { label: 'Node 1' } },
|
|
72
|
+
{ id: '2', position: { x: 200, y: 100 }, data: { label: 'Node 2' } },
|
|
73
|
+
];
|
|
74
|
+
const edges = [{ id: 'e1-2', source: '1', target: '2' }];
|
|
75
|
+
|
|
76
|
+
export default function Flow() {
|
|
77
|
+
return (
|
|
78
|
+
<div style={{ width: '100%', height: '100vh' }}>
|
|
79
|
+
<ReactFlow nodes={nodes} edges={edges} fitView>
|
|
80
|
+
<Background />
|
|
81
|
+
<Controls />
|
|
82
|
+
</ReactFlow>
|
|
83
|
+
</div>
|
|
84
|
+
);
|
|
85
85
|
}`,
|
|
86
86
|
examples: [
|
|
87
87
|
{
|
|
88
88
|
title: "Controlled flow with Zustand",
|
|
89
89
|
category: "state-management",
|
|
90
|
-
code: `import { ReactFlow } from '@xyflow/react';
|
|
91
|
-
import useFlowStore from './store';
|
|
92
|
-
|
|
93
|
-
const selector = (s) => ({
|
|
94
|
-
nodes: s.nodes, edges: s.edges,
|
|
95
|
-
onNodesChange: s.onNodesChange,
|
|
96
|
-
onEdgesChange: s.onEdgesChange,
|
|
97
|
-
onConnect: s.onConnect,
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
export default function Flow() {
|
|
101
|
-
const { nodes, edges, onNodesChange, onEdgesChange, onConnect } = useFlowStore(selector);
|
|
102
|
-
return (
|
|
103
|
-
<ReactFlow
|
|
104
|
-
nodes={nodes} edges={edges}
|
|
105
|
-
onNodesChange={onNodesChange}
|
|
106
|
-
onEdgesChange={onEdgesChange}
|
|
107
|
-
onConnect={onConnect}
|
|
108
|
-
fitView
|
|
109
|
-
/>
|
|
110
|
-
);
|
|
90
|
+
code: `import { ReactFlow } from '@xyflow/react';
|
|
91
|
+
import useFlowStore from './store';
|
|
92
|
+
|
|
93
|
+
const selector = (s) => ({
|
|
94
|
+
nodes: s.nodes, edges: s.edges,
|
|
95
|
+
onNodesChange: s.onNodesChange,
|
|
96
|
+
onEdgesChange: s.onEdgesChange,
|
|
97
|
+
onConnect: s.onConnect,
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
export default function Flow() {
|
|
101
|
+
const { nodes, edges, onNodesChange, onEdgesChange, onConnect } = useFlowStore(selector);
|
|
102
|
+
return (
|
|
103
|
+
<ReactFlow
|
|
104
|
+
nodes={nodes} edges={edges}
|
|
105
|
+
onNodesChange={onNodesChange}
|
|
106
|
+
onEdgesChange={onEdgesChange}
|
|
107
|
+
onConnect={onConnect}
|
|
108
|
+
fitView
|
|
109
|
+
/>
|
|
110
|
+
);
|
|
111
111
|
}`,
|
|
112
112
|
},
|
|
113
113
|
{
|
|
114
114
|
title: "Uncontrolled flow",
|
|
115
115
|
category: "quickstart",
|
|
116
|
-
code: `import { ReactFlow } from '@xyflow/react';
|
|
117
|
-
|
|
118
|
-
const defaultNodes = [
|
|
119
|
-
{ id: '1', position: { x: 0, y: 0 }, data: { label: 'Hello' } },
|
|
120
|
-
{ id: '2', position: { x: 200, y: 100 }, data: { label: 'World' } },
|
|
121
|
-
];
|
|
122
|
-
const defaultEdges = [{ id: 'e1-2', source: '1', target: '2' }];
|
|
123
|
-
|
|
124
|
-
export default function Flow() {
|
|
125
|
-
return <ReactFlow defaultNodes={defaultNodes} defaultEdges={defaultEdges} fitView />;
|
|
116
|
+
code: `import { ReactFlow } from '@xyflow/react';
|
|
117
|
+
|
|
118
|
+
const defaultNodes = [
|
|
119
|
+
{ id: '1', position: { x: 0, y: 0 }, data: { label: 'Hello' } },
|
|
120
|
+
{ id: '2', position: { x: 200, y: 100 }, data: { label: 'World' } },
|
|
121
|
+
];
|
|
122
|
+
const defaultEdges = [{ id: 'e1-2', source: '1', target: '2' }];
|
|
123
|
+
|
|
124
|
+
export default function Flow() {
|
|
125
|
+
return <ReactFlow defaultNodes={defaultNodes} defaultEdges={defaultEdges} fitView />;
|
|
126
126
|
}`,
|
|
127
127
|
},
|
|
128
128
|
],
|
|
@@ -147,15 +147,15 @@ const backgroundComponent = {
|
|
|
147
147
|
{ name: "color", type: "string", description: "Pattern color." },
|
|
148
148
|
{ name: "lineWidth", type: "number", description: "Stroke width for lines/cross variant.", default: "1" },
|
|
149
149
|
],
|
|
150
|
-
usage: `<ReactFlow nodes={nodes} edges={edges}>
|
|
151
|
-
<Background variant={BackgroundVariant.Dots} gap={20} size={1} />
|
|
150
|
+
usage: `<ReactFlow nodes={nodes} edges={edges}>
|
|
151
|
+
<Background variant={BackgroundVariant.Dots} gap={20} size={1} />
|
|
152
152
|
</ReactFlow>`,
|
|
153
153
|
examples: [
|
|
154
154
|
{
|
|
155
155
|
title: "Cross pattern background",
|
|
156
156
|
category: "styling",
|
|
157
|
-
code: `import { Background, BackgroundVariant } from '@xyflow/react';
|
|
158
|
-
|
|
157
|
+
code: `import { Background, BackgroundVariant } from '@xyflow/react';
|
|
158
|
+
|
|
159
159
|
<Background variant={BackgroundVariant.Cross} gap={24} size={2} color="#ddd" />`,
|
|
160
160
|
},
|
|
161
161
|
],
|
|
@@ -173,19 +173,19 @@ const controlsComponent = {
|
|
|
173
173
|
{ name: "position", type: "PanelPosition", description: "Corner position.", default: "'bottom-left'" },
|
|
174
174
|
{ name: "orientation", type: "'horizontal' | 'vertical'", description: "Layout direction.", default: "'vertical'" },
|
|
175
175
|
],
|
|
176
|
-
usage: `<ReactFlow nodes={nodes} edges={edges}>
|
|
177
|
-
<Controls position="bottom-left" />
|
|
176
|
+
usage: `<ReactFlow nodes={nodes} edges={edges}>
|
|
177
|
+
<Controls position="bottom-left" />
|
|
178
178
|
</ReactFlow>`,
|
|
179
179
|
examples: [
|
|
180
180
|
{
|
|
181
181
|
title: "Custom control button",
|
|
182
182
|
category: "interaction",
|
|
183
|
-
code: `import { Controls, ControlButton } from '@xyflow/react';
|
|
184
|
-
|
|
185
|
-
<Controls>
|
|
186
|
-
<ControlButton onClick={() => console.log('custom action')}>
|
|
187
|
-
<Icon />
|
|
188
|
-
</ControlButton>
|
|
183
|
+
code: `import { Controls, ControlButton } from '@xyflow/react';
|
|
184
|
+
|
|
185
|
+
<Controls>
|
|
186
|
+
<ControlButton onClick={() => console.log('custom action')}>
|
|
187
|
+
<Icon />
|
|
188
|
+
</ControlButton>
|
|
189
189
|
</Controls>`,
|
|
190
190
|
},
|
|
191
191
|
],
|
|
@@ -205,8 +205,8 @@ const miniMapComponent = {
|
|
|
205
205
|
{ name: "pannable", type: "boolean", description: "Allow panning via minimap.", default: "false" },
|
|
206
206
|
{ name: "zoomable", type: "boolean", description: "Allow zooming via minimap.", default: "false" },
|
|
207
207
|
],
|
|
208
|
-
usage: `<ReactFlow nodes={nodes} edges={edges}>
|
|
209
|
-
<MiniMap nodeColor={(n) => n.type === 'input' ? '#6366f1' : '#94a3b8'} pannable zoomable />
|
|
208
|
+
usage: `<ReactFlow nodes={nodes} edges={edges}>
|
|
209
|
+
<MiniMap nodeColor={(n) => n.type === 'input' ? '#6366f1' : '#94a3b8'} pannable zoomable />
|
|
210
210
|
</ReactFlow>`,
|
|
211
211
|
examples: [],
|
|
212
212
|
relatedApis: ["ReactFlow", "Background", "Controls"],
|
|
@@ -219,10 +219,10 @@ const panelComponent = {
|
|
|
219
219
|
props: [
|
|
220
220
|
{ name: "position", type: "PanelPosition", description: "Corner or side position. E.g. 'top-left', 'top-right', 'bottom-left', 'bottom-right'." },
|
|
221
221
|
],
|
|
222
|
-
usage: `<ReactFlow nodes={nodes} edges={edges}>
|
|
223
|
-
<Panel position="top-left">
|
|
224
|
-
<h3>Flow Title</h3>
|
|
225
|
-
</Panel>
|
|
222
|
+
usage: `<ReactFlow nodes={nodes} edges={edges}>
|
|
223
|
+
<Panel position="top-left">
|
|
224
|
+
<h3>Flow Title</h3>
|
|
225
|
+
</Panel>
|
|
226
226
|
</ReactFlow>`,
|
|
227
227
|
examples: [],
|
|
228
228
|
relatedApis: ["ReactFlow", "Controls", "MiniMap"],
|
|
@@ -242,31 +242,31 @@ const handleComponent = {
|
|
|
242
242
|
{ name: "isValidConnection", type: "IsValidConnection", description: "Custom validation logic for connections to this handle." },
|
|
243
243
|
{ name: "onConnect", type: "OnConnect", description: "Callback when connection is made to this handle." },
|
|
244
244
|
],
|
|
245
|
-
usage: `import { Handle, Position } from '@xyflow/react';
|
|
246
|
-
|
|
247
|
-
function CustomNode({ data }) {
|
|
248
|
-
return (
|
|
249
|
-
<>
|
|
250
|
-
<Handle type="target" position={Position.Left} />
|
|
251
|
-
<div>{data.label}</div>
|
|
252
|
-
<Handle type="source" position={Position.Right} />
|
|
253
|
-
</>
|
|
254
|
-
);
|
|
245
|
+
usage: `import { Handle, Position } from '@xyflow/react';
|
|
246
|
+
|
|
247
|
+
function CustomNode({ data }) {
|
|
248
|
+
return (
|
|
249
|
+
<>
|
|
250
|
+
<Handle type="target" position={Position.Left} />
|
|
251
|
+
<div>{data.label}</div>
|
|
252
|
+
<Handle type="source" position={Position.Right} />
|
|
253
|
+
</>
|
|
254
|
+
);
|
|
255
255
|
}`,
|
|
256
256
|
examples: [
|
|
257
257
|
{
|
|
258
258
|
title: "Multiple handles",
|
|
259
259
|
category: "custom-nodes",
|
|
260
|
-
code: `function MultiHandleNode({ data }) {
|
|
261
|
-
return (
|
|
262
|
-
<div className="p-4 border rounded bg-white">
|
|
263
|
-
<Handle type="target" position={Position.Top} id="a" />
|
|
264
|
-
<Handle type="target" position={Position.Left} id="b" />
|
|
265
|
-
<div>{data.label}</div>
|
|
266
|
-
<Handle type="source" position={Position.Bottom} id="c" />
|
|
267
|
-
<Handle type="source" position={Position.Right} id="d" />
|
|
268
|
-
</div>
|
|
269
|
-
);
|
|
260
|
+
code: `function MultiHandleNode({ data }) {
|
|
261
|
+
return (
|
|
262
|
+
<div className="p-4 border rounded bg-white">
|
|
263
|
+
<Handle type="target" position={Position.Top} id="a" />
|
|
264
|
+
<Handle type="target" position={Position.Left} id="b" />
|
|
265
|
+
<div>{data.label}</div>
|
|
266
|
+
<Handle type="source" position={Position.Bottom} id="c" />
|
|
267
|
+
<Handle type="source" position={Position.Right} id="d" />
|
|
268
|
+
</div>
|
|
269
|
+
);
|
|
270
270
|
}`,
|
|
271
271
|
},
|
|
272
272
|
],
|
|
@@ -293,29 +293,29 @@ const nodeResizerComponent = {
|
|
|
293
293
|
{ name: "lineStyle", type: "CSSProperties", description: "Style the resize border lines." },
|
|
294
294
|
{ name: "keepAspectRatio", type: "boolean", description: "Maintain aspect ratio when resizing.", default: "false" },
|
|
295
295
|
],
|
|
296
|
-
usage: `import { NodeResizer } from '@xyflow/react';
|
|
297
|
-
|
|
298
|
-
function ResizableNode({ data, selected }) {
|
|
299
|
-
return (
|
|
300
|
-
<>
|
|
301
|
-
<NodeResizer isVisible={selected} minWidth={100} minHeight={50} />
|
|
302
|
-
<div className="p-4">{data.label}</div>
|
|
303
|
-
</>
|
|
304
|
-
);
|
|
296
|
+
usage: `import { NodeResizer } from '@xyflow/react';
|
|
297
|
+
|
|
298
|
+
function ResizableNode({ data, selected }) {
|
|
299
|
+
return (
|
|
300
|
+
<>
|
|
301
|
+
<NodeResizer isVisible={selected} minWidth={100} minHeight={50} />
|
|
302
|
+
<div className="p-4">{data.label}</div>
|
|
303
|
+
</>
|
|
304
|
+
);
|
|
305
305
|
}`,
|
|
306
306
|
examples: [
|
|
307
307
|
{
|
|
308
308
|
title: "Resizable node with handles",
|
|
309
309
|
category: "custom-nodes",
|
|
310
|
-
code: `function ResizableNode({ data, selected }) {
|
|
311
|
-
return (
|
|
312
|
-
<>
|
|
313
|
-
<NodeResizer isVisible={selected} minWidth={150} minHeight={80} />
|
|
314
|
-
<Handle type="target" position={Position.Left} />
|
|
315
|
-
<div className="p-4 h-full flex items-center justify-center">{data.label}</div>
|
|
316
|
-
<Handle type="source" position={Position.Right} />
|
|
317
|
-
</>
|
|
318
|
-
);
|
|
310
|
+
code: `function ResizableNode({ data, selected }) {
|
|
311
|
+
return (
|
|
312
|
+
<>
|
|
313
|
+
<NodeResizer isVisible={selected} minWidth={150} minHeight={80} />
|
|
314
|
+
<Handle type="target" position={Position.Left} />
|
|
315
|
+
<div className="p-4 h-full flex items-center justify-center">{data.label}</div>
|
|
316
|
+
<Handle type="source" position={Position.Right} />
|
|
317
|
+
</>
|
|
318
|
+
);
|
|
319
319
|
}`,
|
|
320
320
|
},
|
|
321
321
|
],
|
|
@@ -333,18 +333,18 @@ const nodeToolbarComponent = {
|
|
|
333
333
|
{ name: "offset", type: "number", description: "Distance from node.", default: "10" },
|
|
334
334
|
{ name: "nodeId", type: "string | string[]", description: "Attach to specific node(s)." },
|
|
335
335
|
],
|
|
336
|
-
usage: `import { NodeToolbar, Position } from '@xyflow/react';
|
|
337
|
-
|
|
338
|
-
function ToolbarNode({ data }) {
|
|
339
|
-
return (
|
|
340
|
-
<>
|
|
341
|
-
<NodeToolbar position={Position.Top}>
|
|
342
|
-
<button>Edit</button>
|
|
343
|
-
<button>Delete</button>
|
|
344
|
-
</NodeToolbar>
|
|
345
|
-
<div className="p-4">{data.label}</div>
|
|
346
|
-
</>
|
|
347
|
-
);
|
|
336
|
+
usage: `import { NodeToolbar, Position } from '@xyflow/react';
|
|
337
|
+
|
|
338
|
+
function ToolbarNode({ data }) {
|
|
339
|
+
return (
|
|
340
|
+
<>
|
|
341
|
+
<NodeToolbar position={Position.Top}>
|
|
342
|
+
<button>Edit</button>
|
|
343
|
+
<button>Delete</button>
|
|
344
|
+
</NodeToolbar>
|
|
345
|
+
<div className="p-4">{data.label}</div>
|
|
346
|
+
</>
|
|
347
|
+
);
|
|
348
348
|
}`,
|
|
349
349
|
examples: [],
|
|
350
350
|
relatedApis: ["EdgeToolbar", "Handle"],
|
|
@@ -354,49 +354,49 @@ const edgeLabelRendererComponent = {
|
|
|
354
354
|
kind: "component",
|
|
355
355
|
description: "Portal for rendering complex HTML labels on edges. Since edges are SVG, this provides a div-based renderer positioned on top of edges.",
|
|
356
356
|
importPath: "import { EdgeLabelRenderer } from '@xyflow/react'",
|
|
357
|
-
usage: `import { EdgeLabelRenderer, getBezierPath } from '@xyflow/react';
|
|
358
|
-
|
|
359
|
-
function CustomEdge({ id, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition }) {
|
|
360
|
-
const [edgePath, labelX, labelY] = getBezierPath({ sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition });
|
|
361
|
-
|
|
362
|
-
return (
|
|
363
|
-
<>
|
|
364
|
-
<path id={id} className="react-flow__edge-path" d={edgePath} />
|
|
365
|
-
<EdgeLabelRenderer>
|
|
366
|
-
<div style={{ position: 'absolute', transform: \`translate(-50%, -50%) translate(\${labelX}px,\${labelY}px)\`, pointerEvents: 'all' }}
|
|
367
|
-
className="nodrag nopan">
|
|
368
|
-
<button onClick={() => console.log('delete', id)}>x</button>
|
|
369
|
-
</div>
|
|
370
|
-
</EdgeLabelRenderer>
|
|
371
|
-
</>
|
|
372
|
-
);
|
|
357
|
+
usage: `import { EdgeLabelRenderer, getBezierPath } from '@xyflow/react';
|
|
358
|
+
|
|
359
|
+
function CustomEdge({ id, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition }) {
|
|
360
|
+
const [edgePath, labelX, labelY] = getBezierPath({ sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition });
|
|
361
|
+
|
|
362
|
+
return (
|
|
363
|
+
<>
|
|
364
|
+
<path id={id} className="react-flow__edge-path" d={edgePath} />
|
|
365
|
+
<EdgeLabelRenderer>
|
|
366
|
+
<div style={{ position: 'absolute', transform: \`translate(-50%, -50%) translate(\${labelX}px,\${labelY}px)\`, pointerEvents: 'all' }}
|
|
367
|
+
className="nodrag nopan">
|
|
368
|
+
<button onClick={() => console.log('delete', id)}>x</button>
|
|
369
|
+
</div>
|
|
370
|
+
</EdgeLabelRenderer>
|
|
371
|
+
</>
|
|
372
|
+
);
|
|
373
373
|
}`,
|
|
374
374
|
examples: [
|
|
375
375
|
{
|
|
376
376
|
title: "Edge with delete button",
|
|
377
377
|
category: "custom-edges",
|
|
378
|
-
code: `function ButtonEdge({ id, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition }) {
|
|
379
|
-
const [edgePath, labelX, labelY] = getBezierPath({
|
|
380
|
-
sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition,
|
|
381
|
-
});
|
|
382
|
-
const { setEdges } = useReactFlow();
|
|
383
|
-
|
|
384
|
-
return (
|
|
385
|
-
<>
|
|
386
|
-
<BaseEdge path={edgePath} />
|
|
387
|
-
<EdgeLabelRenderer>
|
|
388
|
-
<div style={{
|
|
389
|
-
position: 'absolute',
|
|
390
|
-
transform: \`translate(-50%, -50%) translate(\${labelX}px,\${labelY}px)\`,
|
|
391
|
-
pointerEvents: 'all',
|
|
392
|
-
}} className="nodrag nopan">
|
|
393
|
-
<button onClick={() => setEdges((es) => es.filter((e) => e.id !== id))}>
|
|
394
|
-
Delete
|
|
395
|
-
</button>
|
|
396
|
-
</div>
|
|
397
|
-
</EdgeLabelRenderer>
|
|
398
|
-
</>
|
|
399
|
-
);
|
|
378
|
+
code: `function ButtonEdge({ id, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition }) {
|
|
379
|
+
const [edgePath, labelX, labelY] = getBezierPath({
|
|
380
|
+
sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition,
|
|
381
|
+
});
|
|
382
|
+
const { setEdges } = useReactFlow();
|
|
383
|
+
|
|
384
|
+
return (
|
|
385
|
+
<>
|
|
386
|
+
<BaseEdge path={edgePath} />
|
|
387
|
+
<EdgeLabelRenderer>
|
|
388
|
+
<div style={{
|
|
389
|
+
position: 'absolute',
|
|
390
|
+
transform: \`translate(-50%, -50%) translate(\${labelX}px,\${labelY}px)\`,
|
|
391
|
+
pointerEvents: 'all',
|
|
392
|
+
}} className="nodrag nopan">
|
|
393
|
+
<button onClick={() => setEdges((es) => es.filter((e) => e.id !== id))}>
|
|
394
|
+
Delete
|
|
395
|
+
</button>
|
|
396
|
+
</div>
|
|
397
|
+
</EdgeLabelRenderer>
|
|
398
|
+
</>
|
|
399
|
+
);
|
|
400
400
|
}`,
|
|
401
401
|
},
|
|
402
402
|
],
|
|
@@ -414,11 +414,11 @@ const baseEdgeComponent = {
|
|
|
414
414
|
{ name: "label", type: "ReactNode", description: "Edge label content." },
|
|
415
415
|
{ name: "interactionWidth", type: "number", description: "Width of invisible click target.", default: "20" },
|
|
416
416
|
],
|
|
417
|
-
usage: `import { BaseEdge, getStraightPath } from '@xyflow/react';
|
|
418
|
-
|
|
419
|
-
function CustomEdge({ sourceX, sourceY, targetX, targetY }) {
|
|
420
|
-
const [edgePath] = getStraightPath({ sourceX, sourceY, targetX, targetY });
|
|
421
|
-
return <BaseEdge path={edgePath} />;
|
|
417
|
+
usage: `import { BaseEdge, getStraightPath } from '@xyflow/react';
|
|
418
|
+
|
|
419
|
+
function CustomEdge({ sourceX, sourceY, targetX, targetY }) {
|
|
420
|
+
const [edgePath] = getStraightPath({ sourceX, sourceY, targetX, targetY });
|
|
421
|
+
return <BaseEdge path={edgePath} />;
|
|
422
422
|
}`,
|
|
423
423
|
examples: [],
|
|
424
424
|
relatedApis: ["EdgeLabelRenderer", "getBezierPath", "getSmoothStepPath"],
|
|
@@ -428,12 +428,12 @@ const viewportPortalComponent = {
|
|
|
428
428
|
kind: "component",
|
|
429
429
|
description: "Renders components in the same viewport coordinate system as nodes and edges. Content zooms and pans with the flow.",
|
|
430
430
|
importPath: "import { ViewportPortal } from '@xyflow/react'",
|
|
431
|
-
usage: `<ReactFlow nodes={nodes} edges={edges}>
|
|
432
|
-
<ViewportPortal>
|
|
433
|
-
<div style={{ position: 'absolute', transform: 'translate(100px, 100px)' }}>
|
|
434
|
-
I move with the flow!
|
|
435
|
-
</div>
|
|
436
|
-
</ViewportPortal>
|
|
431
|
+
usage: `<ReactFlow nodes={nodes} edges={edges}>
|
|
432
|
+
<ViewportPortal>
|
|
433
|
+
<div style={{ position: 'absolute', transform: 'translate(100px, 100px)' }}>
|
|
434
|
+
I move with the flow!
|
|
435
|
+
</div>
|
|
436
|
+
</ViewportPortal>
|
|
437
437
|
</ReactFlow>`,
|
|
438
438
|
examples: [],
|
|
439
439
|
relatedApis: ["ReactFlow", "Panel"],
|
|
@@ -446,17 +446,17 @@ const edgeToolbarComponent = {
|
|
|
446
446
|
props: [
|
|
447
447
|
{ name: "position", type: "Position", description: "Side of edge.", default: "Position.Top" },
|
|
448
448
|
],
|
|
449
|
-
usage: `import { EdgeToolbar } from '@xyflow/react';
|
|
450
|
-
|
|
451
|
-
function CustomEdge(props) {
|
|
452
|
-
return (
|
|
453
|
-
<>
|
|
454
|
-
<BaseEdge path={edgePath} />
|
|
455
|
-
<EdgeToolbar>
|
|
456
|
-
<button>Edit</button>
|
|
457
|
-
</EdgeToolbar>
|
|
458
|
-
</>
|
|
459
|
-
);
|
|
449
|
+
usage: `import { EdgeToolbar } from '@xyflow/react';
|
|
450
|
+
|
|
451
|
+
function CustomEdge(props) {
|
|
452
|
+
return (
|
|
453
|
+
<>
|
|
454
|
+
<BaseEdge path={edgePath} />
|
|
455
|
+
<EdgeToolbar>
|
|
456
|
+
<button>Edit</button>
|
|
457
|
+
</EdgeToolbar>
|
|
458
|
+
</>
|
|
459
|
+
);
|
|
460
460
|
}`,
|
|
461
461
|
examples: [],
|
|
462
462
|
relatedApis: ["NodeToolbar", "EdgeLabelRenderer"],
|
|
@@ -483,18 +483,18 @@ const nodeResizeControlComponent = {
|
|
|
483
483
|
{ name: "autoScale", type: "boolean", description: "Scale controls with zoom level.", default: "true" },
|
|
484
484
|
{ name: "resizeDirection", type: "'horizontal' | 'vertical'", description: "Constrain resize direction." },
|
|
485
485
|
],
|
|
486
|
-
usage: `import { NodeResizeControl } from '@xyflow/react';
|
|
487
|
-
import { GripVertical } from 'lucide-react';
|
|
488
|
-
|
|
489
|
-
function ResizableNode({ data, selected }) {
|
|
490
|
-
return (
|
|
491
|
-
<>
|
|
492
|
-
<NodeResizeControl minWidth={100} minHeight={50}>
|
|
493
|
-
<GripVertical className="w-3 h-3" />
|
|
494
|
-
</NodeResizeControl>
|
|
495
|
-
<div className="p-4">{data.label}</div>
|
|
496
|
-
</>
|
|
497
|
-
);
|
|
486
|
+
usage: `import { NodeResizeControl } from '@xyflow/react';
|
|
487
|
+
import { GripVertical } from 'lucide-react';
|
|
488
|
+
|
|
489
|
+
function ResizableNode({ data, selected }) {
|
|
490
|
+
return (
|
|
491
|
+
<>
|
|
492
|
+
<NodeResizeControl minWidth={100} minHeight={50}>
|
|
493
|
+
<GripVertical className="w-3 h-3" />
|
|
494
|
+
</NodeResizeControl>
|
|
495
|
+
<div className="p-4">{data.label}</div>
|
|
496
|
+
</>
|
|
497
|
+
);
|
|
498
498
|
}`,
|
|
499
499
|
examples: [],
|
|
500
500
|
tips: [
|
|
@@ -511,30 +511,30 @@ const controlButtonComponent = {
|
|
|
511
511
|
props: [
|
|
512
512
|
{ name: "...props", type: "ButtonHTMLAttributes<HTMLButtonElement>", description: "Any valid HTML button props." },
|
|
513
513
|
],
|
|
514
|
-
usage: `import { Controls, ControlButton } from '@xyflow/react';
|
|
515
|
-
|
|
516
|
-
<Controls>
|
|
517
|
-
<ControlButton onClick={() => alert('Magic!')} title="Do magic">
|
|
518
|
-
<span>✨</span>
|
|
519
|
-
</ControlButton>
|
|
514
|
+
usage: `import { Controls, ControlButton } from '@xyflow/react';
|
|
515
|
+
|
|
516
|
+
<Controls>
|
|
517
|
+
<ControlButton onClick={() => alert('Magic!')} title="Do magic">
|
|
518
|
+
<span>✨</span>
|
|
519
|
+
</ControlButton>
|
|
520
520
|
</Controls>`,
|
|
521
521
|
examples: [
|
|
522
522
|
{
|
|
523
523
|
title: "Custom control with layout button",
|
|
524
524
|
category: "interaction",
|
|
525
|
-
code: `import { Controls, ControlButton } from '@xyflow/react';
|
|
526
|
-
|
|
527
|
-
function FlowControls({ onLayout }) {
|
|
528
|
-
return (
|
|
529
|
-
<Controls>
|
|
530
|
-
<ControlButton onClick={() => onLayout('TB')} title="Vertical layout">
|
|
531
|
-
↕
|
|
532
|
-
</ControlButton>
|
|
533
|
-
<ControlButton onClick={() => onLayout('LR')} title="Horizontal layout">
|
|
534
|
-
↔
|
|
535
|
-
</ControlButton>
|
|
536
|
-
</Controls>
|
|
537
|
-
);
|
|
525
|
+
code: `import { Controls, ControlButton } from '@xyflow/react';
|
|
526
|
+
|
|
527
|
+
function FlowControls({ onLayout }) {
|
|
528
|
+
return (
|
|
529
|
+
<Controls>
|
|
530
|
+
<ControlButton onClick={() => onLayout('TB')} title="Vertical layout">
|
|
531
|
+
↕
|
|
532
|
+
</ControlButton>
|
|
533
|
+
<ControlButton onClick={() => onLayout('LR')} title="Horizontal layout">
|
|
534
|
+
↔
|
|
535
|
+
</ControlButton>
|
|
536
|
+
</Controls>
|
|
537
|
+
);
|
|
538
538
|
}`,
|
|
539
539
|
},
|
|
540
540
|
],
|
|
@@ -545,15 +545,15 @@ const reactFlowProviderComponent = {
|
|
|
545
545
|
kind: "component",
|
|
546
546
|
description: "Provides the React Flow context to child components. Required when using hooks like useReactFlow outside of the ReactFlow component.",
|
|
547
547
|
importPath: "import { ReactFlowProvider } from '@xyflow/react'",
|
|
548
|
-
usage: `import { ReactFlowProvider } from '@xyflow/react';
|
|
549
|
-
|
|
550
|
-
function App() {
|
|
551
|
-
return (
|
|
552
|
-
<ReactFlowProvider>
|
|
553
|
-
<Flow />
|
|
554
|
-
<Sidebar /> {/* Can use useReactFlow() here */}
|
|
555
|
-
</ReactFlowProvider>
|
|
556
|
-
);
|
|
548
|
+
usage: `import { ReactFlowProvider } from '@xyflow/react';
|
|
549
|
+
|
|
550
|
+
function App() {
|
|
551
|
+
return (
|
|
552
|
+
<ReactFlowProvider>
|
|
553
|
+
<Flow />
|
|
554
|
+
<Sidebar /> {/* Can use useReactFlow() here */}
|
|
555
|
+
</ReactFlowProvider>
|
|
556
|
+
);
|
|
557
557
|
}`,
|
|
558
558
|
examples: [],
|
|
559
559
|
tips: [
|