Skip to Content
⭐️ Leave a star →
ComponentsPagination

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

Configurable siblingCount and boundaryCount with ellipsis gaps.
Pure getPaginationItems() helper exposed for custom renderers.
Previous / Next buttons auto-disable at edges.
Current page exposes data-active and aria-current="page".
Can be controlled or uncontrolled.

Example

Page 4 of 10

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

PropTypeDefaultDescription
totalPagesnumberrequiredTotal number of pages (>= 1)
pagenumberControlled current page (1-based)
defaultPagenumber1Initial page (uncontrolled)
onChange(page: number) => voidCalled when the page changes
siblingCountnumber1Sibling pages on each side of current
boundaryCountnumber1Pages always shown at start / end

Item props

PropTypeDescription
pagenumberPage number (1-based)
disabledbooleanDisable 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.

PropTypeDescription
children(item: number | 'ellipsis', index: number) => ReactNodeRender each item

Data attributes

AttributeElementWhen present
data-activeItem buttonItem matches the current page
data-hoverItem / Previous / NextMouse is over the button
data-focus-visibleItem / Previous / NextButton has keyboard focus
data-active (interactive)Item / Previous / NextButton is being pressed

The Item button also receives aria-current="page" when active and aria-label="Page N".

Accessibility

  • Root renders as <nav> with aria-label="Pagination" (override via aria-label).
  • Previous / Next receive aria-label="Previous page" / "Next page".
  • Ellipsis renders as <li role="presentation" aria-hidden="true">.

Keyboard Interactions

KeyDescription
TabMoves focus through Previous, page items, and Next.
Space / EnterActivates the focused button.
Last updated on

MIT License © 2026 wire-ui

Pagination – Wire UI