Skip to content

Basics

Loading example…

getSubRows turns a flat list of objects into a tree. Every row keeps its depth, the first visible data column is indented by it, and the expand toggle appears on rows that have children.

<DataTable data={departments} getSubRows={(row) => row.children} columns={columns} />

Children are ordinary rows: they sort, filter, select and export like any other. Sorting orders siblings within their parent rather than flattening the tree.

Loading children when a branch opens

Loading example…

A tree that is too big to send at once loads a branch at a time. dataSource.fetchChildren is called when a row is expanded; the toggle shows a spinner while it runs and reports an error inline if it fails.

The table cannot know whether an unloaded row has children, so tell it:

<DataTable dataSource={dataSource} getRowCanExpand={(row) => row.original.childCount > 0} />

Loaded children are cached per row and invalidated when the query changes, so re-opening a branch does not refetch and a new filter does not show stale children.

Filtering a tree

By default a row is matched on its own values. filterFromLeafRows keeps a parent whenever any descendant matches and auto-expands the path to it, the behaviour you want when searching a file tree. maxLeafRowFilterDepth caps how deep that search goes.

Selection

enableSubRowSelection cascades a parent's checkbox down to its children, and shows the parent as indeterminate when only some are selected. See Row selection.

Customization

treeColumnId moves the indentation and the toggle to a specific column instead of the first visible one. The indentation step is the --tk-tree-indent token, and the toggle is a slot, so a file tree can show folder icons rather than chevrons.

A selectable tree is announced as a treegrid, so assistive technology gets the level and expanded state without any extra attributes from you.

Limitations

  • Sorting never reorders across levels. Children stay inside their parent; that is what makes it a tree rather than a list.
  • Pagination counts top-level rows unless paginateExpandedRows is set, so an expanded branch does not push its siblings onto the next page.
  • Lazily loaded children cannot be searched before they are loaded. Client-side search only sees rows the browser has; move search to the server for a lazy tree.

API

  • DataTableProps: getSubRows, getRowCanExpand, treeColumnId, filterFromLeafRows, maxLeafRowFilterDepth, paginateExpandedRows, enableSubRowSelection, enableExpandAll, manualExpanding.
  • Row: depth, subRows, getParentRow, getLeafRows, getCanExpand, toggleExpanded.
  • TableInstance: getRowChildrenStatus, getExpandedRowModel.