--- title: Tree description: Trees display hierarchical data (file systems, org charts, or nested categories) with expand/collapse per branch. category: Data display --- import { meta as TreeMeta, Default } from '@/content/stories/tree'; import Canvas from '@/components/component-docs/canvas'; import Demo from '@/components/component-docs/demo'; export const config = { dependencies: { components: [Canvas, Demo], scripts: [ '../../components/component-docs/demo.script.tsx', '../../components/component-docs/canvas.script.tsx', '../../components/component-docs/controls.script.tsx', ], }, }; # Tree

Trees display hierarchical data (file systems, org charts, or nested categories) with expand/collapse per branch.

## Try it ## Usage Pass a `nodes` tree structure or compose tree items as children. Bind `value` to the selected node id. ```tsx import { RuiTree, type RuiTreeNode } from '@ecopages/radiant-ui/tree'; const nodes: RuiTreeNode[] = [ { id: 'src', label: 'src', children: [{ id: 'app', label: 'app.ts' }] }, ]; ``` ## Custom markup `` coordinates any light-DOM tree that matches its query contract. The `RuiTree` helper stamps these targets; it is not required. ```tsx import '@ecopages/radiant-ui/tree';
; ``` ## Node selection

Bind `value` to highlight the active node. Use keyboard arrows to navigate and expand branches.

## Theming Tree maps to **semantic surface and status roles**, never Tailwind palette steps: | Part | CSS roles | | --- | --- | | Surface (`rui-tree`) | `background`, `on-background`, `border`, `radius-container`, `shadow-sm` | | Branch guides | `border` | | Node hover | `surface` | | Selected node | `primary-container`, `on-primary-container` | | Node focus | `surface`, `focus-ring` | Override at the theme layer, not in component CSS. ## API `RuiTree` is a custom element (``) that owns selection, expansion, and roving-tabindex navigation; the `RuiTree` JSX view authors tree items from a `nodes` structure. ### Attributes | Attribute | Type | Default | Description | | --- | --- | --- | --- | | `label` | `string` | `''` | Accessible name for the tree. | | `value` | `string` | `''` | Selected item's `data-value` / id. | ### Light-DOM contract | Target | Required | Host writes | Author owns | | --- | --- | --- | --- | | `[role="tree"]` | yes | — | root list; view sets `aria-label`, `aria-multiselectable` | | `[role="treeitem"]` | yes | `aria-selected`, roving `tabIndex` | `data-value`, `aria-expanded` (branch nodes) | | `data-value` | per item | — | selection identity; fallback `id` or text | | `[role="group"]` | for branches | `hidden` | sibling after expandable treeitem | Do not set `aria-selected` or `tabIndex` on treeitems. Nested hosts: none. ### Events | Event | Detail | Description | | --- | --- | --- | | `rui-change` | `{ value: string }` | Emitted when a tree item is selected. | ### Props | Prop | Type | Default | Description | | --- | --- | --- | --- | | `nodes` | `RuiTreeNode[]` | | Tree structure for the `RuiTree` view. | `RuiTreeNode` is `{ id, label, children?, expanded? }`. ### View helpers | Component | Target stamped | Notes | | --- | --- | --- | | `RuiTree` | `[role="tree"]` with `data-ref="root"` | Accepts `nodes` or `children`. | ### CSS classes Public BEM classes (documented via `@cssclass`): | Class | Description | | --- | --- | | `.rui-tree` | Root list (`role="tree"`). | | `.rui-tree__item` | List item wrapping a node. | | `.rui-tree__node` | Node button (`role="treeitem"`). | ### Theme roles | Part | CSS variables consumed | | --- | --- | | Surface | `--background`, `--on-background`, `--border`, `--radius-container`, `--shadow-control` | | Branch guides | `--border` | | Node hover | `--surface` | | Selected node | `--primary-container`, `--on-primary-container` | | Node focus | `--surface`, `--focus-ring` | ## Accessibility - Tree exposes `role="tree"` with `role="treeitem"` children. - Expand/collapse state is communicated with `aria-expanded`. - Provide `label` so users know what hierarchy the tree represents.