refactor(createDataTable): drop items option for registry pattern#236
Merged
Conversation
|
commit: |
b7cd0c0 to
f1a66b8
Compare
createDataTable predated the registry-pattern convention used by every
other collection composable in v0 (createRegistry, createModel,
createSelection, createSortable, createKanban, …). The items option
put row identity outside the composable's registry, forced
MaybeRefOrGetter plumbing, and split ownership between the caller's
array and the internal state.
Drop the items option. createDataTable now owns an internal
createRegistry({ events: true, reactive: true }) and spreads its
surface into the returned context, so consumers register rows via the
inherited register / onboard / unregister / clear / upsert methods.
Row identity comes from the ticket id at register time. The itemValue
option goes away with it; consumers pass id: value.id when they want a
domain-stable identifier (selection, expansion, grouping all key off
the ticket id, which equals the caller-supplied id by convention).
Adapters are unchanged — they still receive context.items / allItems
refs that project ticket.value through the pipeline.
Migration shape:
// before
createDataTable({ items: data, ... })
// after
const table = createDataTable({ ... })
table.onboard(data.map(value => ({ id: value.id, value })))
A reactive items source is no longer auto-synced; callers drive
register / unregister, or watch and do clear() + onboard() (see the
ServerDataTableAdapter prose for the canonical server pattern).
Codified in PHILOSOPHY §6.10 "Collection composables: no items option"
plus a checklist line in composables.md and new-feature-checklist.md.
The PHILOSOPHY entry lists createDataGrid as also compliant in
anticipation of the follow-up grid PR that adopts the same surface
inherited via spread.
Co-authored-by: dev-table <noreply@anthropic.com>
Co-authored-by: docs-table <noreply@anthropic.com>
Co-authored-by: philosophy <noreply@anthropic.com>
f1a66b8 to
7e92f30
Compare
…up reopen - selection/expansion subscribe to unregister:ticket and clear:registry so stale ids cannot diverge from the registry - replace rowId(item) reverse lookup with ticket-walking computeds so two tickets sharing a row value reference both participate in selectAll / isAllSelected / toggleAll (catalog buckets keyed by object identity used to collapse onto ids[0]) - guard selectableIds against tickets registered without a value - openAll watcher tracks autoOpened keys and only opens new group keys, so registering more rows no longer reopens groups the user explicitly closed - drop stale createDataGrid references from PHILOSOPHY §6.10, composables rule, and columns JSDoc - rename example fetch -> fetchPage to stop shadowing the global
Drop the `columns` factory option. Columns are now registered the same
way rows are — via `table.columns.register({ id, title, sortable })` and
`table.columns.onboard([...])`. Mirrors the createKanban pattern and
brings createDataTable in line with PHILOSOPHY §6.10.
- new DataTableColumnTicketInput<T> / DataTableColumnTicket<T> pair
- table.columns: RegistryContext<...> namespaced under `columns`
- leaves, headers, sortable, filterable, customSorts, customColumnFilters
are all reactive derivations over columns.values() (were one-shot before)
- sort group reconciles via watch(sortable, ..., { flush: 'sync' }) — new
sortable columns onboard automatically, removed ones drop from the order
array so stale SortEntry rows can't leak through
- adapter context's filterableKeys / customSorts / customColumnFilters
widened to MaybeRefOrGetter<...> so adapter.setup() doesn't snapshot
empty values when columns onboard post-construction
- column id field uses Extensible<keyof T & string> for autocomplete on
known row keys while still accepting derived columns
- docs + PHILOSOPHY §6.10 updated; all four examples migrated to the new
surface and iterate columns via table.columns.values() to demonstrate
reactivity
…istry tip into Usage
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
createDataTablepredated the registry-pattern convention used by every other collection composable in v0. Theitems: MaybeRefOrGetter<T[]>option put row identity outside the composable's registry, forced reactivity plumbing on the caller, and split ownership between the caller's array and the table's internal state. This PR dropsitemsanditemValueand routes row management through the inherited registry surface.Convention codified
PHILOSOPHY.md §6.10 "Collection composables: no items option"plus a checklist line in.claude/rules/composables.mdand.claude/rules/new-feature-checklist.md. The PHILOSOPHY entry listscreateDataGridas also compliant in anticipation of the follow-up grid PR (#174) that adopts the same surface inherited via spread.API change
Internally,
createDataTablenow owns acreateRegistry({ events: true, reactive: true })and spreads its surface into the returned context, so consumers getregister/onboard/unregister/upsert/clear/get/move/ etc. for free.DataTableContext<T>now extendsRegistryContext<DataTableTicketInput<T>, DataTableTicket<T>>.allItems/filteredItems/sortedItems/itemskeep their existingReadonly<Ref<readonly T[]>>shape — they projectticket.valuethrough the pipeline.context.itemsas before.sizeis re-declared as a getter after the registry spread (otherwise{ ...registry }freezes it at construction).Migration shape
Reactive items sources are no longer auto-synced. Callers either drive
register/unregisterthemselves, or watch a source and doclear() + onboard()— the canonical server pattern is documented in the ServerDataTableAdapter section of the docs page.Co-author credit
Built by parallel agents per the project's team convention:
dev-table— source + testsdocs-table— docs page + 4 examplesphilosophy— PHILOSOPHY §6.10 + rules