Skip to content

Pagination

Links to the pages of a long list: the first and the last, the current page and its neighbours, and the pages before and after.

import { Pagination } from '@zitdevs/ui';
<Pagination page={5} pageCount={12} href={(page) => `/projects?page=${page}`} />

A gap stands for each run of pages left out; one that would hide a single page shows that page instead. Before the first page and after the last, the arrow is drawn but is no link.

import Link from 'next/link';
import * as es from '@zitdevs/ui/labels/es';
<Pagination
page={page}
pageCount={pageCount}
href={(page) => `/es/proyectos?pagina=${page}`}
linkAs={Link}
labels={es.pagination}
/>;
Prop Type Default Notes
page number required The page being read, from 1. Kept within 1 and pageCount.
pageCount number required How many pages there are. With one or none, nothing renders.
href (page: number) => string required Each page’s address.
linkAs LinkComponent 'a' Renders each link: Next’s Link, or any router’s.
labels Partial<PaginationLabels> English { pagination, previous, next, page }. es.pagination from labels/es.
ref Ref<HTMLElement> — The <nav>.
className string — Placement.
anything else <nav> attributes — Except aria-label, which labels.pagination sets: name it after the list on a page with two.

Exported types: PaginationProps, PaginationLabels, and the label sets paginationLabels.

  • A <nav> landmark named “Pagination” (“Paginación”), holding a list. Name it after its list (labels={{ pagination: 'Project pages' }}) on a page with more than one.
  • Every page is a link named “Page 3” (“Página 3”): the number for the eye, the word for a screen reader. The current page is marked aria-current="page".
  • The arrows are links named “Previous page” and “Next page”, with rel="prev" and rel="next". Where there is no page to go to, the arrow is drawn for the eye, hidden from assistive technology, and no link: a control that does nothing is not offered.
  • The ellipses are hidden; the page numbers around them say what is shown.
  • Every box is 32px square at least, above the 24px target minimum. Each link draws the kit’s focus ring itself.

Every page is a link the server renders, so it works with no script: the list page reads the page from its URL and renders the pagination again. It holds no state and renders as a Server Component, through a router’s link too.

primary and on-primary (the current page), surface-raised, body, border-default and surface-hover (the other pages), ink (the arrows), border-strong (an arrow with no page), muted (the ellipses); the focus ring.