import { useState } from "react";
import { Pagination } from "@cloudflare/kumo";
export function PaginationBasicDemo() {
const [page, setPage] = useState(1);
return (
<Pagination page={page} setPage={setPage} perPage={10} totalCount={100} />
);
} Installation
Barrel
import { Pagination } from "@cloudflare/kumo";Granular
import { Pagination } from "@cloudflare/kumo/components/pagination"; Usage
import { useState } from "react";
import { Pagination } from "@cloudflare/kumo";
export default function Example() {
const [page, setPage] = useState(1);
return (
<Pagination page={page} setPage={setPage} perPage={10} totalCount={100} />
);
} Examples
Full Controls (Default)
The default pagination includes first, previous, page input, next, and last buttons.
import { useState } from "react";
import { Pagination } from "@cloudflare/kumo";
export function PaginationFullDemo() {
const [page, setPage] = useState(1);
return (
<Pagination
page={page}
setPage={setPage}
perPage={10}
totalCount={100}
controls="full"
/>
);
} Simple Controls
Use controls="simple" for a minimal pagination with only previous and next
buttons.
import { useState } from "react";
import { Pagination } from "@cloudflare/kumo";
export function PaginationSimpleDemo() {
const [page, setPage] = useState(1);
return (
<Pagination
page={page}
setPage={setPage}
perPage={10}
totalCount={100}
controls="simple"
/>
);
} Mid-Page State
Pagination in the middle of a dataset with all navigation enabled.
import { useState } from "react";
import { Pagination } from "@cloudflare/kumo";
export function PaginationMidPageDemo() {
const [page, setPage] = useState(5);
return (
<Pagination page={page} setPage={setPage} perPage={10} totalCount={100} />
);
} Large Dataset
Pagination handles large datasets with many pages.
import { useState } from "react";
import { Pagination } from "@cloudflare/kumo";
export function PaginationLargeDatasetDemo() {
const [page, setPage] = useState(1);
return (
<Pagination page={page} setPage={setPage} perPage={25} totalCount={1250} />
);
} Custom Text
You can set custom pagination text.
import { useState } from "react";
import { Pagination } from "@cloudflare/kumo";
export function PaginationCustomTextDemo() {
const [page, setPage] = useState(1);
return (
<Pagination
text={({ perPage }: { perPage?: number }) =>
`Page ${page} - showing ${perPage} per page`
}
page={page}
setPage={setPage}
perPage={25}
totalCount={100}
/>
);
} Compound Components
For more control over layout and features, use the compound component API. This allows you to compose Pagination.Info, Pagination.PageSize, Pagination.Controls, and Pagination.Separator in any order.
Page Size Selector
Add a dropdown to let users select the number of items per page.
import { useState } from "react";
import { Pagination } from "@cloudflare/kumo";
/** Pagination with a page size selector using compound components. */
export function PaginationPageSizeSelectorDemo() {
const [page, setPage] = useState(1);
const [perPage, setPerPage] = useState(25);
return (
<Pagination
page={page}
setPage={setPage}
perPage={perPage}
totalCount={500}
>
<Pagination.Info />
<Pagination.Separator />
<Pagination.PageSize
value={perPage}
onChange={(size) => {
setPerPage(size);
setPage(1);
}}
/>
<Pagination.Controls />
</Pagination>
);
} Custom Page Size Options
Customize the available page size options with the options prop. Defaults to
[25, 50, 100, 250].
import { useState } from "react";
import { Pagination } from "@cloudflare/kumo";
/** Pagination with custom page size options using compound components. */
export function PaginationCustomPageSizeOptionsDemo() {
const [page, setPage] = useState(1);
const [perPage, setPerPage] = useState(10);
return (
<Pagination
page={page}
setPage={setPage}
perPage={perPage}
totalCount={200}
>
<Pagination.Info />
<Pagination.Separator />
<Pagination.PageSize
value={perPage}
onChange={(size) => {
setPerPage(size);
setPage(1);
}}
options={[10, 20, 50]}
/>
<Pagination.Controls />
</Pagination>
);
} Custom Info Text
Use a render function to customize the info text.
import { useState } from "react";
import { Pagination } from "@cloudflare/kumo";
/** Pagination with custom info text using compound components. */
export function PaginationCompoundCustomInfoDemo() {
const [page, setPage] = useState(1);
return (
<Pagination page={page} setPage={setPage} perPage={25} totalCount={100}>
<Pagination.Info>
{({ page, totalCount }) =>
`Page ${page} of ${Math.ceil((totalCount ?? 1) / 25)}`
}
</Pagination.Info>
<Pagination.Controls />
</Pagination>
);
} Custom Layout
Arrange components in any order. Here the page size selector is on the right.
import { useState } from "react";
import { Pagination } from "@cloudflare/kumo";
/** Pagination with page size selector on the right side. */
export function PaginationPageSizeRightDemo() {
const [page, setPage] = useState(1);
const [perPage, setPerPage] = useState(25);
return (
<Pagination
page={page}
setPage={setPage}
perPage={perPage}
totalCount={500}
>
<Pagination.Info />
<div className="flex items-center gap-2">
<Pagination.Controls />
<Pagination.Separator />
<Pagination.PageSize
value={perPage}
onChange={(size) => {
setPerPage(size);
setPage(1);
}}
/>
</div>
</Pagination>
);
} Dropdown Page Selector
Use pageSelector="dropdown" on Pagination.Controls to render a dropdown
select instead of a text input for page navigation. This is useful when you
want users to pick from a list of available pages rather than typing a number.
<Pagination page={page} setPage={setPage} perPage={perPage} totalCount={500}>
<Pagination.Info />
<Pagination.Separator />
<Pagination.PageSize
value={perPage}
onChange={(size) => {
setPerPage(size);
setPage(1);
}}
/>
<Pagination.Controls pageSelector="dropdown" />
</Pagination> Internationalization
Use the labels prop to customize all UI strings for different locales. All labels default to English.
import { useState } from "react";
import { Pagination } from "@cloudflare/kumo";
/** Pagination with French labels for internationalization. */
export function PaginationI18nDemo() {
const [page, setPage] = useState(1);
return (
<Pagination
page={page}
setPage={setPage}
perPage={10}
totalCount={100}
labels={{
firstPage: "Première page",
previousPage: "Page précédente",
nextPage: "Page suivante",
lastPage: "Dernière page",
pageNumber: "Numéro de page",
pageSize: "Taille de page",
}}
>
<Pagination.Info>
{({ pageShowingRange, totalCount }) => (
<>
Affichage de{" "}
<span className="tabular-nums">{pageShowingRange}</span> sur{" "}
<span className="tabular-nums">{totalCount}</span>
</>
)}
</Pagination.Info>
<Pagination.Controls />
</Pagination>
);
} API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
| setPage* | (page: number) => void | - | Callback when page changes |
| page | number | - | Current page number (1-indexed). |
| perPage | number | - | Number of items displayed per page. |
| totalCount | number | - | Total number of items across all pages. |
| className | string | - | Additional CSS classes for the container |
| labels | PaginationLabels | - | Labels for internationalization of aria-labels. All labels have English defaults. For visible text like "Showing X of Y", use render props on sub-components: - `Pagination.Info` children for the info text - `Pagination.PageSize` label prop for the "Per page:" text |
| children | ReactNode | - | Compound component children for custom layouts. Use Pagination.Info, Pagination.PageSize, Pagination.Controls, and Pagination.Separator. |
| controls | "full" | "simple" | "full" | - |
| text | object | - | - |