Data table: Pagination
The data table paginates by default: it shows ten rows a page, with previous and next buttons, a page counter and a page-size control under the table. Pass pagination with onPaginationChange to control the page, and pageSizeOptions to change the sizes offered.
| Lena Park | Engineer | Platform | Active | 2021-03-08 |
| Omar Haddad | Designer | Product | Active | 2020-11-16 |
| Sofia Reyes | Engineer | Payments | Away | 2022-01-24 |
| Yuki Tanaka | Manager | Platform | Active | 2019-06-03 |
| Amir Nasser | Analyst | Growth | Active | 2023-02-13 |
Rows 1–5 of 12
import { useState } from "react";
import { DataTable, type DataTablePaginationState } from "slotsmith/data-table";
import { columns, people } from "../shared/people";
export default function Pagination() {
const [pagination, setPagination] = useState<DataTablePaginationState>({ pageIndex: 0, pageSize: 5 });
const first = pagination.pageIndex * pagination.pageSize + 1;
const last = Math.min(first + pagination.pageSize - 1, people.length);
return (
<>
<DataTable
data={people}
columns={columns}
getRowId={(person) => person.id}
pagination={pagination}
onPaginationChange={setPagination}
// The sizes the page-size control offers.
pageSizeOptions={[5, 10, 20]}
/>
<p>{`Rows ${first}–${last} of ${people.length}`}</p>
</>
);
}import type { DataTableColumnDef } from "slotsmith/data-table";
export type Person = { id: string; name: string; role: string; team: string; status: string; joined: string };
export const people: Person[] = [
{ id: "1", name: "Lena Park", role: "Engineer", team: "Platform", status: "Active", joined: "2021-03-08" },
{ id: "2", name: "Omar Haddad", role: "Designer", team: "Product", status: "Active", joined: "2020-11-16" },
{ id: "3", name: "Sofia Reyes", role: "Engineer", team: "Payments", status: "Away", joined: "2022-01-24" },
{ id: "4", name: "Yuki Tanaka", role: "Manager", team: "Platform", status: "Active", joined: "2019-06-03" },
{ id: "5", name: "Amir Nasser", role: "Analyst", team: "Growth", status: "Active", joined: "2023-02-13" },
{ id: "6", name: "Chloe Martin", role: "Engineer", team: "Payments", status: "On leave", joined: "2021-09-27" },
{ id: "7", name: "Jonas Weber", role: "Support", team: "Care", status: "Active", joined: "2022-07-11" },
{ id: "8", name: "Priya Nair", role: "Designer", team: "Product", status: "Away", joined: "2020-04-20" },
{ id: "9", name: "Diego Alvarez", role: "Engineer", team: "Growth", status: "Active", joined: "2023-05-30" },
{ id: "10", name: "Hana Kim", role: "Manager", team: "Care", status: "Active", joined: "2018-10-01" },
{ id: "11", name: "Tomas Novak", role: "Analyst", team: "Payments", status: "On leave", joined: "2022-12-05" },
{ id: "12", name: "Nadia Farouk", role: "Support", team: "Care", status: "Active", joined: "2024-01-15" },
];
export const columns: DataTableColumnDef<Person>[] = [
{ accessorKey: "name", header: "Name" },
{ accessorKey: "role", header: "Role" },
{ accessorKey: "team", header: "Team" },
{ accessorKey: "status", header: "Status" },
{ accessorKey: "joined", header: "Joined" },
];Use the buttons to move between pages, or pick another page size. The text under the table follows the controlled state.
Page state
The state is { pageIndex, pageSize }, with pageIndex counting from 0.
paginationandonPaginationChangecontrol it, as the demo does. Leave them out and usedefaultPaginationfor a starting page the table keeps itself; the default is the first page of ten rows.pageSizeOptionslists the sizes the page-size control offers.resetSelectionOnPageChangeclears the selection when the page or the page size changes.
Turning it off
enablePaginationset tofalserenders every row and no controls.hidePaginationhides the controls but keeps paging: the table shows only the current page, so drivepaginationfrom controls of your own.
For data that is paged on a server, set manualPagination, pass the current page as data and the total as rowCount. The server data guide covers it.
The controls
The controls are the Pagination slot: a <nav> named by the pagination label, holding two PaginationButton slots, the page counter and the PageSizeSelect slot. The counter reads the pageInfo label, “Page 1 of 3”, in an aria-live region, so a page change is read out. The page-size control is the slotsmith Autocomplete, named by the visible rowsPerPage text. Replace any of these slots with your design system’s own.