| import React from "react"; |
| function parseTree(content) { |
| const lines = content.split("\n").filter(l => l.trim()); |
| const root = { name: "Root", children: [], level: -1 }; |
| const stack = [root]; |
| lines.forEach(line => { |
| const indentMatch = line.match(/^([ │]*)([├└]─+ )?(.*)$/); |
| if (!indentMatch) return; |
| const [_, indent, marker, name] = indentMatch; |
| const depth = Math.floor(indent.length / 4) + (marker ? 1 : 0); |
| const node = { name: name.trim(), children: [] }; |
| while (stack.length > depth + 1) { |
| stack.pop(); |
| } |
| stack[stack.length - 1].children.push(node); |
| stack.push(node); |
| }); |
| return root.children; |
| } |
| function TreeNode({ node, isLast }) { |
| const hasChildren = node.children && node.children.length > 0; |
| return ( |
| <div className={`tree-node-wrapper ${hasChildren ? 'has-children' : ''}`}> |
| <div className="tree-node-content"> |
| <div className="node-dot" /> |
| <span className="node-text">{node.name}</span> |
| </div> |
| {hasChildren && ( |
| <div className="tree-children-container"> |
| {node.children.map((child, idx) => ( |
| <TreeNode |
| key={idx} |
| node={child} |
| isLast={idx === node.children.length - 1} |
| /> |
| ))} |
| </div> |
| )} |
| </div> |
| ); |
| } |
| export function InteractiveTree({ content }) { |
| try { |
| const treeData = parseTree(content); |
| return ( |
| <div className="creative-tree-root"> |
| <div className="tree-background-grid" /> |
| <div className="tree-scroll-container"> |
| {treeData.map((rootNode, idx) => ( |
| <TreeNode key={idx} node={rootNode} isLast={idx === treeData.length - 1} /> |
| ))} |
| </div> |
| </div> |
| ); |
| } catch (e) { |
| return <pre className="ascii-tree-diagram"><code>{content}</code></pre>; |
| } |
| } |
|
|