Skip to content

TreeTable

A table whose rows form a tree: branch rows expand to show their children, and each column shows a value for every visible row.

See also: DataTable for flat data · Tree when you don’t need columns.

Learn more: Lists & scrolling

Import: package:fleury/fleury.dart, or package:fleury/fleury_core.dart in browser code.

TreeTable<String>(
treeColumnId: 'name',
// Start with the lib branch expanded.
controller: TreeTableController(expandedKeys: const <Object>{'lib'}),
columns: const <DataTableColumn>[
DataTableColumn(id: 'name', title: 'Name'),
DataTableColumn(id: 'size', title: 'Size'),
],
roots: const <TreeTableNode<String>>[
TreeTableNode(
key: 'lib',
label: 'lib',
cells: <String, String>{'size': '—'},
children: <TreeTableNode<String>>[
TreeTableNode(
key: 'main',
label: 'main.dart',
cells: <String, String>{'size': '1.2k'},
),
TreeTableNode(
key: 'app',
label: 'app.dart',
cells: <String, String>{'size': '8.4k'},
),
],
),
TreeTableNode(
key: 'pub',
label: 'pubspec.yaml',
cells: <String, String>{'size': '512'},
),
],
)

Up and Down move the cursor; PageUp, PageDown, Home, and End jump. Right expands a collapsed branch or, on an expanded one, steps into its first child. Left collapses an expanded branch or steps out to the parent row. Enter or a click expands or collapses a branch and passes any other row to onSelect. Ctrl+C copies the row under the cursor (see copySelectedRow and copyOptions).

The TreeTableController holds which nodes are expanded, by TreeTableNode.key. The cursor stays on its node when rows change, and moves to the nearest visible ancestor when its node is hidden. With a filter, the table shows every matching row and its ancestors, expanded or not.

The table rebuilds its rows from roots whenever roots, columns, cellBuilder, filter, or searchIndex is a different object than on the last build, even an equal one; moving the cursor does not. For a large tree, keep those objects the same across rebuilds instead of creating new ones in build.

ParameterTypeDefaultDescription
roots:List<TreeTableNode<T>>requiredRoot nodes of the retained hierarchy.
columns:List<DataTableColumn>requiredColumns displayed for each visible row.
treeColumnId:String?—Id of the column that shows each node’s label, indented by depth, with ▸ or ▾ on branch rows. Defaults to the first column.
cellBuilder:TreeTableCellBuilder<T>?—Optional app-provided cell text builder for non-tree columns.
controller:TreeTableController?—External expansion and selection controller.
focusNode:FocusNode?—Focus node used for keyboard navigation.
autofocus:boolfalseWhether the table should request focus when mounted.
semanticLabel:String'Tree table'Semantic label for the table.
maxVisible:int12Maximum visible body rows before the list scrolls.
filter:TreeTableFilterDescriptor?—Shows only the rows that match, plus their ancestors, whether or not they are expanded.
searchIndex:TreeTableSearchIndex<T>?—Optional prebuilt search index for large trees. While filter has a query, the table lists rows from the index instead of roots, so build a new index whenever the tree changes.
onSelect:void Function(TreeTableRow<T> row)?—Called with a row that has no children when the user activates it with Enter or a click. On a branch row, those expand or collapse it instead.
copySelectedRow:booltrueWhether Ctrl+C (and the semantic copy action) copies the row under the cursor.
copyOptions:TreeTableCopyOptionsconst TreeTableCopyOptions()Export and clipboard options used when copying rows.
onCopy:void Function(TreeTableCopyResult<T> result)?—Called after a copy attempt completes.
columnSpacing:int1Empty cells inserted between adjacent columns.
headerSeparator:booltrueWhether to draw a separator below the header row.
separatorStyle:CellStyle?—Style used for header and row separators.
selectedStyle:CellStyle?—Style merged onto the selected row.

TreeTable is defined in packages/fleury/lib/src/catalog/tree_table.dart.

Category: Lists & data · All widgets