Showing 1-10 of 100
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} />
);
}安装
批量导入
import { Pagination } from "@cloudflare/kumo";细粒度导入
import { Pagination } from "@cloudflare/kumo/components/pagination";用法
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} />
);
}示例
完整控件 (默认)
默认的分页包含首页、上一页、页码输入框、下一页和末页按钮。
Showing 1-10 of 100
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"
/>
);
}简化控件
使用 controls="simple" 获得只包含上一页和下一页按钮的精简分页。
Showing 1-10 of 100
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"
/>
);
}总数未知
当数据源不返回总条数时,请使用 hasNextPage。这在基于游标的 API 中很常见——
计算总数可能代价高昂甚至不可用。根据响应中的下一页信号来设置它,
以便仅在还存在下一组结果时才启用「下一页」。
没有总数时,用户只能顺序翻页,因此 Pagination 会隐藏首页、末页和页码选择控件。
page 的值对 UI 仍有用,但存储并发送每次请求的游标或续传令牌是你的应用的责任。
const [page, setPage] = useState(1);
const { data } = useQuery({
queryKey: ["events", page],
queryFn: () => getEvents({ cursor: cursors[page - 1] }),
});
return (
<Pagination
page={page}
setPage={setPage}
hasNextPage={data.hasMore}
text={() => `Page ${page}`}
/>
);Page 1
import { useState } from "react";
import { Pagination } from "@cloudflare/kumo";
/** Pagination for an API that reports whether another page exists, but not a total. */
export function PaginationUnknownTotalDemo() {
const [page, setPage] = useState(1);
const hasNextPage = page < 3;
return (
<Pagination
text={() => `Page ${page}`}
page={page}
setPage={setPage}
hasNextPage={hasNextPage}
/>
);
}中间页状态
位于数据集中间的分页,所有导航均可用。
Showing 41-50 of 100
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} />
);
}大数据集
分页可处理页数很多的大数据集。
Showing 1-25 of 1250
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} />
);
}自定义文本
你可以自定义分页的显示文本。
Page 1 - showing 25 per page
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}
/>
);
}复合组件
如果想更精细地控制布局和功能,请使用复合组件 API。它允许你以任意顺序组合 Pagination.Info、Pagination.PageSize、Pagination.Controls 和 Pagination.Separator。
每页条数选择器
添加一个下拉菜单,让用户选择每页显示的条目数。
Showing 1-25 of 500
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>
);
}自定义每页条数选项
通过 options 属性自定义可选的每页条数,默认为
[25, 50, 100, 250]。
Showing 1-10 of 200
Per page:
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>
);
}自定义信息文本
使用渲染函数自定义信息文本。
Page 1 of 4
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>
);
}自定义布局
以任意顺序排列组件。这里每页条数选择器位于右侧。
Showing 1-25 of 500
Per page:
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>
);
}下拉式页码选择器
在 Pagination.Controls 上使用 pageSelector="dropdown",可将页码导航的文本输入框
替换为下拉选择器。当希望用户从可用页码列表中选择,而不是手动输入数字时,这很实用。
Showing 1-25 of 500
Per page:
<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>国际化
使用 labels 属性可针对不同语言环境自定义所有界面文案,所有标签默认为英文。
Affichage de 1-10 sur 100
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 参考
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| 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. |
| hasNextPage | boolean | - | Whether another page exists when the total count is unknown. Ignored when `totalCount` is provided. Unknown totals use sequential controls only. |
| 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 | - | - |