Skip to content

TkxMindMap

import { TkxMindMap, type MindMapNode } from 'tekivex-ui';

TkxMindMap renders a recursive tree as a horizontal tidy layout (root on the left, children fanning out right) with cubic-Bezier SVG links and HTML-rendered, focusable nodes. It supports expand/collapse, full keyboard navigation, and either internal or controlled selection + collapse state. Use it for mind maps, outlines, taxonomies, decision trees — any hierarchy you want to browse and fold.

Pass a single root node; children nest via children.

import { TkxMindMap, type MindMapNode } from 'tekivex-ui';
const root: MindMapNode = {
id: 'root',
label: 'Product',
children: [
{ id: 'a', label: 'Frontend', children: [
{ id: 'a1', label: 'Components' },
{ id: 'a2', label: 'Theming' },
]},
{ id: 'b', label: 'Backend', collapsed: true, children: [
{ id: 'b1', label: 'API' },
]},
],
};
<TkxMindMap
root={root}
onSelect={(id) => console.log('selected', id)}
onToggle={(id, collapsed) => console.log(id, collapsed)}
/>;
PropTypeDefaultDescription
rootMindMapNoderequiredThe tree’s root node.
selectedIdstring | nullControlled selected node id. Omit for internal selection (defaults to the root).
collapsedIdsSet<string>Controlled set of collapsed ids. Omit to use internal collapse state.
onSelect(id: string, node: MindMapNode) => voidFired on click and keyboard move.
onToggle(id: string, nextCollapsed: boolean) => voidFired when a node is expanded/collapsed.
leafHeightnumber44Vertical px reserved per leaf.
levelWidthnumber200Horizontal px between depth levels.
nodeWidthnumber160Node card width in px.
classNamestring
styleCSSPropertiesMerged onto the scroll container.
interface MindMapNode {
id: string;
label: string;
children?: MindMapNode[]; // omit or [] for a leaf
color?: string; // accent for border, toggle dot, and the incoming link
collapsed?: boolean; // pre-collapsed at first render (seeds internal state)
data?: unknown; // free-form payload echoed to callbacks
}
  • Two independently controllable states. Selection (selectedId) and collapse (collapsedIds) are each separately controlled-or-uncontrolled. Omit either prop to let the component own that piece while still firing the matching callback.
  • node.collapsed only seeds internal state. It is read once to build the initial collapsed set; in controlled mode, drive folding via collapsedIds instead.
  • Keyboard model (focus the tree — it is role="tree"):
    • → — if the node is collapsed, expands it; otherwise moves to the first child.
    • ← — moves to the parent; at the root, collapses it.
    • ↑ / ↓ — move between siblings.
    • Enter / Space — toggle expand/collapse of the selected node.
  • Double-click a node with children to toggle it; the inline + / button on each parent also toggles (and stops propagation so it doesn’t also select).
  • Labels are sanitised with sanitizeString before render (and as the title tooltip), so untrusted labels can’t smuggle control characters.
  • Layout is leaf-count proportional: each subtree reserves vertical space by its visible leaf count and the parent sits at the centroid of its children — collapsing a branch reflows the whole map.
  • Nodes are absolutely positioned inside a scrollable box; the SVG link layer is aria-hidden and shifted so negative y positions stay in view.