Skip to content
EspañolEnglish
All components (204)

Tree

Navigation · Tree · .amset-tree

What it is and when to use it

Things within things: the categories of the store, the folders of an archive. Each branch opens and closes, and one, several or none can be chosen.

When to use it

  • Hierarchies of three levels or more, or of two but long ones, where you need to see what each thing hangs from.
  • detail for the small text on the right (how many products are inside); icon to tell the branches apart at a glance.
  • selection="multiple" to check several categories, with cascade if checking a branch has to check everything inside it (the half-checked branch is shown and announced as "partially selected"); "none" if the tree is only for browsing.
  • loadData to request the children of a branch when it is opened (a branch with isLeaf: false and without children): while they arrive it carries its ring and loadingText ("Loading…") is announced.

When not to

  • Two short levels: a SelectableList with sections almost always reads better.
  • For the application menu: SideNav.
  • For collapsible text sections: Accordion.

Keyboard: Tab enters the tree. The up and down arrows go through the visible branches, and Home and End go to the first and the last; right opens a closed branch and left closes it or goes up to the parent, as in any file explorer. Enter or Space choose, and typing the first letters jumps to the branch that starts that way. A disabled branch does not take focus and cannot be chosen.

Accessibility: it is a treegrid with a required name (label). Each branch states its level (aria-level) and whether it is open (aria-expanded), not only with the arrow. The icons are decorative and the checked mark always takes up its space, so that the rows do not jump around.

Fine-tuning: CSS variables --amset-tree-*: -detail, -font, -gap, -padding, -radius, -row-padding. The size changes the padding of the box and of each row, and the font size.

What it looks like

Images

<Tree
  label="Folders"
  branches={[
    { key: 'docs', label: 'Documents', children: [
      { key: 'with', label: 'Contracts', detail: '12 files' },
    ] },
  ]}
/>

Props

Import it with import { Tree } from '@amset/ui'. Required props are marked.

PropTypeWhat it does
branchesrequiredreadonly TreeNode[]—
labelrequiredstringWhat the tree is about: "Store categories". Required.
cascadebooleanChecking a branch checks everything inside it, and a branch with only part checked is shown as "half". The value is the set of checked keys: a branch appears only if everything that can be checked inside it is. What is disabled is not touched.
classNamestringMerged with the library classes; it does not replace them.
initialOpenKeysreadonly string[]—
initialValuestring | readonly string[]—
loadData(key: string) => Promise<readonly TreeNode[]>Asks for the children of a branch the first time it is opened (lazy loading). The branch carries `isLeaf: false` and has no `children`. If it fails, the branch stays closed and can be retried.
loadingTextstringWhat is announced while the children arrive. By default, "Loading…".
onChange((key: string | null) => void) | ((keys: readonly string[]) => void)—
onOpen(keys: readonly string[]) => void—
openKeysreadonly string[]Open keys. If not passed, the tree keeps them internally.
selection"multiple" | "none" | "single"—
size"sm" | "md" | "lg"The padding of each row and the font size.
valuestring | readonly string[] | null—

It also accepts the attributes of the element it renders: className, style, data-*, aria-* and its events.

CSS variables

These CSS variables are how you adapt it. Declare them on the component's selector, not on :root: the stylesheet redeclares them in the rule itself, and a declaration on the same element always wins.

VariableDefault
--amset-tree-paddingvar(--amset-space-1)
--amset-tree-row-paddingvar(--amset-space-2)
--amset-tree-gapvar(--amset-space-2)
--amset-tree-fontvar(--amset-text-base)
--amset-tree-detailvar(--amset-text-sm)
--amset-tree-radiusvar(--amset-radius)

How to change it

.amset-tree {
  --amset-tree-padding: ...;
  --amset-tree-row-padding: ...;
}

In the test bench

Every state and variant, to try one at a time, on its page at ui.amset.tech: