Skip to main content

Tree

A virtualised, lazy-loading tree view.

Guidance​

Trees show nested things one level at a time: the query source browser (source, database, schema, table, column), a dbt project, folders of dashboards. Rows are dense (32px, 28px in compact density), with a chevron, a provider logo or icon, the label, quiet secondary text (a row count in tabular figures, or a column type in mono with secondaryMono), optional tags, and actions that appear on hover and focus.

Nodes may be static (children) or loaded on expand: give a node hasChildren and set loadChildren(node, signal) on the tree. A "Loading" row appears only if loading takes longer than 200ms; a failure shows an error row that retries on Enter, Space or click. With filterable, a filter field above the tree highlights matching labels and expands their ancestors (among loaded nodes).

Only visible rows are rendered (@lit-labs/virtualizer), so 50,000 nodes stay fast. The tree grows with its content up to --mm-tree-height and then scrolls.

Keyboard follows the WAI-ARIA tree view pattern (https://www.w3.org/WAI/ARIA/apg/patterns/treeview/): focus stays on the tree and the active row is aria-activedescendant. Down and Up move; Right expands, or moves to the first child; Left collapses, or moves to the parent (both flipped in right-to-left); Home and End go to the first and last row; Enter activates (mm-activate); Space selects (mm-select; with selection="multiple" it toggles); * expands every sibling; typing a few letters moves to the next row starting with them. Tab moves to the active row's actions, then out of the tree. Clicking a row selects it, clicking the chevron toggles it, and double-clicking activates it.

Properties​

PropertyAttributeTypeDefaultDescription
nodesTreeNode[][]The root nodes.
labellabelstring''Accessible name of the tree, e.g. "Query sources". Required.
selectionselection'none' | 'single' | 'multiple''single'none, single (default) or multiple.
expandedIdsstring[][]Expanded node ids. Updated as the person expands and collapses.
selectedIdsstring[][]Selected node ids. Updated as the person selects.
loadChildrenTreeLoader | undefinedLoads the children of a node with hasChildren. Abort when signal aborts.
actionsTreeAction[] | ((node: TreeNode) => TreeAction[])[]Actions for every node, shown on hover and focus. A node's own actions win.
filterablefilterablebooleanfalseShows a filter field above the tree.
filterfilterstring''The filter text. Matching labels are highlighted and their ancestors expanded.
filterLabelfilter-labelstring''Label of the filter field.
filterPlaceholderfilter-placeholderstring''Placeholder of the filter field.
loadingloadingbooleanfalseShows skeleton rows in place of the tree.
errorerrorstring''Shows an error with a retry button in place of the tree.
emptyTextempty-textstring''Sentence for the empty state.

Methods​

MethodDescription
expand()Expands a node, loading its children if needed.
collapse()Collapses a node.
expandAll()Expands every loaded node. Does not load lazy children.
collapseAll()Collapses every node.
focus()Moves focus to the tree.

Events​

EventDetailDescription
mm-selectCustomEvent<MmTreeSelectDetail>A node was selected or deselected with Space or a click.
mm-activateCustomEvent<MmTreeNodeDetail>A node was activated with Enter or a double-click.
mm-expandCustomEvent<MmTreeExpandDetail>A node was expanded or collapsed by the person.
mm-actionCustomEvent<MmTreeActionDetail>A row action was clicked.
mm-retryCustomEvent<null>The retry button in the error state was activated.

Slots​

SlotDescription
emptyShown when there are no nodes. Defaults to a compact empty state using empty-text.

CSS parts​

PartDescription
filterThe filter field.
treeThe element with role tree.
rowEach row.

CSS custom properties​

PropertyDescription
--mm-tree-heightThe height at which the tree stops growing and scrolls. Defaults to 24rem; use 100% to fill a sized parent.

Examples​

Every state of mm-tree in Storybook, with keyboard and screen reader tests.