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.
Links or buttons
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
navlandmark namedPaginationby default.labelrenames 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.