

# Tree

Hierarchical expandable list with APG tree keyboard behavior. Compose nested `Tree.Item`s or pass a recursive `items` array; control expand/selection with `expandedKeys` / `selectedKeys`.

## Examples

### Default

A small file tree with one folder expanded.

```tsx
import { Tree } from '@var-ui/react';

<Tree
  aria-label="Files"
  defaultExpandedKeys={['src']}
  items={[{ id: 'src', label: 'src', children: [{ id: 'app', label: 'App.tsx' }] }]}
/>
```

```astro
<!-- No Astro binding yet — use @var-ui/react -->
```

```html
<!-- No HTML demo yet — use @var-ui/react -->
```

### Expanded selection

Seed nested expansion with `defaultExpandedKeys` and highlight a leaf via `selectionMode` + `defaultSelectedKeys`.

```tsx
import { Tree } from '@var-ui/react';

<Tree
  aria-label="Project files"
  selectionMode="single"
  defaultExpandedKeys={['src', 'components']}
  defaultSelectedKeys={['button']}
  items={[
    {
      id: 'src',
      label: 'src',
      children: [
        {
          id: 'components',
          label: 'components',
          children: [{ id: 'button', label: 'Button.tsx' }],
        },
      ],
    },
  ]}
/>
```

```astro
<!-- No Astro binding yet — use @var-ui/react -->
```

```html
<!-- No HTML demo yet — use @var-ui/react -->
```

## Props

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| aria-label | string \| undefined | no |  |  |
| children | ReactNode | no |  |  |
| className | string \| undefined | no |  |  |
| defaultExpandedKeys | Iterable<string> \| undefined | no |  |  |
| defaultSelectedKeys | Iterable<string> \| undefined | no |  |  |
| density | "compact" \| "balanced" \| "spacious" \| undefined | no |  |  |
| expandedKeys | Iterable<string> \| undefined | no |  |  |
| items | TreeItemData[] \| undefined | no |  |  |
| onExpandedChange | ((keys: Set<string>) => void) \| undefined | no |  |  |
| onSelectionChange | ((keys: Set<string>) => void) \| undefined | no |  |  |
| renderEnd | ((item: TreeItemData) => ReactNode) \| undefined | no |  |  |
| renderStart | ((item: TreeItemData) => ReactNode) \| undefined | no |  |  |
| selectedKeys | Iterable<string> \| undefined | no |  |  |
| selectionMode | TreeSelectionMode \| undefined | no |  |  |

## Accessibility

Root uses `role="tree"`; nodes are `treeitem` with `aria-level`, `aria-expanded`, and optional `aria-selected`. Provide an `aria-label` (or labelled-by) on the tree. Arrow keys move focus (roving tabindex); Left/Right collapse/expand; Space/Enter select when `selectionMode` is not `"none"`.
