Accepted 2026-10-31 by the owner: on consolidating the data components ”=> yes”, and the same day
“all accepted merege and proceed”, and the ADR itself “all confirmed” (design-system session c6, STA-1371). It supersedes the
resource-query part of 0318
(
ResourceQuery, ResourceQueryContractProps, FilterState and the query and
onQueryChange props of DataTable and FilterBar), amends
0313 (Table’s sortDescriptor
gives way to sort[]) and the 2026-10-28 DataGrid amendment of
0317 (DataGridColumn,
rows, height, frozenColumns), and reverses the data-collection plan’s rule (owner,
2026-10-29) that DataTable and DataGrid “keep their APIs”.Context
The owner asked why the data components seemed duplicated. A research audit (2026-10-31,stackra-notes/design-system-research-2026-10-31/data-family-audit.md) found that Table, DataTable, DataGrid and List
were mostly proper layers, but the duplication sat around them: two engines (the app-held ResourceQuery of 0318 and
the useCollection engine of the data-collection plan), three column types (TableColumn, CollectionColumn,
DataGridColumn), two filter models with three filter UIs, three saved-view models with four UIs, two column
visibility UIs and two pagers. It came from one day: the product-audit wave of 2026-10-28 built hidden columns, saved
views, group-by and facets on ResourceQuery; seven hours later the data-collection plan built them again on the
engine and, to keep the earlier work, said the old components “keep their APIs”. DataView had to hand DataTable a fake
query, the same columns were declared up to three times, and the panel’s resource table kept a third copy of the state
by hand.
Decision
1. Nine public components and one hook
2. One column type
CollectionColumn is the only column a data component takes. Its type is one enum, RuleFieldType: text,
number, choice, date and boolean (it replaces DataGridCellType; select is now choice). It gains the
editor’s fields: isEditable (DataTable edits it in place with onCellEdit), isReadOnly (DataGrid edits every
column but these), isRequired, min, max and validate. TableColumn stays as the presentational subset Table
reads; DataGridColumn, DataGridOption (now SelectItem), gridColumns and editableColumns are removed.
3. One filter model
CollectionFilter is the only filter. RuleOperator gains in, not_in, between, before, after, is_true
and is_false; a condition’s value is a RuleValue, text or a list of text ([from, to] for between, an empty end
open). A quick filter (a FilterBar chip, a FilterPanel facet) is one top-level condition with the id
filter:<column> (quickFilterIdOf), so the bar, the panel and DataView on one engine show the same filter. The
filter kind comes from the column: text contains, number and date between, choice in, boolean is_true or
is_false. ruleMatches evaluates the new operators the same way on the client and the server.
4. One saved-views model
A saved view is aCollectionView of the engine. SavedViews draws it as a menu (apply, save, save as, rename, share,
make default, delete), as tabs or as chips. A product’s database view store is a CollectionStore adapter.
5. One pager
The pager reads the engine’s paging (page, cursor with the cursors kept for Previous, or infinite). DataView
owns it; DataTable and DataGrid draw it when they stand alone. Server mode without fetch takes the app’s
nextCursor.
6. Old to new
These are no longer exported (internal parts):
ColumnEditorPanel, ColumnMenu, CollectionFilterEditor,
CollectionSortEditor, DataViewCards, DataViewBoard, CollectionRowPanel, DataTableCellEditor and
DataGridEditor.
Consequences
- One declaration of a dataset’s columns feeds the table, the grid, inline edit, the filters and the facets.
- The breaking prop changes land at once, with every caller in the repository (playground, mobile, panel, docs, showcase registry) moved in the same change; there are no deprecated aliases.
- A filter can no longer carry a menu icon, a disabled state, a placeholder, a number step or format, or custom yes
and no words, because filters derive from columns; a column that should not be filtered sets
isFilterable: false. - The panel’s resource table runs on
useCollectionin server mode and gains the board, cards, column editor and multi-sort it did not draw.
Enforcement
stackra gen --checkand the showcase gen keep the generated API pages in step with the props.- The ui package’s tests cover the filter model (
quick-filter.function.test.ts) and each component on the engine.