back to logs
FILE TREE
a recursive file tree component built from an interview question. paste an indentation-based schema on the left and see the collapsible folder structure render live on the right.
use 2 spaces or tabs for nesting.
Preview
Source
"use client";import { useState, useCallback } from "react";interface FileTreeNode {name: string;children?: FileTreeNode[];}function getFileIcon(filename: string) {const ext = filename.split(".").pop()?.toLowerCase();const map: Record<string, string> = {json: "📋", ts: "🔷", tsx: "🔷", js: "🟨", jsx: "🟨",css: "🎨", md: "📝", mdx: "📝", png: "🖼️", svg: "🖼️",};return map[ext || ""] || "📄";}function TreeNode({ node, depth, path, expanded, onToggle }) {const isFolder = Boolean(node.children?.length);const isOpen = expanded.has(path);return (<div><divonClick={() => isFolder && onToggle(path)}style={{ paddingLeft: depth * 12 + 8, cursor: isFolder ? "pointer" : "default" }}className="flex items-center gap-1.5 py-1 text-sm font-mono hover:bg-accent/50 rounded">{isFolder ? (isOpen ? "📂" : "📁") : getFileIcon(node.name)}<span>{node.name}</span></div>{isFolder && isOpen && node.children.map((child, i) => (<TreeNode key={i} node={child} depth={depth + 1}path={`${path}/${child.name}`} expanded={expanded} onToggle={onToggle} />))}</div>);}export function FileTree({ data }) {const [expanded, setExpanded] = useState(new Set(["src"]));const toggle = useCallback((p) =>setExpanded(prev => { const n = new Set(prev); n.has(p) ? n.delete(p) : n.add(p); return n; }), []);return (<div className="rounded-lg border p-2 font-mono text-sm">{data.map((node, i) => (<TreeNode key={i} node={node} depth={0} path={node.name} expanded={expanded} onToggle={toggle} />))}</div>);}