Skip to main content

Overview

Pagination renders page number buttons, previous/next arrows, and an ellipsis for large page counts. It can be controlled or uncontrolled and pairs naturally with the Table component.

Installation

npm install @araf-ds/core

Usage

import { Pagination } from "@araf-ds/core"

export default function Example() {
  const [page, setPage] = useState(1)
  return (
    <Pagination
      page={page}
      totalPages={10}
      onPageChange={setPage}
    />
  )
}

Variants

Basic

<Pagination totalPages={5} defaultPage={1} onPageChange={(p) => console.log(p)} />

With Ellipsis (Many Pages)

<Pagination
  page={7}
  totalPages={50}
  siblingCount={1}
  onPageChange={setPage}
/>
{/* renders: « 1 ... 6 [7] 8 ... 50 » */}

Usage with Data Table

function UsersTable({ users }: { users: User[] }) {
  const [page, setPage] = useState(1);
  const pageSize = 10;
  const totalPages = Math.ceil(users.length / pageSize);
  const visibleUsers = users.slice((page - 1) * pageSize, page * pageSize);

  return (
    <div>
      <Table>
        {/* rows from visibleUsers */}
      </Table>
      <div className="flex justify-end mt-4">
        <Pagination
          page={page}
          totalPages={totalPages}
          onPageChange={setPage}
        />
      </div>
    </div>
  );
}

API Reference

page
number
Controlled current page (1-indexed).
onPageChange
(page: number) => void
Callback fired when the user navigates to a different page.
defaultPage
number
default:"1"
Uncontrolled default page.
totalPages
number
Total number of pages (required).
siblingCount
number
default:"1"
Number of page buttons shown on each side of the current page.
showFirstLast
boolean
default:"true"
Shows first («) and last (») page jump buttons.
size
string
default:"md"
Button size. Values: sm · md · lg
className
string
Additional Tailwind classes for custom overrides.

Accessibility

  • Pagination uses a <nav> element with aria-label="Pagination"
  • Active page button has aria-current="page"
  • Disabled previous/next buttons have aria-disabled="true"
  • Ellipsis elements use aria-hidden="true" as they are decorative
  • Previous/Next buttons have descriptive aria-label attributes

Do’s & Don’ts

Do

  • Always pair Pagination with a data table or list
  • Show the total count of items alongside the pagination control
  • Use siblingCount={2} for very large datasets (100+ pages)
  • Keep the Pagination at the bottom of the data, aligned to the right

Don't

  • Don’t use Pagination for fewer than 2 pages — hide it entirely
  • Don’t change totalPages during interaction unless data has changed
  • Don’t place Pagination above the data — users expect it at the bottom
  • Don’t use Pagination when infinite scroll is more appropriate for the UX