Skip to content

feat(createDataTable): add new composable#138

Merged
johnleider merged 18 commits intomasterfrom
feat/composable-data-table
Feb 18, 2026
Merged

feat(createDataTable): add new composable#138
johnleider merged 18 commits intomasterfrom
feat/composable-data-table

Conversation

@johnleider
Copy link
Copy Markdown
Member

@johnleider johnleider commented Feb 17, 2026

Summary

  • New createDataTable composable that composes v0 primitives (createGroup, createFilter, createPagination) into a complete data pipeline
  • Adapter pattern with three strategies: ClientAdapter (default), ServerAdapter, and VirtualAdapter
  • Full feature set: sorting (multi-column, mandate, custom comparators), filtering (per-column custom filters), pagination, selection (single/page/all strategies), expansion, and grouping
  • Trinity pattern support via createDataTableContext / useDataTable
  • Type-safe generic DataTableColumn<T> with keyof T & string column keys
  • Documentation page with 4 live examples (basic, server, features, virtual)

Test plan

  • pnpm typecheck passes
  • pnpm lint:fix passes (only pre-existing unrelated catalog error)
  • 3-pass inspection (typescript, v0 patterns, SSR, a11y, testing, code review)
  • Manual verification of all 4 doc examples in browser
  • Verify column key autocomplete works in IDE

Composes createFilter, createGroup (tri-state sort), and
createPagination into a unified data table pipeline with
row selection and auto page reset.
Extract pipeline into adapter hierarchy following v0 patterns
(ThemeAdapter/LoggerAdapter). Abstract DataTableAdapter provides
shared filter/sort; ClientAdapter (v0.ts), ServerAdapter, and
VirtualAdapter implement pipeline strategies.
Rename variables to remove redundant prefixes where context is clear:
sortGroup→group, sortOrder→order, toggleSort→toggle, resetSort→reset,
sortableColumns→sortable, filterableKeys→filterable, paginatedItems→visible,
getRowId→rowId. Public API: sort.sortBy→sort.entries.
…forcement

- Add sort.direction(key) and sort.priority(key) for aria-sort support
- Add total: ComputedRef<number> to all adapters for aria-rowcount
- Enforce readonly on computed array returns and sort order
- Guard compareValues against NaN using isNaN from v0 utilities
…port

Readonly enforcement (selectedIds, columns), type-safe itemValue,
rename sort.entries to sort.columns, locale-aware sorting via useLocale
fallback chain, loading/error adapter states, and selection scope docs.
Lightweight Set-based expansion with expand/collapse/toggle per row,
expandAll/collapseAll bulk ops, and accordion mode via expandMultiple.
…/filter, grouping

- selectStrategy: 'single' | 'page' | 'all' for selection scope control
- mustSort: prevent clearing sort (asc ↔ desc cycle)
- firstSortOrder: 'asc' | 'desc' for initial sort direction
- DataTableColumn.sort: per-column custom sort comparator
- DataTableColumn.filter: per-column custom filter function
- itemSelectable: per-row selectability with isSelectable() guard
- groupBy: row grouping with open/close state management
- mustSort → mandate
- search ref → search() function + query ref
- isOpen → opened
- ServerAdapter totalItems → total
- Add 'data' to nav subcategory ordering
- Update all cross-references across docs
- Add createDataTable docs with 4 multi-file examples
…dd ariaSort

- Make DataTableColumn generic with key: keyof T & string
- Constrain groupBy to keyof T, itemValue to KeysOfType<T, ID>
- Make columns input readonly, remove unsafe casts
- Add ariaSort() method for ARIA-ready sort values
- Fix filterable derivation to require explicit filterable: true
- Fix isSelectable to return false for non-existent items
- Add SSR warning JSDoc, clarify expansion scope asymmetry
ARIA translation belongs in the component layer, not the headless
composable. Consumers map sort.direction() to aria-sort values themselves.
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Feb 17, 2026

Open in StackBlitz

commit: ab952d3

Use isNullOrUndefined from v0 utilities, remove section comments,
simplify watch source in server example.
…y locale

- Replace computed with toRef where caching is unnecessary (.length,
  toValue(), ternary, constants)
- Update interfaces from ComputedRef to Readonly<Ref>
- Use toSorted instead of spread + sort
- Simplify locale resolution to use useLocale() built-in fallback
- Replace triangle sort icons with chevrons in examples
Cover search, sort cycles (mandate/firstSortOrder/multi), selection
strategies (single/page/all with itemSelectable), expansion, grouping,
client/server/virtual adapters, trinity context, and edge cases.
Cover initialization, search/sort/selection pipelines, grouping,
computed access caching, full end-to-end pipeline, and client vs
virtual adapter comparison at 1K and 10K dataset sizes.
@johnleider johnleider changed the title feat(createDataTable): composable data table with adapter pattern feat(createDataTable): add new composable Feb 18, 2026
@johnleider johnleider self-assigned this Feb 18, 2026
@johnleider johnleider added this to the v0.2.0 milestone Feb 18, 2026
@johnleider johnleider added the enhancement New feature or request label Feb 18, 2026
…ction performance

- Rename grouping.opened() → isOpen() for consistency with isSelected/isExpanded
- Change DataTableGroup.value type from unknown to T[keyof T & string]
- Fix enroll initialization to handle async data sources via watcher fallback
- Constrain itemSelectable to KeysOfType<T, boolean>
- Cache selectable IDs in computed Set for O(1) lookups (was O(n) per call)
- Narrow adapter context types: filterableKeys, customSorts, customColumnFilters
- Add explicit type assertions on loading/error destructured defaults
- Add useDataTable @typeparam JSDoc recommending trinity pattern
- Add Options reference table and sort.order to docs
@johnleider johnleider force-pushed the feat/composable-data-table branch from 24370a5 to ab952d3 Compare February 18, 2026 18:32
@johnleider johnleider merged commit 575d344 into master Feb 18, 2026
12 of 13 checks passed
@johnleider johnleider deleted the feat/composable-data-table branch February 18, 2026 18:43
johnleider added a commit that referenced this pull request Mar 21, 2026
* feat(createDataTable): composable data table from v0 primitives

Composes createFilter, createGroup (tri-state sort), and
createPagination into a unified data table pipeline with
row selection and auto page reset.

* feat(createDataTable): adapter pattern with v0 naming conventions

Extract pipeline into adapter hierarchy following v0 patterns
(ThemeAdapter/LoggerAdapter). Abstract DataTableAdapter provides
shared filter/sort; ClientAdapter (v0.ts), ServerAdapter, and
VirtualAdapter implement pipeline strategies.

* refactor(createDataTable): tighten internal naming to single-word focus

Rename variables to remove redundant prefixes where context is clear:
sortGroup→group, sortOrder→order, toggleSort→toggle, resetSort→reset,
sortableColumns→sortable, filterableKeys→filterable, paginatedItems→visible,
getRowId→rowId. Public API: sort.sortBy→sort.entries.

* feat(createDataTable): add sort helpers, total count, and readonly enforcement

- Add sort.direction(key) and sort.priority(key) for aria-sort support
- Add total: ComputedRef<number> to all adapters for aria-rowcount
- Enforce readonly on computed array returns and sort order
- Guard compareValues against NaN using isNaN from v0 utilities

* feat(createDataTable): harden types, add locale and loading/error support

Readonly enforcement (selectedIds, columns), type-safe itemValue,
rename sort.entries to sort.columns, locale-aware sorting via useLocale
fallback chain, loading/error adapter states, and selection scope docs.

* feat(createDataTable): add row expansion support

Lightweight Set-based expansion with expand/collapse/toggle per row,
expandAll/collapseAll bulk ops, and accordion mode via expandMultiple.

* feat(createDataTable): add select strategy, sort options, custom sort/filter, grouping

- selectStrategy: 'single' | 'page' | 'all' for selection scope control
- mustSort: prevent clearing sort (asc ↔ desc cycle)
- firstSortOrder: 'asc' | 'desc' for initial sort direction
- DataTableColumn.sort: per-column custom sort comparator
- DataTableColumn.filter: per-column custom filter function
- itemSelectable: per-row selectability with isSelectable() guard
- groupBy: row grouping with open/close state management

* refactor(createDataTable): refine API surface

- mustSort → mandate
- search ref → search() function + query ref
- isOpen → opened
- ServerAdapter totalItems → total

* docs(createDataTable): add data category and documentation page

- Add 'data' to nav subcategory ordering
- Update all cross-references across docs
- Add createDataTable docs with 4 multi-file examples

* refactor(createDataTable): harden types, fix filter/selection bugs, add ariaSort

- Make DataTableColumn generic with key: keyof T & string
- Constrain groupBy to keyof T, itemValue to KeysOfType<T, ID>
- Make columns input readonly, remove unsafe casts
- Add ariaSort() method for ARIA-ready sort values
- Fix filterable derivation to require explicit filterable: true
- Fix isSelectable to return false for non-existent items
- Add SSR warning JSDoc, clarify expansion scope asymmetry

* refactor(createDataTable): remove ariaSort from headless composable

ARIA translation belongs in the component layer, not the headless
composable. Consumers map sort.direction() to aria-sort values themselves.

* refactor(createDataTable): clean up adapter utilities and examples

Use isNullOrUndefined from v0 utilities, remove section comments,
simplify watch source in server example.

* refactor(createDataTable): use toRef for trivial derivations, simplify locale

- Replace computed with toRef where caching is unnecessary (.length,
  toValue(), ternary, constants)
- Update interfaces from ComputedRef to Readonly<Ref>
- Use toSorted instead of spread + sort
- Simplify locale resolution to use useLocale() built-in fallback
- Replace triangle sort icons with chevrons in examples

* docs(createDataTable): improve adapter docs, fix server example, update sort icons

* docs(createDataTable): fix group toggle icons, fix virtual table border bleed

* test(createDataTable): add comprehensive test suite

Cover search, sort cycles (mandate/firstSortOrder/multi), selection
strategies (single/page/all with itemSelectable), expansion, grouping,
client/server/virtual adapters, trinity context, and edge cases.

* perf(createDataTable): add benchmark suite

Cover initialization, search/sort/selection pipelines, grouping,
computed access caching, full end-to-end pipeline, and client vs
virtual adapter comparison at 1K and 10K dataset sizes.

* perf(createDataTable): improve type safety, API consistency, and selection performance

- Rename grouping.opened() → isOpen() for consistency with isSelected/isExpanded
- Change DataTableGroup.value type from unknown to T[keyof T & string]
- Fix enroll initialization to handle async data sources via watcher fallback
- Constrain itemSelectable to KeysOfType<T, boolean>
- Cache selectable IDs in computed Set for O(1) lookups (was O(n) per call)
- Narrow adapter context types: filterableKeys, customSorts, customColumnFilters
- Add explicit type assertions on loading/error destructured defaults
- Add useDataTable @typeparam JSDoc recommending trinity pattern
- Add Options reference table and sort.order to docs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant