The Tree component exposes application data as a hierarchy of nested, expandable levels. Trees can be explored and organized in different ways. They may offer searching, filtering, and sorting functionality.
Like the Accordion, the Tree is useful for progressively disclosing data. Unlike the Accordion, this data cannot be arbitrary content. It must be a hierarchy.
| Use case | Tree | Accordion |
|---|---|---|
| Progressive disclosure of content (several levels of data) | ✅ | ❌ |
| Progressive disclosure of content (single level of data) | ❌ | ✅ |
| Items include arbitrary content and functionality | ❌ | ✅ |
| Items include associated actions only | ✅ | ❌ |
Structure
Section titled “Structure”Components
Section titled “Components”A Tree constitutes three key components:
Tree.Root: The container, defining a single Tree.Tree.Item: Items belonging directly toTree.Root.Tree.ItemAction: A supplementary action for theTree.Item.
Hierarchy
Section titled “Hierarchy”Tree.Items are supplied as children of Tree.Root. The components themselves are not nestable. Instead, the aria-level prop (required) describes the level of the item in the hierarchy. The aria-posinset and aria-setsize props are also required.
<Tree.Root> <Tree.Item label="Parent" aria-level={1} aria-posinset={1} aria-setsize={1} /> <Tree.Item label="Child 1" aria-level={2} aria-posinset={1} aria-setsize={2} /> <Tree.Item label="Child 2" aria-level={2} aria-posinset={2} aria-setsize={2} /></Tree.Root>Supplementary actions
Section titled “Supplementary actions”Unlike the Accordion, items cannot take arbitrary content or functionality. The Tree.Item component itself is self-closed. However, the actions and inlineActions props lets you insert an array of supplementary actions.
| Prop | Action placement |
|---|---|
actions | Available in a dropdown menu |
inlineActions | Available inline, outside and preceding the dropdown menu |
Each action must use a Tree.ItemAction component. Other components are not permitted.
actions={[ <Tree.ItemAction key="bring-to-front" label="Bring to front" />, <Tree.ItemAction key="send-to-back" label="Send to back" />]}Interaction
Section titled “Interaction”Tree.Items support two primary interactions:
Expansion
Section titled “Expansion”Any Tree.Item can be expanded to reveal other Tree.Items. If the expanded prop is omitted, the Tree.Item is considered a leaf. “Child 1” and “Child 2” are both leaves in the following example.
<Tree.Root> <Tree.Item label="Parent" aria-level={1} aria-posinset={1} aria-setsize={1} expanded={isExpanded} onExpandedChange={() => isExpanded = !isExpanded} /> {isExpanded && ( <Tree.Item label="Child 1" aria-level={2} aria-posinset={1} aria-setsize={2} /> <Tree.Item label="Child 2" aria-level={2} aria-posinset={2} aria-setsize={2} /> )}</Tree.Root>A button to the left of each item is reserved for expanding and collapsing it, where nested items are included. This is handled by onExpandedChange.
Selection
Section titled “Selection”Item selection is facilitated with selected and the onSelectedChange callback. No specific selection behavior is supported out of the box, since different applications have different needs.
Single selection
Section titled “Single selection”One approach is to make items behave like radio buttons, wherein only one can be selected at a time.
Cumulative selection
Section titled “Cumulative selection”If desired, each Tree.Item can act independently, as a simple toggle button. This means they can be selected cumulatively.
In the following example, “Item 1.1” and “Item 3” are selected from the outset.
- Use Tree to let users explore multi-tiered data.
- Create expandable items that reveal nested items.
- Supply supplementary actions via the
actionsandinlineActionsprops. - Prioritize actions by adding them via
inlineActions. - Implement a selection behavior suited to your users.
- Use an
aria-levelvalue that reflects the level of the item in the hierarchy.
🚫 Don’t
Section titled “🚫 Don’t”- Don’t make expandable items reveal items of the same
aria-level. They must be the parent’s level plus1. - Don’t try to place
Tree.Items insideTree.Items. EachTree.Itemis a sibling under aTree.Rootparent. - Don’t put any components besides
Tree.ItemActioninTree.Item’saction.