On this page
Import
import { Tree } from '@envsemble/envui';
Usage
<Tree
aria-label="Files"
items={[
{
value: 'src',
depth: 0,
label: 'src',
icon: <IconFolder />,
expandable: true,
expanded: true,
},
{ value: 'src/index.ts', depth: 1, label: 'index.ts', icon: <IconDescription /> },
]}
value={selected}
onAction={(row) => setSelected(row.value)}
onExpandedChange={(row, open) => toggle(row.value, open)}
/>
items are the visible rows in order, flattened: an expanded row is followed by its visible descendants. Each row, a TreeItem, has a stable, unique value, such as a path, which it carries as data-id; its depth, 0 for a top-level row, each level indenting it by 0.75 rem; its label; and an optional decorative icon, a muted description, such as a status or a path, end content, such as a Badge with a count, a native tooltip, textValue for type-ahead where the label isn't plain text, and disabled.
Expanding
expandable gives a row a chevron, and expanded shows its children, the rows that follow it in items. onExpandedChange receives the row and its new state from a press on its chevron, → on a collapsed row and ← on an expanded one, mirrored in right-to-left text; the application updates items, removing a collapsed row's descendants.
Opening, previewing and selection
onAction receives the row people open and { preview }, a TreeActionDetails: true on a single click and Space, false on a double click and Enter. Expandable rows call it too, and disabled rows don't. The tree doesn't select by itself: set value, the selected row's value, from onAction; that row takes the navigation selection colors and scrolls into view when it changes.
Context menu
contextMenu returns the menu items for the row, or for the tree's empty area when the row is null; without it, the browser's own context menu stays. contextMenuLabel names the menu.
Thousands of rows
<div style={{ blockSize: '16rem' }}>
<Tree
aria-label="Build logs"
items={rows}
onAction={(row) => setSelected(row.value)}
onExpandedChange={(row, open) => toggle(row.value, open)}
/>
</div>
The tree renders only the rows in view, and is as tall as its parent: give the parent a height, or the tree one through style. Build rows in a useMemo from the expanded set, such as 50 folders of 200 logs each, over 10,000 rows when all are open. className, style and ref reach the tree, the element that scrolls and holds focus.
Density
density is xs, sm, the default, md or lg, the rows' block padding: in the comfortable scale sm rows are 1.75 rem tall and md rows 2.25 rem, and under a coarse pointer every row is at least 2.75 rem.
Accessibility
You provide
- An
aria-labelfor every tree, and the context menu's name in the application's language. - The visible rows, their expansion, the selection, and what opening does.
- A
textValuefor rows whose label isn't plain text, and a name for a count inend.
envUI provides
- A
treeoftreeitemrows with their level, position, size, expanded, selected and disabled states. - One tab stop with
aria-activedescendant, the active row kept rendered and in view. - Each row's description and end read with its label; icons and chevrons hidden.
- Rows 2.75 rem tall on coarse pointers.
Props
Tree
A virtualized tree of rows for large hierarchies such as file trees. The application passes the visible rows and owns expansion and selection; the tree owns focus, keyboard navigation and scrolling. It fills its parent's height, scrolls itself and renders only the rows in view.
| Prop | Type | Description |
|---|---|---|
itemsrequired | readonly Item[ | The visible rows in order, flattened: an expanded row is followed by its visible descendants. The application owns expansion; collapsing a row removes its descendants from items. |
aria-labelrequired | string | The tree's accessible name, such as Files. |
valueDefault null | stringnull | The selected row's value: it takes the navigation selection colors and scrolls into view when it changes. The application sets it, usually from onAction. |
onActionrequired | ( | Called when people open a row: with preview true on a single click and Space, and false on a double click and Enter. Expandable rows call it too, and disabled rows don't. |
onExpandedChangerequired | ( | Called with the row and its new state from a press on its chevron, the right arrow key on a collapsed row and the left arrow key on an expanded one, mirrored in right-to-left text. The application updates items. |
contextMenu | ( | Menu items for the row people right-click, or press Shift+F10 or the Menu key on, or for the tree's empty area when the item is null. Without it, the browser's own context menu stays. |
contextMenuLabelDefault 'Actions', or EnvUIProvider's messages.tree.contextMenu | string | The context menu's accessible name. |
densityDefault 'sm' | 'xs''sm''md''lg' | How tightly the rows pack: xs, sm, md or lg changes only their block padding, never the text or the icons. In the comfortable scale sm rows are 1.75 rem tall and md rows 2.25 rem. Under a coarse pointer every row is at least 2.75 rem. |
Also accepts the native props of <div>, such as ref, className and aria-* attributes.
Part names
Each part's class and state attributes are public and versioned, for an application's CSS to style.
env-tree- The tree.
env-tree-chevron- The chevron that expands an item.
env-tree-description- An item's description.
env-tree-end- The end of an item, for a count or actions.
env-tree-group- The rows an expanding or collapsing item reveals or hides, while they grow or shrink.
env-tree-icon- An item's icon.
env-tree-item- One item.
env-tree-label- An item's label.
env-tree-rows- The rows of a level.
data-densitylg·md·sm·xsdata-ending-style- Present on env-tree-group
data-expanded- Present on env-tree-chevron
data-focus-visible- Present
data-highlighted- Present on env-tree-item
data-id- Any value, or present on env-tree-item
data-starting-style- Present on env-tree-group, env-tree-item
Strings
EnvUIProvider's messages overrides each, and a component's own label prop wins over it.
messages.tree.contextMenu"Actions"Names an item's menu of actions.
Changelog
- 1.0.0
selectedIdisvalueandonOpenisonAction, withTreeActionDetails; a TreeItem'sdetailisdescriptionand itstrailingisend. The context menu's default name comes frommessages.tree, and the tree takesrefandstyle. A row's class isenv-tree-item(wasenv-tree-row), andenv-tree-detailand-trailingareenv-tree-descriptionand-end; a description keeps more room from its label.- 1.0.0-prerelease.6
A collapsing row's children fade over the whole collapse,
--env-motion-duration-medium, so they leave no empty band.A row's children grow from its end and fade in as it expands, and shrink and fade out as it collapses, in
env-tree-groupuntil they have closed, as an accordion's panel does, while the rows below glide with them; the chevron turns at the pace of the other chevrons.A row under the pointer takes three quarters of
--env-color-bg-row-hover, and pressed the whole of it, a step quieter than a table's rows, so the light tint of the selected row always reads strongest.- 1.0.0-prerelease.5
A row is keyed by
value, which the tree'svaluenames, where it hadid, and its native tooltip istooltip, where it wastitle.TreeActionOptionsisTreeActionDetails. The tree takes the native props, such asidanddata-*.