vaiperui

components / pagination

Pagination

Moves between pages of results; the parent owns the page and fetches the data.

How to use

A controlled component: pass `page` (starting at 1), `pageCount` and `onPageChange`. With many pages it shows the first, last, current and `siblingCount` neighbors with ellipses, keeping the bar the same width. Every built-in text is overridable (`previousLabel`, `nextLabel`, `pageLabel`, `aria-label`). If each page has its own URL, prefer real links.

preview
Pagination.tsx
import { Pagination } from "vaiperui";
const [page, setPage] = useState(1);
<Pagination
page={page}
pageCount={20}
onPageChange={setPage}
previousLabel="Previous page"
nextLabel="Next page"
pageLabel={(n) => `Page ${n}`}
/>

Colors

preview
primary
success
warning
danger
colors.tsx
<Pagination page={page} pageCount={20} onPageChange={setPage} variantColor="primary" />
<Pagination page={page} pageCount={20} onPageChange={setPage} variantColor="success" />
<Pagination page={page} pageCount={20} onPageChange={setPage} variantColor="warning" />
<Pagination page={page} pageCount={20} onPageChange={setPage} variantColor="danger" />

Sizes

preview
sm
md
lg
sizes.tsx
<Pagination page={page} pageCount={20} onPageChange={setPage} size="sm" />
<Pagination page={page} pageCount={20} onPageChange={setPage} size="md" />
<Pagination page={page} pageCount={20} onPageChange={setPage} size="lg" />

Radius

preview
none
sm
md
lg
full
radius.tsx
<Pagination page={page} pageCount={20} onPageChange={setPage} radius="none" />
<Pagination page={page} pageCount={20} onPageChange={setPage} radius="sm" />
<Pagination page={page} pageCount={20} onPageChange={setPage} radius="md" />
<Pagination page={page} pageCount={20} onPageChange={setPage} radius="lg" />
<Pagination page={page} pageCount={20} onPageChange={setPage} radius="full" />

Custom color

preview
Orange
Violet
custom-color.tsx
<Pagination page={page} pageCount={20} onPageChange={setPage} customColor="#f97316" />
<Pagination page={page} pageCount={20} onPageChange={setPage} customColor="#8b5cf6" />

Siblings

preview
siblingCount={2}
siblings.tsx
<Pagination page={page} pageCount={30} siblingCount={2} onPageChange={setPage} />

Props

PropValuesDefaultDescription
pagenumberrequiredCurrent page, starting at 1
pageCountnumberrequiredTotal number of pages
onPageChange(page: number) => voidrequiredCalled with the chosen page
siblingCountnumber1Pages shown on each side of the current one
previousLabelstringPrevious pageAccessible name of the previous button
nextLabelstringNext pageAccessible name of the next button
pageLabel(page: number) => stringPage nAccessible name of a page button
aria-labelstringPaginationName of the navigation
disabledbooleanfalseDisables every button
variantColorprimary | success | warning | dangerprimaryAccent color of the active state and focus ring
customColorstring | { light, dark }noneAny CSS color (or a pair per theme). Overrides variantColor
sizesm | md | lgmdSize of the control and its text
radiusnone | sm | md | lg | fullmdCorner rounding
animationnone | smooth | fast | bouncesmoothTransition between states

Accessibility

  • Renders a `<nav>` with `aria-label` (default "Pagination") containing a list (`<ul>`/`<li>`) of native buttons.
  • The current page button has `aria-current="page"` and does nothing when clicked.
  • Each button has an `aria-label` from `previousLabel`, `nextLabel` and `pageLabel(n)`; the chevron icons are `aria-hidden`.
  • Previous is disabled on the first page and next on the last; `disabled` disables every button.
  • The "…" ellipses are `aria-hidden` and not focusable.

Keyboard

KeyAction
Tab / Shift+TabMoves through the enabled buttons in order.
Enter / SpaceActivates the focused button (native behavior).

Keep in mind

  • Translate `previousLabel`, `nextLabel`, `pageLabel` and `aria-label`; their defaults are in English.
  • Changing page does not move focus or announce anything; handle that in `onPageChange` if needed.