Data
File Tree
A tree of folders and files with the icons already wired up: the folder icon switches between closed and open, files get a document icon, and folders get a chevron. Built on Tree View, so every Tree View prop works here too.
Pass plain data (id, name, children) instead of writing a render function. Use TreeView directly when you need checkboxes, renaming or a fully custom row.
Import
import { FileTree } from "@indoku/ui"Anatomy
<FileTree items={[{ id, name, children?, icon? }]} />node with children (even []) -> folder: chevron + folder icon (closed or open) + namenode without children -> file: file icon + nameExamples
Default icons
Folders open and close, and the icon follows. Folders with an empty children array still count as folders.
Project
function FileTreeBasic() { return <FileTree items={files} label="Project" defaultExpandedValue={["src"]} maxW="xs" />}Icons by file type
fileIcon accepts a function that receives the node, so you can choose an icon from the name or extension. folderIcon and folderOpenIcon take plain elements.
function FileTreeByExtension() { const iconFor = (node: FileTreeNode) => { const ext = node.name.split(".").pop() if (ext === "ts" || ext === "tsx") return <LuFileCode /> if (ext === "json") return <LuFileJson /> if (ext === "md") return <LuFileText /> if (ext === "png" || ext === "svg") return <LuImage /> return <LuFile /> } return ( <FileTree items={files} defaultExpandedValue={["src", "src/components"]} folderIcon={<LuFolder />} folderOpenIcon={<LuFolderOpen />} fileIcon={iconFor} maxW="xs" /> )}Icon on a single node
Set icon on a node to override the icon for that node, in both the open and closed state.
function FileTreeNodeIcon() { const items: FileTreeNode[] = [ { id: "docs", name: "docs", icon: <LuBookOpen />, children: [{ id: "docs/intro.md", name: "intro.md" }] }, { id: "src", name: "src", children: [{ id: "src/index.ts", name: "index.ts" }] }, ] return <FileTree items={items} defaultExpandedValue={["docs", "src"]} maxW="xs" />}Controlled
Use expandedValue and selectedValue to drive the tree from your own state. Values are node ids.
Selected: none
No chevron, no guides, multiple selection
Turn off the chevron with showChevron={false} and the guide lines with indentGuides={false}. selectionMode comes straight from Tree View.
function FileTreeMinimal() { return <FileTree items={files} showChevron={false} indentGuides={false} selectionMode="multiple" defaultExpandedValue={["src"]} maxW="xs" />}Props
FileTree
| Prop | Type | Default | Description |
|---|---|---|---|
items* | FileTreeNode[] | – | Top-level nodes. |
label | ReactNode | – | Heading shown above the tree. |
folderIcon | ReactNode | ((node: FileTreeNode) => ReactNode) | a folder icon | Icon of a closed folder. |
folderOpenIcon | ReactNode | ((node: FileTreeNode) => ReactNode) | an open folder icon | Icon of an open folder. |
fileIcon | ReactNode | ((node: FileTreeNode) => ReactNode) | a document icon | Icon of a file; pass a function to choose by name or extension. |
showChevron | boolean | true | Show the chevron before folders. |
indentGuides | boolean | true | Vertical guide lines for nested levels. |
* required. Style props and HTML attributes are accepted as well.
Accessibility
- Same behavior as Tree View: WAI-ARIA tree pattern, arrow keys to move and expand or collapse, Home and End, Enter or Space to select.
- Default icons are decorative (
aria-hidden). When you pass your own icons, keep them decorative too; the node name carries the meaning.
Notes
itemsshould be a stable reference (module constant oruseMemo). A new array on every render rebuilds the tree.- Node
idmust be unique across the whole tree, not just among siblings. Paths such assrc/components/button.tsxwork well. - Default icons are inline SVG, so the component adds no icon dependency. Any React element works as a custom icon.
Created by @indokudev