@takazudo/mindmap-board
React component library for an interactive mind map with two view modes: an outline (collapsible tree list) and a visual mind map (SVG connector layout). Built on @takazudo/mindmap-parser for data types. The board keeps view settings explicit so a host can persist them with the owning frame.
Main Exports
import {
MindMapBoard,
OutlineView,
MindMapView,
MindMapNodeComponent,
SvgConnectors,
} from "@takazudo/mindmap-board";
import {
useMindMapKeyboard,
flattenVisibleNodes,
} from "@takazudo/mindmap-board";
import type {
MindMapBoardProps,
OutlineViewProps,
MindMapViewProps,
MindMapNodeProps,
SvgConnectorsProps,
ConnectorLine,
UseMindMapKeyboardOptions,
UseMindMapKeyboardReturn,
MindMapKeyBindings,
MindmapPlacement,
MindmapViewState,
} from "@takazudo/mindmap-board";MindMapBoard
The main container component. Renders either an outline view or a visual mind map depending on the view prop. Manages focus, collapse state, and inline editing internally.
import { MindMapBoard } from "@takazudo/mindmap-board";
import type { MindMapTree } from "@takazudo/mindmap-parser";
function MyMindMap({ tree }: { tree: MindMapTree }) {
return (
<MindMapBoard
tree={tree}
view="outline"
onNodeAdd={(parentId, label) => { /* ... */ }}
onNodeRemove={(nodeId) => { /* ... */ }}
onNodeLabelUpdate={(nodeId, newLabel) => { /* ... */ }}
/>
);
}Props
| Prop | Type | Description |
|---|---|---|
tree | MindMapTree | Tree data from mindmap-parser |
view | "outline" | "mindmap" | Which view to render |
onNodeAdd? | (parentId: string, label: string) => void | Called when a node is added |
onNodeRemove? | (nodeId: string) => void | Called when a node is deleted |
onNodeMove? | (nodeId: string, newParentId: string, index?: number) => void | Called when a node is reparented |
onNodeLabelUpdate? | (nodeId: string, newLabel: string) => void | Called when a node label is edited |
focusedNodeId? | string | null | Controlled focus state |
onFocusChange? | (nodeId: string | null) => void | Focus change callback |
mindmapViewState? | MindmapViewState | Map placement, node width, Outline density, and structure-guide settings |
onMindmapViewStateChange? | (state: MindmapViewState) => void | Called with a normalized view-state candidate; the host owns frame persistence (or can keep it controlled) |
MindmapViewState accepts placement: "free" | "vertical" | "horizontal", nodeWidthMode: "free" | "maxWidth" | "fixed", maxNodeWidth (clamped to 180–800px), fixedNodeWidth (clamped to 180–360px), outlineDensity: "comfortable" | "compact", and showStructureGuides. Free width measures every visible label without a cap; Max width caps measured labels at maxNodeWidth; Fixed gives all nodes the same fixedNodeWidth. Structured placements use orthogonal connectors and place collapsed badges outward on the right. Free placement retains each branch's remembered left/right side. Omitted or invalid values are normalized to the canonical defaults by the board; the package does not persist them itself. A dedicated frame host should serialize this state with that frame, while a Note Tray host may keep it session-local.
OutlineView
A collapsible tree list with indentation. Click triangle icons to fold/unfold branches. Double-click a node to edit its label inline.
import { OutlineView } from "@takazudo/mindmap-board";
<OutlineView
root={tree.root}
focusedNodeId={focusedId}
collapsedIds={collapsedSet}
onFocus={(nodeId) => setFocused(nodeId)}
onToggleCollapse={(nodeId) => toggleCollapse(nodeId)}
onLabelUpdate={(nodeId, newLabel) => updateLabel(nodeId, newLabel)}
/>Props
| Prop | Type | Description |
|---|---|---|
root | MindMapNode | Root node of the tree |
focusedNodeId | string | null | Currently focused node |
collapsedIds | Set<string> | Set of collapsed node IDs |
editingNodeId? | string | null | Node currently in inline-edit mode |
onFocus | (nodeId: string) => void | Focus callback |
onToggleCollapse | (nodeId: string) => void | Collapse toggle callback |
onLabelUpdate? | (nodeId: string, newLabel: string) => void | Label edit callback |
onEditStart? | (nodeId: string) => void | Called when inline edit begins |
onEditEnd? | () => void | Called when inline edit ends |
MindMapView
A visual tree layout with the root node centered and SVG connector lines linking parent and child nodes. Click to focus, double-click to edit.
Hooks
useMindMapKeyboard
Vim-style keyboard navigation for the mind map. Attaches a keydown listener to a container element.
import { useMindMapKeyboard } from "@takazudo/mindmap-board";
const { containerRef } = useMindMapKeyboard({
tree,
focusedNodeId,
collapsedIds,
onFocusChange: setFocused,
onToggleCollapse: toggleCollapse,
onAddNode: handleAdd,
onRemoveNode: handleRemove,
onEditNode: handleEdit,
view: "mindmap",
placement: "vertical",
});Default key bindings:
| Key | Action |
|---|---|
J / ArrowDown | Move focus to next visible node |
K / ArrowUp | Move focus to previous visible node |
H / ArrowLeft | Collapse current node (or move to parent) |
L / ArrowRight | Expand current node (or move to first child) |
Tab | Toggle collapse/expand |
O | Add child node |
A | Add sibling node |
D / Delete | Delete focused node |
E / Enter | Edit focused node label |
Escape | Clear focus |
Key bindings are configurable via the keyBindings option.
For a visual map, pass both view: "mindmap" and the current placement to useMindMapKeyboard. Free keeps the legacy side-aware arrow behavior and reads layoutSides; Vertical traverses visible preorder rows, with Left collapsing or returning to the parent and Right expanding or entering the first child. Horizontal treats the root as the upper-left anchor, uses Left/Right for top-level branch columns, and uses Up/Down for rootward/descendant movement within a branch. Structured navigation intentionally ignores Free's bilateral side map.
The board's small fold badge remains a compact visual disc inside a 44×44px hit area. Hosts should preserve that target floor for toolbar, Outline, zoom, find, focus, and settings controls at widths through 640px while avoiding horizontal overflow.
flattenVisibleNodes
Utility that flattens a tree into a visible node list, skipping children of collapsed nodes. Used internally by useMindMapKeyboard.
import { flattenVisibleNodes } from "@takazudo/mindmap-board";
const visibleNodes = flattenVisibleNodes(tree.root, collapsedIds);Dependencies
@takazudo/mindmap-parser— tree data types@takazudo/color-themes— theme color tokens@takazudo/ui-components— shared UI components@panzoom/panzoom— pan and zoom for the visual mind-map viewPeer dependencies:
react >= 18,react-dom >= 18