Components Navigation
Pagination
StableAccessible page navigation for long lists and tables, with previous, next and compact modes.
Use Pagination below tables and lists that are split into pages. The visible page numbers keep a stable width as the page changes, so the control never jumps under the pointer. Use the compact variant in tight spaces, and getHref when each page has its own URL.
Overview
import { useState } from 'react';
import { Pagination } from '@bindshq/stance-react';
export function Basic() {
const [page, setPage] = useState(4);
return <Pagination page={page} pageCount={24} onPageChange={setPage} />;
}Light, dark and high contrast
Every Stance component is designed and tested in all three appearance modes.
Import
import { Pagination } from '@bindshq/stance-react';Playground
<Pagination />Examples
Compact
“Page x of y” with previous and next buttons; the summary is announced politely when it changes.
import { useState } from 'react';
import { Pagination } from '@bindshq/stance-react';
export function Compact() {
const [page, setPage] = useState(3);
return <Pagination variant="compact" page={page} pageCount={12} onPageChange={setPage} />;
}As links
getHref renders anchors, so pages can be opened in new tabs and crawled.
import { Pagination } from '@bindshq/stance-react';
export function Links() {
return <Pagination page={2} pageCount={8} getHref={(p) => `#page-${p}`} />;
}import { useState } from 'react';
import { Pagination } from '@bindshq/stance-react';
export function MoreSiblings() {
const [page, setPage] = useState(10);
return (
<Pagination
page={page}
pageCount={40}
siblingCount={2}
boundaryCount={2}
onPageChange={setPage}
/>
);
}import { useState } from 'react';
import { Pagination } from '@bindshq/stance-react';
export function Small() {
const [page, setPage] = useState(1);
return (
<Pagination size="sm" showPrevNextLabels page={page} pageCount={5} onPageChange={setPage} />
);
}API reference
| Prop | Type | Default | Description |
|---|---|---|---|
page* required | number | None | Current page, 1-based. |
pageCount* required | number | None | Total number of pages. |
onPageChange | (page: number) => void | None | Called with the requested page. |
siblingCount | number | 1 | Pages shown either side of the current page. |
boundaryCount | number | 1 | Pages always shown at each end. |
variant | 'full' | 'compact' | 'full' | Page numbers or a “Page x of y” summary. |
size | 'sm' | 'md' | 'md' | Item height. |
getHref | (page: number) => string | None | Render items as links. |
showPrevNextLabels | boolean | false | Show “Previous” / “Next” text beside the arrows. |
labels | Partial<PaginationLabels> | None | Translatable strings: nav, previous, next, page(n), summary(n, count). |
disabled | boolean | false | Disable all items, e.g. while loading. |
Accessibility
- A <nav> landmark named “Pagination” (configurable) containing a list.
- Every item has a spoken label such as “Page 4”; the current page has aria-current="page".
- Previous and next are disabled at the ends instead of disappearing, so the layout does not shift.
- Ellipses are decorative and hidden from assistive technology.
Keyboard
| Keys | Action |
|---|---|
| Tab | Moves between page controls. |
| Enter Space | Goes to the page. |
Usage guidelines
Do
- Show the total number of results near the table.
- Move focus to the top of the results after changing page.
Don’t
- Use pagination for fewer than two pages.
- Combine with infinite scroll on the same list.