UIUpdated April 28, 2026

Pagination

Composable pagination primitives for navigating paged content without routing or data logic.

UIPagination

Controlled navigation for paged contentLink to section

The Pagination component provides composable UI primitives for navigating paged content.

Use it for:

  • data tables
  • admin lists
  • reports
  • invoices
  • users
  • projects
  • search results
  • paged dashboard views

Pagination is intentionally dumb. It does not own routing, fetching, URL sync, cursor logic, page-size logic, or server state.

The page or data layer owns the logic. The UI renders navigation.

Core idea

Pagination should render page navigation, not own the data model.

ImportLink to section

pagination-import.tsx
import { Pagination } from "@pycolors/ui";

Basic usageLink to section

Pagination is composed from small primitives:

  • Pagination → wrapper navigation element
  • PaginationContent → list container
  • PaginationItem → item wrapper
  • PaginationLink → page control
  • PaginationPrevious / PaginationNext → directional controls
  • PaginationEllipsis → compact overflow indicator

Page 1 / 12

PaginationLink, PaginationPrevious, and PaginationNext support the asChild composition pattern. Pass a real anchor (or a framework Link) as the child and the control renders it as the root element while preserving all styling, data-slot, accessible labels, and — for PaginationPrevious and PaginationNext — the built-in icon and visible text.

Framework links

Replace <a href="..."> with your router's Link component (Next.js, React Router, TanStack Router, etc.) — the composition pattern is router-neutral.

PaginationPrevious and PaginationNext with asChild

You only need to supply the anchor element as the child. The built-in ChevronLeft / ChevronRight icon and the visible Previous / Next text are rendered automatically alongside your child element.

Use Pagination when users need controlled access to a finite set of pages.

Tables

Use pagination when dense tables need stable page navigation.

Paged data

Use when the backend or data layer exposes page-based navigation.

Search results

Use when results are finite and users need predictable navigation.

Table + PaginationLink to section

This example demonstrates a common SaaS pattern: a Table with local Pagination control.

No backend logic is included. Replace the mock slice with your real data layer later.

Mock data — swap with Prisma later.
NameStatusUpdatedActions
Project 1Active2026-01-21
Project 2Active2026-01-21
Project 3Paused2026-01-21
Project 4Active2026-01-21
Project 5Archived2026-01-21

Showing 15 of 23

Architecture rule

Pagination should receive state and callbacks. The feature layer should own the data source, filters, sorting, and URL sync.

buildPaginationRangeLink to section

Use buildPaginationRange to generate compact page tokens with ellipsis.

build-pagination-range.ts
const tokens = buildPaginationRange({
  page,
  totalPages,
});

The returned tokens can represent:

  • page numbers
  • active page
  • ellipsis markers

This keeps rendering logic clean while keeping Pagination controlled.

Usage patternsLink to section

Keep page state outside the component

Store page, pageSize, and totalPages in the page, feature hook, or data layer.

Disable impossible navigation

Disable Previous on the first page and Next on the last page.

Use ellipsis for large page counts

Avoid rendering dozens of page links. Compact large ranges with ellipsis.

Sync URL only at the product layer

URL syncing belongs to your page or routing layer, not the UI primitive.

Pair with loading and empty states

Pagination should work with Table, loading states, empty states, and filters as one product pattern.

Pagination vs infinite scrollLink to section

SituationUse
Admin tablePagination
Search results with known page countPagination
Invoices, users, subscriptionsPagination
Feed-style browsingInfinite scroll
Cursor-only API with no page conceptProduct-level cursor controls
Small data setNo pagination

Decision rule

Use Pagination when the user benefits from a stable position in a finite result set.

APILink to section

Component

ComponentDescription
PaginationWrapper nav element with pagination semantics
PaginationContentList container
PaginationItemItem wrapper
PaginationLinkPage control with active state
PaginationPreviousPrevious button
PaginationNextNext button
PaginationEllipsisVisual overflow indicator
PropTypeDefaultDescription
asChildbooleanfalseRender as a Slot wrapper; supply a real anchor or framework link as the child
isActivebooleanfalseMarks the current page
sizestring"icon-sm"Maps to Button sizes
classNamestringAdditional Tailwind classes

PaginationPrevious props

PropTypeDefaultDescription
asChildbooleanfalseRender as a Slot wrapper; built-in icon and text are preserved
labelstring"Previous page"Accessible label for screen readers
classNamestringAdditional Tailwind classes

PaginationNext props

PropTypeDefaultDescription
asChildbooleanfalseRender as a Slot wrapper; built-in icon and text are preserved
labelstring"Next page"Accessible label for screen readers
classNamestringAdditional Tailwind classes

buildPaginationRange options

OptionTypeDescription
pagenumberCurrent page
totalPagesnumberTotal number of pages

AccessibilityLink to section

Pagination should be understandable and keyboard accessible.

Guidelines:

  • use semantic nav with pagination labeling
  • mark the active page with aria-current="page"
  • keep buttons keyboard accessible
  • disable Previous and Next when unavailable
  • make ellipsis non-interactive
  • avoid tiny click targets in dense layouts
  • provide URL sync at the page layer when deep linking matters

Accessibility rule

Pagination controls should be navigable, understandable, and predictable without relying on visual position alone.

Prefer / avoidLink to section

Prefer

  • controlled page state
  • disabled unavailable controls
  • ellipsis for large page counts
  • URL sync in the route layer when needed
  • clear loading and empty states around paged data

Avoid

  • fetching data inside Pagination
  • rendering every page for large ranges
  • clickable ellipsis
  • pagination for tiny data sets
  • using pagination for feed-style discovery

Product copy guidelinesLink to section

Pagination labels should be short and predictable.

Previous / Next

Use familiar labels for core navigation. Avoid clever wording or ambiguous actions.

Previous · Next

Common questionsLink to section