Pagination

A pagination component for React: previous and next buttons around a window of five page numbers, with a mark that glides to the current page and numbers that slide as the window moves. It is fully controlled, so keep the page in state or the URL and fetch in onPageChange. The current page carries aria-current.

pnpm dlx shadcn@latest add @uiarc/pagination
Live · keyboard ready
  • Paged server results and long tables.
  • Lists where the page should live in the URL or state and fetch on change.
  • Use carousel for browsing slides.
  • Use timeline with maxHeight for a scrolling feed instead of pages.

Installation

Add Pagination with the shadcn CLI, or copy the source by hand.

pnpm dlx shadcn@latest add @uiarc/pagination

Adds the component and its local dependencies, and installs motion, lucide-react. First time? Add the @uiarc registry to components.json, or use the full URL:

example.tsx
import { useState } from "react";import { Pagination } from "@/components/arc/pagination/pagination"; export function Results() {  const [page, setPage] = useState(1);  return <Pagination page={page} pageCount={12} onPageChange={setPage} />;}

Pagination

Previous and next buttons around a sliding five page window with a traveling current page mark.

PropTypeDefaultDescription
pageRequirednumber–Current page, 1-based. Clamped to the range.
pageCountRequirednumber–Total pages. Zero renders an empty nav.
onPageChangeRequired(page: number) => void–Called with the requested page.
labelstring"Pagination"Accessible name for the nav landmark.
Tab
Moves between the previous, page, and next buttons.
EnterorSpace
Goes to that page.
  • Renders a nav landmark with the label as its name.
  • Page buttons are labelled "Page 3" and the current one has aria-current="page".
  • Previous and next are disabled at the ends and carry aria-labels.
  • The current page mark springs to the selected button.
  • When the window shifts, numbers slide like a belt by the number of slots moved.
  • Reduced motion jumps the mark and swaps numbers without sliding.
  • It always shows a five page window plus arrows, so it stays the same width on any screen.
  • The row wraps if its container is narrower than the buttons, and the current mark re-measures on resize.
  • Only five page buttons render regardless of pageCount; one ResizeObserver repositions the current mark.

Notes for AI

Give your coding assistant the Markdown reference instead of screenshots.

  • Use for paged server results and long tables. Use carousel for browsing slides.
  • It is fully controlled: keep page in state or the URL and fetch on onPageChange.

The full library index for assistants is at /llms.txt.