Pagination
Navigation controls for moving through pages of records with responsive sizing and server-friendly callbacks.
Pagination gives users a compact way to move through a finite collection of pages. It supports client-side and server-side data flows, controlled and uncontrolled state, quick jumping, condensed ranges, loading states, and accessible navigation labels.
Basic usage
Use totalPages when the data source already knows the number of pages:
const [page, setPage] = useState(1);
<Pagination
current={page}
totalPages={24}
onChange={(nextPage) => setPage(nextPage)}
/>Use defaultCurrent for an internally managed current page. onChange receives the next page, which makes it suitable for loading a new server response.
Total records
Pass totalItems and a fixed pageSize when the API returns a record count rather than a page count. totalPages takes precedence when both are supplied. Pagination does not render a page-size selector; the parent data layer owns the fixed page size:
<Pagination
totalItems={247}
pageSize={20}
onChange={(page) => loadRecords({ page, size: 20 })}
/>Page ranges and condensed navigation
Long ranges automatically display boundary pages and ellipses. Tune the visible range with boundaryCount and siblingCount:
<Pagination
current={12}
totalPages={100}
boundaryCount={2}
siblingCount={2}
firstLast
/>The first and last controls are shown by default. Set firstLast={false} for a compact previous/next-only control. Ellipsis controls jump across the hidden range and remain keyboard accessible.
Previous/next-only mode
Set mode="steps" when users should move one page at a time without displaying the numbered page list. By default, the mode includes First, Previous, Next and Last controls; set firstLast={false} if only Previous and Next are needed. The controls remain disabled at the relevant boundaries. This mode works with controlled or uncontrolled pagination, loading, disabled states and optional page information.
<Pagination
mode="steps"
current={page}
totalPages={12}
onChange={(nextPage) => setPage(nextPage)}
firstLabel="First"
previousLabel="Back"
nextLabel="Forward"
lastLabel="Last"
showPageInfo
pageInfo={`Step ${page} of 12`}
/>Quick jump and page information
showQuickJumper adds the framework's InputNumber component with its increment/decrement controls and the framework's Button component for confirmation. The InputNumber is configured with step={1}, min={1} and max={totalPages}. This keeps the jump value numeric, bounded and consistent with the rest of the form controls. showPageInfo adds a status label; provide pageInfo when the application needs record-specific text:
<Pagination
totalItems={1240}
pageSize={25}
showPageInfo
pageInfo="Items 101–125 of 1,240"
showQuickJumper
/>Full-width layout
Set fullWidth when Pagination should stretch across the available container. In this layout, page information stays on the left while the page controls and Go to quick navigation stay on the right. It is especially useful for toolbars and table footers.
<Pagination
current={page}
totalPages={25}
onChange={(nextPage) => setPage(nextPage)}
fullWidth
showPageInfo
pageInfo={`Showing page ${page} of 25`}
showQuickJumper
/>Localization
Pagination supports en, uk, de and fr. The locale translates navigation labels, page announcements, ellipsis actions, the Go to label and the confirmation button. A local locale prop takes precedence over the global ConfigProvider locale.
<Pagination locale="uk" totalPages={12} showQuickJumper />For an application-wide language, set the locale once on ConfigProvider; Pagination and Calendar will use it automatically:
<ConfigProvider locale="uk">
<Pagination totalPages={12} showQuickJumper />
<Calendar />
</ConfigProvider>Sizes, variants, and states
The component supports default, sm, and xs sizes. Visual variants are default and minimal. Use compact when the surrounding layout should keep the controls especially tight. The active page uses the shared --mm-color-primary token.
<Pagination size="default" totalPages={12} />
<Pagination size="sm" totalPages={12} />
<Pagination size="xs" variant="minimal" firstLast={false} totalPages={8} />
<Pagination loading totalPages={12} />
<Pagination disabled totalPages={12} />loading disables navigation and displays a spinner. disabled prevents all interaction. hideOnSinglePage returns no navigation when there is only one page.
Custom labels and rendering
Use previousLabel and nextLabel to replace the default icons. renderItem can replace the default numbered page buttons while preserving the calculated page range:
<Pagination
totalPages={8}
previousLabel="Previous"
nextLabel="Next"
renderItem={(item, active) => (
<button aria-current={active ? 'page' : undefined}>{item}</button>
)}
/>When using a custom renderer, the renderer owns the interaction and accessible attributes for numbered items. Ellipsis and previous/next controls remain managed by Pagination.
Accessibility
The component renders a nav landmark with an aria-label, native buttons, aria-current="page" on the active page, and explicit labels for first, previous, next, last, and ellipsis actions. Keyboard users can tab through controls and activate them with Enter or Space. Provide a more specific aria-label when a page contains multiple pagination regions.
API Reference
| Property | Type | Default | Description |
|---|---|---|---|
totalPages | number | — | Total number of pages. |
totalItems | number | 0 | Total records used to calculate pages. |
current | number | — | Controlled current page. |
defaultCurrent | number | 1 | Initial uncontrolled page. |
onChange | (page) => void | — | Called when the page changes. |
pageSize | number | 10 | Controlled records per page. |
siblingCount | number | 1 | Pages shown on each side of the current page. |
boundaryCount | number | 1 | Pages always shown at each boundary. |
firstLast | boolean | true | Shows first and last page buttons. |
firstLabel, lastLabel | ReactNode | first/last icons | Content of the first and last page buttons. |
showQuickJumper | boolean | false | Shows a direct page-number field. |
showPageInfo | boolean | false | Shows page status text. |
pageInfo | ReactNode | automatic | Custom page status content. |
hideOnSinglePage | boolean | false | Hides the component when there is one page. |
loading | boolean | false | Disables controls and shows a loading indicator. |
disabled | boolean | false | Disables all interaction. |
fullWidth | boolean | false | Stretches the paginator and places page information left and controls right. |
locale | en | uk | de | fr | ConfigProvider locale or en | Language for navigation labels and accessibility text. |
size | default | sm | xs | default | Control size. |
variant | default | minimal | default | Visual treatment. |
mode | pages | steps | pages | Shows numbered pages or only previous/next step controls. |
compact | boolean | false | Uses tighter spacing. It does not hide the page list; use mode="steps" for that. |
renderItem | (item, active) => ReactNode | — | Custom numbered-item renderer. |
previousLabel | ReactNode | previous icon | Previous control content. |
nextLabel | ReactNode | next icon | Next control content. |
aria-label | string | Pagination | Accessible name for the navigation landmark. |
className | string | — | Additional class on the navigation element. |
Theme tokens
Pagination uses shared tokens for text, surfaces, borders, focus, typography, and radius. Component-only layout rules are kept in Pagination.css.
| Token | Purpose |
|---|---|
--mm-color-text | Active page and control text. |
--mm-color-muted-text | Inactive page and informational text. |
--mm-color-placeholder | Disabled control text. |
--mm-color-control-filled | Hover and auxiliary control surfaces. |
--mm-color-primary | Active page background and text. |
--mm-color-primary-hover | Active page hover background. |
--mm-color-control-border | Outlined controls and native fields. |
--mm-color-primary | Active page background and loading color. |
--mm-color-focus | Keyboard focus ring. |
--mm-radius-control | Control radius. |