Paginator
A paginator steps through data shown in pages and tells readers where they are in the set. It holds only the numbers and fires an event on each move, so your page decides which rows to show. The paginators below are live, so press the arrows and watch the position change.
Reference docs
Built in
- It works out the page count from
anditem-count , and shows the range on screen, such as 1-10 of 100.items-per-page adds a page size select and sets the starting page size.items-per-page-selection andpositionFormatter replace the range text and the page size options, for another language or wording.itemsPerPageFormatter- First, previous, next, and last buttons step through the pages, and each press fires an event.
Using paginators well
- Put the paginator at the end of the table or list it pages, aligned to the trailing edge.
- Set
when the paginator sits inside a table that already draws a border.no-border - Set
for the page size you want, or giveitems-per-page and let its first value apply.items-per-page-selection - Slice or fetch the rows in your own listener, and read
from the paginator when the page size changes.page-number - Keep the default range text, in the form first-last of total, and replace it with
only to translate it.positionFormatter
These rules follow Material 3 Expressive's guidance for data tables, on material.io.
Position and pages
item-countitems-per-page
page-numberpage-number="2" is the third page. The range text and the live region count from 1. Setting it beyond the last page moves it back to the last one, and fires no event.
items-per-pageitem-count
Page size
items-per-page-selection
Changing the size keeps the reader near the same items and fires items-per-page-change. No page-number-change fires for the recomputed page, so read page-number
positionFormatteritemsPerPageFormatter
Moving by code
firstPagepreviousPagenextPagelastPagepage-number-change with the new pageNumber when the page changes, and does nothing at an end or while the paginator is disabled.
Setting page-numberpage-number
Disabled
disabled
In a bordered table
The paginator draws a border along its top edge. Set no-border
Properties
| Property | Attribute | Type | Description |
|---|---|---|---|
disabled | disabled | booleandefault false | Whether the paginator controls are disabled. When disabled, the navigation buttons and select are non-interactive, and firstPage(), previousPage(), nextPage() and lastPage() do nothing. See Disabled. |
itemCount | item-count | numberdefault 0 | Total number of items being paginated. Used to calculate the number of pages and position display. See Position and pages. |
itemsPerPage | items-per-page | numberdefault 12 | The number of items on a page. When items-per-page-selection is set and does not offer this number, the paginator takes that list's first value. See Position and pages. |
itemsPerPageFormatter | (itemsPerPage: number) => Promise<string> | Custom formatter for the items-per-page display text. Receives the current items per page value, returns a promise of the display string. The text shows its default (or the last formatted text) until the promise resolves; a result for a replaced formatter is ignored. Useful for localization (e.g., async (n) => n + " éléments par page"). See Page size. | |
itemsPerPageSelection | items-per-page-selection | number[]default [] | Available options for items per page in the dropdown. Example: [10, 25, 50, 100]. The select dropdown is hidden if only one option. See Page size. |
noBorder | no-border | booleandefault false | Hides the top border. Set to true when used inside a data table that already has borders. See In a bordered table. |
pageNumber | page-number | numberdefault 0 | The current page, counted from 0. Set it to change page from code. Setting it fires no event, and a value out of range is clamped to the first or last page. See Position and pages, Page size, Moving by code. |
positionFormatter | (first: number, last: number, total: number) => Promise<string> | Custom formatter for the position display text. Receives first item index, last item index, and total count, returns a promise of the display string. The text shows its default (or the last formatted text) until the promise resolves; a result for a replaced formatter is ignored. Useful for localization (e.g., async (f, l, t) => f + "-" + l + " sur " + t). See Page size. |
Events
| Event | Type | Detail | Description |
|---|---|---|---|
page-number-change | PageNumberChangeEvent | PageNumberChangeEventDetail | When the page changes through a button or a page method. It bubbles and is composed. |
items-per-page-change | ItemsPerPageChangeEvent | ItemsPerPageChangeEventDetail | When the user chooses a different items-per-page value. The page number is recomputed without a page-number-change event. It bubbles and is composed. |
Methods
| Method | Returns | Description |
|---|---|---|
firstPage() | void | Goes to the first page, firing page-number-change if the page changes. Does nothing while disabled is set. |
lastPage() | void | Goes to the last page, firing page-number-change if the page changes. Does nothing while disabled is set. |
nextPage() | void | Goes to the next page, firing page-number-change if the page changes. Does nothing while disabled is set. |
previousPage() | void | Goes to the previous page, firing page-number-change if the page changes. Does nothing while disabled is set. |
Props
| Prop | Type | Description |
|---|---|---|
disabled | booleandefault false | Whether the paginator controls are disabled. When disabled, the navigation buttons and select are non-interactive, and firstPage(), previousPage(), nextPage() and lastPage() do nothing. See Disabled. |
itemCount | numberdefault 0 | Total number of items being paginated. Used to calculate the number of pages and position display. See Position and pages. |
itemsPerPage | numberdefault 12 | The number of items on a page. When itemsPerPageSelection is set and does not offer this number, the paginator takes that list's first value. See Position and pages. |
itemsPerPageFormatter | (itemsPerPage: number) => Promise<string> | Custom formatter for the items-per-page display text. Receives the current items per page value, returns a promise of the display string. The text shows its default (or the last formatted text) until the promise resolves; a result for a replaced formatter is ignored. Useful for localization (e.g., async (n) => n + " éléments par page"). See Page size. |
itemsPerPageSelection | number[]default [] | Available options for items per page in the dropdown. Example: [10, 25, 50, 100]. The select dropdown is hidden if only one option. See Page size. |
noBorder | booleandefault false | Hides the top border. Set to true when used inside a data table that already has borders. See In a bordered table. |
pageNumber | numberdefault 0 | The current page, counted from 0. Set it to change page from code. Setting it fires no event, and a value out of range is clamped to the first or last page. See Position and pages, Page size, Moving by code. |
positionFormatter | (first: number, last: number, total: number) => Promise<string> | Custom formatter for the position display text. Receives first item index, last item index, and total count, returns a promise of the display string. The text shows its default (or the last formatted text) until the promise resolves; a result for a replaced formatter is ignored. Useful for localization (e.g., async (f, l, t) => f + "-" + l + " sur " + t). See Page size. |
Events
| Prop | Argument | Description |
|---|---|---|
onPageNumberChange | PageNumberChangeEvent | When the page changes through a button or a page method. It bubbles and is composed. Its detail carries pageNumber. |
onItemsPerPageChange | ItemsPerPageChangeEvent | When the user chooses a different items-per-page value. The page number is recomputed without a page-number-change event. It bubbles and is composed. Its detail carries itemsPerPage. |
Methods
Call these on the element the ref holds.
| Method | Returns | Description |
|---|---|---|
firstPage() | void | Goes to the first page, firing page-number-change if the page changes. Does nothing while disabled is set. |
lastPage() | void | Goes to the last page, firing page-number-change if the page changes. Does nothing while disabled is set. |
nextPage() | void | Goes to the next page, firing page-number-change if the page changes. Does nothing while disabled is set. |
previousPage() | void | Goes to the previous page, firing page-number-change if the page changes. Does nothing while disabled is set. |
Parameters
| Parameter | Type | Description |
|---|---|---|
Disabled | bool?default false | Whether the paginator controls are disabled. When disabled, the navigation buttons and select are non-interactive, and firstPage(), previousPage(), nextPage() and lastPage() do nothing. See Disabled. |
ItemCount | int?default 0 | Total number of items being paginated. Used to calculate the number of pages and position display. See Position and pages. |
ItemsPerPage | int?default 12 | The number of items on a page. When ItemsPerPageSelection is set and does not offer this number, the paginator takes that list's first value. See Position and pages. |
ItemsPerPageFormatter | Func<int, Task<string>>? | Custom formatter for the items-per-page display text. Receives the current items per page value, returns a promise of the display string. The text shows its default (or the last formatted text) until the promise resolves; a result for a replaced formatter is ignored. Useful for localization (e.g., async (n) => n + " éléments par page"). See Page size. |
ItemsPerPageSelection | IEnumerable<int>?default [] | Available options for items per page in the dropdown. Example: [10, 25, 50, 100]. The select dropdown is hidden if only one option. See Page size. |
NoBorder | bool?default false | Hides the top border. Set to true when used inside a data table that already has borders. See In a bordered table. |
PageNumber | int?default 0 | The current page, counted from 0. Set it to change page from code. Setting it fires no event, and a value out of range is clamped to the first or last page. See Position and pages, Page size, Moving by code. |
PositionFormatter | Func<int, int, int, Task<string>>? | Custom formatter for the position display text. Receives first item index, last item index, and total count, returns a promise of the display string. The text shows its default (or the last formatted text) until the promise resolves; a result for a replaced formatter is ignored. Useful for localization (e.g., async (f, l, t) => f + "-" + l + " sur " + t). See Page size. |
Event callbacks
| Parameter | Type | Description |
|---|---|---|
OnPageNumberChange | EventCallback<PageNumberChangeEventArgs> | When the page changes through a button or a page method. It bubbles and is composed. Its detail carries PageNumber. |
OnItemsPerPageChange | EventCallback<ItemsPerPageChangeEventArgs> | When the user chooses a different items-per-page value. The page number is recomputed without a page-number-change event. It bubbles and is composed. Its detail carries ItemsPerPage. |
Inputs
| Input | Type | Description |
|---|---|---|
disabled | booleandefault false | Whether the paginator controls are disabled. When disabled, the navigation buttons and select are non-interactive, and firstPage(), previousPage(), nextPage() and lastPage() do nothing. See Disabled. |
itemCount | numberdefault 0 | Total number of items being paginated. Used to calculate the number of pages and position display. See Position and pages. |
itemsPerPage | numberdefault 12 | The number of items on a page. When itemsPerPageSelection is set and does not offer this number, the paginator takes that list's first value. See Position and pages. |
itemsPerPageFormatter | (itemsPerPage: number) => Promise<string> | Custom formatter for the items-per-page display text. Receives the current items per page value, returns a promise of the display string. The text shows its default (or the last formatted text) until the promise resolves; a result for a replaced formatter is ignored. Useful for localization (e.g., async (n) => n + " éléments par page"). See Page size. |
itemsPerPageSelection | number[]default [] | Available options for items per page in the dropdown. Example: [10, 25, 50, 100]. The select dropdown is hidden if only one option. See Page size. |
noBorder | booleandefault false | Hides the top border. Set to true when used inside a data table that already has borders. See In a bordered table. |
pageNumber | numberdefault 0 | The current page, counted from 0. Set it to change page from code. Setting it fires no event, and a value out of range is clamped to the first or last page. See Position and pages, Page size, Moving by code. |
positionFormatter | (first: number, last: number, total: number) => Promise<string> | Custom formatter for the position display text. Receives first item index, last item index, and total count, returns a promise of the display string. The text shows its default (or the last formatted text) until the promise resolves; a result for a replaced formatter is ignored. Useful for localization (e.g., async (f, l, t) => f + "-" + l + " sur " + t). See Page size. |
Outputs
| Output | Event | Description |
|---|---|---|
cwPageNumberChange | PageNumberChangeEvent | When the page changes through a button or a page method. It bubbles and is composed. Its detail carries pageNumber. |
cwItemsPerPageChange | ItemsPerPageChangeEvent | When the user chooses a different items-per-page value. The page number is recomputed without a page-number-change event. It bubbles and is composed. Its detail carries itemsPerPage. |
Props
| Prop | Type | Description |
|---|---|---|
disabled | booleandefault false | Whether the paginator controls are disabled. When disabled, the navigation buttons and select are non-interactive, and firstPage(), previousPage(), nextPage() and lastPage() do nothing. See Disabled. |
itemCount | numberdefault 0 | Total number of items being paginated. Used to calculate the number of pages and position display. See Position and pages. |
itemsPerPage | numberdefault 12 | The number of items on a page. When itemsPerPageSelection is set and does not offer this number, the paginator takes that list's first value. See Position and pages. |
itemsPerPageFormatter | (itemsPerPage: number) => Promise<string> | Custom formatter for the items-per-page display text. Receives the current items per page value, returns a promise of the display string. The text shows its default (or the last formatted text) until the promise resolves; a result for a replaced formatter is ignored. Useful for localization (e.g., async (n) => n + " éléments par page"). See Page size. |
itemsPerPageSelection | number[]default [] | Available options for items per page in the dropdown. Example: [10, 25, 50, 100]. The select dropdown is hidden if only one option. See Page size. |
noBorder | booleandefault false | Hides the top border. Set to true when used inside a data table that already has borders. See In a bordered table. |
pageNumber | numberdefault 0 | The current page, counted from 0. Set it to change page from code. Setting it fires no event, and a value out of range is clamped to the first or last page. See Position and pages, Page size, Moving by code. |
positionFormatter | (first: number, last: number, total: number) => Promise<string> | Custom formatter for the position display text. Receives first item index, last item index, and total count, returns a promise of the display string. The text shows its default (or the last formatted text) until the promise resolves; a result for a replaced formatter is ignored. Useful for localization (e.g., async (f, l, t) => f + "-" + l + " sur " + t). See Page size. |
Events
| Event | Type | Description |
|---|---|---|
pageNumberChange | PageNumberChangeEvent | When the page changes through a button or a page method. It bubbles and is composed. Its detail carries pageNumber. |
itemsPerPageChange | ItemsPerPageChangeEvent | When the user chooses a different items-per-page value. The page number is recomputed without a page-number-change event. It bubbles and is composed. Its detail carries itemsPerPage. |
Props
| Prop | Type | Description |
|---|---|---|
disabled | booleandefault false | Whether the paginator controls are disabled. When disabled, the navigation buttons and select are non-interactive, and firstPage(), previousPage(), nextPage() and lastPage() do nothing. See Disabled. |
itemCount | numberdefault 0 | Total number of items being paginated. Used to calculate the number of pages and position display. See Position and pages. |
itemsPerPage | numberdefault 12 | The number of items on a page. When itemsPerPageSelection is set and does not offer this number, the paginator takes that list's first value. See Position and pages. |
itemsPerPageFormatter | (itemsPerPage: number) => Promise<string> | Custom formatter for the items-per-page display text. Receives the current items per page value, returns a promise of the display string. The text shows its default (or the last formatted text) until the promise resolves; a result for a replaced formatter is ignored. Useful for localization (e.g., async (n) => n + " éléments par page"). See Page size. |
itemsPerPageSelection | number[]default [] | Available options for items per page in the dropdown. Example: [10, 25, 50, 100]. The select dropdown is hidden if only one option. See Page size. |
noBorder | booleandefault false | Hides the top border. Set to true when used inside a data table that already has borders. See In a bordered table. |
pageNumber | numberdefault 0 | The current page, counted from 0. Set it to change page from code. Setting it fires no event, and a value out of range is clamped to the first or last page. See Position and pages, Page size, Moving by code. |
positionFormatter | (first: number, last: number, total: number) => Promise<string> | Custom formatter for the position display text. Receives first item index, last item index, and total count, returns a promise of the display string. The text shows its default (or the last formatted text) until the promise resolves; a result for a replaced formatter is ignored. Useful for localization (e.g., async (f, l, t) => f + "-" + l + " sur " + t). See Page size. |
Events
| Prop | Type | Description |
|---|---|---|
onPageNumberChange | PageNumberChangeEvent | When the page changes through a button or a page method. It bubbles and is composed. Its detail carries pageNumber. |
onItemsPerPageChange | ItemsPerPageChangeEvent | When the user chooses a different items-per-page value. The page number is recomputed without a page-number-change event. It bubbles and is composed. Its detail carries itemsPerPage. |
Names and states
A screen reader announces the paginator as a navigation landmark holding a group of controls. It follows no single WAI-ARIA Authoring Practices pattern: its buttons follow the WAI-ARIA Authoring Practices: Button pattern, and its page size field is an ordinary select.
- The landmark takes its name from an
aria-labelon the paginator, and is "Pagination navigation" when none is set. Give each paginator its ownaria-labelwhen two share a page, such as a table with controls above and below. - Only
aria-labeltakes effect on the paginator. Any otheraria-*attribute has no effect. - The controls sit in a group named "Pagination controls". The four buttons are named "First page", "Previous page", "Next page", and "Last page", and the select is named "Items per page". These names are fixed English text with no setting.
- A screen reader announces "Page N of M" each time the page changes.
andpositionFormatter do not reach it, so a translated page still has English there.itemsPerPageFormatter takes every control out of the Tab order. The first and previous buttons disable on the first page, and the next and last buttons on the last.disabled
Keyboard and focus
| Key | Action |
|---|---|
| Tab | Moves focus through the enabled buttons and the select, and on to the next control |
| Enter | Activates the focused button |
| Space | Activates the focused button |
Tab, Enter, and Space work as they do on any button. The paginator adds no arrow, Home or End keys, so each button is its own Tab stop; the select's keys are the select's own.
- A focus ring shows on keyboard focus.
- A disabled button leaves the Tab order, so focus skips first and previous on the first page, and next and last on the last.
Pointer and touch
- The page buttons are icon buttons, and the paginator sets no touch target of its own, so their size follows the icon button's touch target setting. The row itself is 48 pixels tall.
Display settings
- Forced colors: the buttons and select follow the system colors.
- Reduced motion: the paginator adds no motion of its own.
- In a right-to-left layout the four icons mirror and the row's order reverses.
Standards
With its defaults, the paginator meets four WCAG 2.2 success criteria:
- 1.3.1 Info and Relationships (A)
- 2.1.1 Keyboard (A)
- 2.4.7 Focus Visible (AA)
- 4.1.2 Name, Role, Value (A)
Two more depend on how you use it: