Data Pagination
A pagination footer over a consumer-owned useReactTable() instance — selection count, rows-per-page select, page indicator, and first/prev/next/last controls.
| Invoice | Customer | Amount |
|---|---|---|
| 1 | Customer 1 | $100 |
| 2 | Customer 2 | $137 |
| 3 | Customer 3 | $174 |
| 4 | Customer 4 | $211 |
| 5 | Customer 5 | $248 |
| 6 | Customer 6 | $285 |
| 7 | Customer 7 | $322 |
| 8 | Customer 8 | $359 |
| 9 | Customer 9 | $396 |
| 10 | Customer 10 | $433 |
DataPagination is a headless-composition component over the same
useReactTable() instance you'd pass to Data Grid,
Data Filter, and
Data Search — a sibling toolbar control, not a
prop on any of them. It drives TanStack's own pagination state; it never
slices rows itself.
Installation
pnpm dlx shadcn@latest add @syncblocks/data-paginationUsage
import { DataPagination } from "@/components/ui/data-pagination"const table = useReactTable({
data,
columns,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
})
<DataPagination table={table} />getPaginationRowModel() is required — without it table.getRowModel()
returns every row and the controls page through nothing.
Inside Data Grid you don't render it yourself:
the grid appends DataPagination automatically whenever the table it's given
has a getPaginationRowModel, the same way it only offers search and filters
when a filtered row model is present.
Features
- Selection count —
N of M row(s) selected, counted against the filtered row model so it reflects what's actually reachable. On a table withenableRowSelection: falseit degrades to a plainM row(s)count instead of a permanent "0 of M selected". - Rows per page — a select bound to
table.setPageSize(). Override the choices withpageSizeOptions. - Page indicator —
Page X of Y. An empty table reads "Page 1 of 1" rather than TanStack's raw "of 0". - First / previous / next / last — laid out in the shadcn
Paginationnav/list structure, disabled at the boundaries viagetCanPreviousPage()/getCanNextPage(), each with an explicitaria-labelsince they're icon-only. They'reButtons rather thanPaginationLink/PaginationNext: those render an<a>with nohref, which can't be disabled or activated from the keyboard — and paging a client-side table isn't navigation.
API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
table | Table<TData> | - | A useReactTable() instance you create and own. Needs getPaginationRowModel(). (required) |
pageSizeOptions | number[] | [10, 20, 30, 40, 50] | Choices in the rows-per-page select. |
className | string | - | Extra classes on the footer row. |