Glin UI
Primitive / Moleculebeta

Tree

Hierarchical tree view for file structures, navigation, and nested data.

Edit on GitHub

Installation

Install from
pnpm dlx @glinui/cli@latest add tree

Prefer the package?

Usage

Variants

Every vocabulary variant on the default tone. Omit variant to follow the ambient design style.

index.ts
package.json
index.ts
package.json
index.ts
package.json
index.ts
package.json
index.ts
package.json
index.ts
package.json
index.ts
package.json
import { Tree } from "@glinui/ui"
export function TreeVariantsDemo() {
return (
<div className="grid gap-4 md:grid-cols-2">
<Tree variant="glinr" nodes={[{ label: "src", children: [{ label: "index.ts" }] }, { label: "package.json" }]} />
<Tree variant="solid" nodes={[{ label: "src", children: [{ label: "index.ts" }] }, { label: "package.json" }]} />
<Tree variant="plain" nodes={[{ label: "src", children: [{ label: "index.ts" }] }, { label: "package.json" }]} />
<Tree variant="soft" nodes={[{ label: "src", children: [{ label: "index.ts" }] }, { label: "package.json" }]} />
<Tree variant="outline" nodes={[{ label: "src", children: [{ label: "index.ts" }] }, { label: "package.json" }]} />
<Tree variant="ghost" nodes={[{ label: "src", children: [{ label: "index.ts" }] }, { label: "package.json" }]} />
<Tree variant="gradient" nodes={[{ label: "src", children: [{ label: "index.ts" }] }, { label: "package.json" }]} />
</div>
)
}

All Variants

Four surface variants match the design system, `default`, `glass`, `outline`, and `ghost`.

import { Tree } from "@glinui/ui"

const nodes = [
  { label: "src", children: [{ label: "index.ts" }, { label: "App.tsx" }] },
  { label: "package.json" }
]

export function TreeVariantsDemo() {
  return (
    <div className="grid grid-cols-2 gap-4">
      <div>
        <p className="mb-2 text-xs font-semibold text-neutral-500 uppercase tracking-widest">Default</p>
        <Tree nodes={nodes} variant="default" />
      </div>
      <div>
        <p className="mb-2 text-xs font-semibold text-neutral-500 uppercase tracking-widest">Glass</p>
        <Tree nodes={nodes} variant="glass" />
      </div>
      <div>
        <p className="mb-2 text-xs font-semibold text-neutral-500 uppercase tracking-widest">Outline</p>
        <Tree nodes={nodes} variant="outline" />
      </div>
      <div>
        <p className="mb-2 text-xs font-semibold text-neutral-500 uppercase tracking-widest">Ghost</p>
        <Tree nodes={nodes} variant="ghost" />
      </div>
    </div>
  )
}

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.

import { Tree, buildFileTree } from "@glinui/ui"

const paths = [
  "src/components/button.tsx",
  "src/components/input.tsx",
  "src/lib/cn.ts",
  "src/lib/utils.ts",
  "src/index.ts",
  "package.json"
]

export function TreeBuildFileTreeDemo() {
  const nodes = buildFileTree(paths)
  return <Tree nodes={nodes} className="max-w-xs" />
}

// With href links and badges:
export function TreeBuildFileTreeLinkedDemo() {
  const nodes = buildFileTree(paths, {
    hrefPrefix: "https://github.com/org/repo/blob/main",
    getBadge: (path) => {
      if (path.endsWith(".tsx")) return { badge: "tsx", badgeVariant: "info" }
      if (path.endsWith(".ts"))  return { badge: "ts",  badgeVariant: "default" }
      return null
    }
  })
  return <Tree nodes={nodes} className="max-w-xs" />
}

Collapsed by Default

Set `defaultExpanded={false}` to render all folders in their collapsed state initially.

import { Tree } from "@glinui/ui"

const nodes = [
  {
    label: "src",
    children: [
      { label: "components", children: [{ label: "button.tsx" }, { label: "input.tsx" }] },
      { label: "index.ts" }
    ]
  },
  { label: "package.json" }
]

export function TreeCollapsedDemo() {
  return <Tree nodes={nodes} defaultExpanded={false} className="max-w-xs" />
}

Accessibility

  • Folder nodes are interactive buttons with expand/collapse behavior.
  • Linked leaf nodes render as anchor elements.
  • Tree structure is conveyed visually through indentation and icons.
  • The chevron icon provides a clear visual indicator of expanded/collapsed state.
  • Leaf nodes that have an `href` render as `<a>` elements with proper `rel="noopener noreferrer"` when `external` is set.
  • Nesting depth is communicated visually through `padding-left` indentation. For screen-reader depth cues, consider wrapping the component in a `<nav>` with an `aria-label`.

Keyboard Interactions

KeyAction
Enter / SpaceToggle folder expand/collapse.
TabNavigate between interactive nodes.

Reduced Motion

Chevron rotation uses CSS transition that respects `prefers-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.

Affected properties

transform

API Reference

PropTypeRequiredDefaultDescription
nodesTreeNode[]Yes-Array of tree data nodes to render.
variantSurfaceVariant | "default" | "raised" | "frosted"Noambient (glinr)Surface variant. Omit to follow the ambient design style (glinr by default, plain for minimal, glass for glass).
toneSurfaceToneNoneutralColour tone for the vocabulary variants.
defaultExpandedbooleanNotrueExpand all folders by default.
classNamestringNo-Extra classes for the tree root wrapper.

Source

Import directly from the package or browse the source on GitHub. Click any file to view it.

Import

import { Tree } from "@glinui/ui"

Source Files

Dependencies

@glinui/ui

Generated API Snapshot

Beta

Auto-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-10-08T01:41:21.546Z · Full index: /docs/api-metadata

Primary Props Type

TreeProps

TreeProps

PropTypeRequiredDefaultDescription
classNamestringNo-Extra classes for the tree root wrapper.
defaultExpandedbooleanNotrueExpand all folders by default
nodesTreeNode[]Yes-Tree data
toneSurfaceToneNo--
variantSurfaceVariant | "default" | "raised" | "frosted"No-Visual variant. Omit for the ambient design style (glinr: lift shell; plain: flat bordered list).