- src
- components
- button.tsx
- card.tsx
- tree-view.tsx
- lib
- styles
- README.md
- package.json
Installation
npx logic2b@next add tree-viewUsage
import { TreeItem, TreeView } from "@/components/ui/tree-view"
<TreeView aria-label="Files" defaultExpanded={["src"]}>
<TreeItem value="src" label="src">
<TreeItem value="button" label="button.tsx" />
<TreeItem value="card" label="card.tsx" />
</TreeItem>
<TreeItem value="readme" label="README.md" />
</TreeView>
Nesting TreeItem children turns an item into a branch — the chevron,
aria-expanded state and indentation are derived automatically.
Examples
Controlled
Drive expansion and selection externally — expand/collapse everything from the outside and react to the selected value.
- workspace
- apps
- packages
Selected: none
Accessibility
- Follows the WAI-ARIA Tree View pattern.
- Arrow Up / Arrow Down move through visible items; Home / End jump to the first/last.
- Arrow Right expands a collapsed branch (then steps into it); Arrow Left collapses an expanded branch or moves to the parent.
- Enter or Space selects the focused item (and toggles branches).
- Items expose
aria-level,aria-expandedandaria-selected; disabled items arearia-disabledand skipped.
Live playground
Edit the component props and inspect the exact JSX before copying it. The preview loads only when this section enters the viewport.
Generated JSX
<TreeView
defaultExpanded={["packages"]}
defaultSelected="registry"
aria-label="Repository files"
>
<TreeItem
value="packages"
label="packages"
>
<TreeItem
value="registry"
label="registry"
/>
<TreeItem
value="web"
label="web"
/>
</TreeItem>
<TreeItem
value="roadmap"
label="ROADMAP.md"
/>
</TreeView>- packages
- registry
- web
- ROADMAP.md
API reference
Generated from the public TypeScript exports in src/ui/tree-view.tsx.
TreeView
ComponentProps: Omit<React.ComponentProps<"ul">, "onSelect"> & { expanded?: string[] defaultExpanded?: string[] onExpandedChange?: (expanded: string[]) => void selected?: string | null defaultSelected?: string | null onSelectedChange?: (selected: string | null) => void }| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
expanded | string[] | No | — | — |
defaultExpanded | string[] | No | — | — |
onExpandedChange | (expanded: string[]) => void | No | — | — |
selected | string | null | No | — | — |
defaultSelected | string | null | No | — | — |
onSelectedChange | (selected: string | null) => void | No | — | — |
TreeItem
ComponentProps: Omit<React.ComponentProps<"li">, "onSelect"> & { value: string label: React.ReactNode icon?: React.ReactNode disabled?: boolean }| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
value | string | Yes | — | — |
label | React.ReactNode | Yes | — | — |
icon | React.ReactNode | No | — | — |
disabled | boolean | No | — | — |
Accessibility contract
Machine-readable behavior and consumer responsibilities for tree-view.
- Support
- Authored behavior
- Pattern
- tree
| Keys | Behavior |
|---|---|
| ArrowUp ArrowDown ArrowLeft ArrowRight | Move within the composite control. |
| Home End | Move to the first or last visible node. |
| Enter Space | Select or activate the focused node. |
Built-in semantics
- Uses tree/treeitem/group roles with aria-expanded, aria-selected, level and set position metadata.
Consumer responsibilities
- Give the tree a label and ensure node actions are distinguishable from expand/collapse.