TreeView

TreeView is a hierarchical list of items that may have a parent-child relationship where children can be toggled into view by expanding or collapsing their parent item.

Page navigation navigation

Anatomy

Edit in Figma
  1. Parent node: Expands/collapses to show/hide child nodes.
  2. End node: A node with no children
  3. Chevron: Expands/collapses a parent node and indicates expanded/collapsed state.
  4. Nesting level indicator lines: Each line represents a level of nesting depth
  5. Leading action (optional): An IconButton to allow interaction with the node besides activating or expanding.
  6. Leading visual (optional): A visual cue for additional context
  7. Node label: The text label for the node
  8. Trailing visual (optional): Same as a leading visual, but at the end

Content

Node label

Node labels should be a succinct title for whatever entity the node represents. For example, a file name.

By default, labels are truncated to a single line. However, node labels may be wrapped to multiple lines in cases where the entire label must always be visible.

When a node's text is truncated, it should still be accessible to users in some fashion. Truncation is only accessibly acceptable if there is some way for users - including those navigating with a keyboard - to see the non-truncated text.

Edit in Figma
Single line truncation
Edit in Figma
Wrapping node label text

Leading and trailing visuals

Leading and trailing visuals may be used as visual cues that communicate more information about a node.

If the leading or trailing visual contains useful information, make sure it has a screen-reader accessible text label. Note that the file and folder icons are not considered useful information, as the TreeView's underlying markup will communicate their presence.

Either all nodes have leading visuals, or no nodes have leading visuals. Leading visuals must be accompanied by a text label.

Do
Edit in Figma
Render all nodes with leading visuals and text labels or just with text labels
Don’t
Edit in Figma
Don't have a tree where only some nodes have leading visuals

Interaction

Keyboard users can expand or collapse nodes without activating them by using the left and right arrow keys.

To give cursor users an equivalent experience, there are two click areas:

  • clicking the chevron only expands or collapses the node
  • clicking anywhere else will activate the node

If the node cannot be activated, clicking anywhere on the node will expand it.

Edit in Figma
Two click areas - toggle expanded or activate link
Edit in Figma
One click area - toggle expanded

Nodes may not contain any other interactive elements besides the chevron. Activating a node can only perform one action. For example, following a link.

Do
Edit in Figma
Limit nodes to a single action
Don’t
Edit in Figma
Don't put other interactive elements in a node

We have investigated the feasibility of supporting a context menu for each node, and that could be something we support in the future if we find we need it.

Usage

TreeViews are only for hierarchical lists

A TreeView solves a very specific problem. It's not a multi-purpose tool like an ActionList or meant for site navigation like a NavList.

Tree views are used to communicate a hierarchical list of items, and allow a user to navigate through, select, and take action on one or more items. A comparable experience would be a list of files in a code editor, or an operating system file explorer. While they may visually look like navigation, tree views have specific interaction modes and expectations for assistive technology that differs from other patterns. Trying to use a tree view for something that looks visually appropriate, but is not functionally inline with its intended use case may cause confusion or an unusable experience, especially if the user cannot see the screen.

Before reaching for a TreeView, first make sure that:

  • the items in the TreeView represent a list
  • the list items are likely to have a parent-child relationship with more than 1 level of nesting
  • the expand and collapse behavior aids in navigation instead of just making it more complex

Some good cases for a TreeView are:

  • navigating the file structure of a repo
  • navigating a codebase's symbols (types, constants, functions, etc) organized by their scope hierarchy

A TreeView would not be appropriate for:

  • global sidebar navigation
  • an FAQ that collapses answers under question headings
Do
Edit in Figma
Use a TreeView for a list
Don’t
Edit in Figma
Don't use a TreeView for expanding and collapsing sections of content

Expanding and collapsing nodes

A TreeView can be a frustrating pattern if it forces users to spend a lot of time expanding and collapsing nodes to find what they're looking for.

Expanded by default

When a child node is active, all of it's parent nodes should be expanded.

If it's likely that a user will want to interact with all or most of the nodes in the tree, render the tree with all parent nodes expanded to start. For example: when reviewing a pull request, all of the changed files are shown to make it easy for reviewers to scan and navigate the changed files.

Edit in Figma

Preserve expanded state when parent node is collapsed

If a user expands nested parent nodes and then collapses a parent node higher in the hierarchy, persist the expanded parent nodes lower in the hierarchy. It could be frustrating to have to re-expand the nodes that were already opened.

Optionally combine parent nodes

If no end nodes are in the ancestry and the parent nodes cannot be activated, you may combine parent nodes into a single parent node to reduce the levels of nesting. Less levels of nesting make for a more compact tree and less nodes for the user to expand to get to child nodes.

Edit in Figma

Handling deeply nested nodes

Navigating through deeply nested nodes can be cumbersome and visually clunky. If accessing nodes deeper than 10 levels deep is a common interaction for your use-case, reconsider whether a TreeView is the best pattern.

TreeViews are designed to be horizontally compact in order to support many levels of nesting and long node labels. This makes content truncation and horizontal overflow less likely to occur for deeply nested nodes, but infinite nesting makes those cases impossible to prevent entirely.

There are some strategies to avoid a TreeView that horizontally overflows it's container:

  • Allow the TreeView's container to be manually resized
  • Once a certain depth is reached, start the TreeView from a deeper parent node and provide a way to navigate back up the tree
  • Remove leading and trailing visuals

If a TreeView is truly the best pattern for your use-case and none of the suggested strategies prevent horizontal overflow, opt for horizontal scrolling as a last resort instead of hiding overflowing content.

Handling errors loading child nodes

Inform users why the data cannot be retrieved and give them a path to resolve it. The error message cannot appear in the TreeView because it is not semantically a node in the tree. Instead, the error message should appear in a Dialog with an optional call-to-action that can resolve the error.

If the user dismisses the Dialog, focus should be moved back to the collapsed parent node. If the user clicks a call-to-action that attempts to load the child nodes again, focus should be moved to the node in the tree that communicates the child nodes are loading.

If we don't have enough information to write a useful error message, it's ok to write something generic like "Couldn't load".

Edit in Figma

Composition

Split layout

A common pattern is to render a TreeView in a split PageLayout where the TreeView is in the left pane, and a view for the selected file is rendered in the main content area.

Edit in Figma

Example

Edit in Figma
A TreeView being rendered in a split PageLayout.

Standalone

However, a TreeView can also be rendered on it's own.

Edit in Figma

Example

Edit in Figma
A TreeView that replaces itself with the content of the activated node.

Provide sufficient vertical space

Be considerate of the amount of vertical space a TreeView can take up when all of it's nodes are expanded.

Do
Edit in Figma
Render a TreeView in an area with enough vertical space to comfortably browse the list, and doesn't push important content or controls below the bottom of the viewport
Don’t
Edit in Figma
Don't render a TreeView in an area that pushes down other content or forces users to scroll through small segments of the list