Better file tree
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { Folder, FolderMinus, FolderPlus, File } from "lucide-react";
|
||||
|
||||
type TreeNode = {
|
||||
type: "directory" | "file";
|
||||
uri: string;
|
||||
children?: TreeNode[];
|
||||
};
|
||||
|
||||
interface FileTreeProps {
|
||||
tree: TreeNode;
|
||||
level?: number; // for indentation
|
||||
}
|
||||
|
||||
export const FileTree: React.FC<FileTreeProps> = ({ tree, level = 0 }) => {
|
||||
const [expanded, setExpanded] = useState(
|
||||
tree.type !== "directory" || level === 0 ? true : false,
|
||||
);
|
||||
|
||||
const toggleExpand = () => {
|
||||
if (tree.type === "directory") {
|
||||
setExpanded(!expanded);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
{/* Directory/File Row */}
|
||||
<div
|
||||
onClick={toggleExpand}
|
||||
style={{
|
||||
paddingLeft: level * 20,
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
cursor: tree.type === "directory" ? "pointer" : "default",
|
||||
userSelect: "none",
|
||||
}}
|
||||
>
|
||||
{tree.type === "directory" ? (
|
||||
expanded ? (
|
||||
<FolderMinus size={16} className="mr-2" />
|
||||
) : (
|
||||
<FolderPlus size={16} className="mr-2" />
|
||||
)
|
||||
) : (
|
||||
<File size={16} className="mr-2" />
|
||||
)}
|
||||
{tree.uri}
|
||||
</div>
|
||||
|
||||
{/* Children */}
|
||||
{expanded &&
|
||||
tree.children?.map((child) => (
|
||||
<FileTree key={child.uri} tree={child} level={level + 1} />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
+13
-5
@@ -1,12 +1,14 @@
|
||||
"use client";
|
||||
|
||||
import { FileTree } from "@sinm/react-file-tree";
|
||||
import CodeMirror, { EditorState } from "@uiw/react-codemirror";
|
||||
import { vscodeDark } from "@uiw/codemirror-theme-vscode";
|
||||
|
||||
import { Card, CardContent } from "@/components/ui/card";
|
||||
import RunTimer, { RunInfo } from "./components/RunTimer";
|
||||
import RunChat, { ChatMessage } from "./components/RunChat";
|
||||
import { useState } from "react";
|
||||
import { FileTree } from "./components/FileTree";
|
||||
import { File } from "lucide-react";
|
||||
|
||||
export default function Run() {
|
||||
const runInfo: RunInfo = {
|
||||
@@ -34,16 +36,22 @@ export default function Run() {
|
||||
tree={{
|
||||
type: "directory",
|
||||
uri: "my-app",
|
||||
expanded: true,
|
||||
children: [{ type: "file", uri: "myfile.js" }],
|
||||
children: [
|
||||
{ type: "file", uri: "myfile.js" },
|
||||
{
|
||||
type: "directory",
|
||||
uri: "my-app",
|
||||
children: [{ type: "file", uri: "myfile.js" }],
|
||||
},
|
||||
],
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Code */}
|
||||
<div className="flex-1 pl-5 flex flex-col">
|
||||
<header className="text-sm font-medium text-muted-foreground">
|
||||
myfile.js
|
||||
<header className="text-sm font-medium text-muted-foreground flex items-center gap-1">
|
||||
<File size={16} /> myfile.js
|
||||
</header>
|
||||
|
||||
<div className="flex-1 pt-3 pb-5">
|
||||
|
||||
Reference in New Issue
Block a user