Pagination
Moves between pages of a long list or table.
Preview
Installation
pnpm add @syntara/react @syntara/tokensimport { Pagination } from '@syntara/react';Usage
import { useState } from 'react';
import { Pagination } from '@syntara/react';
export function Results() {
const [page, setPage] = useState(1);
return <Pagination page={page} pageCount={12} onPageChange={setPage} />;
}Examples
Compact
"Page 3 of 12" between previous and next, for tight spaces.
More siblings
siblingCount={2} shows two pages either side of the current one.
Accessibility
| Keys | Action |
|---|---|
| TaborShiftTab | Moves between previous, page and next buttons. |
| EnterorSpace | Goes to the focused page. |
- Renders <nav aria-label="Pagination"> around a list of buttons (a labelled group with landmark={false}). Give each instance a unique label when a page has more than one.
- The current page has aria-current="page", a raised bordered key and semibold figures, not only a colour change.
- Page buttons are named "Page 3"; ellipses are hidden from assistive technology.
- At the first or last page, previous/next keep focus and are marked aria-disabled instead of being removed from the tab order.
- The compact summary is a polite live region, so page changes are announced.
- Responds to its own width: labels hide below 520px and page buttons collapse to "Page 3 of 12" below 400px. Chevrons mirror in right-to-left layouts.
Guidelines
Do
- Pair with a result count ("Showing 1–10 of 48") — DataTablePagination does this for tables.
- Keep the page size stable while people page.
- Reset to page 1 when filters change.
- Give each pagination on a page its own label, e.g. "Search results pages".
Don’t
- Don't paginate lists short enough to show in full.
- Don't use for infinite feeds — load more on scroll instead.
- Don't hide the current page number.
API reference
Pagination
pageRequirednumberCurrent page, 1-based.
pageCountRequirednumberTotal number of pages.
onPageChange(page: number) => voidCalled with the new page. Not called for the current page or past either end.
siblingCountnumberPages shown each side of the current page.
Default
1boundaryCountnumberPages always shown at the start and end.
Default
1variantdefaultdefaultcompact
compact shows "Page 3 of 12" instead of page buttons.
labelstringAccessible name. Landmarks must be unique on a page: with more than one pagination, name each for what it pages ("Search results pages").
Default
'Pagination'landmarkbooleanRender as a <nav> landmark. false renders a labelled group, for paging that belongs to a component (DataTablePagination defaults to false).
Default
truepreviousLabelstringPrevious button text; stays its accessible name when the text is hidden.
Default
'Previous'nextLabelstringNext button text; stays its accessible name when the text is hidden.
Default
'Next'pageLabelstringWord used in page button names ("Page 3") and the compact summary.
Default
'Page'ofLabelstringWord used in the compact summary ("Page 3 of 12").
Default
'of'isDisabledbooleanDisables every button, e.g. while a page loads.
Default
false
Tokens
The semantic tokens this component reads, grouped by what they control. Swatches show this site’s theme; change a tenant’s brand and the component follows with no code change.
- Colour6
text.defaultfocus.ringborder.defaultsurface.raisedtext.disabledtext.subtle- Type5
font.size.mdfont.weight.mediumline-height.tightfont.weight.semiboldfont.size.sm- Space and size4
space.1control-heightspace.2space.3- Shape1
radius.button- Depth2
shadow.highlightshadow.raised- Motion4
motion.duration.fastmotion.easingmotion.duration.springmotion.spring