Passer au contenu principal

Pagination

Implemented

Page-number navigator with prev/next — button pager by default, <a href> SEO mode via href. Computes totalPages from totalItems/pageSize and hides itself when there is ≤1 page.

Categorymolecules
Sourcepatterns/molecules/pagination.html
AI HintButton pager by default; href(page) switches to <a> SEO mode (modifier clicks keep native behaviour). Window shows {1, current±1, N} ∪ ellipses; renders null when ≤1 page — do not wrap it in a conditional. With next-intl: the placeholder-bearing label keys (goToPage, currentPage, outOf, sizeSummary) MUST come from t.raw() — plain t() yields FORMATTING_ERROR. fill() substitutes simple {name} placeholders only — never put ICU plurals/selects in pagination.* label keys.

Windowed page navigator with first/prev/next/last edges and an optional page-size row. Composes the PageSizeDropdown atom. Renders real anchors in href (SEO) mode; renders null when there is one page or fewer.

Pagination

molecules

Button-driven pager by default: windowed page numbers (1 … current-1/current/current+1 … N) with ellipses, 44px tap targets, and a "Showing N out of M" size row. Pass href(page) to render crawlable <a> links.

Props

Preview

Pagination

Prop
Type
Required
Default
Description
currentPage
number
Required
—

1-based; clamped into [1, ceil(totalItems/pageSize)]

onPageChange
(page: number) => void
Required
—

Fires on page clicks (also in href mode, on plain clicks).

totalItems
number
Required
—

Total item count — totalPages is derived, not passed.

pageSize
number
Required
—

Items per page.

onPageSizeChange
(size: number) => void
Optional
—

Fires from the page-size dropdown (requires showPageSize).

pageSizeOptions
number[]
Optional
—

Choices offered in the page-size dropdown.

showPageSize
boolean
Optional
true

Renders the PageSizeDropdown row.

ariaLabel
string
Optional
'Pagination'

Accessible name of the nav landmark — pass a localized value.

href
(page: number) => string
Optional
—

Link-based SEO pager mode — page controls render as <a href> anchors. onPageChange still fires on plain click; modifier clicks keep native behaviour.

labels
PaginationLabels
Optional
—

i18n label overrides (goToPage, currentPage, showing, outOf, itemsPerPage, sizeSummary + edge labels). {page}/{total}/{size} placeholders substituted. Under next-intl the 4 placeholder keys MUST be sourced via t.raw().

className
string
Optional
—

Additional CSS classes on the nav.

id
string
Optional
—

Stable root id.

Quick use:<Pagination />

Accessibility

ARIA rolenavigation

Type

1 rule

NASA Rule 7

currentPage is clamped into [1, ceil(totalItems/pageSize)]; totalPages is derived, never passed (NASA Rule 7)

ARIA

1 rule

WAI-ARIA Pagination Pattern

<nav aria-label>; current page button has aria-current='page'

Usage

Import

tsxSnippet
import { Pagination } from "@epasslive/design-system"

Example 1

tsxSnippet
<Pagination totalItems={128} pageSize={8} currentPage={3} onPageChange={setPage} />

Example 2

tsxSnippet
<Pagination totalItems={128} pageSize={8} currentPage={page} onPageChange={setPage} href={(p) => `/events?page=${p}`} labels={paginationLabels} />

Anti-patterns

— Do not pass totalPages — it is derived from totalItems/pageSize

— Do not use plain t() on placeholder-bearing pagination label keys (next-intl FORMATTING_ERROR); use t.raw()

— Do not use ICU plurals/selects in pagination.* label keys — fill() only substitutes simple {name} placeholders

Design System v4.1.0 | ePassLive