Paginator
A paginator component allows users to navigate through multiple pages of content by selecting page numbers or using previous/next controls.
<sl-paginator-status></sl-paginator-status>
<sl-paginator></sl-paginator>
<sl-paginator-page-size page-size="10" page-sizes="[5,10,15]"></sl-paginator-page-size>
<script>
// This is an example with manual management of the pagination state
const paginatorStatus = document.querySelector('sl-paginator-status');
const paginator = document.querySelector('sl-paginator');
const paginatorPageSize = document.querySelector('sl-paginator-page-size');
const students = Array.from({ length: 120 }).map((_, index) => `Student ${index + 1}`);
const update = ({ page, pageSize }) => {
if (typeof pageSize === 'number' && pageSize !== paginator.pageSize) {
page = 0;
} else {
page ??= paginator.page;
}
pageSize ??= paginator.pageSize;
paginator.page = paginatorPageSize.page = page;
paginator.pageSize = paginatorPageSize.pageSize = pageSize;
};
const onPageChange = ({ detail: page }) => update({ page });
const onPageSizeChange = ({ detail: pageSize }) => update({ pageSize });
paginator?.addEventListener('sl-page-change', onPageChange);
paginatorPageSize?.addEventListener('sl-page-size-change', onPageSizeChange);
paginator.totalItems = students.length;
paginatorStatus.totalItems = students.length;
paginatorStatus.itemLabel = 'students';
paginatorPageSize.itemLabel = 'Students';
</script>When to use
Large Datasets
When there is too much data to display within a single page or component view, and you want to break it into manageable chunks so users can scan, compare, and keep their place more easily. Also when loading all available data at once would be slow, heavy or resource-intensive, and you need to keep performance predictable.
Precise Navigation
When users need explicit control over where they are in a list, for example, jumping to a specific page, returning to a remembered page number, or sharing a URL that always opens the same subset of results.
When not to use
Linear Journeys Flows
For multi-step processes such as forms, wizards, or checkout flows where the user should move forward or backward step by step. In these cases, use buttons or a progress indicator instead of paginator.
Short, Small, or Simple Content
When the content fits comfortably on a single page without performance issues, or when the dataset is small gives a simpler, more natural experience.
Anatomy
Page Size
Control that lets users choose how many items are shown per page. Changing this value recalculates the total number of pages.
| Item | Name | Description | Optional |
|---|---|---|---|
| 1 | Label | Text that describes the page size control (e.g. “Items per page”). | yes |
| 2 | Select | Dropdown used to choose how many items are displayed per page. | yes |
Paginator
The main navigation for moving across pages.
| Item | Name | Description | Optional |
|---|---|---|---|
| 1 | Prev/Next buttons | Move one page backward or forward. Previous is disabled on the first page, and Next is disabled on the last page. | yes |
| 2 | Page Button | A numbered button that takes the user to a specific page. | yes |
| 3 | Selected page | The current page, visually highlighted. | yes |
| 4 | Overflow Button | A menu button that exposes hidden pages when there are more pages than can be displayed at once. | yes |
Status
Text that communicates where the user is in the full result set, typically:
| Item | Name | Description | Optional |
|---|---|---|---|
| 1 | Range Items | Text element that displays the current range, the start and end of it. | yes |
| 2 | Total Items | Text element that displays the total. | yes |
| 3 | Items Label | Text that describes the items in the range (e.g. “items”, “results”). | yes |
Widths
Control how many page buttons are visible at once before pages are moved into the overflow menu.
- LG: Shows up to 13 page items in a single row.
- MD: Shows up to 11 page items.
- SM: Shows up to 9 page items.
- XS: When the available space is very limited, page buttons are replaced by a single select field so users can pick a page from a dropdown.
Use wider versions when the Paginator is a primary control, for example, at the bottom of a data table and narrower versions when space is constrained or the pagination is secondary.
Emphasis
The Paginator supports two emphasis levels:
- Subtle: Low-contrast styling that keeps pagination in the background while still discoverable. Use when pagination is supportive, not the main focus of the page.
- Bold: Higher visual weight for cases where pagination is a primary navigation element or is critical to the user’s workflow.
Choose the emphasis that matches the visual hierarchy of surrounding content.
Sizes
The Paginator offers three control sizes:
- Large: For dense layouts, large data tables or touch-first experiences where targets need to be easier to hit.
- Medium: The default size for most use cases and general content pages.
- Small: For compact layouts, side panels, or areas where vertical space is limited.
Ideally, match the Paginator size to the height of related controls, for example, table rows or filter inputs.
Figma Options
With these options, you can tweak the appearance of the paginator in Figma. They are available in the Design Panel so you can compose the paginator to exactly fit the user experience need for the use case you are working on.
Paginator
| Item | Options | Description |
|---|---|---|
| Size | lg, md, sm | Sets the paginator control size. |
| Width | lg, md, sm, xs | Defines how many page buttons are visible before overflow. |
| Emphasis | subtle, bold | Sets the visual impact style. |
| Arrow Start | boolean | Controls visibility of the previous-page arrow. |
| Overflow Start | boolean | Controls visibility of the leading overflow. |
| Overflow End | boolean | Controls visibility of the trailing overflow. |
| Arrow End | boolean | Controls visibility of the next-page arrow. |
Paginator Status
| Item | Options | Description |
|---|---|---|
| Item label | text | Text label used for items (e.g. “items”, students). |
| Total Range | number | Total number of items in the dataset. |
| High Range | number | Last item index displayed on the current page. |
| Low Range | number | First item index displayed on the current page. |
Paginator Size
| Item | Options | Description |
|---|---|---|
| Item label | text | Change the "Items" label for the page size control. |
Behaviours
Keyboard navigation
Users can move through the Paginator with the keyboard using Tab and Shift+Tab to follow a logical focus order across controls, and use Enter or Space to activate Previous and Next, select a page, or open and confirm options in overflow menus, while arrow keys help navigate within any the overflow dropdown.
Overflow pages
When there are more pages than can be shown at once, hidden pages are moved into an overflow menu represented by an ellipsis, which adapts depending on the current page (start or end of the range) while keeping the overall layout stable and avoiding any width changes.
Responsive behaviour
On larger viewports, the Paginator can show more page buttons alongside Previous and Next, while on smaller or constrained layouts it reduces the number of visible pages and, at the narrowest widths, can replace numbered buttons with a page select field to keep pagination usable and readable on mobile.
Related components
- Text Field: If you want a free-form text input.
- Select: Selecting from predefined numeric options.
<sl-paginator-status id="status"></sl-paginator-status>
<sl-paginator id="paginator"></sl-paginator>
<sl-paginator-page-size id="page-size" page-sizes="[5,10,15,20]"></sl-paginator-page-size>
<script>
// This is an example with DataSource managing the pagination state
import { ArrayListDataSource } from '@sl-design-system/data-source';
const paginatorStatus = document.querySelector("#status");
const paginator = document.querySelector("#paginator");
const pageSize = document.querySelector("#page-size");
const exams = Array.from({ length: 60 }).map((_, index) => `Exam ${index + 1}`);
const ds = new ArrayListDataSource(exams, {
pagination: true,
page: 1,
pageSize: 10
});
paginatorStatus.dataSource = ds;
paginator.dataSource = ds;
pageSize.dataSource = ds;
</script>Using data source with paginator
A data source is an interface that manages data fetching, state, and pagination logic. It allows you to connect paginator components to your data in a consistent way, whether that data comes from an API, an in memory array, or any other source.
Setting up a data source
To use a data source with the paginator components, follow these steps:
- Create a data source instance - Use
FetchListDataSourcefor API based data orArrayListDataSourcefor in memory arrays. You can also implement your own data source by extending the ListDataSource class and implementing the required methods. - Configure pagination settings - Set
pageSizeand enablepagination. - Implement data fetching - Define the
fetchPagemethod to retrieve data for each page (for API based data). - Connect to components - Assign the same data source instance to
sl-paginator,sl-paginator-status, andsl-paginator-page-size.
Example
const ds = new FetchListDataSource({
pageSize: 10,
pagination: true,
fetchPage: async ({ page, pageSize }) => {
const response = await fetch(
`https://api.example.com/data?skip=${page * pageSize}&limit=${pageSize}`
);
if (response.ok) {
const { items, total } = await response.json();
return { items, totalItems: total };
} else {
throw new FetchListDataSourceError('Failed to fetch data', response);
}
}
});
// Connect the data source to all paginator components
paginatorStatus.dataSource = ds;
paginator.dataSource = ds;
pageSize.dataSource = ds;Once connected, the paginator components will automatically:
- Display the correct page information
- Fetch new data when users navigate between pages
- Update when the page size changes
- Show the total number of items and current range
Paginator page size API
Paginator page size component provides properties to configure available page size options and current selection.
Properties
| Name | Attribute | Type | Default | Description |
|---|---|---|---|---|
dataSource | - | ListDataSource<T> | undefined | By setting a dataSource, the paginator will listen for changes on the data source and control the data source when the user selects a new page in the component. This can be very useful when the paginator is used in combination with a data source-driven component, such as <sl-grid>. | |
itemLabel | - | string | undefined | The label to display for the 'items' per page selector. If not set, defaults to "Items". You can use this to set a custom label, such as "Students" or "Books" or something else. Please remember to provide a translation for the label in your application. | |
pageSize | page-size | number | Items per page. | |
pageSizes | page-sizes | number[] | undefined | Available page sizes. |
Events
| Name | Event type | Description |
|---|---|---|
sl-page-size-change | SlChangeEvent<number> | Emits when the page size has been selected/changed. |
Paginator API
The paginator component offers settings for various scenarios.
Properties
| Name | Attribute | Type | Default | Description |
|---|---|---|---|---|
dataSource | - | ListDataSource<T> | undefined | By setting a dataSource, the paginator will listen for changes on the data source and control the data source when the user selects a new page in the component. This can be very useful when the paginator is used in combination with a data source-driven component, such as <sl-grid>. | |
emphasis | emphasis | 'subtle' | 'bold' | undefined | 'subtle' | The emphasis style. |
page | page | number | 0 | Current page. |
pageSize | page-size | LIST_DATA_SOURCE_DEFAULT_PAGE_SIZE | Items per page. Default to the first item of pageSizes. | |
size | size | 'sm' | 'md' | 'lg' | undefined | 'md' | The size of the paginator which determines the size of the elements in it. |
totalItems | total-items | number | 1 | Total number of items. |
width | width | 'xs' | 'sm' | 'md' | 'lg' | undefined | The width of the paginator. This is used to determine how many pages are visible at once. For xs a select component will be used to select the page. For all other widths, buttons will be used. |
Events
| Name | Event type | Description |
|---|---|---|
sl-page-change | SlChangeEvent<number> | Emits when the page has been changed. |
Paginator status API
Paginator status component displays pagination information using page, pageSize, and totalItems properties.
Properties
| Name | Attribute | Type | Default | Description |
|---|---|---|---|---|
dataSource | - | ListDataSource<T> | undefined | By setting a dataSource, the component will listen for changes on the data source and control the data source when the user selects a new page size in the component. | |
itemLabel | - | string | undefined | The label to display for the 'items'. If not set, defaults to "Items". You can use this to set a custom label, such as "students" or "books" or something else. Please remember to provide a translation for the label in your application. | |
page | page | number | 0 | Current page. |
pageSize | page-size | LIST_DATA_SOURCE_DEFAULT_PAGE_SIZE | Items per page. | |
totalItems | total-items | number | 1 | Total number of items. |
Keyboard interactions
The paginator provides full keyboard navigation to move between the pages of a list:
| Command | Description |
|---|---|
Tab | Moves focus through the paginator controls: previous button, page buttons, next button, and page select dropdown (on smaller widths). |
Shift + Tab | Moves focus backward through the paginator controls. |
Enter or Space | Activates the focused button to navigate to the selected page, or opens the page select dropdown. |
Arrow keys | When the page select dropdown is focused, use up/down arrows to navigate between page options. |
Announcements
The paginator provides screen reader announcements for important state changes:
- Page changes: When navigating between pages using previous/next buttons or selecting a page directly, the new page number and total pages are announced.
- Page size changes: When changing the number of items per page, the new page size is announced to inform users of the updated display.
- Status updates: When the page, page size, or total items change, the current page range and total item count are immediately announced to screen readers to provide context about the displayed content.
These announcements help users understand pagination changes without needing to navigate back to check the current state.
WAI-ARIA
In the component itself we use multiple aria-attributes to assure the component works well with a range of assistive technologies. For some attributes however it is not possible for the Design System to add a meaningful value, because it relies on the context or way a component is used.
Attributes that we recommend you add in certain scenarios are mentioned below.
Paginator
| Attribute | Value | Description |
|---|---|---|
aria-label | string | Labels the navigation region. Defaults to "Pagination" if not provided. |