Pagination
A numbered page navigator for lists that are split across static pages.
Contract
Pages are derived, not enumerated: pass currentPage and totalPages and the component decides which numbers to show. hrefFor maps a page number to a URL, which keeps every cell a real link that works without JavaScript. renderLink injects a router element without coupling the component to routing state.
| Axis | Contract |
|---|---|
| current page | renders as text, not a link, and carries aria-current="page" |
| window | boundaryCount pages stay pinned at each end and siblingCount pages sit on each side of the current page |
| gaps | a gap wider than one page collapses into an ellipsis hidden from assistive tech; a gap of exactly one page renders that page |
| steps | previous and next carry rel="prev" and rel="next", and become non-interactive at the first and last page |
| empty state | a single page renders nothing |
Install
pnpm add @tinyrack/uiScroll inside the code area to read long lines.
Styles
@import '@tinyrack/ui/components/pagination.css';Scroll inside the code area to read long lines.
Imports
import { TRPagination } from '@tinyrack/ui/components/pagination';Scroll inside the code area to read long lines.
Playground
Usage
Examples
Raise boundaryCount and siblingCount when the list is long enough that a wider window helps readers jump around. Both default to 1.
API
currentPage and totalPages are required and drive the whole sequence; a currentPage outside the range is clamped. hrefFor(page) is required and returns the URL for a page, so page one can point at an unpaginated path such as /blog/ rather than /blog/page/1/.
boundaryCount sets how many pages stay pinned at each end and siblingCount how many sit on each side of the current page. Set boundaryCount to 0 to drop the pinned ends.
label names the landmark and defaults to Pagination. previousLabel and nextLabel default to Previous and Next. pageLabel(page) builds the accessible name of each page link and defaults to Page {n}; the step links combine it with their direction label. Set all four to localize the control.
renderLink(page, state) receives the target page and a state object carrying current and, for the steps, direction. Use it to compose React Router or another client router without nesting anchors. It is not called for the disabled steps.
getPaginationRange is exported from the same subpath for callers that need the visible sequence without the markup.
The root preserves native nav attributes, className, style, events, and React 19 ref. Styles use Tinyrack semantic color, spacing, and typography tokens, and expose --tr-pagination-radius, --tr-pagination-gap, --tr-pagination-border-color, --tr-pagination-current-background, and --tr-pagination-current-text for per-instance overrides.