Pagination
A controlled page navigator — first / prev / numbered pages with ellipsis / next / last. Pure view, pair it with usePagination for state.
Installation
- $npx litefy@latest add pagination
- $pnpm dlx litefy@latest add pagination
- $yarn dlx litefy@latest add pagination
- $bun --bun litefy@latest add pagination
Usage
A fully controlled view — pair it with usePagination, which owns the page state.
"use client";
import * as React from "react";
import { Pagination, usePagination } from "@/ui";
const TOTAL_PAGES = 24;
export default function Demo() {
const pagination = usePagination({ base: 1, total: TOTAL_PAGES });
return (
<div className="w-full max-w-xl">
<Pagination
page={pagination.index}
totalPages={TOTAL_PAGES}
onPageChange={pagination.goTo}
summary={`Page ${pagination.index} of ${TOTAL_PAGES}`}
/>
</div>
);
}
Disabled
Pass disabled to freeze every button, e.g. while a page request is loading:
"use client";
import { Pagination, usePagination } from "@/ui";
const TOTAL_PAGES = 24;
export default function Demo() {
const pagination = usePagination({ base: 1, total: TOTAL_PAGES });
return (
<div className="flex w-full max-w-xl flex-col">
<Pagination
disabled
page={pagination.index}
totalPages={TOTAL_PAGES}
onPageChange={pagination.goTo}
summary={`Page ${pagination.index} of ${TOTAL_PAGES} (loading)`}
/>
</div>
);
}
Summary text
Pass summary to render a page-count text on the left; in narrow containers it wraps onto new lines while the controls stay on the row:
"use client";
import * as React from "react";
import { Pagination, usePagination } from "@/ui";
const TOTAL_PAGES = 12;
const TOTAL_ITEMS = 1286;
const SELECTED = 3;
export default function PaginationLongSummaryDemo() {
const pagination = usePagination({ base: 1, total: TOTAL_PAGES });
const pageSize = 10;
return (
<div className="w-full max-w-md">
<Pagination
page={pagination.index}
totalPages={TOTAL_PAGES}
onPageChange={pagination.goTo}
summary={`Showing ${(pagination.index - 1) * pageSize + 1}–${Math.min(
pagination.index * pageSize,
TOTAL_ITEMS,
)} of ${TOTAL_ITEMS.toLocaleString()} items · ${SELECTED} selected`}
/>
</div>
);
}
With SelectableTable
The recommended composition with SelectableTable is covered in its Pagination guide.
API Reference
Pagination
| Prop | Type | Default | Description |
|---|---|---|---|
page | number | - | Current 1-based page. Required |
totalPages | number | - | Total page count. Required |
onPageChange | (page: number) => void | - | Fired by every button click |
siblingCount | number | 1 | Page numbers shown on each side of the current page before collapsing into ellipsis |
disabled | boolean | false | Disables every button (e.g. while a page is loading) |
summary | React.ReactNode | - | Page-count text on the left; takes the remaining width and wraps, controls stay on the row vertically centered |
className | ClassNameValue | - | Custom classes, applied to the root nav |
classNames | { pages?, summary? } | - | Custom classes for the numbered-pages group and the summary text |
styles | { summary? } | - | Custom styles for the summary text |
Parts
| Part | Element | Built-in classes | Description |
|---|---|---|---|
PaginationRoot | <nav> | flex items-center gap-1 | Row container, aria-label="pagination" |
PaginationFirst | Button | text variant, px-0 | Jump to page 1 (ChevronsLeft) |
PaginationPrev | Button | text variant, px-0 | Previous page (ChevronLeft) |
PaginationPages | <div> | flex items-center gap-1 | Numbered buttons + ellipsis markers |
PaginationNext | Button | text variant, px-0 | Next page (ChevronRight) |
PaginationLast | Button | text variant, px-0 | Jump to the last page (ChevronsRight) |
PaginationEllipsis | <span> | size-8 text-muted-foreground | Collapsed pages marker (MoreHorizontal) |
PaginationSummary | <span> | min-w-0 flex-1 text-sm text-muted-foreground | Summary text slot, absorbs the remaining width and wraps |
The current page renders as an outline Button with aria-current="page"; all other page numbers render as text Buttons.
Number Input
A bordered numeric input with a non-interactive up/down cue in the trailing area — stepping is keyboard-only. The form-friendly sibling of NumberField.
Pager
A controlled single-DOM pager with touch gesture dragging, loop and View-Transition page switching, built for manga-style readers and paged content