dequelabs / dequelabs/cauldron

Add TreeView Component

Open
#1,290 2 comments 0 reactions 1 assignee Claimed by @mateoviilla1 View on GitHub
rfc ux debt
Dominant language
TypeScript
Stars
127
Forks
31
Avg merge
2d 12h
Merged PRs (30d)
8

Description

# TreeView

## Overview

`TreeView` is a collection of components that display items in a nested hierarchical list structure that can be expanded or collapsed. This component follows the [ARIA Authoring Practices Guide (APG) tree view pattern](https://www.w3.org/WAI/ARIA/apg/patterns/treeview/).

### Problem Statement

Deque products contain existing hierarchical organizational structures that represent nested content, such as DOM element trees, component hierarchies, and other complex nested organizational structures. Currently, there is no standardized, accessible way to present this type of hierarchical information across Deque products. `TreeView` should provide a reusable, accessible solution for displaying and interacting with nested data.

This component is intended to replace existing hierarchical implementations across Deque products as well as support potential future use cases. The design and feature set must take these existing use cases into consideration to ensure `TreeView` can successfully support all current and any known future requirements.

## Component Design

### Visual Design

https://www.figma.com/design/CEFVdiecqDjLSjhorjHUzI/branch/Ijp18pacN84LbITfkryXnq/Product-Foundations--Cauldron--Library?node-id=6462-25&p=f&m=dev

### Interface / Props

TBD

### Accessibility

`TreeView` should follow APG guidelines for all of the necessary roles in a treeview as outlined in the [treeview example](https://www.w3.org/WAI/ARIA/apg/patterns/treeview/examples/treeview-1a/#rps_label).

`TreeView` should also require a label either via `aria-label` or `aria-labelledby`. Additionally, the expanded/collapsed icons can be customized but will default to a `triangle-down` icon when an item is expanded, or a `triangle-right` icon when an item is collapsed.

If there are a number of nested children within a tree component that exceeds the horizontal space within the tree's outer container, horizontal scrolling should be allowed to display the nested items that are not able to fit within the container.

#### Semantic Elements

`

    ` and `
  • ` elements should provide the base structure for the root component and any group or collection of child items.

    #### Focus

    This component should behave as a single tabstop. The tabstop can be maintained with a roving tab index OR with `aria-activedescendent`. The author can choose which approach should be used for this component.

    > [!NOTE]
    > As a referencing example, the [Listbox](https://github.com/dequelabs/cauldron/blob/develop/packages/react/src/components/Listbox/Listbox.tsx) component uses `aria-activedescendent` as its navigation strategy.

    #### Keyboard Navigation

    `TreeView` should minimally follow APG guidelines for all of the necessary keyboard behavior in a treeview as outlined in the [treeview example](https://www.w3.org/WAI/ARIA/apg/patterns/treeview/examples/treeview-1a/#kbd_label).

    For the mnemonic behavior (e.g. navigating items via a-z keypresses), there should be a Cauldron utility that can assist with this: https://github.com/dequelabs/cauldron/issues/1909

    ### Responsiveness

    There is not a visual alternative to represent the same structure for a treeview in narrow viewports or containers. Horizontal scrolling is required to allow users to navigate tree items that overflow the treeview container.

    When the treeview container is scrollable, navigating to a tree item should bring it into view if it's not in view.

    ### Interactive States

    There are multiple different interactive states that need to be considered, including:

    - The tree itself as a single tab stop
    - Each tree item when navigating through the tree
    - Interactive items within a tree (focusable buttons, links, other controls)

    > [!NOTE]
    > Tree items with children should support both controlled and uncontrolled expansion states. By default, items should manage their own expansion state (uncontrolled). However, the API should allow parent components to control expansion programmatically when needed (e.g., "expand all" functionality or tree items open on initial render or controlled programmatically).

    ### Usage Examples

    Each tree node should minimal support the following:

    - Selections
    - Trailing Actions
    - Labels

    It will need to be evaluated whether the selection type is only maintained at the top of the tree, or if different tree groups can have different selection states (single vs multiple vs none).

    #### Default Example

    ```jsx

    A
    B

    C

    1
    2
    3

    ```

    #### Single-select

    ```jsx

    A
    B

    C

    1
    2
    3

    ```

    > [!NOTE]
    > This is matches the existing [single select pattern from ActionMenu](https://cauldron.dequelabs.com/components/ActionMenu#single-selection).

    #### Multi-select

    ```jsx

    A
    B

    C

    1
    2
    3

    ```

    > [!NOTE]
    > This is matches the existing [multiple select pattern from ActionMenu](https://cauldron.dequelabs.com/components/ActionMenu#multiple-selection).

    ### Referencing Examples

    - [ARIA Authoring Practices Tree View Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/treeview/)
    - [GitHub Primer TreeView](https://primer.style/product/components/tree-view/)
    - [Adobe Spectrum TreeView](https://spectrum.adobe.com/page/tree-view/)
    - [MUI TreeView](https://mui.com/x/react-tree-view/)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.