Repository navigation
feat(data-table): sub-rows for nested data, sharing Tree's selection model - #681
interacsean wants to merge 4 commits into
Conversation
The pure tree model (building, indexing, filtering, flattening, and reading / ticking / writing a value under each propagation and value strategy) moves from the Tree component to lib/tree, so other tree-shaped UIs can share it, starting with DataTable sub-rows. Expansion state moves into a useTreeExpansion hook, which can now also be controlled (expandedIds / onExpandedChange). Tree uses it uncontrolled, as before. TreeSelectionPropagation, TreeValueStrategy and the TreeSelectionBehaviorProps union are declared with the model and re-exported from Tree, so the public API doesn't change. No behaviour changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…odel
useDataTable takes subRows: { getSubRows, column?, expandedIds /
defaultExpandedIds / onExpandedChange }. The page's rows are the top
level, so pagination counts them and each parent's sub-rows stay on its
page.
- Hierarchy column: the first column (or subRows.column) carries the
indent, the open / close caret and, when selection propagates, the
checkbox. It's locked first and pinned left wherever it's defined;
useColumns ignores hiding, unpinning or moving it (or anything in
front of it), and column settings and the header pin menu show it as
locked.
- Selection: rowSelection takes the same selectionPropagation and
valueStrategy as Tree (default full / leaves), using the shared model
to read, tick and write the selected ids. Ids from other pages pass
through. Under full / down the checkboxes, select-all included, move
into the hierarchy column; under none they stay in the left column.
- The caret is a button with aria-expanded, named from the hierarchy
column's value; full treegrid keyboard navigation is a follow-up.
- subRows can't be combined with rowExpansion: subRows wins, with a
console warning. The hierarchy cell stays read-only under inline
editing.
Exports SubRowsOptions and DataTableTreeRow; documents Sub-rows and
Selecting sub-rows; adds a showcase page.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
cc4af19 to
9ec245a
Compare
…tree # Conflicts: # docs-manifest.json
|
Could we consolidate There are only five valid combinations: Proposed names and behavior: Assume a parent P with two leaf children, A and B. Each scenario below starts with an empty selection.
A few important distinctions:
This would replace the two public props with one, while retaining the existing propagation and value-formatting logic internally. Since these behaviors are shared with |
|
Following up on the selectionStrategy proposal, I would like to propose two additional changes. 1. Define a dedicated
|
Passing both is now a compile error rather than a runtime warning. The warning stays for untyped callers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Summary
Adds sub-rows to
DataTable, so a table can show nested data (a chart of accounts, a BOM, locations within warehouses) as expandable rows, with the same selection model asTree.This is stacked on #675, so the diff is just the table work. It's the tree grid that PR deferred: a hierarchy with real columns belongs with
DataTable, notTree.Commits
refactor(tree)moves the tree model and expansion state fromcomponents/treeintolib/tree, soTreeandDataTableshare one implementation.Tree's behaviour is unchanged.feat(data-table)buildssubRowson top of it.API
subRows:getSubRows(row)returns a row's children, andcolumnnames the column that carries the hierarchy (defaults to the first). Open rows are controlled withexpandedIds+onExpandedChange, or uncontrolled withdefaultExpandedIds.rowSelectiontakes the sameselectionPropagationandvalueStrategyasTree, with the same defaults ("full"/"leaves") and the same rules about which combinations are allowed.SubRowsOptionsandDataTableTreeRow.subRowsandrowExpansioncan't be combined. A row shows either its sub-rows or a detail panel, sorowExpansionis ignored with a console warning.Behaviour worth a look
columnnames a column defined later. Column settings won't hide it, unpin it, or move it or anything in front of it, and it shows a lock. Persisted column state from before sub-rows were turned on is corrected on load. Making the lock opt-in is on https://github.com/tailor-platform/app-shell/tree/feat/data-table-tree-lock-column-opt-in, held back for now."full"/"down"they sit in the hierarchy column, indented with the row, so a parent and the rows it ticks line up. Under"none"every row is independent, so they stay in the usual selection column.aria-expanded. A fulltreegridkeyboard model is a follow-up.Open question
Under
selectionPropagation: "none", select-all also ticks sub-rows hidden inside closed parents, so a bulk action can hit rows nobody saw. That's expected under"full"and"down". I'm checking whether"none"should tick visible rows only.Test plan
vitest: sub-row tests for expansion (controlled and not), the locked column, every selection mode, page-scoped select-all, cycles and warn-once. Full suite: 2,828 passing.tsc,oxlint,oxfmt --check,pnpm docs:check,check-dts./showcase/data-table-tree: each propagation and strategy, the locked column in the Columns popover, and alignment in each mode.🤖 Generated with Claude Code