Skip to content

Instantly share code, notes, and snippets.

@satyam4p
Created November 14, 2024 06:42
Show Gist options
  • Save satyam4p/654b83454b4b686154ab5e54ab8617d9 to your computer and use it in GitHub Desktop.
Save satyam4p/654b83454b4b686154ab5e54ab8617d9 to your computer and use it in GitHub Desktop.
file explorere like ui
import { useState } from "react";
import "./styles.css";
const data = [
{
id: 1,
name: "README.md",
},
{
id: 2,
name: "Documents",
children: [
{
id: 3,
name: "Word.doc",
},
{
id: 4,
name: "Powerpoint.ppt",
},
],
},
{
id: 5,
name: "Downloads",
children: [
{
id: 6,
name: "unnamed.txt",
},
{
id: 7,
name: "Misc",
children: [
{
id: 8,
name: "foo.txt",
},
{
id: 9,
name: "bar.txt",
},
],
},
],
},
];
export default function FileExplorer({ data }) {
return <FileList data={data} level={1} />;
}
function FileList({ data, level }) {
let directories = data.filter((i) => i.children);
directories.sort((a, b) => a.name.localeCompare(b.name));
let nonDirectories = data.filter((i) => !i.children);
nonDirectories.sort((a, b) => a.name.localeCompare(b.name));
const finalDir = [...directories, ...nonDirectories];
return (
<ul className="file-list">
{finalDir.map((dir) => (
<FileObject key={dir.id} file={dir} level={level} />
))}
</ul>
);
}
function FileObject({ file, level }) {
const [isExpanded, expand] = useState(false);
const isDirectory = file.children?.length > 0;
const { children: fileChildren, name: fileName } = file;
return (
<li className="file-item">
<button
className={[
"file-item-button",
isDirectory && "file-item-button--directory",
]
.filter(Boolean)
.join(" ")}
onClick={isDirectory ? () => expand(!isExpanded) : () => {}}
>
{isDirectory ? `${fileName} [${isExpanded ? "-" : "+"}]` : fileName}
</button>
{fileChildren && fileChildren.length > 0 && isExpanded && (
<FileList data={fileChildren} level={level + 1} />
)}
</li>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment