Data display
Tree
Hierarchical structure for nested data — workspaces, folders, and documents. Every row is a disclosure chevron, a type icon, a label, and a child count; indentation plus hairline guides make depth legible at a glance. Full WAI-ARIA tree keyboard navigation, with expansion and selection each controlled or uncontrolled.
npx shadcn@latest add @orbit/treeOverview
A live tree with the header chrome: title, total item count, and expand-all / collapse-all actions. Click a row to select it (containers also toggle), or click just the chevron to toggle without selecting.
- Orbit Workspace3
- Product2
- Roadmap2
- Q3 Planning
- Q4 Planning
- Specs2
- Design2
- Design System2
- Components
- Foundations
- Mockups1
- Engineering2
- Marketing1
- Campaigns2
- Q3 Launch
- Social Calendar
Anatomy
Three node types: an accent chip marks a workspace (space), a filled folder a container — its fill tints while open — and a sheet a leaf document. The chevron rotates 90° on expand, labels truncate with ellipsis, and a mono count sits right on containers. Selected rows tint with the brand soft.
- Orbit Workspace2
- Roadmap2
- Q3 Planning
- Q4 Planning
- Specs1
Tweaks
Two boolean props tune density without touching behavior: showCounts drops the mono child counts, connectingLines removes the hairline depth guides. Each instance below is independently live.
- Orbit Workspace
- Product
- Roadmap
- Q3 Planning
- Q4 Planning
- Specs
- Design
- Design System
- Components
- Foundations
- Mockups
- Engineering
- Marketing
- Campaigns
- Q3 Launch
- Social Calendar
- Orbit Workspace3
- Product2
- Roadmap2
- Q3 Planning
- Q4 Planning
- Specs2
- Design2
- Design System2
- Components
- Foundations
- Mockups1
- Engineering2
- Marketing1
- Campaigns2
- Q3 Launch
- Social Calendar
Controlled
Pass expandedIds / selectedId with their change callbacks to own the state — drive the tree from a router, a search field, or external buttons. Leave them off (or use the default* props) and the tree manages itself.
- Orbit Workspace3
- Product2
- Roadmap2
- Specs2
- Design2
- Engineering2
- Marketing1
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| items | TreeItem[] | — | Nested nodes: { id, label, type?, children? }. type is "space" | "folder" | "doc"; defaults to folder for nodes with children, doc otherwise. |
| title | string | "Project structure" | Header title; also labels the tree for assistive tech. |
| showCounts | boolean | true | Mono child-count on container rows. |
| connectingLines | boolean | true | Hairline depth guides on nested rows. |
| expandedIds | string[] | — | Controlled expanded container ids; pair with onExpandedChange. |
| defaultExpandedIds | string[] | [] | Containers that start expanded (uncontrolled). |
| onExpandedChange | (ids: string[]) => void | — | Fires on any expand / collapse, including the header expand-all and collapse-all buttons. |
| selectedId | string | null | — | Controlled selected node id; pair with onSelect. |
| defaultSelectedId | string | null | null | Initially selected node (uncontrolled). |
| onSelect | (id, item) => void | — | Called when a node is selected by click, Enter, or Space. |
| …rest | HTMLAttributes | — | Everything else is forwarded to the root <div>, including ref. |
Usage
Use it for real hierarchy
Nested folders, org charts, doc trees — anywhere parent/child is the point. Depth carries meaning here.
Nest more than a few deep
Past four or five levels the indentation eats the row. Flatten, or split into linked trees.
Show counts on containers
A child count tells you what’s collapsed without opening it — cheap orientation for big trees.
Use it for a flat list
No nesting means no tree. A table or list is lighter and more scannable for single-level data.
Keyboard & accessibility
The list uses the WAI-ARIA tree pattern: role=tree on the list, treeitem rows with aria-expanded, aria-selected, and aria-level, children in role=group, and a roving tabindex so the tree is one Tab stop. Focus shows the 3px themed ring.
- Orbit Workspace2
- Roadmap2
- Specs1