Skip to contentAsheeUIAsheeUI

Pagination

The trail at the foot of a paged collection, as links or as buttons.

Pagination states where a reader is in a paged collection, offers the pages next to that place, and keeps the two ends of the collection one press away. It is the one navigation component that has to work twice, because a paged collection either has addresses, in which case a page is a link, or it does not, in which case a page is a handler.

The trail is computed from the collection rather than written by hand: the first and last page are always offered, a window of pages sits either side of the reader, and a gap between two shown pages becomes an ellipsis that is decoration rather than a control.

Usage

import { Pagination } from "@asheeui/web";

// `page` is the page the collection is showing, held by the page that owns it.
<Pagination page={page} pageCount={24} onPageChange={setPage} />

page is counted from one and is clamped to the collection, so a state that has drifted past the last page renders the last page rather than an empty trail. An empty collection still renders its controls, disabled, so a page does not have to guard the trail while its first response is in flight.

The window

siblingCount is how many pages are shown on each side of the reader, and it defaults to 1: one page back, the current page, one page forward. The window clamps at the ends of the collection rather than sliding, so the first page of twenty reads 1 2 … 20 and the trail narrows at the boundary instead of shifting.

showEdges adds a control for the first and last page, either side of the previous and next ones. The pairs wear the same chevron, so only their names tell them apart.

hrefForPage decides the element and the meaning at once. Supply it and every control is an anchor whose destination is what the function returns, which is what a collection with real addresses wants: a page can be opened in a new tab, copied, shared and crawled. Leave it out and every control is a button that reports the chosen page through onPageChange.

The current page is marked aria-current="page" in both modes, and is never reported as a change, because it is already where the reader is. In link mode the report still happens: pressing an anchor calls onPageChange as well as navigating, so a page can keep its own state in step with the address. A control that cannot be used, the previous arrow on the first page, loses its destination and its tab stop, rather than keeping an href to a page that does not exist.

link={{ component, props }} renders every anchor as the application's own router link, so a paginated collection with real addresses can still navigate client-side. See Links and substitution.

Props

The registered defaults are size md, radius md, siblingCount 1 and showEdges false. size reaches the controls in both modes, so a trail of links is as large as a trail of buttons. variant and color are deliberately not registered: they resolve from the application's defaultVariant and defaultColor, falling back to bordered and primary, so a product states its control treatment once rather than at every trail.

page, pageCount, hrefForPage, link, onPageChange, label and isDisabled are instance-only, because where a collection is, how it is addressed and whether it is loading are statements about one collection rather than about the design. label names the landmark and defaults to Pagination in the component rather than in configuration.

Accessibility

  • The trail is a nav landmark named Pagination by default. label renames it, and a page with two trails should name both, so they can be told apart in a landmark list.
  • The controls are an ordered list, so a reader is told how many there are, and every control has a name of its own: Page 4, Previous page, Next page, First page, Last page. The chevrons are decorative and hidden from the accessibility tree, and so is the ellipsis between two shown pages, because a gap read aloud is noise.
  • The current page carries aria-current="page", so the reader's place is announced rather than only coloured.
  • At the ends of the collection the previous and next controls are aria-disabled: in button mode the press is refused and the control stays in the reading order, so a reader can still find out that there is nothing before the first page.