Pagination
Pagination moves through the pages of a long list: arrows, page numbers with ellipses that jump over the hidden pages, and optionally a page size picker and a field to type a page. It is a <nav> landmark; the current page carries aria-current="page" and every item has a name (“Page 3”, “Next page”, “Jump forward to page 8”).
Demos
Basic
Simple
simple replaces the page list with a field holding the current page and the total. Type a page and press Enter or leave the field.
Page slot
pageSlot is how many slots the page list takes, ellipses included. Hover or focus an ellipsis to see which way it jumps.
Quick jumper
showQuickJumper adds a field to type a page. It jumps on Enter or on blur, clamped to the page range.
Size
small, medium and large match the control heights, so the size picker and the jumper line up with the pages.
Page size picker
With itemCount the page count follows from the page size. showSizePicker lets the user pick it from pageSizes; when larger pages leave fewer of them, the page moves back into range. Both page and pageSize can be controlled.
Disabled
Prefix and suffix
prefix and suffix take a node or a function of the pagination’s state: page, pageSize, pageCount, itemCount, startIndex and endIndex.
Custom arrows and labels
prev, next and goto replace the arrows and the jumper’s text; label renders a page or an ellipsis. The accessible names stay the same.
Display order
displayOrder orders the page list, the size picker and the quick jumper.
Links
getHref(page) turns every page, arrow and ellipsis into an <a href>, so crawlers can follow the pages and a middle click opens one in a new tab. A plain click still calls onUpdatePage; a modified click only follows the link. The arrows get rel="prev" / rel="next", and a disabled arrow loses its href.
Router links
renderItem(props, info) renders each item yourself, e.g. with your router’s Link: spread props on it (class, accessible name, aria-current, href and the click handler). The handler runs first, so the router can still navigate without a reload.
Pagination Props
| Name | Type | Default | Description | Version |
|---|---|---|---|---|
page | number | undefined | Current page, from 1, when controlled. | Unreleased |
defaultPage | number | 1 | Initial page when uncontrolled. | Unreleased |
onUpdatePage | (page: number) => void | undefined | Called with the new page. | Unreleased |
pageCount | number | 1 | Total pages. Ignored when itemCount is set. | Unreleased |
itemCount | number | undefined | Total items; the page count follows from it and the page size. | Unreleased |
pageSize | number | undefined | Items per page when controlled. | Unreleased |
defaultPageSize | number | first of pageSizes, else 10 | Initial page size when uncontrolled. | Unreleased |
onUpdatePageSize | (pageSize: number) => void | undefined | Called with the new page size. | Unreleased |
pageSizes | Array<number | PaginationSizeOption> | [10] | Choices in the size picker. A number is labelled “10 / page”. | Unreleased |
showSizePicker | boolean | false | Shows a page size picker. | Unreleased |
selectProps | Partial<SelectProps> | undefined | More props for the size picker’s Select. | Unreleased |
showQuickJumper | boolean | false | Shows a field to type a page to go to. | Unreleased |
pageSlot | number | 9 | How many slots the page list takes, ellipses included. | Unreleased |
simple | boolean | false | A field with the current page and the total instead of the page list. | Unreleased |
disabled | boolean | false | Disables every control. | Unreleased |
size | small | medium | large | medium | Item, picker and field size. | Unreleased |
displayOrder | Array<'pages' | 'size-picker' | 'quick-jumper'> | ['pages', 'size-picker', 'quick-jumper'] | Order of the parts. | Unreleased |
prefix | ReactNode | (info: PaginationInfo) => ReactNode | undefined | Before everything. | Unreleased |
suffix | ReactNode | (info: PaginationInfo) => ReactNode | undefined | After everything. | Unreleased |
prev | ReactNode | (info: PaginationInfo) => ReactNode | undefined | Replaces the previous-page arrow. | Unreleased |
next | ReactNode | (info: PaginationInfo) => ReactNode | undefined | Replaces the next-page arrow. | Unreleased |
goto | ReactNode | () => ReactNode | locale’s “Go to” | The quick jumper’s text. | Unreleased |
label | (info: PaginationLabelInfo) => ReactNode | undefined | Content of a page or an ellipsis. | Unreleased |
getHref | (page: number) => string | undefined | Link mode: items become <a href>. | Unreleased |
renderItem | (props: PaginationItemProps, info: PaginationItemInfo) => ReactNode | undefined | Renders an item’s element yourself. | Unreleased |
Other attributes, such as aria-label, go to the root <nav>.
Types
type PaginationInfo = {
page: number;
pageSize: number;
pageCount: number;
itemCount: number; // `itemCount`, or pageCount × pageSize
startIndex: number; // first item on the page, from 0
endIndex: number; // last item on the page
};
type PaginationLabelInfo =
| { type: "page"; node: number; active: boolean }
| { type: "fast-backward" | "fast-forward"; node: ReactNode; active: false };
type PaginationItemInfo = {
type: "page" | "prev" | "next" | "fast-backward" | "fast-forward";
page: number; // where the item goes
active: boolean;
disabled: boolean;
href: string | undefined;
};
type PaginationItemProps = {
"aria-current": "page" | undefined;
"aria-disabled": true | undefined;
"aria-label": string;
children: ReactNode;
className: string;
href: string | undefined;
rel: "prev" | "next" | undefined;
onClick: (event: MouseEvent<HTMLElement>) => void;
};Notes
prefix,suffix,prev,nextandgototake a node or a render function.- The ellipses jump on click and name their target page.
- Sizes follow the control heights (28 / 34 / 40px), the same as the size picker and the jumper.