Skip to content

Pagination

Moves between pages of a long list. Previous and Next are 44px; narrow screens show "Page 3 of 12". With onLoadMore it is a Load more button instead.

  • Free core, MIT
  • Version 2.0.0-rc.1
  • APG pattern: Navigation (list of links or buttons)

Examples

These are the real React components. Use them with a mouse, touch or keyboard, and switch the theme and density for every example at once.

Default

Show the code

Default, code

function Buttons({ start = 5, count = 12 }: { start?: number; count?: number }) {
  const [page, setPage] = useState(start);
  return <Pagination page={page} pageCount={count} onPageChange={setPage} />;
}

<Buttons />

Load more

Showing 20 of 48

Show the code

Load more, code

function More() {
  const [page, setPage] = useState(1);
  return <Pagination page={page} pageCount={3} onLoadMore={() => setPage((p) => p + 1)} shownCount={Math.min(page * 20, 48)} totalCount={48} />;
}

<More />

Links

Show the code

Links, code

<Pagination page={5} pageCount={12} getHref={(p) => `#page-${p}`} />

First page

Show the code

First page, code

function Buttons({ start = 5, count = 12 }: { start?: number; count?: number }) {
  const [page, setPage] = useState(start);
  return <Pagination page={page} pageCount={count} onPageChange={setPage} />;
}

<Buttons start={1} />

Few pages

Show the code

Few pages, code

function Buttons({ start = 5, count = 12 }: { start?: number; count?: number }) {
  const [page, setPage] = useState(start);
  return <Pagination page={page} pageCount={count} onPageChange={setPage} />;
}

<Buttons start={2} count={4} />

Tokens

The 12 design tokens Pagination reads, with the value each has in the theme and density chosen above. Change a token and the component follows, in Figma and in code.

Show all 12 tokens
Tokens Pagination reads
TokenValue nowCSS variable
color.action.primary…--sd-color-action-primary
color.bg.muted…--sd-color-bg-muted
color.bg.subtle…--sd-color-bg-subtle
color.text.default…--sd-color-text-default
color.text.disabled…--sd-color-text-disabled
color.text.on-primary…--sd-color-text-on-primary
color.text.secondary…--sd-color-text-secondary
shape.radius-control…--sd-shape-radius-control
spacing.gap.sm…--sd-spacing-gap-sm
spacing.gap.xs…--sd-spacing-gap-xs
spacing.inset.sm…--sd-spacing-inset-sm
target.min…--sd-target-min

Install

The npm package isn’t published yet. When it is, this is the install line; until then, this page runs the same build of the package (from commit fa3abf8).

Install

npm i @superduperui/react @superduperui/tokens

Import

import { Pagination, pageSlots } from "@superduperui/react"

Props

Pagination also takes the props of the React Aria component it’s built on.

Pagination props
PropTypeWhat it does
pagerequirednumberCurrent page, 1-based.
pageCountrequirednumberNumber of pages.
getHref(page: number) => stringLink mode: the URL of a page. Pages are links (best for lists people share or bookmark).
onPageChange(page: number) => voidButton mode: called with the chosen page.
onLoadMore() => voidLoad more mode: called by a Load more button that replaces the page numbers, for lists that grow in place (feeds, search results). `page` is the pages loaded so far; the button goes once page reaches pageCount. After loading, move focus to the first new item.
shownCountnumberLoad more mode: items shown so far, for the polite "Showing 20 of 60" status.
totalCountnumberLoad more mode: items in all.
isLoadingMorebooleanLoad more mode: the next page is loading (the button is busy and shows a spinner).
siblingsnumberDefault 1Pages shown either side of the current one. Default 1.
aria-labelstringDefault 'Pagination'Names the navigation landmark. Default "Pagination".
classNamestring

When to use it

Use it for

  • Long lists and tables paged on the server
  • Search results
  • Feeds that grow in place: Load more mode (onLoadMore), with a polite "Showing 20 of 60" status

Use something else for

  • Short lists: show everything
  • Scrolling that loads more on its own: keyboard and screen reader users can't reach what comes after the list

Accessibility

Screen readers announce "Pagination, navigation" then "Page 5, current page, button".

WCAG 2.2 AAA criteria the component meets in Comfortable density: 1.4.6, 1.4.9, 2.1.3, 2.3.2, 2.4.13, 2.5.5, 2.5.6.

Compact density meets AA (2.5.8, 24px targets), not AAA.

What your product still has to do

  • Keep focus sensible after a page change (move it to the list heading)
  • In Load more mode, move focus to the first new item after it loads

Shared patterns it ships with: 2.4.8 (aria-current="page" on the current page).

This release’s test results

Test results for Pagination in this release
axe-core (WCAG A, AA, AAA and best practice)120 runs across every story, theme, density and width: 0 violations
Rendered text contrast380 text runs: 0 below 7:1, lowest 11.42:1
Target size120 targets: 0 under 44px in Comfortable
Focus appearance (2.4.13)126 focus stops in 3 browser engines: all pass
Keyboard scriptChromium 4 of 4, Firefox 4 of 4, WebKit 4 of 4

Manual passes with VoiceOver and NVDA haven’t been done yet.

Keyboard

Each step is scripted and run in Chromium, Firefox and WebKit.

Pagination keyboard steps
KeyWhat happens
TabTab reaches Previous
TabTab reaches the first page
Shift+TabBack to Previous
EnterEnter goes to the previous page; it becomes current

In Figma

The Figma component is Pagination, with Mode (Buttons, Links); Layout (Wide, Narrow, Load more). The Figma library isn’t published yet.

Figma to code: Mode (Buttons = onPageChange, Links = getHref); Page → page; Page count → pageCount; Layout (Wide, Narrow, Load more = onLoadMore); Shown → shownCount when Layout=Load more; Total → totalCount when Layout=Load more; nested Previous → (page - 1); nested Next → (page + 1).