Skip to main content

TreeView

A hierarchical list component that allows users to navigate, expand, and select nested items. Supports controlled selection, default expansion, keyboard navigation, accessibility semantics, and custom icons.


Usage

Basic usage

import { TreeView } from '@nofinite/nui';

const data = [
{ id: '1', label: 'Parent 1' },
{ id: '2', label: 'Parent 2' },
];

<TreeView data={data} />;

With default expanded nodes

<TreeView data={data} defaultExpandedIds={['1']} />

Controlled selection

const [selectedId, setSelectedId] = useState<string | undefined>();

<TreeView
data={data}
selectedId={selectedId}
onSelect={(id) => setSelectedId(id)}
/>;

With icons and nested children

const data = [
{
id: '1',
label: 'Parent 1',
icon: <FolderIcon />,
children: [
{ id: '1-1', label: 'Child 1' },
{ id: '1-2', label: 'Child 2' },
],
},
];

<TreeView data={data} />;

Props

PropTypeDefaultDescription
dataTreeNode[]Array of tree nodes to render
selectedIdstringControlled selected node ID
defaultExpandedIdsstring[][]List of node IDs to expand by default
onSelect(id: string, node: TreeNode) => voidCallback when a node is selected
classNamestringAdditional wrapper styling

TreeNode type

PropTypeDescription
idstringUnique identifier for the node
labelReactNodeNode label
iconReactNodeOptional icon
childrenTreeNode[]Nested child nodes
disabledbooleanDisables selection and expansion

Variants

Nested tree with icons

<TreeView data={nestedData} />

Disabled nodes

const data = [
{ id: '1', label: 'Active Node' },
{ id: '2', label: 'Disabled Node', disabled: true },
];
<TreeView data={data} />;

Available variants

  • Single-level tree
  • Multi-level nested tree
  • Controlled selection
  • Default expanded nodes
  • Nodes with icons
  • Disabled nodes

Guidelines

  • Use for hierarchical datasets like folders, categories, or menus
  • Provide icons for clarity when representing types of nodes
  • Keep nested levels reasonable for readability
  • Use disabled nodes for non-interactable items

States

  • Default (collapsed)
  • Expanded
  • Selected
  • Disabled
  • Focus-visible
  • Hover
  • Nested levels

Keyboard Interaction

  • ArrowUp / ArrowDown → navigate visible nodes
  • ArrowRight → expand collapsed node or move to first child
  • ArrowLeft → collapse expanded node or move to parent
  • Enter / Space → select node and toggle expansion
  • Home → focus first visible node
  • End → focus last visible node
  • Disabled nodes skipped in navigation

Accessibility

  • role="tree" on root, role="group" on nested lists, role="treeitem" on items
  • aria-expanded for nodes with children
  • aria-selected for selected node
  • aria-disabled for disabled nodes
  • Keyboard navigable according to WAI-ARIA TreeView standard
  • Focus visible styling applied for accessibility

Design Tokens

TokenUsage
--nui-font-sansFont family
--nui-fg-defaultText color
--nui-fg-mutedChevron / icon color
--nui-bg-subtleHover / focus background
--nui-color-primarySelected / focus outline
--nui-radius-mdNode border radius
--nui-space-1Vertical padding
--nui-space-2Horizontal padding / gap
--nui-text-smLabel font size
--nui-weight-mediumSelected label font weight
--nui-border-defaultChevron hover background

Best Practices

Do

  • Use for hierarchical data structures
  • Provide visual cues like icons or chevrons
  • Keep nesting levels readable (2–3 levels recommended)
  • Use disabled state for non-interactive nodes
  • Support keyboard navigation for accessibility

Don’t

  • Overload tree with too many levels or items
  • Hide interactive functionality from keyboard users
  • Mix unrelated actions inside tree nodes
  • Remove focus indicators
  • Use long labels that overflow without ellipsis