# Pagination URL: https://ark-ui.com/docs/components/pagination Source: https://raw.githubusercontent.com/chakra-ui/ark/refs/heads/main/website/src/content/pages/components/pagination.mdx A navigation component that allows users to browse through pages. --- ## Anatomy ```tsx ``` ## Examples **Example: basic** ```ripple import { Pagination } from 'ark-ripple/pagination'; import { ChevronLeft, ChevronRight } from 'lucide-ripple'; import styles from 'styles/pagination.module.css'; export component Basic() {
component children({ context }) { for (const [index, page] of @context.pages.entries(); key page.value) { if (page.type === 'page') { {page.value} } else { {'…'} } } }
} ``` ### Controlled To create a controlled Pagination component, manage the state of the current page using the `page` prop and update it when the `onPageChange` event handler is called: **Example: controlled** ```ripple import { track } from 'ripple'; import { Pagination } from 'ark-ripple/pagination'; import { ChevronLeft, ChevronRight } from 'lucide-ripple'; import styles from 'styles/pagination.module.css'; export component Controlled() { let currentPage = track(1); { @currentPage = details.page; }} class={styles.Root} >
component children({ context }) { for (const [index, page] of @context.pages.entries(); key page.value) { if (page.type === 'page') { {page.value} } else { {'…'} } } }
} ``` ### Root Provider An alternative way to control the pagination is to use the `RootProvider` component and the `usePagination` hook. This way you can access the state and methods from outside the component. **Example: root-provider** ```ripple import { Pagination, usePagination } from 'ark-ripple/pagination'; import { ChevronLeft, ChevronRight } from 'lucide-ripple'; import styles from 'styles/pagination.module.css'; export component RootProvider() { const pagination = usePagination({ count: 5000, pageSize: 10, siblingCount: 2 });
component children({ context }) { for (const [index, page] of @context.pages.entries(); key page.value) { if (page.type === 'page') { {page.value} } else { {'…'} } } }
} ``` ### Customization You can customize the Pagination component by setting various props such as `dir`, `pageSize`, `siblingCount`, and `translations`. Here's an example of a customized Pagination: **Example: customized** ```ripple import { Pagination } from 'ark-ripple/pagination'; import { ChevronLeft, ChevronRight } from 'lucide-ripple'; import styles from 'styles/pagination.module.css'; export component Customized() { `Page ${details.page}`, }} class={styles.Root} >
component children({ context }) { for (const [index, page] of @context.pages.entries(); key page.value) { if (page.type === 'page') { {page.value} } else { {'…'} } } }
} ``` ### Context Access pagination state and methods with `Pagination.Context` or the `usePaginationContext` hook. You get methods like `setPage`, `setPageSize`, `goToNextPage`, `goToPrevPage`, `goToFirstPage`, `goToLastPage`, as well as properties like `totalPages` and `pageRange`. **Example: context** ```ripple import { Pagination } from 'ark-ripple/pagination'; import { ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight } from 'lucide-ripple'; import styles from 'styles/pagination.module.css'; export component Context() { component children({ context }) {

{'Page '} {@context.page} {' of '} {@context.totalPages}

}
} ``` ### Data Slicing Use the `slice()` method to paginate actual data arrays. This method automatically slices your data based on the current page and page size. **Example: data-slicing** ```ripple import { Pagination } from 'ark-ripple/pagination'; import { ChevronLeft, ChevronRight } from 'lucide-ripple'; import styles from 'styles/pagination.module.css'; const users = [ { id: 1, name: 'Emma Wilson', email: 'emma@example.com' }, { id: 2, name: 'Liam Johnson', email: 'liam@example.com' }, { id: 3, name: 'Olivia Brown', email: 'olivia@example.com' }, { id: 4, name: 'Noah Davis', email: 'noah@example.com' }, { id: 5, name: 'Ava Martinez', email: 'ava@example.com' }, { id: 6, name: 'Ethan Garcia', email: 'ethan@example.com' }, { id: 7, name: 'Sophia Rodriguez', email: 'sophia@example.com' }, { id: 8, name: 'Mason Lee', email: 'mason@example.com' }, { id: 9, name: 'Isabella Walker', email: 'isabella@example.com' }, { id: 10, name: 'James Hall', email: 'james@example.com' }, { id: 11, name: 'Mia Allen', email: 'mia@example.com' }, { id: 12, name: 'Benjamin Young', email: 'benjamin@example.com' }, { id: 13, name: 'Charlotte King', email: 'charlotte@example.com' }, { id: 14, name: 'William Wright', email: 'william@example.com' }, { id: 15, name: 'Amelia Scott', email: 'amelia@example.com' }, { id: 16, name: 'Henry Green', email: 'henry@example.com' }, { id: 17, name: 'Harper Adams', email: 'harper@example.com' }, { id: 18, name: 'Sebastian Baker', email: 'sebastian@example.com' }, { id: 19, name: 'Evelyn Nelson', email: 'evelyn@example.com' }, { id: 20, name: 'Jack Carter', email: 'jack@example.com' }, ]; export component DataSlicing() { component children({ context }) {
for (const user of @context.slice(users); key user.id) {
{user.name} {user.email}
}
for (const [index, page] of @context.pages.entries(); key page.value) { if (page.type === 'page') { {page.value} } else { {'…'} } }
}
} ``` ### Page Range Display the current page range information using the `pageRange` property. This shows which items are currently visible (e.g., "Showing 1-10 of 100 results"). **Example: page-range** ```ripple import { Pagination } from 'ark-ripple/pagination'; import { ChevronLeft, ChevronRight } from 'lucide-ripple'; import styles from 'styles/pagination.module.css'; export component PageRange() { component children({ context }) {
for (const [index, page] of @context.pages.entries(); key page.value) { if (page.type === 'page') { {page.value} } else { {'…'} } }

{'Showing '} {@context.pageRange.start + 1} {'-'} {@context.pageRange.end} {' of '} {@context.count} {' results'}

{'Page '} {@context.page} {' of '} {@context.totalPages}

}
} ``` ### Page Size Control the number of items per page dynamically using `setPageSize()`. This example shows how to integrate a native select element to change the page size. > **Note:** For uncontrolled behavior, use `defaultPageSize` to set the initial value. For controlled behavior, use > `pageSize` and `onPageSizeChange` to programmatically manage the page size. **Example: page-size-control** ```ripple import { Pagination } from 'ark-ripple/pagination'; import { ChevronLeft, ChevronRight } from 'lucide-ripple'; import styles from 'styles/pagination.module.css'; export component PageSizeControl() { component children({ context }) {
for (const [index, page] of @context.pages.entries(); key page.value) { if (page.type === 'page') { {page.value} } else { {'…'} } }

{'Page '} {@context.page} {' of '} {@context.totalPages}

}
} ``` ### Links Create pagination with link navigation for better SEO and accessibility. This example shows how to use the pagination component with anchor links instead of buttons. **Example: link** ```ripple import { Pagination, usePagination } from 'ark-ripple/pagination'; import { ChevronLeft, ChevronRight } from 'lucide-ripple'; import styles from 'styles/pagination.module.css'; export component Link() { const pagination = usePagination( { type: 'link', count: 100, pageSize: 10, siblingCount: 2, getPageUrl: ({ page }) => `/page=${page}`, }, );
for (const [index, page] of @pagination.pages.entries(); key page.value) { if (page.type === 'page') { {page.value} } else { {'…'} } }
} ``` ## API Reference ### Props **Component API Reference** **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `boundaryCount` | `number` | No | Number of pages to show at the beginning and end | | `count` | `number` | No | Total number of data items | | `defaultPage` | `number` | No | The initial active page when rendered. Use when you don't need to control the active page of the pagination. | | `defaultPageSize` | `number` | No | The initial number of data items per page when rendered. Use when you don't need to control the page size of the pagination. | | `getPageUrl` | `(details: PageUrlDetails) => string` | No | Function to generate href attributes for pagination links. Only used when `type` is set to "link". | | `ids` | `Partial<{ root: string ellipsis: (index: number) => string firstTrigger: string prevTrigger: string nextTrigger: string lastTrigger: string item: (page: number) => string }>` | No | The ids of the elements in the accordion. Useful for composition. | | `onPageChange` | `(details: PageChangeDetails) => void` | No | Called when the page number is changed | | `onPageSizeChange` | `(details: PageSizeChangeDetails) => void` | No | Called when the page size is changed | | `page` | `number` | No | The controlled active page | | `pageSize` | `number` | No | The controlled number of data items per page | | `siblingCount` | `number` | No | Number of pages to show beside active page | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `type` | `'button' | 'link'` | No | The type of the trigger element | **Ellipsis Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **FirstTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **FirstTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | first-trigger | | `[data-disabled]` | Present when disabled | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `type` | `'page'` | Yes | | | `value` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | item | | `[data-index]` | The index of the item | | `[data-selected]` | Present when selected | **LastTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **LastTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | last-trigger | | `[data-disabled]` | Present when disabled | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | next-trigger | | `[data-disabled]` | Present when disabled | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | prev-trigger | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePaginationReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `page` | `number` | The current page. | | `count` | `number` | The total number of data items. | | `pageSize` | `number` | The number of data items per page. | | `totalPages` | `number` | The total number of pages. | | `pages` | `Pages` | The page range. Represented as an array of page numbers (including ellipsis) | | `previousPage` | `number` | The previous page. | | `nextPage` | `number` | The next page. | | `pageRange` | `PageRange` | The page range. Represented as an object with `start` and `end` properties. | | `slice` | `(data: V[]) => V[]` | Function to slice an array of data based on the current page. | | `setPageSize` | `(size: number) => void` | Function to set the page size. | | `setPage` | `(page: number) => void` | Function to set the current page. | | `goToNextPage` | `VoidFunction` | Function to go to the next page. | | `goToPrevPage` | `VoidFunction` | Function to go to the previous page. | | `goToFirstPage` | `VoidFunction` | Function to go to the first page. | | `goToLastPage` | `VoidFunction` | Function to go to the last page. |