Pagination
Page navigation primitive. Configurable sibling + boundary counts produce a tidy sequence of pages and ellipsis markers. Headless: the Items render-prop emits the computed sequence so you control the markup.
Features
getPaginationItems() helper exposed for custom renderers.data-active and aria-current="page".Example
Page 4 of 10
Anatomy
import { Pagination } from '@wire-ui/react'
<Pagination.Root totalPages={10} defaultPage={1}>
<Pagination.List>
<li><Pagination.Previous>‹</Pagination.Previous></li>
<Pagination.Items>
{(item, i) =>
item === 'ellipsis'
? <Pagination.Ellipsis key={`e-${i}`} />
: <Pagination.Item key={item} page={item}>{item}</Pagination.Item>
}
</Pagination.Items>
<li><Pagination.Next>›</Pagination.Next></li>
</Pagination.List>
</Pagination.Root>Styling
The current page exposes data-active. Previous / Next set the native disabled attribute when at the start / end. Item buttons also expose interactive state attributes (data-hover, data-focus-visible, data-active).
<Pagination.Item page={3}>
<span className="
data-[active]:bg-black data-[active]:text-white
hover:bg-[#f5f5f5]
">3</span>
</Pagination.Item>Using data attributes
button[data-active] { background: #000; color: #fff; }
button[aria-current="page"] { font-weight: 600; }
button:disabled { opacity: 0.4; cursor: not-allowed; }getPaginationItems helper
The pure function used internally is exported for custom renderers:
import { getPaginationItems } from '@wire-ui/react'
const items = getPaginationItems(10, 4, /* siblingCount */ 1, /* boundaryCount */ 1)
// [1, 2, 3, 4, 5, 'ellipsis', 10]Returns (number | 'ellipsis')[] — page numbers are 1-based.
Root props
| Prop | Type | Default | Description |
|---|---|---|---|
totalPages | number | required | Total number of pages (>= 1) |
page | number | — | Controlled current page (1-based) |
defaultPage | number | 1 | Initial page (uncontrolled) |
onChange | (page: number) => void | — | Called when the page changes |
siblingCount | number | 1 | Sibling pages on each side of current |
boundaryCount | number | 1 | Pages always shown at start / end |
Item props
| Prop | Type | Description |
|---|---|---|
page | number | Page number (1-based) |
disabled | boolean | Disable the button |
Previous / Next props
Accept all standard <button> attributes. Native disabled is auto-applied at the start / end.
Items props
Render-prop component that emits the computed item sequence.
| Prop | Type | Description |
|---|---|---|
children | (item: number | 'ellipsis', index: number) => ReactNode | Render each item |
Data attributes
| Attribute | Element | When present |
|---|---|---|
data-active | Item button | Item matches the current page |
data-hover | Item / Previous / Next | Mouse is over the button |
data-focus-visible | Item / Previous / Next | Button has keyboard focus |
data-active (interactive) | Item / Previous / Next | Button is being pressed |
The Item button also receives aria-current="page" when active and aria-label="Page N".
Accessibility
- Root renders as
<nav>witharia-label="Pagination"(override viaaria-label). - Previous / Next receive
aria-label="Previous page"/"Next page". - Ellipsis renders as
<li role="presentation" aria-hidden="true">.
Keyboard Interactions
| Key | Description |
|---|---|
| Tab | Moves focus through Previous, page items, and Next. |
| Space / Enter | Activates the focused button. |