Strongtie Design System
Getting StartedComponents

Command Palette

Search for a command to run...

Getting Started
  • Introduction
  • Setup Guide
  • Package Installation
  • Code Quality Setup
  • Migration Guide
  • Resources
Registry
  • Getting Started
  • Combobox
  • Datepicker
  • MultiSelect
  • Tree
Guides
  • Framework Recommendations
Foundations
  • States
  • Variables
Components
  • Accordion
  • Alert
  • Alert Dialog
  • Avatar
  • Badge
  • Breadcrumb
  • Button
  • Button Group
  • Calendar
  • Card
  • Carousel
  • Chart
  • Checkbox
  • Collapsible
  • Command
  • Combobox
  • Context Menu
  • Date Picker
  • Dialog
  • Drawer
  • Dropdown Menu
  • Empty
  • Field
  • Hover Card
  • Input
  • Input Group
  • Item
  • Kbd
  • Label
  • Menubar
  • Multi Select
  • Navigation Menu
  • Pagination
  • Popover
  • Progress
  • Radio Group
  • Scroll Area
  • Select
  • Separator
  • Sheet
  • Sidebar
  • Skeleton
  • Slider
  • Switch
  • Table
  • Tabs
  • Textarea
  • Toaster
  • Toggle
  • Toggle Group
  • Tooltip
  • Tree
2026 Simpson Strong-Tie
  1. Docs
  2. Components
  3. Tree

Tree

PreviousNext

A hierarchical list component that displays nested data in an expandable tree structure.

Tree views are used to display hierarchical data such as file systems, organizational charts, navigation menus, or any nested data structure. Users can expand and collapse parent nodes to reveal or hide their children, making it easy to navigate through complex nested information.

This is a composable component that provides full control over the tree structure. Use TreeItem, TreeItemTrigger, TreeItemIndicator, TreeItemIcon, TreeItemLabel, and TreeItemContent to build your tree.

Example

"use client"

import * as React from "react"
import {
  Tree,
  TreeItem,
  TreeItemContent,
  TreeItemIcon,
  TreeItemIndicator,
  TreeItemLabel,
  TreeItemTrigger,
} from "@strongtie/design-system/tree"
import type { TreeItemData } from "@strongtie/design-system/tree"

const treeData: TreeItemData[] = [
  {
    id: "1",
    name: "src",
    type: "folder",
    children: [
      {
        id: "2",
        name: "components",
        type: "folder",
        children: [
          { id: "3", name: "Button.tsx", type: "file" },
          { id: "4", name: "Input.tsx", type: "file" },
          { id: "5", name: "Card.tsx", type: "file" },
        ],
      },
      {
        id: "6",
        name: "utils",
        type: "folder",
        children: [
          { id: "7", name: "helpers.ts", type: "file" },
          { id: "8", name: "constants.ts", type: "file" },
        ],
      },
      { id: "9", name: "index.ts", type: "file" },
    ],
  },
  {
    id: "10",
    name: "public",
    type: "folder",
    children: [
      {
        id: "11",
        name: "images",
        type: "folder",
        children: [{ id: "12", name: "logo.png", type: "file" }],
      },
    ],
  },
  { id: "13", name: "package.json", type: "file" },
  { id: "14", name: "README.md", type: "file" },
]

interface TreeDataItem extends TreeItemData {
  children?: TreeDataItem[]
}

function renderTreeItems(items: TreeDataItem[]) {
  return items.map((item) => (
    <TreeItem key={item.id} id={item.id} value={item}>
      <TreeItemTrigger>
        <TreeItemIndicator />
        <TreeItemIcon />
        <TreeItemLabel>{item.name}</TreeItemLabel>
      </TreeItemTrigger>
      {item.children && (
        <TreeItemContent>{renderTreeItems(item.children)}</TreeItemContent>
      )}
    </TreeItem>
  ))
}

export function TreeDefault() {
  const [selected, setSelected] = React.useState<string>()

  return (
    <div className="w-full max-w-md rounded-md border p-4">
      <Tree
        selected={selected}
        onSelect={(id) => {
          setSelected(id)
          console.log("Selected:", id)
        }}
      >
        {renderTreeItems(treeData)}
      </Tree>
    </div>
  )
}

Installation

npm install @strongtie/design-system
import { Tree } from "@strongtie/design-system/tree"

Components

This module exports the following components:

  • Tree
  • TreeItem
  • TreeItemTrigger
  • TreeItemIndicator
  • TreeItemIcon
  • TreeItemLabel
  • TreeItemContent

Props

<Tree>

PropTypeDefaultDescription
defaultExpandedstring[]-
expandedstring[]-
onExpandedChange((expanded: string[]) => void)-
onSelect((id: string, item: TreeItemData) => void)-
selectedstring-

<TreeItem>

PropTypeDefaultDescription
id *string-
value *TreeItemData-

<TreeItemTrigger>

PropTypeDefaultDescription
size"default" | "sm" | "lg" | "icon" | "icon-sm" | "icon-lg" | null-
variant"link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | null-

<TreeItemIcon>

PropTypeDefaultDescription
fileIconReactNode-
folderIconReactNode-

Examples

"use client"

import * as React from "react"
import {
  Tree,
  TreeItem,
  TreeItemContent,
  TreeItemIcon,
  TreeItemIndicator,
  TreeItemLabel,
  TreeItemTrigger,
} from "@strongtie/design-system/tree"
import type { TreeItemData } from "@strongtie/design-system/tree"

const treeData: TreeItemData[] = [
  {
    id: "1",
    name: "src",
    type: "folder",
    children: [
      {
        id: "2",
        name: "components",
        type: "folder",
        children: [
          { id: "3", name: "Button.tsx", type: "file" },
          { id: "4", name: "Input.tsx", type: "file" },
          { id: "5", name: "Card.tsx", type: "file" },
        ],
      },
      {
        id: "6",
        name: "utils",
        type: "folder",
        children: [
          { id: "7", name: "helpers.ts", type: "file" },
          { id: "8", name: "constants.ts", type: "file" },
        ],
      },
      { id: "9", name: "index.ts", type: "file" },
    ],
  },
  {
    id: "10",
    name: "public",
    type: "folder",
    children: [
      {
        id: "11",
        name: "images",
        type: "folder",
        children: [{ id: "12", name: "logo.png", type: "file" }],
      },
    ],
  },
  { id: "13", name: "package.json", type: "file" },
  { id: "14", name: "README.md", type: "file" },
]

interface TreeDataItem extends TreeItemData {
  children?: TreeDataItem[]
}

function renderTreeItems(items: TreeDataItem[]) {
  return items.map((item) => (
    <TreeItem key={item.id} id={item.id} value={item}>
      <TreeItemTrigger>
        <TreeItemIndicator />
        <TreeItemIcon />
        <TreeItemLabel>{item.name}</TreeItemLabel>
      </TreeItemTrigger>
      {item.children && (
        <TreeItemContent>{renderTreeItems(item.children)}</TreeItemContent>
      )}
    </TreeItem>
  ))
}

export function TreeDefault() {
  const [selected, setSelected] = React.useState<string>()

  return (
    <div className="w-full max-w-md rounded-md border p-4">
      <Tree
        selected={selected}
        onSelect={(id) => {
          setSelected(id)
          console.log("Selected:", id)
        }}
      >
        {renderTreeItems(treeData)}
      </Tree>
    </div>
  )
}

Custom Icons

"use client"

import * as React from "react"
import {
  Tree,
  TreeItem,
  TreeItemContent,
  TreeItemIcon,
  TreeItemIndicator,
  TreeItemLabel,
  TreeItemTrigger,
} from "@strongtie/design-system/tree"
import {
  Activity,
  Calendar,
  Cpu,
  Database,
  HardDrive,
  Hash,
  Key,
  Link,
  ListTree,
  Lock,
  Server,
  Settings,
  Shield,
  Table,
  ToggleLeft,
  Type,
  Users,
} from "lucide-react"

export function TreeCustomIcons() {
  const [selected, setSelected] = React.useState<string>()

  return (
    <div className="w-full max-w-lg rounded-md border p-4">
      <Tree
        selected={selected}
        onSelect={(id) => setSelected(id)}
        defaultExpanded={["db", "users-table", "infrastructure"]}
      >
        {/* Database Section */}
        <TreeItem id="db" value={{ id: "db", name: "Production Database" }}>
          <TreeItemTrigger>
            <TreeItemIndicator />
            <TreeItemIcon>
              <Database className="size-4 text-blue-500" />
            </TreeItemIcon>
            <TreeItemLabel>Production Database</TreeItemLabel>
          </TreeItemTrigger>
          <TreeItemContent>
            {/* Users Table */}
            <TreeItem
              id="users-table"
              value={{ id: "users-table", name: "users" }}
            >
              <TreeItemTrigger>
                <TreeItemIndicator />
                <TreeItemIcon>
                  <Table className="size-4 text-emerald-500" />
                </TreeItemIcon>
                <TreeItemLabel>users</TreeItemLabel>
              </TreeItemTrigger>
              <TreeItemContent>
                <TreeItem id="users-id" value={{ id: "users-id", name: "id" }}>
                  <TreeItemTrigger>
                    <TreeItemIndicator />
                    <TreeItemIcon>
                      <Key className="size-4 text-amber-500" />
                    </TreeItemIcon>
                    <TreeItemLabel>id (primary key)</TreeItemLabel>
                  </TreeItemTrigger>
                </TreeItem>
                <TreeItem
                  id="users-email"
                  value={{ id: "users-email", name: "email" }}
                >
                  <TreeItemTrigger>
                    <TreeItemIndicator />
                    <TreeItemIcon>
                      <Type className="size-4 text-purple-500" />
                    </TreeItemIcon>
                    <TreeItemLabel>email (varchar)</TreeItemLabel>
                  </TreeItemTrigger>
                </TreeItem>
                <TreeItem
                  id="users-created"
                  value={{ id: "users-created", name: "created_at" }}
                >
                  <TreeItemTrigger>
                    <TreeItemIndicator />
                    <TreeItemIcon>
                      <Calendar className="size-4 text-rose-500" />
                    </TreeItemIcon>
                    <TreeItemLabel>created_at (timestamp)</TreeItemLabel>
                  </TreeItemTrigger>
                </TreeItem>
                <TreeItem
                  id="users-active"
                  value={{ id: "users-active", name: "is_active" }}
                >
                  <TreeItemTrigger>
                    <TreeItemIndicator />
                    <TreeItemIcon>
                      <ToggleLeft className="size-4 text-cyan-500" />
                    </TreeItemIcon>
                    <TreeItemLabel>is_active (boolean)</TreeItemLabel>
                  </TreeItemTrigger>
                </TreeItem>
              </TreeItemContent>
            </TreeItem>

            {/* Posts Table */}
            <TreeItem
              id="posts-table"
              value={{ id: "posts-table", name: "posts" }}
            >
              <TreeItemTrigger>
                <TreeItemIndicator />
                <TreeItemIcon>
                  <Table className="size-4 text-emerald-500" />
                </TreeItemIcon>
                <TreeItemLabel>posts</TreeItemLabel>
              </TreeItemTrigger>
              <TreeItemContent>
                <TreeItem id="posts-id" value={{ id: "posts-id", name: "id" }}>
                  <TreeItemTrigger>
                    <TreeItemIndicator />
                    <TreeItemIcon>
                      <Key className="size-4 text-amber-500" />
                    </TreeItemIcon>
                    <TreeItemLabel>id (primary key)</TreeItemLabel>
                  </TreeItemTrigger>
                </TreeItem>
                <TreeItem
                  id="posts-user"
                  value={{ id: "posts-user", name: "user_id" }}
                >
                  <TreeItemTrigger>
                    <TreeItemIndicator />
                    <TreeItemIcon>
                      <Link className="size-4 text-orange-500" />
                    </TreeItemIcon>
                    <TreeItemLabel>user_id (foreign key)</TreeItemLabel>
                  </TreeItemTrigger>
                </TreeItem>
                <TreeItem
                  id="posts-title"
                  value={{ id: "posts-title", name: "title" }}
                >
                  <TreeItemTrigger>
                    <TreeItemIndicator />
                    <TreeItemIcon>
                      <Type className="size-4 text-purple-500" />
                    </TreeItemIcon>
                    <TreeItemLabel>title (varchar)</TreeItemLabel>
                  </TreeItemTrigger>
                </TreeItem>
              </TreeItemContent>
            </TreeItem>

            {/* Indexes */}
            <TreeItem id="indexes" value={{ id: "indexes", name: "Indexes" }}>
              <TreeItemTrigger>
                <TreeItemIndicator />
                <TreeItemIcon>
                  <ListTree className="size-4 text-indigo-500" />
                </TreeItemIcon>
                <TreeItemLabel>Indexes</TreeItemLabel>
              </TreeItemTrigger>
              <TreeItemContent>
                <TreeItem
                  id="idx-email"
                  value={{ id: "idx-email", name: "idx_users_email" }}
                >
                  <TreeItemTrigger>
                    <TreeItemIndicator />
                    <TreeItemIcon>
                      <Hash className="size-4 text-gray-500" />
                    </TreeItemIcon>
                    <TreeItemLabel>idx_users_email</TreeItemLabel>
                  </TreeItemTrigger>
                </TreeItem>
                <TreeItem
                  id="idx-created"
                  value={{ id: "idx-created", name: "idx_posts_created" }}
                >
                  <TreeItemTrigger>
                    <TreeItemIndicator />
                    <TreeItemIcon>
                      <Hash className="size-4 text-gray-500" />
                    </TreeItemIcon>
                    <TreeItemLabel>idx_posts_created</TreeItemLabel>
                  </TreeItemTrigger>
                </TreeItem>
              </TreeItemContent>
            </TreeItem>
          </TreeItemContent>
        </TreeItem>

        {/* Infrastructure Section */}
        <TreeItem
          id="infrastructure"
          value={{ id: "infrastructure", name: "Infrastructure" }}
        >
          <TreeItemTrigger>
            <TreeItemIndicator />
            <TreeItemIcon>
              <Server className="size-4 text-slate-600" />
            </TreeItemIcon>
            <TreeItemLabel>Infrastructure</TreeItemLabel>
          </TreeItemTrigger>
          <TreeItemContent>
            <TreeItem id="storage" value={{ id: "storage", name: "Storage" }}>
              <TreeItemTrigger>
                <TreeItemIndicator />
                <TreeItemIcon>
                  <HardDrive className="size-4 text-blue-400" />
                </TreeItemIcon>
                <TreeItemLabel>Storage (256GB SSD)</TreeItemLabel>
              </TreeItemTrigger>
            </TreeItem>
            <TreeItem id="compute" value={{ id: "compute", name: "Compute" }}>
              <TreeItemTrigger>
                <TreeItemIndicator />
                <TreeItemIcon>
                  <Cpu className="size-4 text-green-500" />
                </TreeItemIcon>
                <TreeItemLabel>Compute (4 vCPUs)</TreeItemLabel>
              </TreeItemTrigger>
            </TreeItem>
            <TreeItem
              id="monitoring"
              value={{ id: "monitoring", name: "Monitoring" }}
            >
              <TreeItemTrigger>
                <TreeItemIndicator />
                <TreeItemIcon>
                  <Activity className="size-4 text-red-500" />
                </TreeItemIcon>
                <TreeItemLabel>Monitoring</TreeItemLabel>
              </TreeItemTrigger>
            </TreeItem>
          </TreeItemContent>
        </TreeItem>

        {/* Settings Section */}
        <TreeItem id="settings" value={{ id: "settings", name: "Settings" }}>
          <TreeItemTrigger>
            <TreeItemIndicator />
            <TreeItemIcon>
              <Settings className="size-4 text-gray-500" />
            </TreeItemIcon>
            <TreeItemLabel>Settings</TreeItemLabel>
          </TreeItemTrigger>
          <TreeItemContent>
            <TreeItem
              id="security"
              value={{ id: "security", name: "Security" }}
            >
              <TreeItemTrigger>
                <TreeItemIndicator />
                <TreeItemIcon>
                  <Shield className="size-4 text-green-600" />
                </TreeItemIcon>
                <TreeItemLabel>Security</TreeItemLabel>
              </TreeItemTrigger>
            </TreeItem>
            <TreeItem
              id="access"
              value={{ id: "access", name: "Access Control" }}
            >
              <TreeItemTrigger>
                <TreeItemIndicator />
                <TreeItemIcon>
                  <Users className="size-4 text-blue-600" />
                </TreeItemIcon>
                <TreeItemLabel>Access Control</TreeItemLabel>
              </TreeItemTrigger>
            </TreeItem>
            <TreeItem
              id="encryption"
              value={{ id: "encryption", name: "Encryption" }}
            >
              <TreeItemTrigger>
                <TreeItemIndicator />
                <TreeItemIcon>
                  <Lock className="size-4 text-amber-600" />
                </TreeItemIcon>
                <TreeItemLabel>Encryption</TreeItemLabel>
              </TreeItemTrigger>
            </TreeItem>
          </TreeItemContent>
        </TreeItem>
      </Tree>
    </div>
  )
}

Styling

Components can be styled using the className prop. The design system uses Tailwind CSS for styling.

Classes

CSS classes used by this component:

  • tree
  • tree-item
  • tree-item-content
  • tree-item-icon
  • tree-item-indicator
  • tree-item-label
  • tree-item-trigger

Accessibility

Ensure proper accessibility attributes are added when implementing this component.

TooltipStates and State Management

On This Page

ExampleInstallationComponentsProps<Tree><TreeItem><TreeItemTrigger><TreeItemIcon>ExamplesCustom IconsStylingClassesAccessibility

Contribute

  • Report an issue
  • Request a feature
  • Edit this page