@og-mcp/reactflow-mcp 1.0.4 → 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.
@@ -7,37 +7,37 @@ const useReactFlowHook = {
7
7
  description: "Returns a ReactFlowInstance to update nodes/edges, manipulate the viewport, or query flow state. Does NOT cause re-renders on state changes.",
8
8
  importPath: "import { useReactFlow } from '@xyflow/react'",
9
9
  returns: "ReactFlowInstance",
10
- usage: `const { getNodes, setNodes, addNodes, getEdges, setEdges, addEdges,
11
- fitView, zoomIn, zoomOut, getViewport, setViewport,
12
- screenToFlowPosition, deleteElements, updateNode, updateNodeData,
10
+ usage: `const { getNodes, setNodes, addNodes, getEdges, setEdges, addEdges,
11
+ fitView, zoomIn, zoomOut, getViewport, setViewport,
12
+ screenToFlowPosition, deleteElements, updateNode, updateNodeData,
13
13
  getIntersectingNodes, toObject } = useReactFlow();`,
14
14
  examples: [
15
15
  {
16
16
  title: "Add node on button click",
17
17
  category: "interaction",
18
- code: `function AddNodeButton() {
19
- const { addNodes, screenToFlowPosition } = useReactFlow();
20
- const onClick = () => {
21
- addNodes({
22
- id: crypto.randomUUID(),
23
- position: screenToFlowPosition({ x: 200, y: 200 }),
24
- data: { label: 'New Node' },
25
- });
26
- };
27
- return <button onClick={onClick}>Add Node</button>;
18
+ code: `function AddNodeButton() {
19
+ const { addNodes, screenToFlowPosition } = useReactFlow();
20
+ const onClick = () => {
21
+ addNodes({
22
+ id: crypto.randomUUID(),
23
+ position: screenToFlowPosition({ x: 200, y: 200 }),
24
+ data: { label: 'New Node' },
25
+ });
26
+ };
27
+ return <button onClick={onClick}>Add Node</button>;
28
28
  }`,
29
29
  },
30
30
  {
31
31
  title: "Delete selected elements",
32
32
  category: "interaction",
33
- code: `function DeleteButton() {
34
- const { deleteElements, getNodes, getEdges } = useReactFlow();
35
- const onClick = async () => {
36
- const selectedNodes = getNodes().filter((n) => n.selected);
37
- const selectedEdges = getEdges().filter((e) => e.selected);
38
- await deleteElements({ nodes: selectedNodes, edges: selectedEdges });
39
- };
40
- return <button onClick={onClick}>Delete Selected</button>;
33
+ code: `function DeleteButton() {
34
+ const { deleteElements, getNodes, getEdges } = useReactFlow();
35
+ const onClick = async () => {
36
+ const selectedNodes = getNodes().filter((n) => n.selected);
37
+ const selectedEdges = getEdges().filter((e) => e.selected);
38
+ await deleteElements({ nodes: selectedNodes, edges: selectedEdges });
39
+ };
40
+ return <button onClick={onClick}>Delete Selected</button>;
41
41
  }`,
42
42
  },
43
43
  ],
@@ -54,33 +54,33 @@ const useNodesStateHook = {
54
54
  description: "Like React's useState but with a built-in change handler for nodes. Quick prototyping of controlled flows without Zustand.",
55
55
  importPath: "import { useNodesState } from '@xyflow/react'",
56
56
  returns: "[Node[], setNodes, onNodesChange]",
57
- usage: `const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
58
-
57
+ usage: `const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
58
+
59
59
  <ReactFlow nodes={nodes} onNodesChange={onNodesChange} />`,
60
60
  examples: [
61
61
  {
62
62
  title: "Minimal controlled flow",
63
63
  category: "quickstart",
64
- code: `import { ReactFlow, useNodesState, useEdgesState, addEdge } from '@xyflow/react';
65
-
66
- const initialNodes = [
67
- { id: '1', position: { x: 0, y: 0 }, data: { label: 'A' } },
68
- { id: '2', position: { x: 200, y: 100 }, data: { label: 'B' } },
69
- ];
70
- const initialEdges = [{ id: 'e1-2', source: '1', target: '2' }];
71
-
72
- export default function Flow() {
73
- const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
74
- const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
75
- const onConnect = useCallback((connection) => setEdges((eds) => addEdge(connection, eds)), [setEdges]);
76
-
77
- return (
78
- <ReactFlow
79
- nodes={nodes} edges={edges}
80
- onNodesChange={onNodesChange} onEdgesChange={onEdgesChange}
81
- onConnect={onConnect} fitView
82
- />
83
- );
64
+ code: `import { ReactFlow, useNodesState, useEdgesState, addEdge } from '@xyflow/react';
65
+
66
+ const initialNodes = [
67
+ { id: '1', position: { x: 0, y: 0 }, data: { label: 'A' } },
68
+ { id: '2', position: { x: 200, y: 100 }, data: { label: 'B' } },
69
+ ];
70
+ const initialEdges = [{ id: 'e1-2', source: '1', target: '2' }];
71
+
72
+ export default function Flow() {
73
+ const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
74
+ const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
75
+ const onConnect = useCallback((connection) => setEdges((eds) => addEdge(connection, eds)), [setEdges]);
76
+
77
+ return (
78
+ <ReactFlow
79
+ nodes={nodes} edges={edges}
80
+ onNodesChange={onNodesChange} onEdgesChange={onEdgesChange}
81
+ onConnect={onConnect} fitView
82
+ />
83
+ );
84
84
  }`,
85
85
  },
86
86
  ],
@@ -125,24 +125,24 @@ const useNodesDataHook = {
125
125
  description: "Subscribe to data changes of specific nodes by ID. More efficient than useNodes when you only need certain nodes' data.",
126
126
  importPath: "import { useNodesData } from '@xyflow/react'",
127
127
  returns: "Pick<Node, 'id' | 'data' | 'type'>[]",
128
- usage: `const nodesData = useNodesData(['node-1', 'node-2']);
129
- // or single node:
128
+ usage: `const nodesData = useNodesData(['node-1', 'node-2']);
129
+ // or single node:
130
130
  const nodeData = useNodesData('node-1');`,
131
131
  examples: [
132
132
  {
133
133
  title: "Display connected node data",
134
134
  category: "custom-nodes",
135
- code: `function DisplayNode({ id }) {
136
- const connections = useHandleConnections({ type: 'target' });
137
- const sourceIds = connections.map((c) => c.source);
138
- const sourcesData = useNodesData(sourceIds);
139
-
140
- return (
141
- <div>
142
- <Handle type="target" position={Position.Left} />
143
- <div>Connected sources: {sourcesData.map((d) => d.data.label).join(', ')}</div>
144
- </div>
145
- );
135
+ code: `function DisplayNode({ id }) {
136
+ const connections = useHandleConnections({ type: 'target' });
137
+ const sourceIds = connections.map((c) => c.source);
138
+ const sourcesData = useNodesData(sourceIds);
139
+
140
+ return (
141
+ <div>
142
+ <Handle type="target" position={Position.Left} />
143
+ <div>Connected sources: {sourcesData.map((d) => d.data.label).join(', ')}</div>
144
+ </div>
145
+ );
146
146
  }`,
147
147
  },
148
148
  ],
@@ -154,9 +154,9 @@ const useNodeIdHook = {
154
154
  description: "Returns the ID of the node it is used inside. Useful deep in the render tree without prop drilling.",
155
155
  importPath: "import { useNodeId } from '@xyflow/react'",
156
156
  returns: "string | null",
157
- usage: `function DeepChildComponent() {
158
- const nodeId = useNodeId();
159
- return <span>Node: {nodeId}</span>;
157
+ usage: `function DeepChildComponent() {
158
+ const nodeId = useNodeId();
159
+ return <span>Node: {nodeId}</span>;
160
160
  }`,
161
161
  examples: [],
162
162
  relatedApis: ["useInternalNode", "useNodesData"],
@@ -167,24 +167,24 @@ const useConnectionHook = {
167
167
  description: "Returns the current connection state during an active connection interaction. Returns null properties when no connection is active. Useful for colorizing handles based on validity.",
168
168
  importPath: "import { useConnection } from '@xyflow/react'",
169
169
  returns: "ConnectionState",
170
- usage: `const connection = useConnection();
170
+ usage: `const connection = useConnection();
171
171
  // connection.inProgress, connection.fromNode, connection.fromHandle, etc.`,
172
172
  examples: [
173
173
  {
174
174
  title: "Colorize handle during connection",
175
175
  category: "connections",
176
- code: `function CustomHandle({ type, position, id }) {
177
- const connection = useConnection();
178
- const isTarget = connection.inProgress && connection.fromNode?.id !== useNodeId();
179
-
180
- return (
181
- <Handle
182
- type={type}
183
- position={position}
184
- id={id}
185
- style={{ background: isTarget ? '#22c55e' : '#6b7280' }}
186
- />
187
- );
176
+ code: `function CustomHandle({ type, position, id }) {
177
+ const connection = useConnection();
178
+ const isTarget = connection.inProgress && connection.fromNode?.id !== useNodeId();
179
+
180
+ return (
181
+ <Handle
182
+ type={type}
183
+ position={position}
184
+ id={id}
185
+ style={{ background: isTarget ? '#22c55e' : '#6b7280' }}
186
+ />
187
+ );
188
188
  }`,
189
189
  },
190
190
  ],
@@ -215,11 +215,11 @@ const useOnSelectionChangeHook = {
215
215
  kind: "hook",
216
216
  description: "Listen for changes to both node and edge selection.",
217
217
  importPath: "import { useOnSelectionChange } from '@xyflow/react'",
218
- usage: `useOnSelectionChange({
219
- onChange: ({ nodes, edges }) => {
220
- console.log('Selected nodes:', nodes);
221
- console.log('Selected edges:', edges);
222
- },
218
+ usage: `useOnSelectionChange({
219
+ onChange: ({ nodes, edges }) => {
220
+ console.log('Selected nodes:', nodes);
221
+ console.log('Selected edges:', edges);
222
+ },
223
223
  });`,
224
224
  examples: [],
225
225
  relatedApis: ["useReactFlow", "ReactFlow"],
@@ -229,10 +229,10 @@ const useOnViewportChangeHook = {
229
229
  kind: "hook",
230
230
  description: "Listen for viewport changes (pan, zoom). Provides callbacks for start, change, and end phases.",
231
231
  importPath: "import { useOnViewportChange } from '@xyflow/react'",
232
- usage: `useOnViewportChange({
233
- onStart: (viewport) => console.log('move start', viewport),
234
- onChange: (viewport) => console.log('moving', viewport),
235
- onEnd: (viewport) => console.log('move end', viewport),
232
+ usage: `useOnViewportChange({
233
+ onStart: (viewport) => console.log('move start', viewport),
234
+ onChange: (viewport) => console.log('moving', viewport),
235
+ onEnd: (viewport) => console.log('move end', viewport),
236
236
  });`,
237
237
  examples: [],
238
238
  relatedApis: ["useViewport", "useReactFlow"],
@@ -253,7 +253,7 @@ const useStoreHook = {
253
253
  kind: "hook",
254
254
  description: "Subscribe to internal React Flow Zustand store. Re-exported from Zustand. Use selectors to minimize re-renders.",
255
255
  importPath: "import { useStore } from '@xyflow/react'",
256
- usage: `const nodes = useStore((state) => state.nodes);
256
+ usage: `const nodes = useStore((state) => state.nodes);
257
257
  const zoom = useStore((state) => state.transform[2]);`,
258
258
  examples: [],
259
259
  tips: ["Always use a selector function to avoid re-rendering on every state change.", "For most use cases, prefer useReactFlow, useNodes, or useEdges instead."],
@@ -265,8 +265,8 @@ const useStoreApiHook = {
265
265
  description: "Returns the Zustand store object directly for on-demand state access without causing re-renders.",
266
266
  importPath: "import { useStoreApi } from '@xyflow/react'",
267
267
  returns: "StoreApi",
268
- usage: `const store = useStoreApi();
269
- // Access state on demand:
268
+ usage: `const store = useStoreApi();
269
+ // Access state on demand:
270
270
  const nodes = store.getState().nodes;`,
271
271
  examples: [],
272
272
  relatedApis: ["useStore", "useReactFlow"],
@@ -277,29 +277,29 @@ const useNodesInitializedHook = {
277
277
  description: "Returns whether all nodes have been measured and given width/height. Returns false when new nodes are added, then true once measured.",
278
278
  importPath: "import { useNodesInitialized } from '@xyflow/react'",
279
279
  returns: "boolean",
280
- usage: `const initialized = useNodesInitialized();
281
-
282
- useEffect(() => {
283
- if (initialized) {
284
- // Safe to run layout algorithms or fitView
285
- }
280
+ usage: `const initialized = useNodesInitialized();
281
+
282
+ useEffect(() => {
283
+ if (initialized) {
284
+ // Safe to run layout algorithms or fitView
285
+ }
286
286
  }, [initialized]);`,
287
287
  examples: [
288
288
  {
289
289
  title: "Auto-layout on mount",
290
290
  category: "layout",
291
- code: `function LayoutFlow() {
292
- const { fitView } = useReactFlow();
293
- const initialized = useNodesInitialized();
294
-
295
- useEffect(() => {
296
- if (initialized) {
297
- // Run Dagre/ELK layout here, then fitView
298
- fitView({ duration: 300 });
299
- }
300
- }, [initialized, fitView]);
301
-
302
- return <ReactFlow nodes={nodes} edges={edges} />;
291
+ code: `function LayoutFlow() {
292
+ const { fitView } = useReactFlow();
293
+ const initialized = useNodesInitialized();
294
+
295
+ useEffect(() => {
296
+ if (initialized) {
297
+ // Run Dagre/ELK layout here, then fitView
298
+ fitView({ duration: 300 });
299
+ }
300
+ }, [initialized, fitView]);
301
+
302
+ return <ReactFlow nodes={nodes} edges={edges} />;
303
303
  }`,
304
304
  },
305
305
  ],
@@ -311,8 +311,8 @@ const useUpdateNodeInternalsHook = {
311
311
  description: "Notify React Flow when you programmatically add/remove handles or change handle positions on a node.",
312
312
  importPath: "import { useUpdateNodeInternals } from '@xyflow/react'",
313
313
  returns: "(nodeId: string | string[]) => void",
314
- usage: `const updateNodeInternals = useUpdateNodeInternals();
315
- // After modifying handles:
314
+ usage: `const updateNodeInternals = useUpdateNodeInternals();
315
+ // After modifying handles:
316
316
  updateNodeInternals('node-1');`,
317
317
  examples: [],
318
318
  tips: ["Call this after dynamically adding/removing Handle components inside a custom node."],
@@ -324,7 +324,7 @@ const useKeyPressHook = {
324
324
  description: "Listen for specific key codes and returns whether they are currently pressed.",
325
325
  importPath: "import { useKeyPress } from '@xyflow/react'",
326
326
  returns: "boolean",
327
- usage: `const shiftPressed = useKeyPress('Shift');
327
+ usage: `const shiftPressed = useKeyPress('Shift');
328
328
  const ctrlZ = useKeyPress(['Control+z', 'Meta+z']);`,
329
329
  examples: [],
330
330
  relatedApis: ["ReactFlow"],
@@ -335,7 +335,7 @@ const useInternalNodeHook = {
335
335
  description: "Returns an InternalNode object with additional computed properties like positionAbsolute and measured dimensions.",
336
336
  importPath: "import { useInternalNode } from '@xyflow/react'",
337
337
  returns: "InternalNode | undefined",
338
- usage: `const internalNode = useInternalNode('node-1');
338
+ usage: `const internalNode = useInternalNode('node-1');
339
339
  // internalNode.internals.positionAbsolute, internalNode.measured.width, etc.`,
340
340
  examples: [],
341
341
  relatedApis: ["useReactFlow", "useNodeId"],
@@ -1,48 +1,48 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.V12_MIGRATION = void 0;
4
- exports.V12_MIGRATION = `# React Flow v12 Migration Guide (from v11)
5
-
6
- ## Package Change
7
- \`\`\`bash
8
- # Remove old package
9
- npm uninstall reactflow
10
-
11
- # Install v12
12
- npm install @xyflow/react
13
- \`\`\`
14
-
15
- ## Import Changes
16
- \`\`\`tsx
17
- // v11 (OLD)
18
- import ReactFlow, { Background, Controls } from 'reactflow';
19
- import 'reactflow/dist/style.css';
20
-
21
- // v12 (NEW)
22
- import { ReactFlow, Background, Controls } from '@xyflow/react';
23
- import '@xyflow/react/dist/style.css';
24
- \`\`\`
25
-
26
- ## Key Breaking Changes
27
-
28
- | v11 | v12 |
29
- |-----|-----|
30
- | \`node.width\` / \`node.height\` | \`node.measured.width\` / \`node.measured.height\` |
31
- | \`nodeInternals\` | \`nodeLookup\` |
32
- | \`project()\` | \`screenToFlowPosition()\` |
33
- | \`getNode(id)\` returns \`null\` | \`getNode(id)\` returns \`undefined\` |
34
- | \`getEdge(id)\` returns \`null\` | \`getEdge(id)\` returns \`undefined\` |
35
- | Default export | Named export: \`{ ReactFlow }\` |
36
- | \`onEdgeUpdate\` | \`onReconnect\` |
37
- | \`edgesUpdatable\` | \`edgesReconnectable\` |
38
- | \`updateEdge()\` util | \`reconnectEdge()\` util |
39
-
40
- ## Type Changes
41
- \`\`\`tsx
42
- // v11: generic data in Node type
43
- type MyNode = Node<{ label: string }>;
44
-
45
- // v12: data AND type in generic
46
- type MyNode = Node<{ label: string }, 'customType'>;
47
- \`\`\`
4
+ exports.V12_MIGRATION = `# React Flow v12 Migration Guide (from v11)
5
+
6
+ ## Package Change
7
+ \`\`\`bash
8
+ # Remove old package
9
+ npm uninstall reactflow
10
+
11
+ # Install v12
12
+ npm install @xyflow/react
13
+ \`\`\`
14
+
15
+ ## Import Changes
16
+ \`\`\`tsx
17
+ // v11 (OLD)
18
+ import ReactFlow, { Background, Controls } from 'reactflow';
19
+ import 'reactflow/dist/style.css';
20
+
21
+ // v12 (NEW)
22
+ import { ReactFlow, Background, Controls } from '@xyflow/react';
23
+ import '@xyflow/react/dist/style.css';
24
+ \`\`\`
25
+
26
+ ## Key Breaking Changes
27
+
28
+ | v11 | v12 |
29
+ |-----|-----|
30
+ | \`node.width\` / \`node.height\` | \`node.measured.width\` / \`node.measured.height\` |
31
+ | \`nodeInternals\` | \`nodeLookup\` |
32
+ | \`project()\` | \`screenToFlowPosition()\` |
33
+ | \`getNode(id)\` returns \`null\` | \`getNode(id)\` returns \`undefined\` |
34
+ | \`getEdge(id)\` returns \`null\` | \`getEdge(id)\` returns \`undefined\` |
35
+ | Default export | Named export: \`{ ReactFlow }\` |
36
+ | \`onEdgeUpdate\` | \`onReconnect\` |
37
+ | \`edgesUpdatable\` | \`edgesReconnectable\` |
38
+ | \`updateEdge()\` util | \`reconnectEdge()\` util |
39
+
40
+ ## Type Changes
41
+ \`\`\`tsx
42
+ // v11: generic data in Node type
43
+ type MyNode = Node<{ label: string }>;
44
+
45
+ // v12: data AND type in generic
46
+ type MyNode = Node<{ label: string }, 'customType'>;
47
+ \`\`\`
48
48
  `;