Tree data
Hierarchical rows with indentation, expand toggles and children that can be loaded from the server when a branch is opened.
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
paginateExpandedRowsis 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.