A folder and file explorer with semantic tree navigation and file-type icons.
import { FileTree } from "@/components/ballmac/file-tree"
export default function FileTreeDemo() {
return (
<FileTree
className="w-full max-w-xs"
label="Project files"
defaultExpandedIds={["src", "app"]}
defaultSelectedId="dashboard"
files={[
{
id: "src",
label: "src",
type: "folder",
children: [
{
id: "app",
label: "app",
type: "folder",
children: [
{
id: "dashboard",
label: "dashboard.tsx",
type: "file",
extension: "tsx",
},
{
id: "layout",
label: "layout.tsx",
type: "file",
extension: "tsx",
},
],
},
{
id: "components",
label: "components",
type: "folder",
children: [
{
id: "chart",
label: "chart.tsx",
type: "file",
extension: "tsx",
},
],
},
],
},
{ id: "readme", label: "README.md", type: "file", extension: "md" },
]}
/>
)
}Installation
$ pnpm dlx shadcn@latest add @ballmac/file-treeInstall the dependencies.
$ pnpm add lucide-reactAdd the Ballmac items it builds on.
$ pnpm dlx shadcn@latest add @ballmac/tree-view @ballmac/i18nCopy the source into your project.
components/ballmac/file-tree.tsx// Ballmac UI: File Tree. https://ui.ballmac.com/components/file-tree "use client" import * as React from "react" import { FileCode2, FileText, Folder, FolderOpen } from "lucide-react" import { TreeView, type TreeNode } from "@/components/ballmac/tree-view" import { useMessages } from "@/lib/ballmac/i18n" type FileNode = TreeNode & { /** Folder or file type. Folders can contain children. */ type: "folder" | "file" /** Optional language or file extension used for the icon. */ extension?: string /** Nested files and folders. */ children?: FileNode[] } type FileTreeProps = Omit< React.ComponentProps<typeof TreeView>, "nodes" | "renderIcon" | "label" > & { /** Files and folders to display. */ files: FileNode[] /** Accessible name for the file tree. */ label?: string } function FileTree({ files, label, ...props }: FileTreeProps) { const msg = useMessages() label ??= msg("file-tree.label", "Files") return ( <TreeView data-slot="file-tree" nodes={files} label={label} renderIcon={(node, expanded) => { const file = node as FileNode if (file.type === "folder") return expanded ? ( <FolderOpen className="size-4" /> ) : ( <Folder className="size-4" /> ) return file.extension === "tsx" || file.extension === "ts" || file.extension === "js" ? ( <FileCode2 className="size-4" /> ) : ( <FileText className="size-4" /> ) }} {...props} /> ) } export { FileTree, type FileTreeProps, type FileNode }Update the import paths to match your project setup.
Usage
import { FileTree } from "@/components/ballmac/file-tree"The full example is in the Code tab above.
Examples
States and variants
import { FileTree } from "@/components/ballmac/file-tree"
export default function FileTreeStates() {
return (
<FileTree
className="w-full max-w-xs"
label="Documents"
files={[
{
id: "reports",
label: "Reports",
type: "folder",
children: [
{ id: "q3", label: "Q3 summary.md", type: "file", extension: "md" },
],
},
{ id: "notes", label: "Notes.txt", type: "file", extension: "txt" },
]}
/>
)
}API reference
| Prop | Type | Default |
|---|---|---|
files*Files and folders to display. | FileNode[] | — |
labelAccessible name for the file tree. | string | — |
Also accepts the standard attributes of its root element.
Accessibility
| Key | Action |
|---|---|
| Arrow keys / Home / End / Enter / Space | Navigates folders and selects files |
Use with AI
A folder and file explorer with semantic tree navigation and file-type icons. With the shadcn MCP server set up (guide), ask your agent:
Add the Ballmac UI File Tree (@ballmac/file-tree) to this project with the shadcn MCP, then use it where it fits.
Use it for
- Browse a project or document hierarchy
Not for
- Use Tree View for non-file hierarchies
Registry JSON: https://ui.ballmac.com/r/file-tree.json
Credits
Free to use in personal and commercial projects.
- npm
- lucide-react
- Registry
- @ballmac/tree-view@ballmac/i18n
Pairs well with
Tree View
A keyboard-operable hierarchical tree with selection, expansion, and optional node icons.
Activity Feed
A compact actor and action feed with timestamps and an empty state.
Audio Player
A podcast-style audio player: play and pause, skip back and forward, a scrubber with chapter ticks, a named current chapter and a speed control. Works with a real file or as a silent demo.
Avatar Circles
Overlapping avatars that spread on hover, lift individually with a name and role tooltip, show presence, fall back to initials and end in a +N count that can be a button.