import { useState } from "react";
import { Pagination } from "@lark-ui/core";
export function PaginationBasicDemo() {
const [page, setPage] = useState(1);
return (
<Pagination page={page} setPage={setPage} perPage={10} totalCount={100} />
);
}安装
统一导出
import { Pagination } from "@lark-ui/core";按需导出
import { Pagination } from "@lark-ui/core/components/pagination";用法
import { useState } from "react";
import { Pagination } from "@lark-ui/core";
export default function Example() {
const [page, setPage] = useState(1);
return (
<Pagination page={page} setPage={setPage} perPage={10} totalCount={100} />
);
}示例
完整控件(默认)
默认的分页包含首页、上一页、页码输入框、下一页和末页按钮。
import { useState } from "react";
import { Pagination } from "@lark-ui/core";
export function PaginationFullDemo() {
const [page, setPage] = useState(1);
return (
<Pagination
page={page}
setPage={setPage}
perPage={10}
totalCount={100}
controls="full"
/>
);
}简洁控件
使用 controls="simple" 可获得只包含上一页和下一页按钮的极简分页。
import { useState } from "react";
import { Pagination } from "@lark-ui/core";
export function PaginationSimpleDemo() {
const [page, setPage] = useState(1);
return (
<Pagination
page={page}
setPage={setPage}
perPage={10}
totalCount={100}
controls="simple"
/>
);
}未知总数
当数据源不返回总数时,请使用 hasNextPage。这在基于游标的 API 中很常见,因为计算总数
可能代价高昂或根本无法获取。请根据响应中的「还有下一页」信号来设置它,使「下一页」按钮
仅在仍存在后续结果集时保持可用。
没有总数时,用户只能顺序翻页,因此分页(Pagination)会隐藏首页、末页和页码选择器控件。
page 值对界面仍然有用,但每次请求的游标或续传令牌需要由你的应用负责存储和发送。
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}`}
/>
);import { useState } from "react";
import { Pagination } from "@lark-ui/core";
/** 分页(Pagination)适用于只告知是否还有下一页、但不返回总数的 API。 */
export function PaginationUnknownTotalDemo() {
const [page, setPage] = useState(1);
const hasNextPage = page < 3;
return (
<Pagination
text={() => `第 ${page} 页`}
page={page}
setPage={setPage}
hasNextPage={hasNextPage}
/>
);
}中间页状态
位于数据集中间位置、所有导航均可用的分页状态。
import { useState } from "react";
import { Pagination } from "@lark-ui/core";
export function PaginationMidPageDemo() {
const [page, setPage] = useState(5);
return (
<Pagination page={page} setPage={setPage} perPage={10} totalCount={100} />
);
}空结果
当 totalCount={0} 时,分页会显示一个空页面,且 setPage 永远不会被调用为第 0 页。
在第 1 页时,所有导航按钮均为禁用状态。如果在较后面的页面(例如筛选之后)结果可能变为空,
请将 page 重置为 1。
import { useState } from "react";
import { Pagination } from "@lark-ui/core";
/** 结果集为空时渲染单个空页面,并禁用翻页导航。 */
export function PaginationEmptyDemo() {
const [page, setPage] = useState(1);
return (
<Pagination page={page} setPage={setPage} perPage={10} totalCount={0} />
);
}页码输入框
页码输入框只接受整数页码。按回车或将焦点移开即可跳转到该页。超出范围的数字会跳到首页或末页。
其他内容(如 abc、2.5 或 1e1)会恢复当前页,并且不会调用 setPage。
大型数据集
分页组件可以处理页数众多的大型数据集。
import { useState } from "react";
import { Pagination } from "@lark-ui/core";
export function PaginationLargeDatasetDemo() {
const [page, setPage] = useState(1);
return (
<Pagination page={page} setPage={setPage} perPage={25} totalCount={1250} />
);
}自定义文本
你可以自定义分页文本。
import { useState } from "react";
import { Pagination } from "@lark-ui/core";
export function PaginationCustomTextDemo() {
const [page, setPage] = useState(1);
return (
<Pagination
text={({ perPage }: { perPage?: number }) =>
`第 ${page} 页 - 每页显示 ${perPage} 条`
}
page={page}
setPage={setPage}
perPage={25}
totalCount={100}
/>
);
}复合组件
如果需要更多布局和功能上的控制,请使用复合组件 API。你可以按任意顺序组合 Pagination.Info、Pagination.PageSize、Pagination.Controls 和 Pagination.Separator。
每页条数选择器
添加下拉菜单,让用户选择每页显示的条目数。
import { useState } from "react";
import { Pagination } from "@lark-ui/core";
/** 使用复合组件实现每页条数选择器的分页。 */
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]。
import { useState } from "react";
import { Pagination } from "@lark-ui/core";
/** 使用复合组件实现自定义每页条数选项的分页。 */
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>
);
}自定义信息文本
使用渲染函数自定义信息文本。
import { useState } from "react";
import { Pagination } from "@lark-ui/core";
/** 使用复合组件实现自定义信息文案的分页。 */
export function PaginationCompoundCustomInfoDemo() {
const [page, setPage] = useState(1);
return (
<Pagination page={page} setPage={setPage} perPage={25} totalCount={100}>
<Pagination.Info>
{({ page, totalCount }) =>
`第 ${page} 页,共 ${Math.ceil((totalCount ?? 1) / 25)} 页`
}
</Pagination.Info>
<Pagination.Controls />
</Pagination>
);
}自定义布局
可以按任意顺序排列组件。这里每页条数选择器位于右侧。
import { useState } from "react";
import { Pagination } from "@lark-ui/core";
/** 每页条数选择器位于右侧的分页。 */
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",可以用下拉选择器代替文本输入框
进行页码导航。当你希望用户从可用页面列表中选择,而不是手动输入数字时,这会非常有用。
<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 属性可以为不同语言环境自定义所有界面文案。所有标签默认使用英文。
import { useState } from "react";
import { Pagination } from "@lark-ui/core";
/** 支持自定义文案以实现国际化的分页。 */
export function PaginationI18nDemo() {
const [page, setPage] = useState(1);
return (
<Pagination
page={page}
setPage={setPage}
perPage={10}
totalCount={100}
labels={{
firstPage: "首页",
previousPage: "上一页",
nextPage: "下一页",
lastPage: "末页",
pageNumber: "页码",
pageSize: "每页条数",
}}
>
<Pagination.Info>
{({ pageShowingRange, totalCount }) => (
<>
显示 <span className="tabular-nums">{pageShowingRange}</span> 条,共{" "}
<span className="tabular-nums">{totalCount}</span> 条
</>
)}
</Pagination.Info>
<Pagination.Controls />
</Pagination>
);
}API 参考
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| setPage* | (page: number) => void | - | 页码变化时的回调 |
| page | number | - | 当前页码(从 1 开始)。 |
| perPage | number | - | 每页显示的条目数。 |
| totalCount | number | - | 所有页的条目总数。 |
| hasNextPage | boolean | - | 当总数未知时是否还有下一页。提供 `totalCount` 时该属性无效。总数未知时只使用顺序翻页控件。 |
| className | string | - | 容器的额外 CSS 类名 |
| labels | PaginationLabels | - | 用于国际化 aria-label 的标签。所有标签默认提供英文文案。 对于“Showing X of Y”这类可见文字,请使用子组件的 render props: - 信息文字使用 `Pagination.Info` 的 children - “Per page:”文字使用 `Pagination.PageSize` 的 label 属性 |
| children | ReactNode | - | 用于自定义布局的复合组件子元素。可使用 Pagination.Info、Pagination.PageSize、Pagination.Controls 和 Pagination.Separator。 |
| controls | "full" | "simple" | "full" | - |
| text | object | - | - |