A React Flow-based mindmap template with automatic bidirectional layout using d3-flextree.
- Bidirectional mindmap layout (branches extend left and right from center)
- Auto-layout calculation using d3-flextree
- Drag from handle to create new nodes
- Click handle to toggle children visibility
- Double-click to edit node labels
- Delete nodes with Delete/Backspace key
- Built with React Flow v12
# Clone via degit
npx degit meo0/react-mindmap-template my-mindmap
cd my-mindmap
npm install
npm run devOr click "Use this template" on GitHub to create a new repository.
npm install
npm run devnpm run buildsrc/
├── App.tsx # Main application component
├── main.tsx # Entry point
├── index.css # Global styles
├── nodes/
│ ├── index.ts # Node types and initial data
│ ├── types.ts # TypeScript type definitions
│ └── MindmapNode.tsx # Custom mindmap node component
├── edges/
│ └── index.ts # Edge types and initial data
├── hooks/
│ └── useMindmapLayout.ts # Layout management hook
└── lib/
└── layout.ts # d3-flextree layout calculations
The template uses React Flow's built-in state management:
import { useNodesState, useEdgesState } from '@xyflow/react';
import { initialNodes, nodeTypes } from './nodes';
import { initialEdges, edgeTypes } from './edges';
import { useMindmapLayout } from './hooks/useMindmapLayout';
function App() {
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
const { autoLayout, getVisibleNodes, getVisibleEdges } = useMindmapLayout(
nodes,
edges,
setNodes,
{ rootNodeId: 'root' }
);
return (
<ReactFlow
nodes={getVisibleNodes()}
edges={getVisibleEdges()}
nodeTypes={nodeTypes}
// ...
/>
);
}Drag from a node's handle to empty space to create a new child node. The node will automatically be positioned based on the mindmap layout.
Click a node's handle (short drag) to toggle visibility of its children.
Click the "Auto Layout" button or call autoLayout() to recalculate positions.
Edit src/nodes/types.ts:
export type MindmapNodeData = {
label: string;
hidChildren?: boolean;
// Add your custom properties
memo?: string;
color?: string;
};Edit src/nodes/MindmapNode.tsx or src/index.css to customize node appearance.
Edit src/lib/layout.ts to adjust spacing:
const DEFAULT_NODE_WIDTH = 150;
const DEFAULT_NODE_HEIGHT = 40;
const NODE_SPACING_HORIZONTAL = 100;
const NODE_SPACING_VERTICAL = 8;function useMindmapLayout<T extends Node>(
nodes: T[],
edges: Edge[],
setNodes: Dispatch<SetStateAction<T[]>>,
options?: { rootNodeId?: string }
): {
autoLayout: () => void;
getVisibleNodes: () => T[];
getVisibleEdges: () => Edge[];
}calculateMindmapLayout(nodes, edges, rootNodeId)- Calculate bidirectional layoutcalculateLayout(nodes, edges, rootNodeId)- Calculate single-direction tree layoutgetFilteredNodes(nodes, edges)- Get visible nodes (respects hidChildren)getFilteredEdges(nodes, edges)- Get visible edges
@xyflow/react^12.5.1 - React Flowd3-flextree^2.1.2 - Flexible tree layoutuuid^11.1.0 - UUID generation
MIT
Based on React Flow Vite Template