Pagination
Pagination with controlled and uncontrolled modes, automatic range collapsing, an optional page-size selector and jump input, and outline / filled looks.
Installation
Add component
pnpm dlx @elyri/cli@latest add paginationExamples
Basic
The default outline look; the middle range collapses into an ellipsis once edges overflow.
import { Pagination } from './components/elyri/Pagination';
export function Example() {
return <Pagination total={12} defaultPage={1} />;
}Full
Adds a page-size selector and first / last buttons; pages derive from total items over page size.
import { useState } from 'react';
import { Pagination } from './components/elyri/Pagination';
export function Example() {
const [page, setPage] = useState(3);
const [pageSize, setPageSize] = useState(10);
const totalItems = 97;
const totalPages = Math.max(1, Math.ceil(totalItems / pageSize));
return (
<Pagination
total={totalPages}
page={page}
onPageChange={setPage}
pageSize={pageSize}
pageSizeOptions={[10, 20, 50]}
onPageSizeChange={(size) => {
setPageSize(size);
setPage(1);
}}
showEdges
showJump
/>
);
}Variants
Both looks use borderless ghost buttons; only the active-page highlight differs.
import { useState } from 'react';
import { Pagination } from './components/elyri/Pagination';
export function Example() {
const [page, setPage] = useState(4);
return (
<div className="demo-ui-stack">
<Pagination total={20} page={page} onPageChange={setPage} variant="outline" showEdges />
<Pagination total={20} page={page} onPageChange={setPage} variant="filled" showEdges />
</div>
);
}Sizes
Two sizes: sm / md.
import { useState } from 'react';
import { Pagination } from './components/elyri/Pagination';
export function Example() {
const [page, setPage] = useState(3);
return (
<div className="demo-ui-stack">
<Pagination total={10} page={page} onPageChange={setPage} size="sm" />
<Pagination total={10} page={page} onPageChange={setPage} size="md" />
</div>
);
}Range collapsing
One sibling on each side of the current page; even 100 pages stay compact.
import { Pagination } from './components/elyri/Pagination';
export function Example() {
return <Pagination total={100} defaultPage={50} showEdges />;
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
total | number | — | Total number of pages |
page | number | — | Controlled current page (1-based) |
defaultPage | number | 1 | Initial page when uncontrolled |
onPageChange | (page: number) => void | — | Called on every change, controlled or not |
siblingCount | number | '1' | Number of pages shown on each side of the current page |
boundaryCount | number | '1' | Number of pages pinned at the first and last ends |
showEdges | boolean | false | Whether the first / last buttons show |
variant | 'outline' | 'filled' | 'outline' | Appearance: outline (accent outline + tint on the current page) or filled (solid accent) |
size | 'sm' | 'md' | 'md' | Control size: sm / md |
disabled | boolean | false | Disable the whole control |
pageSize | number | — | Controlled page size; the selector shows when pageSizeOptions is set |
defaultPageSize | number | — | Initial page size when uncontrolled, defaults to the first option |
pageSizeOptions | number[] | — | Page-size options; the selector shows once provided |
onPageSizeChange | (pageSize: number) => void | — | Called when the page size changes |
showJump | boolean | false | Whether the jump-to-page input shows |
labels | Partial<PaginationLabels> | — | Override built-in copy (aria labels and hints) |
...rest | HTMLAttributes | — | Remaining props are forwarded to the native nav |