Pagination
A navigation component for paginated content with ellipsis support.
$ npx @beaket/ui add paginationSource
import { useState } from "react";
import { Pagination } from "@/components/ui/pagination";
export default function Example() {
const [page, setPage] = useState(1);
return (
<div className="flex h-full items-center justify-center">
<Pagination
mode="button"
page={page}
totalPages={20}
maxPageButtons={7}
onPageChange={setPage}
/>
</div>
);
}Examples
All States
First Page (Link Mode)
Middle Page (Link Mode)
Last Page (Link Mode)
Few Pages (3)
Many Pages with Ellipsis
Single Page (Hidden)
Pagination is hidden when totalPages = 1
Button Mode — First Page
Button Mode — Middle Page
Button Mode — Last Page
Source
import { useState } from "react";
import { Pagination } from "@/components/ui/pagination";
const buildPageUrl = (page: number) => `?page=${page}`;
export default function PaginationStatesExample() {
const [firstPage, setFirstPage] = useState(1);
const [middlePage, setMiddlePage] = useState(5);
const [lastPage, setLastPage] = useState(10);
return (
<div className="space-y-8">
<div>
<h3 className="mb-4 text-sm font-medium">First Page (Link Mode)</h3>
<Pagination page={1} totalPages={10} buildPageUrl={buildPageUrl} />
</div>
<div>
<h3 className="mb-4 text-sm font-medium">Middle Page (Link Mode)</h3>
<Pagination page={5} totalPages={10} buildPageUrl={buildPageUrl} />
</div>
<div>
<h3 className="mb-4 text-sm font-medium">Last Page (Link Mode)</h3>
<Pagination page={10} totalPages={10} buildPageUrl={buildPageUrl} />
</div>
<div>
<h3 className="mb-4 text-sm font-medium">Few Pages (3)</h3>
<Pagination page={2} totalPages={3} buildPageUrl={buildPageUrl} />
</div>
<div>
<h3 className="mb-4 text-sm font-medium">Many Pages with Ellipsis</h3>
<Pagination page={50} totalPages={100} buildPageUrl={buildPageUrl} />
</div>
<div>
<h3 className="mb-4 text-sm font-medium">Single Page (Hidden)</h3>
<p className="text-fg-muted text-sm">Pagination is hidden when totalPages = 1</p>
<Pagination page={1} totalPages={1} buildPageUrl={buildPageUrl} />
</div>
<div>
<h3 className="mb-4 text-sm font-medium">Button Mode — First Page</h3>
<Pagination mode="button" page={firstPage} totalPages={10} onPageChange={setFirstPage} />
</div>
<div>
<h3 className="mb-4 text-sm font-medium">Button Mode — Middle Page</h3>
<Pagination mode="button" page={middlePage} totalPages={10} onPageChange={setMiddlePage} />
</div>
<div>
<h3 className="mb-4 text-sm font-medium">Button Mode — Last Page</h3>
<Pagination mode="button" page={lastPage} totalPages={10} onPageChange={setLastPage} />
</div>
</div>
);
}Props
| Name | Type | Default | Description |
|---|---|---|---|
| mode | undefined | button | link | — | Use link-based navigation (default). Renders `<a>` tags for SSR-friendly navigation. Use button-based navigation for client-side pagination. Renders `<button>` tags with onClick handlers. |
| buildPageUrl | ((page: number) => string) | ((page: number) => string) | undefined | — | Function to build URL for a given page number. Required when mode is "link". Used by `Pagination.Item` when it renders its own `<a href>`. |
| onPageChange | ((page: number) => void) | ((page: number) => void) | undefined | — | Callback when a page is selected. Required when mode is "button". Used by `Pagination.Item` when it renders its own `<button>`. |
| children | ReactNode | — | Compose the strip yourself from `Pagination.Previous`, `.Item`, `.Ellipsis` and `.Next` instead of letting the root lay it out. |
| labels | PaginationLabels | undefined | — | Accessible names; omitted labels retain their English defaults. |
| page* | number | — | Current page number (1-indexed) |
| totalPages* | number | — | Total number of pages |
| maxPageButtons | number | undefined | — | Maximum number of page buttons to show (default: 5) When there are more pages, ellipsis will be shown |
| Item.page* | number | — | The page this cell navigates to |
| Item.asChild | boolean | false | Renders the consumer's own element (a router `Link`) instead of an `<a>`/`<button>` |
| Previous.asChild | boolean | — | Renders the consumer's own element (a router `Link`) instead of an `<a>`/`<button>` |
| Next.asChild | boolean | — | Renders the consumer's own element (a router `Link`) instead of an `<a>`/`<button>` |
| Ellipsis.asChild | boolean | false | Renders the consumer's own element instead of a `<span>` |