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 值仍可用于界面展示,但你的应用 需要自行保存并随每次请求发送游标 或续页令牌。

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} />
  );
}

大数据集

Pagination 可以处理包含大量页数的数据集。

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.InfoPagination.PageSizePagination.ControlsPagination.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 属性自定义面向不同 locale 的所有界面字符串。所有标签默认均为英文。

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 参考

PropTypeDefaultDescription
setPage*(page: number) => void-Callback when page changes
pagenumber-Current page number (1-indexed).
perPagenumber-Number of items displayed per page.
totalCountnumber-Total number of items across all pages.
hasNextPageboolean-Whether another page exists when the total count is unknown. Ignored when `totalCount` is provided. Unknown totals use sequential controls only.
classNamestring-Additional CSS classes for the container
labelsPaginationLabels-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
childrenReactNode-Compound component children for custom layouts. Use Pagination.Info, Pagination.PageSize, Pagination.Controls, and Pagination.Separator.
controls"full" | "simple""full"-
textobject--