Skip to content

feat(data-table): migrate to TanStack Table v9 - #1928

Merged
zernonia merged 2 commits into
unovue:devfrom
KevinVandy:feat/table-v9
Aug 7, 2026
Merged

feat(data-table): migrate to TanStack Table v9#1928
zernonia merged 2 commits into
unovue:devfrom
KevinVandy:feat/table-v9

Conversation

@KevinVandy

@KevinVandy KevinVandy commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Linked issue

Fixes #1924

Also expected to resolve #1918 — the deselect-all lag comes from v8's coarse re-rendering on selection state changes; v9's fine-grained reactive core (table atoms backed by Vue computed) is designed to eliminate exactly that. Please verify on the preview deploy.

Type of change

  • 📚 Examples / docs / tutorials
  • 🧹 Chore / refactor

Description

Migrates all data-table usage from @tanstack/vue-table@8 to 9.0.0 (npm latest):

  • valueUpdater is deleted (the [Feature]: Update table & relevant docs to tanstack table v9 #1924 ask): the registry table item's utils.ts is removed from both registry sources, the 8 generated style copies, and lib/utils.ts; the table item no longer depends on @tanstack/vue-table. v9 makes the helper obsolete — state is internal and reactive by default.
  • v9 API everywhere: useVueTableuseTable with an explicit tableFeatures() declaration per table; row models are feature slots (filteredRowModel: createFilteredRowModel(), …); the built-in filter/sort functions are registered explicitly (filterFns: { includesString }, sortFns: { alphanumeric, text }) — v9 tree-shakes these, and unregistered string references (including the default 'auto') silently no-op.
  • State: the controlled refs + on*Change updater dance are gone; tables use v9's internal state, and each example keeps exactly one externally managed rowSelection slice (ref + state getter + inline updater-resolving handler) to demonstrate the pattern. Reads use table.atoms.<slice>.get() (reactive in templates; wrapped in computed() in script).
  • Rendering: <FlexRender :header="header" /> / <FlexRender :cell="cell" /> shorthand. One real v9 landmine fixed: a bare onExpand: row.toggleExpanded reference would lose this (v9 methods live on prototypes) — now wrapped.
  • Docs: the data-table guide is rewritten for v9 (new "Set up Table Features" section, per-feature "already registered — add the UI" steps, the external-slice row-selection step, updated tanstack.com/table/latest/... links); the valueUpdater mention in components-json.md is updated.
  • Registry: regenerated public/r output for new-york-v4 + the 8 reka styles; dashboard-01 now ships its features.ts. Frozen legacy outputs (public/r/styles/{default,new-york}) and deprecated/ untouched.

Heads-up for reviewers: many committed public/r/**/*.json files show as perpetually modified on any touch because their blobs contain CRLF while .gitattributes mandates eol=lf — a pre-existing repo issue this PR deliberately leaves alone (none of those files are in this diff).

Validation

  • pnpm --filter v4 typecheck — no errors in any touched file (remaining errors are pre-existing on dev, e.g. the dnd-kit PluginDescriptor mismatch)
  • pnpm test, pnpm --filter v4 registry:check:icons
  • pnpm registry:build
  • pnpm --filter v4 build (Nuxt production build)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Updated payment, task, dashboard, and demo tables with improved sorting, filtering, pagination, column visibility, row selection, and expandable-row support.
    • Enhanced table rendering and reactive state handling for more consistent interactions.
    • Added configurable table capabilities for reusable table experiences.
  • Documentation

    • Refreshed data table guidance and component configuration documentation with updated examples and usage instructions.

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Migrates tables and documentation from TanStack Vue Table v8 to v9. The change adds shared feature registries, typed column helpers, reactive table atoms, updated rendering APIs, and removes the obsolete valueUpdater utility and registry entries.

Changes

TanStack Table v9 migration

Layer / File(s) Summary
Migrate table implementations
apps/v4/components/cards/Payments.vue, apps/v4/components/demo/DataTableDemo.vue, apps/v4/components/examples/*, apps/v4/registry/new-york-v4/blocks/dashboard-01/components/*
Tables now use registered features, useTable, typed column helpers, external row selection, reactive pagination atoms, and direct FlexRender instances.
Update v9 guidance and shared runtime support
apps/v4/content/docs/components/data-table.md, apps/v4/content/docs/03.components-json.md, apps/v4/lib/utils.ts, apps/v4/package.json
Documentation now describes TanStack Table v9. The obsolete valueUpdater helper is removed, and the package requirement is updated to ^9.0.0.
Synchronize registry outputs
apps/v4/public/r/*, apps/v4/registry/**/*
Registry metadata adds dashboard feature files and removes obsolete table utility files and TanStack Vue Table declarations.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant DataTable
  participant features
  participant useTable
  participant FlexRender
  DataTable->>features: provide registered table features
  DataTable->>useTable: create typed table with columns and row selection
  useTable->>FlexRender: provide header and cell instances
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Linked Issues check ❓ Inconclusive The PR covers the v9 migration, documentation updates, and valueUpdater removal, but performance improvement for deselecting all rows is not verifiable from the summary. Provide benchmark or preview evidence that deselecting all rows no longer causes the reported 1–2 second delay.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the primary change: migrating data-table usage to TanStack Table v9.
Out of Scope Changes check ✅ Passed The changes are related to the TanStack Table v9 migration, including implementation, documentation, dependency, utility, and generated registry updates.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@KevinVandy
KevinVandy marked this pull request as ready for review August 6, 2026 22:56

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/v4/components/demo/DataTableDemo.vue`:
- Around line 161-164: Update the DefineTemplate implementation used by
ReuseTemplate to accept and invoke the onExpand callback from the actions menu,
ensuring the menu action triggers row.toggleExpanded through the existing
onExpand prop.

In `@apps/v4/components/examples/tasks/components/DataTablePagination.vue`:
- Around line 39-41: Update the `@update`:model-value binding in
DataTablePagination to convert the emitted string page size to a number before
passing it to table.setPageSize, preserving the numeric pagination state
expected by the table API.

In `@apps/v4/content/docs/components/data-table.md`:
- Around line 1010-1011: Update the `@update`:model-value handler in the
pagination page-size control to convert the selected string value to a number
before passing it to table.setPageSize. Preserve the existing model-value
binding and ensure TanStack pagination state receives a numeric page size.

In `@apps/v4/registry/__index__.ts`:
- Around line 2352-2355: Remove the duplicate registry entry for
registry/new-york-v4/blocks/dashboard-01/components/features.ts from the
generated index, leaving exactly one entry consistent with the source manifest
and published output. Regenerate apps/v4/registry/__index__.ts; if regeneration
restores the duplicate, update the registry build step that produces it.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 7eb9462d-0486-4ea4-9095-24943223bba7

📥 Commits

Reviewing files that changed from the base of the PR and between 431d30f and 2468df9.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (55)
  • apps/v4/components/cards/Payments.vue
  • apps/v4/components/demo/DataTableDemo.vue
  • apps/v4/components/examples/dashboard/components/DataTable.vue
  • apps/v4/components/examples/dashboard/components/DraggableRow.vue
  • apps/v4/components/examples/dashboard/components/features.ts
  • apps/v4/components/examples/tasks/components/DataTable.vue
  • apps/v4/components/examples/tasks/components/DataTableColumnHeader.vue
  • apps/v4/components/examples/tasks/components/DataTableFacetedFilter.vue
  • apps/v4/components/examples/tasks/components/DataTablePagination.vue
  • apps/v4/components/examples/tasks/components/DataTableRowActions.vue
  • apps/v4/components/examples/tasks/components/DataTableToolbar.vue
  • apps/v4/components/examples/tasks/components/DataTableViewOptions.vue
  • apps/v4/components/examples/tasks/components/columns.ts
  • apps/v4/components/examples/tasks/components/features.ts
  • apps/v4/content/docs/03.components-json.md
  • apps/v4/content/docs/components/data-table.md
  • apps/v4/lib/utils.ts
  • apps/v4/package.json
  • apps/v4/public/r/index.json
  • apps/v4/public/r/styles/new-york-v4/dashboard-01.json
  • apps/v4/public/r/styles/new-york-v4/registry.json
  • apps/v4/public/r/styles/new-york-v4/table.json
  • apps/v4/public/r/styles/reka-luma/registry.json
  • apps/v4/public/r/styles/reka-luma/table.json
  • apps/v4/public/r/styles/reka-lyra/registry.json
  • apps/v4/public/r/styles/reka-lyra/table.json
  • apps/v4/public/r/styles/reka-maia/registry.json
  • apps/v4/public/r/styles/reka-maia/table.json
  • apps/v4/public/r/styles/reka-mira/registry.json
  • apps/v4/public/r/styles/reka-mira/table.json
  • apps/v4/public/r/styles/reka-nova/registry.json
  • apps/v4/public/r/styles/reka-nova/table.json
  • apps/v4/public/r/styles/reka-rhea/registry.json
  • apps/v4/public/r/styles/reka-rhea/table.json
  • apps/v4/public/r/styles/reka-sera/registry.json
  • apps/v4/public/r/styles/reka-sera/table.json
  • apps/v4/public/r/styles/reka-vega/registry.json
  • apps/v4/public/r/styles/reka-vega/table.json
  • apps/v4/registry/__index__.ts
  • apps/v4/registry/bases/reka/ui/_registry.ts
  • apps/v4/registry/bases/reka/ui/table/utils.ts
  • apps/v4/registry/new-york-v4/blocks/_registry.ts
  • apps/v4/registry/new-york-v4/blocks/dashboard-01/components/DataTable.vue
  • apps/v4/registry/new-york-v4/blocks/dashboard-01/components/DraggableRow.vue
  • apps/v4/registry/new-york-v4/blocks/dashboard-01/components/features.ts
  • apps/v4/registry/new-york-v4/ui/_registry.ts
  • apps/v4/registry/new-york-v4/ui/table/utils.ts
  • apps/v4/styles/reka-luma/ui/table/utils.ts
  • apps/v4/styles/reka-lyra/ui/table/utils.ts
  • apps/v4/styles/reka-maia/ui/table/utils.ts
  • apps/v4/styles/reka-mira/ui/table/utils.ts
  • apps/v4/styles/reka-nova/ui/table/utils.ts
  • apps/v4/styles/reka-rhea/ui/table/utils.ts
  • apps/v4/styles/reka-sera/ui/table/utils.ts
  • apps/v4/styles/reka-vega/ui/table/utils.ts
💤 Files with no reviewable changes (13)
  • apps/v4/styles/reka-lyra/ui/table/utils.ts
  • apps/v4/registry/new-york-v4/ui/_registry.ts
  • apps/v4/styles/reka-nova/ui/table/utils.ts
  • apps/v4/registry/new-york-v4/ui/table/utils.ts
  • apps/v4/lib/utils.ts
  • apps/v4/styles/reka-maia/ui/table/utils.ts
  • apps/v4/styles/reka-rhea/ui/table/utils.ts
  • apps/v4/registry/bases/reka/ui/table/utils.ts
  • apps/v4/styles/reka-mira/ui/table/utils.ts
  • apps/v4/styles/reka-luma/ui/table/utils.ts
  • apps/v4/registry/bases/reka/ui/_registry.ts
  • apps/v4/styles/reka-sera/ui/table/utils.ts
  • apps/v4/styles/reka-vega/ui/table/utils.ts

Comment thread apps/v4/components/demo/DataTableDemo.vue
Comment thread apps/v4/content/docs/components/data-table.md
Comment thread apps/v4/registry/__index__.ts
KevinVandy and others added 2 commits August 7, 2026 21:57
Replaces @tanstack/vue-table@8 usage with the v9 API across the demo,
tasks and dashboard examples, the dashboard-01 block, and the payments
card:

- useVueTable -> useTable with explicit tableFeatures(); row models are
  feature slots and the built-in filter/sort fns are registered
  (v9 tree-shakes them; unregistered string fns silently no-op)
- delete the valueUpdater helper and the table item's utils.ts from the
  registry (fixes the dead helper on v9); the table item no longer
  depends on @tanstack/vue-table
- drop controlled state refs in favor of v9's internal reactive state;
  each example keeps one externally managed rowSelection slice to show
  the pattern
- FlexRender :header/:cell shorthand; wrap a bare row.toggleExpanded
  reference that would lose `this` on v9's prototype methods
- rewrite the data-table guide for v9 and update tanstack.com links
- regenerate registry output; add the dashboard-01 features.ts to its
  manifest

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@zernonia
zernonia merged commit 18cce30 into unovue:dev Aug 7, 2026
4 of 5 checks passed

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/v4/content/docs/components/data-table.md (1)

226-242: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Constrain TData to RowData.

ColumnDef<TData> expects TData extends RowData, but the current TData generic is unconstrained. Import RowData and add the constraint to the Vue generic declaration.

Proposed fix
-<script setup lang="ts" generic="TData">
-import type { ColumnDef } from '`@tanstack/vue-table`'
+<script setup lang="ts" generic="TData extends RowData">
+import type { ColumnDef, RowData } from '`@tanstack/vue-table`'
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/v4/content/docs/components/data-table.md` around lines 226 - 242, Update
the generic declaration in the data table component to constrain TData to
RowData, and import RowData from `@tanstack/vue-table` alongside ColumnDef. Keep
the existing props and table logic unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/v4/content/docs/components/data-table.md`:
- Around line 681-687: Clarify the header checkbox scope in the columns example
by updating its ariaLabel and the prose around line 701 to state “select all
rows on this page,” matching getIsAllPageRowsSelected() and
toggleAllPageRowsSelected().
- Around line 764-765: Update the table configuration in useTable to provide
getRowCanExpand: () => true, enabling Payment leaf rows to expand and allowing
row.toggleExpanded() to update state; use a row predicate instead if expansion
should be limited to selected rows.
- Around line 425-429: Update the DropdownAction import in the documented
columns.ts example to use the relative path to
components/payments/data-table-dropdown.vue, matching the documented directory
and filename casing.

---

Outside diff comments:
In `@apps/v4/content/docs/components/data-table.md`:
- Around line 226-242: Update the generic declaration in the data table
component to constrain TData to RowData, and import RowData from
`@tanstack/vue-table` alongside ColumnDef. Keep the existing props and table logic
unchanged.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: bdb53dd1-b821-4be7-be8e-08971e9f81a6

📥 Commits

Reviewing files that changed from the base of the PR and between 36fa539 and fb1d66e.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (55)
  • apps/v4/components/cards/Payments.vue
  • apps/v4/components/demo/DataTableDemo.vue
  • apps/v4/components/examples/dashboard/components/DataTable.vue
  • apps/v4/components/examples/dashboard/components/DraggableRow.vue
  • apps/v4/components/examples/dashboard/components/features.ts
  • apps/v4/components/examples/tasks/components/DataTable.vue
  • apps/v4/components/examples/tasks/components/DataTableColumnHeader.vue
  • apps/v4/components/examples/tasks/components/DataTableFacetedFilter.vue
  • apps/v4/components/examples/tasks/components/DataTablePagination.vue
  • apps/v4/components/examples/tasks/components/DataTableRowActions.vue
  • apps/v4/components/examples/tasks/components/DataTableToolbar.vue
  • apps/v4/components/examples/tasks/components/DataTableViewOptions.vue
  • apps/v4/components/examples/tasks/components/columns.ts
  • apps/v4/components/examples/tasks/components/features.ts
  • apps/v4/content/docs/03.components-json.md
  • apps/v4/content/docs/components/data-table.md
  • apps/v4/lib/utils.ts
  • apps/v4/package.json
  • apps/v4/public/r/index.json
  • apps/v4/public/r/styles/new-york-v4/dashboard-01.json
  • apps/v4/public/r/styles/new-york-v4/registry.json
  • apps/v4/public/r/styles/new-york-v4/table.json
  • apps/v4/public/r/styles/reka-luma/registry.json
  • apps/v4/public/r/styles/reka-luma/table.json
  • apps/v4/public/r/styles/reka-lyra/registry.json
  • apps/v4/public/r/styles/reka-lyra/table.json
  • apps/v4/public/r/styles/reka-maia/registry.json
  • apps/v4/public/r/styles/reka-maia/table.json
  • apps/v4/public/r/styles/reka-mira/registry.json
  • apps/v4/public/r/styles/reka-mira/table.json
  • apps/v4/public/r/styles/reka-nova/registry.json
  • apps/v4/public/r/styles/reka-nova/table.json
  • apps/v4/public/r/styles/reka-rhea/registry.json
  • apps/v4/public/r/styles/reka-rhea/table.json
  • apps/v4/public/r/styles/reka-sera/registry.json
  • apps/v4/public/r/styles/reka-sera/table.json
  • apps/v4/public/r/styles/reka-vega/registry.json
  • apps/v4/public/r/styles/reka-vega/table.json
  • apps/v4/registry/__index__.ts
  • apps/v4/registry/bases/reka/ui/_registry.ts
  • apps/v4/registry/bases/reka/ui/table/utils.ts
  • apps/v4/registry/new-york-v4/blocks/_registry.ts
  • apps/v4/registry/new-york-v4/blocks/dashboard-01/components/DataTable.vue
  • apps/v4/registry/new-york-v4/blocks/dashboard-01/components/DraggableRow.vue
  • apps/v4/registry/new-york-v4/blocks/dashboard-01/components/features.ts
  • apps/v4/registry/new-york-v4/ui/_registry.ts
  • apps/v4/registry/new-york-v4/ui/table/utils.ts
  • apps/v4/styles/reka-luma/ui/table/utils.ts
  • apps/v4/styles/reka-lyra/ui/table/utils.ts
  • apps/v4/styles/reka-maia/ui/table/utils.ts
  • apps/v4/styles/reka-mira/ui/table/utils.ts
  • apps/v4/styles/reka-nova/ui/table/utils.ts
  • apps/v4/styles/reka-rhea/ui/table/utils.ts
  • apps/v4/styles/reka-sera/ui/table/utils.ts
  • apps/v4/styles/reka-vega/ui/table/utils.ts
💤 Files with no reviewable changes (13)
  • apps/v4/registry/bases/reka/ui/_registry.ts
  • apps/v4/styles/reka-vega/ui/table/utils.ts
  • apps/v4/styles/reka-sera/ui/table/utils.ts
  • apps/v4/styles/reka-lyra/ui/table/utils.ts
  • apps/v4/styles/reka-mira/ui/table/utils.ts
  • apps/v4/styles/reka-nova/ui/table/utils.ts
  • apps/v4/styles/reka-maia/ui/table/utils.ts
  • apps/v4/lib/utils.ts
  • apps/v4/styles/reka-rhea/ui/table/utils.ts
  • apps/v4/registry/new-york-v4/ui/_registry.ts
  • apps/v4/styles/reka-luma/ui/table/utils.ts
  • apps/v4/registry/new-york-v4/ui/table/utils.ts
  • apps/v4/registry/bases/reka/ui/table/utils.ts
🚧 Files skipped from review as they are similar to previous changes (41)
  • apps/v4/public/r/styles/reka-luma/registry.json
  • apps/v4/public/r/styles/reka-nova/registry.json
  • apps/v4/components/examples/tasks/components/DataTableRowActions.vue
  • apps/v4/public/r/styles/reka-rhea/table.json
  • apps/v4/public/r/styles/reka-mira/registry.json
  • apps/v4/public/r/styles/reka-maia/registry.json
  • apps/v4/public/r/styles/reka-lyra/table.json
  • apps/v4/components/examples/tasks/components/DataTableColumnHeader.vue
  • apps/v4/public/r/styles/reka-lyra/registry.json
  • apps/v4/package.json
  • apps/v4/public/r/styles/reka-sera/registry.json
  • apps/v4/registry/new-york-v4/blocks/dashboard-01/components/DraggableRow.vue
  • apps/v4/public/r/styles/new-york-v4/registry.json
  • apps/v4/components/demo/DataTableDemo.vue
  • apps/v4/content/docs/03.components-json.md
  • apps/v4/public/r/styles/reka-vega/registry.json
  • apps/v4/public/r/styles/reka-sera/table.json
  • apps/v4/components/examples/dashboard/components/DraggableRow.vue
  • apps/v4/public/r/styles/reka-vega/table.json
  • apps/v4/registry/new-york-v4/blocks/dashboard-01/components/features.ts
  • apps/v4/components/examples/tasks/components/DataTableViewOptions.vue
  • apps/v4/public/r/styles/reka-rhea/registry.json
  • apps/v4/components/examples/tasks/components/DataTablePagination.vue
  • apps/v4/components/examples/tasks/components/features.ts
  • apps/v4/components/examples/dashboard/components/features.ts
  • apps/v4/public/r/styles/reka-luma/table.json
  • apps/v4/public/r/index.json
  • apps/v4/registry/new-york-v4/blocks/_registry.ts
  • apps/v4/public/r/styles/new-york-v4/table.json
  • apps/v4/components/examples/tasks/components/DataTable.vue
  • apps/v4/public/r/styles/reka-maia/table.json
  • apps/v4/registry/index.ts
  • apps/v4/public/r/styles/new-york-v4/dashboard-01.json
  • apps/v4/components/examples/tasks/components/columns.ts
  • apps/v4/components/cards/Payments.vue
  • apps/v4/components/examples/tasks/components/DataTableFacetedFilter.vue
  • apps/v4/public/r/styles/reka-nova/table.json
  • apps/v4/components/examples/dashboard/components/DataTable.vue
  • apps/v4/registry/new-york-v4/blocks/dashboard-01/components/DataTable.vue
  • apps/v4/public/r/styles/reka-mira/table.json
  • apps/v4/components/examples/tasks/components/DataTableToolbar.vue

Comment on lines +425 to 429
Update our columns definition to add a new `actions` column. The `actions` cell returns a `<Dropdown />` component. Because the column doesn't read a data field, we define it with `columnHelper.display`.

```ts
import { ColumnDef } from '@tanstack/vue-table'
// components/payments/columns.ts
import DropdownAction from '@/components/DataTableDropDown.vue'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Fix the DropdownAction import path.

The documented project structure places the file at components/payments/data-table-dropdown.vue, but this import resolves @/components/DataTableDropDown.vue. The directory and filename casing do not match. Use the relative path from components/payments/columns.ts.

Proposed fix
-import DropdownAction from '`@/components/DataTableDropDown.vue`'
+import DropdownAction from './data-table-dropdown.vue'
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Update our columns definition to add a new `actions` column. The `actions` cell returns a `<Dropdown />` component. Because the column doesn't read a data field, we define it with `columnHelper.display`.
```ts
import { ColumnDef } from '@tanstack/vue-table'
// components/payments/columns.ts
import DropdownAction from '@/components/DataTableDropDown.vue'
// components/payments/columns.ts
import DropdownAction from './data-table-dropdown.vue'
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/v4/content/docs/components/data-table.md` around lines 425 - 429, Update
the DropdownAction import in the documented columns.ts example to use the
relative path to components/payments/data-table-dropdown.vue, matching the
documented directory and filename casing.

Comment on lines +681 to +687
export const columns = columnHelper.columns([
columnHelper.display({
id: 'select',
header: ({ table }) => h(Checkbox, {
'modelValue': table.getIsAllPageRowsSelected() || (table.getIsSomePageRowsSelected() && 'indeterminate'),
'onUpdate:modelValue': (value: boolean | 'indeterminate') => table.toggleAllPageRowsSelected(!!value),
'ariaLabel': 'Select all',

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== locate file =="
git ls-files | grep -F 'apps/v4/content/docs/components/data-table.md' || true

echo "== relevant lines =="
if [ -f apps/v4/content/docs/components/data-table.md ]; then
  nl -ba apps/v4/content/docs/components/data-table.md | sed -n '650,710p'
fi

echo "== search Select all prose/select checkbox context =="
rg -n "Select all rows|Select all|toggleAllPageRowsSelected|getIsAllPageRowsSelected|getIsAllRowsSelected|toggleAllRowsSelected" apps/v4/content/docs/components/data-table.md || true

Repository: unovue/shadcn-vue

Length of output: 280


🌐 Web query:

Tanstack Table Vue migration getIsAllPageRowsSelected toggleAllPageRowsSelected getIsAllRowsSelected toggleAllRowsSele

💡 Result:

In TanStack Table, row selection APIs are consistent across versions v8 and v9 for Vue, though some behavioral details have been clarified [1][2]. These APIs are primarily used to handle "select all" functionality for either all rows in the dataset or only those currently visible on the page [3][4][5]. Key Row Selection APIs The following table instance methods allow you to check the selection status and toggle selection for your header checkboxes [3][4][5]: 1. All Rows (Full Dataset) - Check status: table.getIsAllRowsSelected returns a boolean indicating if all rows are selected [3][4][5]. - Toggle handler: table.getToggleAllRowsSelectedHandler returns a function to bind to your checkbox's change/input event [3][6]. - Manual toggle: table.toggleAllRowsSelected(value: boolean) allows you to programmatically set the selection state [4][5]. 2. Page Rows (Current Page Only) - Check status: table.getIsAllPageRowsSelected returns a boolean indicating if all rows on the current page are selected [7][4][5]. - Toggle handler: table.getToggleAllPageRowsSelectedHandler returns a function to bind to your checkbox's change/input event [7][4][5]. - Manual toggle: table.toggleAllPageRowsSelected(value: boolean) allows you to programmatically set the selection state for the current page [4][5]. Implementation Tip To implement an indeterminate "select all" checkbox, you should bind the checked state to the "all selected" API and the indeterminate state to the "some rows selected" API [3][7][6]. In v9, the "some rows selected" APIs (table.getIsSomeRowsSelected and table.getIsSomePageRowsSelected) were updated to return true when at least one row is selected [1][2]. To maintain the classic indeterminate look, use the following logic for the indeterminate prop [1][2]: table.getIsSomeRowsSelected &&!table.getIsAllRowsSelected [1][2] For further migration details or framework-specific nuances, consult the official TanStack Table migration guides [1][2].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== relevant lines =="
awk '{ printf "%6d:%s\n", NR, $0 }' apps/v4/content/docs/components/data-table.md | sed -n '650,715p'

echo "== all select-all/page selection occurrences in file =="
awk '{ printf "%6d:%s\n", NR, $0 }' apps/v4/content/docs/components/data-table.md | rg -n "Select all|toggleAllPageRowsSelected|getIsAllPageRowsSelected|toggleAllRowsSelected|getIsAllRowsSelected" || true

echo "== package versions for Tanstack table if present =="
git ls-files | rg '(^|/)package\.json$|pnpm-lock\.yaml|yarn\.lock|package-lock\.json' | while read -r f; do
  if rg -q "`@tanstack`|tanstack" "$f"; then
    echo "-- $f --"
    rg -n '"`@tanstack/table-core`"|"`@tanstack/vue-table`"|"`@tanstack/table`"|table-core|vue-table' "$f" || true
  fi
done

Repository: unovue/shadcn-vue

Length of output: 4149


Clarify the header checkbox scope.

getIsAllPageRowsSelected() and toggleAllPageRowsSelected() apply to the current page only. Update the label and line 701 prose to say “select all rows on this page,” or use the full-dataset APIs if the documentation should cover dataset-wide selection.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/v4/content/docs/components/data-table.md` around lines 681 - 687,
Clarify the header checkbox scope in the columns example by updating its
ariaLabel and the prose around line 701 to state “select all rows on this page,”
matching getIsAllPageRowsSelected() and toggleAllPageRowsSelected().

Comment on lines +764 to 765
Let's make rows expandable. The `rowExpandingFeature` and expanded row model are already registered in our features object, so the table tracks expanded state for us — we just add the UI.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

rg -n -C 4 \
  'getRowCanExpand|row.toggleExpanded|rowExpandingFeature' \
  apps/v4/content/docs/components/data-table.md

Repository: unovue/shadcn-vue

Length of output: 1239


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

# Inspect the relevant DataTable documentation around data model registration, filtering, and expansion.
sed -n '1,210p' apps/v4/content/docs/components/data-table.md
printf '\n--- Expanding section ---\n'
sed -n '700,890p' apps/v4/content/docs/components/data-table.md

# Find concrete Payment/subRows/getRowCanExpand definitions/usages in the docs source.
printf '\n--- broader search ---\n'
rg -n -C 3 'interface Payment|type Payment|subRows|getRowCanExpand|canExpand|toggleExpanded|createExpandedRowModel|rowExpandingFeature' apps/v4/content/docs/components/data-table.md

Repository: unovue/shadcn-vue

Length of output: 13908


🌐 Web query:

TanStack Table v9 getRowCanExpand default subRows false enabledByDefault

💡 Result:

In TanStack Table, the default behavior for row expansion is governed by the presence of sub-rows. Specifically, the row.getCanExpand method returns false by default unless the row contains sub-rows (as determined by your getSubRows configuration) [1][2][3][4]. To customize or override this default behavior, you can provide a custom getRowCanExpand function in your table instance options [1][5][6]. Key points regarding this behavior: 1. Default Logic: By default, a row is only considered "expandable" if it has sub-rows [1][7][8]. 2. Overriding: Providing a getRowCanExpand(row) => boolean function in the table options allows you to force rows to be expandable, even if they lack inherent sub-rows (e.g., when implementing custom expanded UI for rows that do not share the same column structure) [1][2][8]. 3. Configuration: Ensure you have included the necessary expansion features (such as getExpandedRowModel) in your table instance to support this functionality [1][7][4]. Example implementation: const table = useReactTable({ //... other options getRowCanExpand: (row) => true, // Forces all rows to be expandable getCoreRowModel: getCoreRowModel, getExpandedRowModel: getExpandedRowModel, })

Citations:


🌐 Web query:

"@tanstack/vue-table" "getRowCanExpand"

💡 Result:

In @tanstack/vue-table, getRowCanExpand is an optional table instance configuration function used to override the default logic for determining if a row can be expanded [1][2][3]. By default, the row instance method row.getCanExpand returns false unless the row contains subRows [1][2]. You can customize this behavior by providing the getRowCanExpand option to your table initialization hook (such as useAppTable or useTable) [4][5][6][3]. Usage example: const table = useAppTable({ //... other options getRowCanExpand: (row) => true, // Allows all rows to be expanded }) When implemented, this function receives the row object as an argument and must return a boolean indicating whether that specific row should be expandable [3]. This is frequently used when implementing custom sub-components where you want to force rows to be expandable regardless of their data structure [4][5][6].

Citations:


Enable expansion for paid leaf rows.

Payment rows do not have subRows, so row.getCanExpand() is false by default and row.toggleExpanded() will not change state. Add getRowCanExpand: () => true to useTable, or use a per-row predicate if only selected rows should expand.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/v4/content/docs/components/data-table.md` around lines 764 - 765, Update
the table configuration in useTable to provide getRowCanExpand: () => true,
enabling Payment leaf rows to expand and allowing row.toggleExpanded() to update
state; use a row predicate instead if expansion should be limited to selected
rows.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Update table & relevant docs to tanstack table v9 [Bug]: data table deselect all performance issue

2 participants