Treeview
A compound component for building accessible hierarchical tree interfaces with expand/collapse and selection support.
Usage
Display hierarchical data as an expandable, selectable tree. Nodes open and close, selection cascades through parents and children, and v-model tracks the selected nodes.
- Fruits
- Vegetables
- Bread
Anatomy
<script setup lang="ts">
import { Treeview } from '@vuetify/v0'
</script>
<template>
<Treeview.Root>
<Treeview.List>
<Treeview.Item>
<Treeview.Activator>
<Treeview.Cue />
</Treeview.Activator>
<Treeview.Checkbox>
<Treeview.Indicator />
</Treeview.Checkbox>
<Treeview.Content>
<Treeview.Group>
<Treeview.Item />
</Treeview.Group>
</Treeview.Content>
</Treeview.Item>
</Treeview.List>
</Treeview.Root>
</template>Examples
Click a setting to see its description.
Recipes
Expansion Mode
Control how many nodes can be open at once with the open prop:
<template>
<!-- Default: multiple nodes can be open simultaneously -->
<Treeview.Root open="multiple" />
<!-- Accordion: only one node open at a time -->
<Treeview.Root open="single" />
</template>Use open-all to expand all nodes on mount:
<template>
<Treeview.Root open-all>
<!-- All nodes start expanded -->
</Treeview.Root>
</template>Selection Mode
The selection prop controls how selection propagates through the hierarchy:
| Value | Behavior |
|---|---|
cascade (default) | Selecting a parent selects all descendants; parents show tri-state when partially selected |
independent | Each node selected independently, no cascading |
leaf | Only leaf nodes can be selected; selecting a parent selects all its leaf descendants |
<template>
<Treeview.Root v-model="selected" selection="leaf">
<!-- Only leaf nodes appear in v-model -->
</Treeview.Root>
</template>Active Item
The active prop controls single vs. multi-highlight mode (independent of selection):
<template>
<!-- Default: only one item highlighted at a time -->
<Treeview.Root active="single" />
<!-- Multiple items can be highlighted simultaneously -->
<Treeview.Root active="multiple" />
</template>Reveal
Set reveal to automatically open all ancestor nodes when a descendant is opened. Useful for “navigate to item” patterns where a deep node is programmatically opened:
<template>
<Treeview.Root reveal>
<!-- Opening a deep node opens its entire ancestor chain -->
</Treeview.Root>
</template>Cascade Selection
Add v-model to Treeview.Root for cascade selection. Use Treeview.Checkbox and Treeview.Indicator for tri-state checkboxes. Use Treeview.SelectAll for a tree-wide toggle.
<script setup lang="ts">
import { Treeview } from '@vuetify/v0'
import { ref } from 'vue'
const selected = ref<string[]>([])
</script>
<template>
<Treeview.Root v-model="selected">
<Treeview.SelectAll>
<Treeview.Indicator />
Select All
</Treeview.SelectAll>
<Treeview.List>
<Treeview.Item value="users">
<Treeview.Checkbox>
<Treeview.Indicator />
</Treeview.Checkbox>
Users
<Treeview.Group>
<Treeview.Item value="users:view">
<Treeview.Checkbox>
<Treeview.Indicator />
</Treeview.Checkbox>
View
</Treeview.Item>
<Treeview.Item value="users:create">
<Treeview.Checkbox>
<Treeview.Indicator />
</Treeview.Checkbox>
Create
</Treeview.Item>
</Treeview.Group>
</Treeview.Item>
</Treeview.List>
</Treeview.Root>
</template>Styling with Data Attributes
All sub-components expose data attributes for CSS-driven state styling:
| Component | Attribute | Values |
|---|---|---|
| Item | data-selected | Present when selected |
| Item | data-disabled | Present when disabled |
| Item | data-open | Present when expanded |
| Item | data-active | Present when active |
| Activator | data-disabled | Present when disabled |
| Activator | data-open | Present when expanded |
| Checkbox | data-selected | Present when checked |
| Checkbox | data-disabled | Present when disabled |
| Checkbox | data-mixed | Present when indeterminate |
| Cue | data-state | open or closed |
| Indicator | data-state | checked, unchecked, or indeterminate |
The --v0-treeview-depth CSS variable is set on each Item, enabling indentation:
.tree-item {
padding-left: calc(var(--v0-treeview-depth) * 1rem);
}Accessibility
Treeview implements the WAI-ARIA Tree View pattern↗︎. Treeview.List establishes roving tabindex, so only one node is in the Tab order at a time and the arrow keys move focus between nodes. The Activator and Checkbox are tabindex="-1" and are reached through the tree rather than the page’s Tab sequence.
ARIA Attributes
| Attribute | Value | Element |
|---|---|---|
role | tree | List |
aria-multiselectable | true / false | List |
aria-label | Provided label | List |
role | group | Group |
role | treeitem | Item |
aria-expanded | true / false (only when the node has children) | Item |
aria-selected | true / false | Item |
aria-disabled | true / false | Item |
aria-level | Depth (1-based) | Item |
aria-posinset | Position among siblings | Item |
aria-setsize | Sibling count | Item |
aria-current | true when active | Item |
role | checkbox | Checkbox, SelectAll |
aria-checked | true / false / mixed | Checkbox, SelectAll |
aria-hidden | true | Cue, Indicator |
Keyboard Navigation
| Key | Action |
|---|---|
ArrowUp | Moves focus to the previous visible node |
ArrowDown | Moves focus to the next visible node |
ArrowRight | Expands a collapsed node, or moves focus to its first child |
ArrowLeft | Collapses an expanded node, or moves focus to its parent |
Home | Moves focus to the first node |
End | Moves focus to the last visible node |
Enter | Toggles expansion (when expandable) and activates the node |
Space | Toggles selection of the focused node |
* | Expands all sibling nodes at the current level |
Tab | Moves focus to focusable controls inside a row, then out to the next node |
In RTL, the ArrowRight and ArrowLeft directions are swapped. Treeview.SelectAll toggles the whole tree with Enter or Space.
FAQ
cascade (default) selects all descendants when you select a parent and shows tri-state for partial selection; independent selects each node on its own with no propagation; leaf lets only leaf nodes land in v-model, so selecting a parent selects all its leaf descendants.
selection (via v-model and the checkboxes) tracks which nodes are checked. active is a separate single-or-multi highlight, independent of selection, for focus patterns like file explorers, inspectors, and settings panels.
Each Treeview.Item sets a --v0-treeview-depth CSS variable. Multiply it for padding-left — e.g. padding-left: calc(var(--v0-treeview-depth) * 1rem) — so indentation scales automatically with depth.
The tree defaults to open="multiple". Set open="single" on Treeview.Root for accordion behavior, or open-all to expand every node on mount.
Set reveal on Treeview.Root. Opening a descendant then opens its entire ancestor chain — useful for “navigate to item” patterns where a deep node is opened programmatically.