# Tree list (goodtabs UI)

An expandable tree with real tree roles and full arrow key support.

## Install

```bash
npx shadcn@latest add https://ui.goodtabs.co/r/tree-list.json
```

Or, with the @goodtabs namespace configured in components.json: `npx shadcn@latest add @goodtabs/tree-list`

## Usage

```tsx
import { TreeList } from "@/components/ui/tree-list"

<TreeList aria-label="Files" nodes={nodes} selected={id} onSelect={setId} />
```

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| nodes | `TreeNode[]` |  | Nodes with id, label, optional meta and children. |
| defaultExpanded | `string[]` | `[]` | Branch ids that start open. |
| selected | `string` |  | Id of the selected node. |
| onSelect | `(id: string) => void` |  | Called when a node is selected. |
| aria-label | `string` | `"Tree"` | Names the tree for screen readers. |

## When to use

- File and folder browsers
- Any hierarchy the user selects from, not navigates

## When not to use

- Site navigation made of links: use a nav tree
- Flat lists, where a listbox is simpler

## Notes for agents

- Roles are tree, treeitem with aria-level, aria-setsize, aria-posinset and aria-expanded
- One tab stop with a roving tabindex. Up, Down, Left, Right, Home, End, Enter and Space are handled
- Selection is controlled through selected; expansion is internal and seeded by defaultExpanded
- Ids must be unique across the whole tree
- It takes a function, so a demo that passes onSelect must be a client component

Docs: https://ui.goodtabs.co/components/tree-list