abaabil

Pagination

18th lightest of the twenty-three, by js weight

A <nav> around an ordered list of real links. Server-renderable at every tier.

Example (a11y tier)

Import

import Pagination from 'abaabil/pagination'         // structure only
import Pagination from 'abaabil/pagination/styled'  // + CSS
import Pagination from 'abaabil/pagination/a11y'    // + names and aria-current

Links, not buttons

Each page is a URL. Rendering it as a link means it can be opened in a new tab, bookmarked, shared and reached by a crawler; rendering it as a button takes all of that away and gives nothing back. The only thing a button buys is not having to build the URL, which the href prop does for you.

The gap is drawn, and only when it earns its place

The ellipsis is a CSS pseudo-element, not text, so it never reaches the accessibility tree. A screen reader reading “1 ellipsis 5 6 7 ellipsis 20” is reading punctuation aloud.

It also only appears when it stands in for two or more pages. A gap replacing a single number takes the same room and says less, so that number is drawn instead. Getting this wrong is easy and invisible: an early version put an ellipsis where page 2 should have been at page 4 of 12, and it was a test rather than a screenshot that caught it.

Names, not digits

A link whose entire content is “7” is announced as “7”. In a list of links that is meaningless, so every number is named “Page 7” while still drawing only the digit. Previous and Next say where they go.

All four labels are props, because a paginator with hardcoded English is not translatable, and this is the component where that shows up first.

Props

PropTypeDefaultTierDescription
pagenumberallCurrent page, 1-based.
pageCountnumberallTotal pages.
href(page) => stringallBuilds each page's URL.
siblingsnumber1allPages shown either side of the current one.
labelstring'Pagination'a11yNames the <nav>.
pageLabel(n) => string`Page ${n}`a11yNames each number.
previousLabelstring'Previous page'a11y
nextLabelstring'Next page'a11y

At either end, Previous and Next are not links at all, so nothing dead stays in the tab order.