Tree
Hierarchical tree view for file structures, navigation, and nested data.
Installation$
Package Manager$
pnpm add @glinui/ui @glinui/tokensRegistry$
pnpm dlx @glinui/cli@latest add treeUsage$
Pass a nodes array of TreeNode objects. Nodes with a children array render as expandable folders; leaf nodes without children render as files. Folders are expanded by default.
1import { Tree } from "@glinui/ui"23const nodes = [4{5 label: "src",6 children: [7 {8 label: "components",9 children: [10 { label: "button.tsx" },11 { label: "input.tsx" },12 { label: "card.tsx" }13 ]14 },15 { label: "index.ts" },16 { label: "App.tsx" }17 ]18},19{ label: "package.json" },20{ label: "tsconfig.json" }21]2223export function TreeBasicDemo() {24return <Tree nodes={nodes} className="max-w-xs" />25}
Examples$
Glass Variant$
The glass variant applies backdrop-blur and a subtle surface tint, suitable for floating panels and sidebars on blurred backgrounds.
1import { Tree } from "@glinui/ui"23const nodes = [4{5 label: "src",6 children: [7 { label: "components", children: [{ label: "button.tsx" }, { label: "input.tsx" }] },8 { label: "index.ts" }9 ]10},11{ label: "package.json" }12]1314export function TreeGlassDemo() {15return (16 <div className="bg-gradient-to-br from-neutral-950 to-neutral-900 rounded-xl p-6">17 <Tree nodes={nodes} variant="glass" className="max-w-xs" />18 </div>19)20}
All Variants$
Four surface variants match the design system — default, glass, outline, and ghost.
Default
Glass
Outline
Ghost
1import { Tree } from "@glinui/ui"23const nodes = [4{ label: "src", children: [{ label: "index.ts" }, { label: "App.tsx" }] },5{ label: "package.json" }6]78export function TreeVariantsDemo() {9return (10 <div className="grid grid-cols-2 gap-4">11 <div>12 <p className="mb-2 text-xs font-semibold text-neutral-500 uppercase tracking-widest">Default</p>13 <Tree nodes={nodes} variant="default" />14 </div>15 <div>16 <p className="mb-2 text-xs font-semibold text-neutral-500 uppercase tracking-widest">Glass</p>17 <Tree nodes={nodes} variant="glass" />18 </div>19 <div>20 <p className="mb-2 text-xs font-semibold text-neutral-500 uppercase tracking-widest">Outline</p>21 <Tree nodes={nodes} variant="outline" />22 </div>23 <div>24 <p className="mb-2 text-xs font-semibold text-neutral-500 uppercase tracking-widest">Ghost</p>25 <Tree nodes={nodes} variant="ghost" />26 </div>27 </div>28)29}
With Badges$
Add a badge string and optional badgeVariant to any node. Badges appear after the label and support five semantic color tones: default, success, warning, info, and destructive.
1import { Tree } from "@glinui/ui"23const nodes = [4{5 label: "packages",6 children: [7 { label: "ui", badge: "stable", badgeVariant: "success", children: [{ label: "index.ts" }] },8 { label: "tokens", badge: "stable", badgeVariant: "success", children: [{ label: "theme.css" }] },9 { label: "motion", badge: "beta", badgeVariant: "warning", children: [{ label: "index.ts" }] },10 { label: "registry", badge: "wip", badgeVariant: "info", children: [{ label: "index.ts" }] }11 ]12}13]1415export function TreeBadgeDemo() {16return <Tree nodes={nodes} className="max-w-xs" />17}
buildFileTree Utility$
buildFileTree converts a flat array of slash-separated file paths into a nested TreeNode[] structure. Pass an optional hrefPrefix to make leaf nodes into links, or getBadge to attach badges based on file path patterns.
1import { Tree, buildFileTree } from "@glinui/ui"23const paths = [4"src/components/button.tsx",5"src/components/input.tsx",6"src/lib/cn.ts",7"src/lib/utils.ts",8"src/index.ts",9"package.json"10]1112export function TreeBuildFileTreeDemo() {13const nodes = buildFileTree(paths)14return <Tree nodes={nodes} className="max-w-xs" />15}1617// With href links and badges:18export function TreeBuildFileTreeLinkedDemo() {19const nodes = buildFileTree(paths, {20 hrefPrefix: "https://github.com/org/repo/blob/main",21 getBadge: (path) => {22 if (path.endsWith(".tsx")) return { badge: "tsx", badgeVariant: "info" }23 if (path.endsWith(".ts")) return { badge: "ts", badgeVariant: "default" }24 return null25 }26})27return <Tree nodes={nodes} className="max-w-xs" />28}
Collapsed by Default$
Set defaultExpanded={false} to render all folders in their collapsed state initially.
1import { Tree } from "@glinui/ui"23const nodes = [4{5 label: "src",6 children: [7 { label: "components", children: [{ label: "button.tsx" }, { label: "input.tsx" }] },8 { label: "index.ts" }9 ]10},11{ label: "package.json" }12]1314export function TreeCollapsedDemo() {15return <Tree nodes={nodes} defaultExpanded={false} className="max-w-xs" />16}
Accessibility$
- Folder nodes render as
<button>elements, making them keyboard-activatable withEnterandSpace. - The chevron icon provides a clear visual indicator of expanded/collapsed state.
- Leaf nodes that have an
hrefrender as<a>elements with properrel="noopener noreferrer"whenexternalis set. - Nesting depth is communicated visually through
padding-leftindentation. For screen-reader depth cues, consider wrapping the component in a<nav>with anaria-label.
Reduced Motion$
The chevron rotation transition (duration-150) is a lightweight CSS transform. It respects prefers-reduced-motion via Tailwind's motion-reduce:transition-none utility if applied to spotlightClassName, and can be suppressed by adding motion-reduce:transition-none to the className prop.
API Reference$
Tree$
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
className | string | No | - | Extra classes for the tree root wrapper. |
defaultExpanded | boolean | No | true | Expand all folders by default |
nodes | TreeNode[] | Yes | - | Tree data |
variant | "default" | "glass" | "outline" | "ghost" | No | "default" | Variant option from treeVariants. |
TreeNode$
| Prop | Type | Description |
| --- | --- | --- |
| label | string | Display text for the node. |
| children | TreeNode[] | Nested child nodes; presence makes the node a folder. |
| href | string | Optional URL for leaf nodes. |
| external | boolean | Opens href in a new tab with rel="noopener noreferrer". |
| badge | string | Short badge text shown after the label. |
| badgeVariant | "default" \| "success" \| "warning" \| "info" \| "destructive" | Semantic badge tone. |
| icon | React.ReactNode | Custom leaf icon override (defaults to FileText). |
buildFileTree$
1function buildFileTree(2 paths: string[],3 options?: {4 hrefPrefix?: string5 getBadge?: (path: string) => { badge: string; badgeVariant?: TreeNode["badgeVariant"] } | null6 }7): TreeNode[]
Converts a flat array of slash-separated paths into a nested TreeNode[]. The hrefPrefix is prepended to each leaf path to form a link URL. getBadge receives the full file path and returns badge metadata or null.
Source$
1import { Tree, buildFileTree } from "@glinui/ui"
Generated API Snapshot
Beta
Generated API Snapshot
BetaAuto-extracted from TypeScript source in packages/ui/src/components/tree.tsx. This section is in beta and may lag behind hand-curated docs. Regenerate with pnpm --filter @glinui/docs api:generate.
Generated: 2026-02-19T17:59:28.468Z · Full index: /docs/api-metadata
Primary Props Type
TreeProps
TreeProps
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
className | string | No | - | Extra classes for the tree root wrapper. |
defaultExpanded | boolean | No | true | Expand all folders by default |
nodes | TreeNode[] | Yes | - | Tree data |
variant | "default" | "glass" | "outline" | "ghost" | No | "default" | Variant option from treeVariants. |