Skip to content

Pagination

Moves between pages of a long list or table.

Preview

Installation

pnpm add @syntara/react @syntara/tokens
import { 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

KeysAction
TaborShiftTabMoves between previous, page and next buttons.
EnterorSpaceGoes 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

pageRequired
number

Current page, 1-based.

pageCountRequired
number

Total number of pages.

onPageChange
(page: number) => void

Called with the new page. Not called for the current page or past either end.

siblingCount
number

Pages shown each side of the current page.

Default 1

boundaryCount
number

Pages always shown at the start and end.

Default 1

variant
  • defaultdefault
  • compact

compact shows "Page 3 of 12" instead of page buttons.

label
string

Accessible name. Landmarks must be unique on a page: with more than one pagination, name each for what it pages ("Search results pages").

Default 'Pagination'

landmark
boolean

Render as a <nav> landmark. false renders a labelled group, for paging that belongs to a component (DataTablePagination defaults to false).

Default true

previousLabel
string

Previous button text; stays its accessible name when the text is hidden.

Default 'Previous'

nextLabel
string

Next button text; stays its accessible name when the text is hidden.

Default 'Next'

pageLabel
string

Word used in page button names ("Page 3") and the compact summary.

Default 'Page'

ofLabel
string

Word used in the compact summary ("Page 3 of 12").

Default 'of'

isDisabled
boolean

Disables 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