Skip to content
design system
Thème d’affichage, actuellement Auto

molecule · stable · since 2026-09

Pagination

Purpose

The passage from one page of a list to the next: a list of links in a named landmark, each saying its destination out of context, the bounds gone rather than disabled, the truncation honest, the count announced.

When to use, when not

Use it under any list served in pages. Not for steps (a wizard), not for tabs.

Anatomy

  1. The count, a status region: “Résultats 11 à 20 sur 38 utilisateurs”.
  2. The landmark, named.
  3. The links: previous, the numbers with the gaps, next.

Props

Props of Pagination
NameTypeDefaultWhat it does
pagenumberThe current page, from 1.
pagesnumberThe number of pages.
labelstringThe landmark's name: "Pagination des utilisateurs". Two paginations on one screen need two names.
href(page: number) => stringThe address of a page.
onnavigate?(page: number, event: MouseEvent) => voidFor a list updated in place: called with the page and the click, which the page prevents.
total?numberThe number of rows in all, for the count.
perPage?numberThe rows per page, for the count.
rowsName?string'résultats'What is counted, in the plural: "utilisateurs".
class?string''Layout classes only.

States

Seven pages, forty-two pages, and with the count.

counted

With the total and the rows per page, the count is a status region present from the first render.

Light

Résultats 11 à 20 sur 38 utilisateurs

Dark

Résultats 11 à 20 sur 38 utilisateurs

320 px, light

Résultats 11 à 20 sur 38 utilisateurs

320 px, dark

Résultats 11 à 20 sur 38 utilisateurs

216 px, light

Résultats 11 à 20 sur 38 utilisateurs

Forced colours, captured
Pagination, story counted, as Chromium renders it with forced colours active

long

Forty-two pages: the first, the last, the current one with its neighbours, and an ellipsis that is not a link where it skips.

short

Seven pages or fewer: every number shows. Out of context each link says "Page 4"; the current one carries aria-current.

Accessibility contract

  • Role and name: navigation named by label; a list of links; the current page carries aria-current="page". The gaps are hidden and are not links.
  • Keyboard, focus: ordinary links. When a list updates in place and the activated link disappears, the focus is put on the current page’s link.
  • Live regions: the count, role="status", present even with one page.

Content rules

French. The label names what is paginated: “Pagination des utilisateurs”. rowsName is the plural noun of the rows.

Do and don’t

  • Do give two paginations on one screen two labels.
  • Do let the links navigate; intercept them only for a list that updates in place, and then prevent the default in onnavigate.
  • Do not write the first page in the address; the component only makes the links, but the page’s href should drop page=1.

Examples

<Pagination page={state.page} pages={state.pages} total={state.total} perPage={10} rowsName="utilisateurs" label="Pagination des utilisateurs" href={(p) => link(p)} />

Surfaces

  • App: the users list and the two lists of registrations, with the address of a page from the app’s helper.

Related

Table, DataTable, Link.

Decisions

  • 2026-09-24: links only, and the bounds removed rather than greyed, as both sources argue; the truncation is the app’s, which had learnt on the registrations that a sliding window hides the ends.
  • 2026-09-27: the focus is caught only on a change of page, never at mount. On a fresh load the focus is on the body too, and the list took it and scrolled the admin pages down to itself before anyone had pressed a key.

Criteria held by construction

  • 12.6, Les zones de regroupement de contenus présentes dans plusieurs pages web (zones d'en-tête, de navigation principale, de contenu principal, de pied de page et de moteur de recherche) peuvent-elles être atteintes ou évitées ?
    A navigation landmark with its own name, so two paginations on one screen are told apart in the list of regions.
  • 6.1, Chaque lien est-il explicite ?
    Every link says its destination out of context: 'Page 4', 'Page suivante'; a bare number would not.
  • 7.5, Dans chaque page web, les messages de statut sont-ils correctement restitués par les technologies d'assistance ?
    The count is a status region present from the first render, so a list updated in place is announced.
  • 3.1, Dans chaque page web, l'information ne doit pas être donnée uniquement par la couleur. Cette règle est-elle respectée ?
    The current page is told by aria-current and the strong line under it, not by colour alone.

Tokens it reads

  • Colour: --rl-action, --rl-hover, --rl-ink, --rl-ink-soft, --rl-line-control, --rl-line-strong
  • Typography: --rl-weight-bold, --rl-text-sm
  • Spacing: --rl-space-1, --rl-space-2, --rl-space-3
  • Layout: --rl-radius, --rl-border

Seen in patterns