Skip to content

Tree

Trees are interactive hierarchies.

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 caseTreeAccordion
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

A Tree constitutes three key components:

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>

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.

PropAction placement
actionsAvailable in a dropdown menu
inlineActionsAvailable 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" />
]}

Tree.Items support two primary interactions:

  1. Expansion
  2. Selection

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.

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.

One approach is to make items behave like radio buttons, wherein only one can be selected at a time.

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 actions and inlineActions props.
  • Prioritize actions by adding them via inlineActions.
  • Implement a selection behavior suited to your users.
  • Use an aria-level value that reflects the level of the item in the hierarchy.
  • Don’t make expandable items reveal items of the same aria-level. They must be the parent’s level plus 1.
  • Don’t try to place Tree.Items inside Tree.Items. Each Tree.Item is a sibling under a Tree.Root parent.
  • Don’t put any components besides Tree.ItemAction in Tree.Item’s action.