Skip to content
Dethink Components

ComponentsPagination

Pagination

Let users move between pages of results.

On this page

Use this component from the local workspace package. Follow the setup guide first. A public npm package and registry are not available yet.

View registry files

Import the component into your page or component file.

Usage
import {
  Pagination,
  getPaginationRenderItems,
} from "@dethink/components";

Try the examples, then open the code to use them in your app.

Bounded callback controls

Known totals expose previous, next, first, last, current-page state, and deterministic ellipses.

Show sourceexamples/pagination/basic.tsx
examples/pagination/basic.tsx
"use client";

import { useState } from "react";
import { Pagination } from "@dethink/components";

export function PaginationBasic() {
  const [page, setPage] = useState(4);

  return (
    <Pagination
      aria-label="Example result pages"
      page={page}
      pageCount={12}
      showFirstLast
      onPageChange={setPage}
    />
  );
}

Real page URLs with in-place navigation: the selected page follows the URL, browser Back/Forward works, and changing pages preserves your scroll position.

Narrow and RTL

Small hosts collapse to Back/Next controls while preserving logical RTL placement for the page summary.

Saved searches

Small hosts collapse to Back/Next while RTL keeps the page summary at inline-start.

Show sourceexamples/pagination/responsive-card.tsx
examples/pagination/responsive-card.tsx
"use client";

import { useState } from "react";
import { Pagination } from "@dethink/components";

export function PaginationResponsiveCard() {
  const [page, setPage] = useState(5);

  return (
    <div className="border-border bg-background mx-auto max-w-xs rounded-lg border p-4 shadow-sm">
      <div className="space-y-1">
        <h4 className="text-foreground text-sm font-semibold">
          Saved searches
        </h4>
        <p className="text-muted-foreground text-sm leading-6">
          Small hosts collapse to Back/Next while RTL keeps the page summary at
          inline-start.
        </p>
      </div>
      <div className="mt-4" dir="rtl">
        <Pagination
          aria-label="Saved search pages"
          page={page}
          pageCount={12}
          showFirstLast
          onPageChange={setPage}
        />
      </div>
    </div>
  );
}

Examples that combine components for common tasks.

Pagination composes beside row-count copy without owning table state, page size, or fetching.

InvoiceAmountStatus
INV-1048Acme EU$12,420Paid
INV-1049Northstar$8,115Pending
INV-1050Rivet Labs$4,680Paid

Rows 21-30 of 120

Choose the mode that matches the data source and route model.

Callback mode

Use onPageChange when the current page lives in client state, a table model, or a server action wrapper.

Link mode

Use hrefForPage for real URLs. Integrate your router to avoid document reloads. This local-state demo uses Next.js history integration; server-backed results should navigate through the router with scrolling disabled.

Unbounded mode

Omit pageCount and pass hasNextPage for cursor-backed APIs that can page forward but do not know the final page.

Responsive layout

Pagination adapts to its own container width: small hosts use a Back/Next fallback, and larger hosts restore the normal page window.

Pagination renders a nav landmark and generated controls by default, with compound anatomy available for custom composition.

Pagination props
PropWhat it doesDefault
pagenumberCurrent one-based page. Values are clamped to the known pageCount when pageCount is supplied.Not set
pageCountnumberKnown total pages for bounded pagination. Omit for cursor-style or unknown-total lists.Not set
hasNextPagebooleanEnables next-page controls in unbounded mode without inventing a final page.false
onPageChange(page: number) => voidCallback mode for client-owned state updates. Generated controls render as buttons.Not set
hrefForPage(page: number) => string | undefinedLink mode for route-backed pagination. Targets without URLs fall back to onPageChange or render disabled.Not set
compactbooleanReduces page-window density for cards, mobile layouts, and table footers.false
showFirstLast / hideDisabledControlsbooleanAdds first/last controls and chooses whether impossible boundary controls are disabled or hidden.false / false
siblingCount / boundaryCountnumberControls how many pages render around the current page and at the known page boundaries.1 / 1
size"sm" | "md" | "lg"Tokenized control size for dense tables, default pages, or larger touch targets."md"
statusReactNode | falseVisible page summary. Pass false when the surrounding UI already provides the status text.generated
labelsPaginationLabelsCustom accessible labels for the nav landmark, page controls, boundary controls, ellipses, status, and narrow Back/Next text.built-in English labels
childrenReactNodeCompound anatomy escape hatch when consumers need full manual composition.Not set