---
title: Tree View
description: Hierarchical tree view
visibility: guest
draft: false
---

# Tree View

A hierarchical list for displaying nested data structures — file trees, category hierarchies, organization charts. Implements the full [WAI-ARIA Tree View pattern](https://www.w3.org/WAI/ARIA/apg/patterns/treeview/) with keyboard navigation.

## Basic Usage

:::preview{title="Simple file tree"}
<x-wirekit::tree-view>
    <x-wirekit::tree-view.node label="src" expanded>
        <x-wirekit::tree-view.node label="components">
            <x-wirekit::tree-view.node label="Button.php" />
            <x-wirekit::tree-view.node label="Input.php" />
        </x-wirekit::tree-view.node>
        <x-wirekit::tree-view.node label="utils">
            <x-wirekit::tree-view.node label="helpers.php" />
        </x-wirekit::tree-view.node>
    </x-wirekit::tree-view.node>
    <x-wirekit::tree-view.node label="tests">
        <x-wirekit::tree-view.node label="Feature">
            <x-wirekit::tree-view.node label="ButtonTest.php" />
        </x-wirekit::tree-view.node>
    </x-wirekit::tree-view.node>
</x-wirekit::tree-view>
:::

## With Icons

Pass semantic icon aliases to indicate file types:

:::preview{title="Tree with icons"}
<x-wirekit::tree-view>
    <x-wirekit::tree-view.node label="Documents" icon="menu" expanded>
        <x-wirekit::tree-view.node label="Report.pdf" icon="edit" />
        <x-wirekit::tree-view.node label="Budget.xlsx" icon="edit" />
    </x-wirekit::tree-view.node>
    <x-wirekit::tree-view.node label="Images" icon="menu">
        <x-wirekit::tree-view.node label="photo.jpg" icon="eye" />
    </x-wirekit::tree-view.node>
</x-wirekit::tree-view>
:::

## Pre-expanded Nodes

Use the `expanded` prop to open branch nodes by default — great for surfacing the most relevant level of a hierarchy without forcing a click:

:::preview{title="Pre-expanded branches"}
<x-wirekit::tree-view>
    <x-wirekit::tree-view.node label="Workspace" expanded>
        <x-wirekit::tree-view.node label="Pinned" expanded>
            <x-wirekit::tree-view.node label="Dashboard" />
            <x-wirekit::tree-view.node label="Reports" />
        </x-wirekit::tree-view.node>
        <x-wirekit::tree-view.node label="Archive">
            <x-wirekit::tree-view.node label="2024" />
            <x-wirekit::tree-view.node label="2023" />
        </x-wirekit::tree-view.node>
    </x-wirekit::tree-view.node>
</x-wirekit::tree-view>
:::

## Handling Selection

Listen to the `tree-node-select` event to respond to user selections:

```blade
<x-wirekit::tree-view @tree-node-select="console.log($event.detail.label)">
    <x-wirekit::tree-view.node label="Option A" />
    <x-wirekit::tree-view.node label="Option B" />
</x-wirekit::tree-view>
```

## Dynamic Data

Build trees from a Livewire property using recursive Blade:

```php
// In your Livewire component
public array $tree = [
    ['label' => 'src', 'children' => [
        ['label' => 'App.php'],
        ['label' => 'routes', 'children' => [
            ['label' => 'web.php'],
        ]],
    ]],
];
```

```blade
{{-- In your Blade view --}}
<x-wirekit::tree-view>
    @foreach($tree as $node)
        @include('partials.tree-node', ['node' => $node])
    @endforeach
</x-wirekit::tree-view>
```

```blade
{{-- partials/tree-node.blade.php --}}
<x-wirekit::tree-view.node :label="$node['label']">
    @if(!empty($node['children']))
        @foreach($node['children'] as $child)
            @include('partials.tree-node', ['node' => $child])
        @endforeach
    @endif
</x-wirekit::tree-view.node>
```

## Tree View Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `scope` | string\|null | `null` | Scoped personalization key |

## Node Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `label` | string | `''` | Node display text |
| `icon` | string\|null | `null` | Semantic icon alias |
| `expanded` | bool | `false` | Whether branch node starts expanded |
| `selected` | bool | `false` | Whether node starts selected |
| `scope` | string\|null | `null` | Scoped personalization key |

### Slots

| Slot | Purpose |
| --- | --- |
| default | Child nodes (makes this a branch node) |

### Events

| Event | Detail | Description |
| --- | --- | --- |
| `tree-node-select` | `{ label: string }` | Dispatched when Enter/Space is pressed on a focused node |

## Accessibility

- Container uses `role="tree"` — screen readers announce "tree"
- Each node uses `role="treeitem"` — announced as tree item
- Branch nodes have `aria-expanded="true"` or `"false"` — state announced on focus
- Nested children wrapped in `role="group"` — screen readers convey nesting
- Decorative chevrons/spacers marked `aria-hidden="true"`
- Focus ring visible on keyboard navigation
- Full keyboard pattern: arrows, Home, End, Enter, Space

## Keyboard Interaction

The tree view implements the full [WAI-ARIA Tree View keyboard pattern](https://www.w3.org/WAI/ARIA/apg/patterns/treeview/):

| Key | Action |
|-----|--------|
| `Tab` | Move focus into the tree |
| `ArrowDown` / `ArrowUp` | Move to the next / previous visible node |
| `ArrowRight` (collapsed branch) | Expand the branch |
| `ArrowRight` (expanded branch) | Move focus to the first child |
| `ArrowLeft` (expanded branch) | Collapse the branch |
| `ArrowLeft` (collapsed leaf) | Move focus to the parent |
| `Home` / `End` | Jump to first / last visible node |
| `Enter` / `Space` | Activate the focused node (toggles expand/collapse on a branch) |
| Type a character | Type-ahead to focus the next node starting with that character |

## Pitfalls

- **Don't put more than ~500 nodes in a single tree.** WAI-ARIA Authoring Practices warn that virtual focus management degrades for large trees. Lazy-load child nodes on expand.
- **Don't use `<x-wirekit::tree-view>` for non-hierarchical data.** Flat lists belong in `<x-wirekit::data-list>`; the tree's `aria-level` semantics will mislead screen readers.

## Design Tokens

| Element | Token |
| --- | --- |
| Font family | `--font-wk-sans` |
| Text size | `--text-wk-md` |
| Text color | `--color-wk-text` |
| Muted text (chevron) | `--color-wk-text-muted` |
| Hover background | `--color-wk-bg-muted` |
| Focus ring | `--color-wk-ring` / `--ring-wk-width` |
| Node padding | `--padding-wk-x-sm` / `--padding-wk-y-sm` |
| Border radius | `--radius-wk-sm` |
| Transition | `--transition-wk-duration` |

## Customization

Override defaults in `config/wirekit.php`:

```php
'components' => [
    'tree-view' => [],
],
```

## Further Reading

- [WAI-ARIA Tree View Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/treeview/)
- [MDN: `role="tree"`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/tree_role)
- [MDN: `role="treeitem"`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/treeitem_role)
