Tessera UI

Pagination

Navigate between pages of content. Five sizes, three active-page variants (default/primary/outline), five border-radius options (none/sm/md/lg/full), three nav styles (icon/label/none), smart ellipsis truncation, controlled/uncontrolled, and LTR/RTL support.

Installation

pnpm add @tessinaui/ui

Usage

import { Pagination } from "@tessinaui/ui";
{/* Uncontrolled */}
<Pagination count={10} defaultPage={1} />

{/* Controlled */}
<Pagination count={10} page={page} onChange={setPage} />

{/* Primary active style */}
<Pagination count={10} defaultPage={3} variant="primary" />

{/* Text Previous / Next buttons */}
<Pagination count={10} defaultPage={3} navStyle="label" />

{/* Square item shape */}
<Pagination count={10} defaultPage={3} rounded="none" />

{/* Custom truncation */}
<Pagination count={50} defaultPage={25} siblingCount={2} boundaryCount={2} />

{/* RTL */}
<Pagination count={10} defaultPage={3} dir="rtl" navStyle="label" />

Playground

Preview

Showcase

Preview

API Reference

Props

PropTypeDefaultDescription
countnumberRequired. Total number of pages
pagenumberControlled current page (1-indexed)
defaultPagenumber1Uncontrolled initial page
onChange(page: number) => voidCalled when the active page changes
siblingCountnumber1Pages shown on each side of the current page
boundaryCountnumber1Pages always shown at the start and end boundaries
size"xs" | "sm" | "md" | "lg" | "xl""md"Visual size token
variant"default" | "primary" | "outline""default"Active page indicator style
rounded"none" | "sm" | "md" | "lg" | "full""full"Border radius for all buttons
navStyle"icon" | "label" | "none""icon"Navigation button style — see table below
disabledbooleanfalseDisable all interactions
dir"ltr" | "rtl""ltr"Text direction — RTL swaps chevron directions and nav button positions
prevLabelstring"Previous"Label for the Previous button (used with navStyle="label" or "both")
nextLabelstring"Next"Label for the Next button
getPageAriaLabel(page: number, selected: boolean) => stringCustom aria-label generator for page buttons
classNamestringAdditional class on the root <nav> element
ValueDescription
"icon"Chevron icon buttons only — [<] [pages] [>] (default)
"label"Previous / Next text buttons with icons — [← Previous] [pages] [Next →]
"none"No navigation buttons — page items only

Variants

ValueActive page style
"default"bg-secondary (neutral gray fill)
"primary"bg-primary text-on-primary (brand color fill)
"outline"ring-2 ring-inset ring-primary text-primary (outlined border)

Notes

  • Controlled vs uncontrolled: When page is provided the component is fully controlled. Use defaultPage for uncontrolled usage.
  • Ellipsis truncation: Uses the MUI usePagination algorithm — always shows boundaryCount pages at each end and siblingCount pages around the current page, collapsing the rest into .
  • RTL: dir="rtl" flips the chevron icons (ChevronRight becomes "go back") and swaps the positions of prev/next nav buttons so the "next" action is on the leading (left) side, matching Arabic/Hebrew pagination conventions.
  • Accessibility: Renders as <nav role="navigation"> with aria-label="pagination navigation". Active page buttons have aria-current="page". All buttons have descriptive aria-labels that can be customised via getPageAriaLabel.
  • No headless dependency: Pagination is implemented with plain React state — no Base UI primitives needed.

On this page