- Accordion
- Action Bar
- Alert Dialog
- Alert
- Announcement
- Aspect Ratio
- Autocomplete
- Avatar
- Badge
- Bottom Navigation
- Breadcrumb
- Button Group
- Button
- Calendar
- Card
- Carousel
- Chart
- Checkbox
- Circular Progress
- Circular Slider
- Clipboard
- Collapsible
- Color Picker
- Combobox
- Command
- Context Menu
- Data List
- Date Picker
- Dialog
- Drawer
- Editable
- Field
- File Upload
- Float
- Floating Panel
- Frame
- Hint
- Hover Card
- Image Cropper
- Input Group
- Input OTP
- Input
- Item
- Kbd
- Link Overlay
- Listbox
- Marquee
- Menu
- Native Select
- Number Input
- Pagination
- Popover
- Progress
- Prose
- QR Code
- Radio Group
- Rating
- Resizable
- Scroll Area
- Segment Group
- Select
- Separator
- Sheet
- Sidebar
- Signature Pad
- Skeleton
- Skip Nav
- Slider
- Spinner
- Status
- Steps
- Switch
- Table
- Tabs
- Textarea
- Timer
- Toast
- Toggle Group
- Toggle Tooltip
- Toggle
- Tooltip
- Tour
- Tree View
Installation
pnpm dlx shadcn@latest add https://shark.vini.one/r/tree-view.json
Usage
import { TreeView, TreeViewLabel, TreeViewTree, TreeViewNode, TreeViewBranch, TreeViewBranchItem, TreeViewBranchContent, TreeViewContent, TreeViewItem, createTreeCollection, } from "@/components/ui/tree-view";
const collection = createTreeCollection({ rootNode: { id: "ROOT", name: "", children: [...] }, }); const Example = () => ( <TreeView collection={collection}> <TreeViewTree> {collection.rootNode.children?.map((node, index) => ( <TreeNode indexPath={[index]} key={node.id} node={node} /> ))} </TreeViewTree> </TreeView> ) const TreeNode = (props: React.ComponentProps<typeof TreeViewNode>) => { const { node, indexPath } = props; return ( <TreeViewNode indexPath={indexPath} key={node.id} node={node}> {node.children ? ( <TreeViewBranch> <TreeViewBranchItem>{node.name}</TreeViewBranchItem> <TreeViewBranchContent> {node.children.map((child, index) => ( <TreeNode indexPath={[...indexPath, index]} key={child.id} node={child} /> ))} </TreeViewBranchContent> </TreeViewBranch> ) : ( <TreeViewContent> <TreeViewItem>{node.name}</TreeViewItem> </TreeViewContent> )} </TreeViewNode> ); };
Controlled
Use selectedValue and onSelectionChange to control the selected node and react to selection changes.
Select input.tsx
❌
Examples
Multiple selection
Use selectionMode="multiple" to allow selecting multiple nodes.
Hold Shift and click to select a range, or use Ctrl/Cmd+click to toggle individual nodes.
With Context Menu
Right-click on tree items to show a context menu.
Renaming nodes
Use the canRename prop and onRenameComplete callback to enable inline renaming of nodes. Press F2 to activate rename mode on the focused node.
With checkboxes
Use the checkedValue and onCheckedChange props to control the checked nodes.
[ "readme.md" ]
Links
Tree items can be rendered as links. Use asChild on TreeViewContent and wrap an <a> element with TreeViewItem inside.
Docs
Mini Editor
Use the tree view to create a file editor.
Custom icons
There are three ways to customize icons:
- Folder —
iconandexpandedIconprops onTreeViewBranchItem, or per-node viaTreeNodeType - Single item —
iconprop onTreeViewItem - By extension —
fileIconsprop onTreeViewwithcreateFileIcons
Folder icons
Use the icon and expandedIcon props on TreeViewBranchItem to customize folder icons. Pass null to hide the icon.
Single item icon
Pass the icon prop to TreeViewItem to override the icon for a specific leaf node.
With file extensions
Use the fileIcons prop on TreeView with createFileIcons to map file extensions to icon components. Icons are resolved from each node's id; unmatched extensions fall back to FileIcon.
API Reference
TreeView
Root component. Provides tree context and manages expand/selection state.
| Prop | Type | Default |
|---|---|---|
collection | TreeCollection | required |
fileIcons | Record<string, React.JSX.ElementType | null> | - |
selectedValue | string[] | - |
checkedValue | string[] | - |
onCheckedChange | (details: CheckedChangeDetails) => void | - |
canRename | (details: RenameDetails) => boolean | - |
onRenameComplete | (details: RenameCompleteDetails) => void | - |
defaultSelectedValue | string[] | - |
onSelectionChange | (details: SelectionChangeDetails) => void | - |
expandedValue | string[] | - |
defaultExpandedValue | string[] | - |
onExpandedChange | (details: ExpandedChangeDetails) => void | - |
selectionMode | "single" | "multiple" | "single" |
lazyMount | boolean | true |
unmountOnExit | boolean | true |
className | string | - |
| Attribute | Default |
|---|---|
--indentation | --spacing(4) |
--item-gap | --spacing(2) |
--padding-block | --spacing(1.5) |
--padding-inline | --spacing(3) |
--icon-size | --spacing(4) |
TreeViewLabel
Accessible label for the tree (e.g. "File browser").
| Prop | Type | Default |
|---|---|---|
asChild | boolean | false |
className | string | - |
TreeViewTree
Wraps the root-level tree nodes.
| Prop | Type | Default |
|---|---|---|
asChild | boolean | false |
className | string | - |
TreeViewNode
Provides tree node context. Must wrap each branch or item.
| Prop | Type | Default |
|---|---|---|
node | TreeNodeType | required |
indexPath | number[] | required |
className | string | - |
TreeViewBranch
Expandable branch with children. Toggles open/closed.
| Prop | Type | Default |
|---|---|---|
asChild | boolean | false |
className | string | - |
TreeViewBranchItem
Clickable area to expand or collapse a branch.
| Prop | Type | Default |
|---|---|---|
asChild | boolean | false |
icon | React.JSX.ElementType | null | FolderIcon |
expandedIcon | React.JSX.ElementType | null | FolderOpenIcon |
className | string | - |
TreeViewBranchContent
Holds the branch children. Shown when expanded.
| Prop | Type | Default |
|---|---|---|
asChild | boolean | false |
className | string | - |
TreeViewContent
Wrapper for leaf (non-expandable) items.
| Prop | Type | Default |
|---|---|---|
asChild | boolean | false |
className | string | - |
TreeViewItem
Leaf node (non-expandable). The icon prop is fallback when no fileIcons match.
| Prop | Type | Default |
|---|---|---|
icon | React.JSX.ElementType | FileIcon |
className | string | - |
TreeViewCheckbox
Checkbox for selecting a node in multi-select mode.
| Prop | Type | Default |
|---|---|---|
className | string | - |
createTreeCollection
Creates a tree collection from node data. Use with collection prop on TreeView.
Options
| Prop | Type | Default |
|---|---|---|
rootNode | T extends TreeNodeType | required |
nodeToValue | (node: T) => string | (node) => node.id |
nodeToString | (node: T) => string | (node) => node.name |
TreeNodeType — Shape of each node (extend with generic T for custom props):
| Property | Type | Default |
|---|---|---|
id | string | - |
name | string | - |
children | TreeNodeType<T>[] | undefined |
icon | React.JSX.ElementType | null | undefined |
expandedIcon | React.JSX.ElementType | null | undefined |
const collection = createTreeCollection({ rootNode: { id: "ROOT", name: "", children: [...] }, }); // With custom node props type LinkNode = TreeNodeType & { href?: string }; const links = createTreeCollection<LinkNode>({ rootNode: { id: "docs", name: "Docs", children: [{ id: "intro", name: "Intro", href: "/intro" }], }, });
createFileIcons
Creates a type-safe mapping of file extensions to icon components. Use with fileIcons prop on TreeView.
Keys use dotted extensions.
const fileIcons = createFileIcons({ ".tsx": FileCode, ".json": FileJson, ".md": FileText, });
For a complete list of props, see the Ark UI documentation.
On This Page