Trie Viz
A top-down trie (prefix-tree) visualization. Inserts a set of words into a shared-prefix tree and renders each node as a labeled circle joined to its parent. End-of-word nodes carry a concentric inner ring marker — node = letter, inner ring = word ends here. Search-path highlighting lights up the trail of nodes traversed when looking up a prefix; dimUnrelated fades branches off the path.
Customize
Words
cat, car, cap, dog
Search
2
Installation
npx shadcn@latest add https://craftbits.dev/r/trie-viz.jsonUsage
import { TrieViz } from "@craft-bits/core";
<TrieViz words={["cat", "car", "cap", "dog"]} />Trace the lookup for a prefix and fade the rest of the tree:
<TrieViz
words={["cat", "car", "cap", "dog"]}
searchPath="car"
dimUnrelated
/>Understanding the component
- Words in, trie out. The component builds the trie internally from
words— order-independent and deterministic. Each child id is${parentId}-${char}so re-inserting the same word always lands on the same node (idempotent ids let you target them vianodeStyles). - Top-down auto-layout. Each node's
yisdepth * rowHeight. Forx, every parent gives each child a horizontal slice proportional to its leaf-count (a variant of the Reingold-Tilford "every leaf gets one column" heuristic). Children at each level sort by character so the layout doesn't depend on insertion order. - Concentric end-of-word marker. A node that completes a word renders a second, inner circle at ~60% of the outer radius. The outer ring still carries the character so the marker reads visually without needing a separate badge.
- Search-path highlighting.
searchPath="car"walks the trie one character at a time from the root, lighting every node it can reach as"highlight"and thickening the matching edges toSVG_TOKENS.edge.boldin the accent color. Partial prefixes work — the walk halts when a character isn't a child. - Optional
dimUnrelated. WhentruealongsidesearchPath, every node and edge that isn't on the path drops to the"dimmed"style (low-opacity fg fills). This is the "follow the trail" mode. - Reduced motion.
usePrefersReducedMotion()short-circuits every transition to{ duration: 0 }and skips the staggered fade-in entirely.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
words | readonly string[] | required | Words to insert into the trie. Order-independent. |
searchPath | string | — | Prefix to trace from the root. Reached nodes render as highlight. |
dimUnrelated | boolean | false | When true alongside searchPath, off-path nodes / edges render as dimmed. |
nodeStyles | Record<string, "default" | "highlight" | "visited" | "dimmed"> | — | Per-node override keyed by node id. Wins over searchPath / dimUnrelated. |
compact | boolean | false | Smaller node radius + tighter rows / cols. |
className | string | — | Merged onto the outer <svg>. |
Accessibility
- The outer
<svg>isrole="img"with anaria-labellisting the inserted words and the active search prefix when present ("Trie of words: cat, car, cap, dog. Search path: car"). - End-of-word markers are visual chrome — the readable narrative lives in
aria-label. - Every node carries
data-stateanddata-is-endso consumer CSS or test selectors don't have to inspect computed styles. - Color is never the only signal — letter labels render at every state, and the concentric inner ring marks end-of-word nodes without depending on hue.
- Motion respects
prefers-reduced-motion: node entries and edge draws collapse to instant when the user has opted out.
Credits
- Extracted from:
algoflashcards(src/lessons/primitives/viz/TrieViz.tsx). The original was a rich curriculum widget bundled with cascade explosions, reveal flips, trail-edge shatter states, ghost / mystery badges, and tappable trace overlays. The library extract is the trie primitive itself: layout + nodes + edges + end-of-word markers + search-path highlighting.