Overview
Forms & inputs
Search for a command to run or a page to navigate to.
A hierarchical list component that displays nested data in an expandable tree structure.
"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>
)
}
import { Tree } from "@strongtie/design-system/tree"Not installed yet? Add the package to your app:
npm install @strongtie/design-system
This module exports the following components:
TreeTreeItemTreeItemTriggerTreeItemIndicatorTreeItemIconTreeItemLabelTreeItemContent<Tree>| Prop | Type | Default | Description |
|---|---|---|---|
defaultExpanded | string[] | - | |
expanded | string[] | - | |
onExpandedChange | ((expanded: string[]) => void) | - | |
onSelect | ((id: string, item: TreeItemData) => void) | - | |
selected | string | - |
<TreeItem>| Prop | Type | Default | Description |
|---|---|---|---|
id * | string | - | |
value * | TreeItemData | - |
<TreeItemTrigger>| Prop | Type | Default | Description |
|---|---|---|---|
size | "default" | "sm" | "lg" | "icon" | "icon-sm" | "icon-lg" | null | - | |
variant | "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | null | - |
<TreeItemIcon>| Prop | Type | Default | Description |
|---|---|---|---|
fileIcon | ReactNode | - | |
folderIcon | ReactNode | - |
"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>
)
}