Pagination
Pagination renders previous and next buttons, page-number buttons, and ellipses for large page ranges. Optional edge buttons move to the first or last page.
Open in Storybook
Import
import { Pagination } from "@tosui/react";
Basic usage
- Preview
- Code
<Pagination defaultPage={1} totalPages={10} />
Controlled state
Pass page when application state or data loading owns the current page. Update that state from onPageChange.
function PaginatedContent() {
const [page, setPage] = useState(1);
return (
<Pagination page={page} totalPages={10} onPageChange={setPage} />
);
}
Page ranges
Pagination automatically shows ellipsis for large page ranges.
// Few pages - all shown
<Pagination page={1} totalPages={5} showEdges={false} onPageChange={setPage} />
// Shows: « 1 2 3 4 5 »
// Many pages - ellipsis shown
<Pagination page={5} totalPages={20} showEdges={false} onPageChange={setPage} />
// Shows: « 1 … 4 5 6 … 20 »
// Near start
<Pagination page={2} totalPages={20} showEdges={false} onPageChange={setPage} />
// Shows: « 1 2 3 4 5 … 20 »
// Near end
<Pagination page={19} totalPages={20} showEdges={false} onPageChange={setPage} />
// Shows: « 1 … 16 17 18 19 20 »
Siblings
Control how many page numbers appear on each side of the current page.
// 1 sibling (default)
<Pagination page={10} totalPages={20} siblings={1} showEdges={false} onPageChange={setPage} />
// Shows: « 1 … 9 10 11 … 20 »
// 2 siblings
<Pagination page={10} totalPages={20} siblings={2} showEdges={false} onPageChange={setPage} />
// Shows: « 1 … 8 9 10 11 12 … 20 »
First-page and last-page buttons
Set showEdges={false} to hide the buttons that move directly to the first or last page. The numbered range still includes the first and last page.
// With edge buttons (default)
<Pagination page={5} totalPages={20} showEdges onPageChange={setPage} />
// Shows: «« « 1 … 4 5 6 … 20 » »»
// Without edge buttons
<Pagination page={5} totalPages={20} showEdges={false} onPageChange={setPage} />
// Shows: « 1 … 4 5 6 … 20 »
Complete example
function ProductList() {
const [page, setPage] = useState(1);
const { products, totalPages } = useProducts({ page, limit: 10 });
return (
<VStack gap={6}>
<Box>
{products.map(product => (
<ProductCard key={product.id} product={product} />
))}
</Box>
<Pagination
page={page}
totalPages={totalPages}
onPageChange={setPage}
/>
</VStack>
);
}
Props reference
| Prop | Type | Default | Description |
|---|---|---|---|
| page | number | - | Current page for controlled usage (1-indexed) |
| defaultPage | number | 1 | Initial page for uncontrolled usage |
| totalPages | number | - | Total number of pages (required) |
| onPageChange | (page: number) => void | - | Optional page change callback |
| siblings | number | 1 | Number of page numbers on each side of current |
| showEdges | boolean | true | Show first/last page buttons |
| className | string | - | Additional CSS class |
Button states
- The previous and first-page buttons are disabled on page 1.
- The next and last-page buttons are disabled on the final page.
- The current page button uses the
solidvariant. - Other page buttons use the
ghostvariant.
Accessibility
- A
navelement wraps the controls and usesaria-label="Pagination". - Each button has a page or action label, such as
Page 5orPrevious page. - The current page uses
aria-current="page". - Unavailable actions use the native
disabledattribute.
TypeScript
import { Pagination, type PaginationProps } from "@tosui/react";