File size: 1,860 Bytes
0e9d509 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | 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>;
}
}
|