Xzero UI
Pro library

Tree table

A table with nested rows, tri-state selection, hierarchy-preserving sort, and lazy-loaded children.

$ pnpm dlx shadcn@4.23.0 add @xzero-ui/tree-table
Live · keyboard ready

When to use

When not to use

Installation

Register both Xzero UI namespaces in your project's components.json:

{
  "registries": {
    "@xzero-ui": "https://mcp.xzero.co.uk/r/{name}.json",
    "@xzero-ui-pro": "https://mcp.xzero.co.uk/r/pro/{name}.json"
  }
}
npx shadcn@4.23.0 add @xzero-ui/tree-table

Install xzero-foundation once, and import @/components/xzero/foundation.css in your app root. No Xzero token is used by this snapshot. For sample portraits, photos, fonts, or logos, download https://mcp.xzero.co.uk/install-assets.mjs and run node xzero-install-assets.mjs <receiving-project>.

Usage

import { TreeTable } from "@/components/xzero/tree-table/tree-table";
import type { TreeTableColumn, TreeTableRow } from "@/components/xzero/tree-table/tree-table";

type Item = { name: string; size: number; owner: string };

const columns: TreeTableColumn<Item>[] = [
  { id: "name", header: "Name", cell: item => item.name, sortValue: item => item.name, width: "minmax(0, 2fr)" },
  { id: "size", header: "Size", cell: item => `${item.size} MB`, sortValue: item => item.size, align: "end", width: "96px" },
  { id: "owner", header: "Owner", cell: item => item.owner, hideBelow: 520 },
];

export function Files({ rows }: { rows: TreeTableRow<Item>[] }) {
  return (
    <TreeTable
      label="Files"
      rows={rows}
      columns={columns}
      selectable
      rowLabel={item => item.name}
      defaultExpanded={["design"]}
      loadChildren={row => fetchChildren(row.id)}
      maxHeight={480}
    />
  );
}

API reference

TreeTable

A table whose rows nest, with spring expand and collapse, indent guides, tri-state selection, hierarchy safe sorting, and lazy children.

PropTypeDefaultDescription
rows (required)TreeTableRow<T>[]–Top level rows: { id, data, children?, hasChildren? }.
columns (required)TreeTableColumn<T>[]–Columns: { id, header, cell(data, context), sortValue?, width?, align?, hideBelow? }. The first shown column holds the tree.
label (required)string–Accessible name of the table.
expandedstring[]–Controlled ids of expanded rows.
defaultExpandedstring[][]Rows expanded at first when uncontrolled.
onExpandedChange(ids: string[]) => void–Called when rows expand or collapse.
selectablebooleanfalseAdds a checkbox column. Checking a parent checks everything under it.
selectedstring[]–Controlled ids of selected rows.
defaultSelectedstring[][]Rows selected at first when uncontrolled.
onSelectedChange(ids: string[]) => void–Called with the new selection. Parents are added or removed to match their children.
sortTreeTableSort | null–Controlled sort: { columnId, direction: "ascending" | "descending" }.
defaultSortTreeTableSort | nullnullStarting sort when uncontrolled.
onSortChange(sort: TreeTableSort | null) => void–Called as a header cycles ascending, descending, and off.
loadChildren(row: TreeTableRow<T>) => Promise<TreeTableRow<T>[]>–Loads children of a row with hasChildren on first expand. A rejection shows a retry row.
rowLabel(data: T) => string–Names a row for its checkbox, such as the file or team name.
onRowActivate(row: TreeTableRow<T>) => void–Called when a row without children is clicked or gets Enter. Parent rows toggle instead.
maxHeightnumber | string–Caps the height; the header stays pinned while the body scrolls.
emptyStateReactNode"Nothing to show"Shown when there are no rows.
classNamestring–Class on the root.
refRef<HTMLDivElement>–The root element.

collectExpandableIds

Returns the ids of every row whose children are known, for an external expand all.

PropTypeDefaultDescription
rows (required)TreeTableRow<T>[]–The tree to walk.
loadedRecord<string, TreeTableRow<T>[]>–Children loaded so far, keyed by parent id.

Keyboard interactions

KeysAction
ArrowDown / ArrowUpMoves between visible rows.
ArrowRightExpands a row, or moves to its first child when already open.
ArrowLeftCollapses a row, or moves to its parent.
Home / EndMoves to the first or last visible row.
PageDown / PageUpMoves ten rows.
*Expands every sibling of the focused row.
SpaceToggles selection when selectable.
EnterToggles a parent, retries a failed load, or activates a leaf row.
Cmd/Ctrl+ASelects or clears all rows when selectable.

Accessibility

Motion

Responsive behavior

Performance

Notes for AI

Also in tables

Guidance for AI tools

Tree table: A table with nested rows, tri-state selection, hierarchy-preserving sort, and lazy-loaded children. Follow the declared prop types and do not invent props. Keep keyboard access, reduced motion support, and both light and dark themes intact when adapting it.

Full library index: https://ui.xzero.co.uk/llms.txt

Browse all components