Tree view displays hierarchical data with expand/collapse.
Code:
1import { useState } from "react";23interface TreeNode {4 id: string;5 label: string;6 children?: TreeNode[];7}89function TreeView({ nodes }: { nodes: TreeNode[] }) {10 return (11 <ul className="tree">12 {nodes.map(node => (13 <TreeItem key={node.id} node={node} />14 ))}15 </ul>16 );17}1819function TreeItem({ node }: { node: TreeNode }) {20 const [isOpen, setIsOpen] = useState(false);21 const hasChildren = node.children && node.children.length > 0;2223 return (24 <li>25 <div className="tree-item">26 {hasChildren && (27 <button28 className="toggle"29 onClick={() => setIsOpen(!isOpen)}30 aria-expanded={isOpen}31 >32 {isOpen ? "▼" : "▶"}33 </button>34 )}35 <span>{node.label}</span>36 </div>37 {hasChildren && isOpen && (38 <TreeView nodes={node.children!} />39 )}40 </li>41 );42}4344// Usage45const data: TreeNode[] = [46 {47 id: "1",48 label: "Root",49 children: [50 {51 id: "2",52 label: "Child 1",53 children: [54 { id: "3", label: "Grandchild 1" },55 { id: "4", label: "Grandchild 2" },56 ],57 },58 { id: "5", label: "Child 2" },59 ],60 },61];6263<TreeView nodes={data} />
With state management:
1function TreeView({ nodes, selectedId, onSelect }) {2 const [expandedIds, setExpandedIds] = useState<Set<string>>(new Set());34 const toggleExpand = (id: string) => {5 setExpandedIds(prev => {6 const next = new Set(prev);7 if (next.has(id)) next.delete(id);8 else next.add(id);9 return next;10 });11 };1213 // ... render with expandedIds and onSelect14}