Skip to main content

Pagination

Pagination is an interface that allows navigating between pages that contain split information, instead of being shown on a single page.

Properties

Installation

To use the pagination machine in your project, run the following command in your command line:

npm install @zag-js/pagination @zag-js/vue # or yarn add @zag-js/pagination @zag-js/vue

Anatomy

To set up the pagination correctly, you'll need to understand its anatomy and how we name its parts.

Each part includes a data-part attribute to help identify them in the DOM.

Usage

First, import the pagination package into your project

import * as pagination from "@zag-js/pagination"

The pagination package exports two key functions:

  • machine — The state machine logic for the pagination widget.
  • connect — The function that translates the machine's state to JSX attributes and event handlers.

You'll also need to provide a unique id to the useMachine hook. This is used to ensure that every part has a unique identifier.

<script setup> import * as pagination from "@zag-js/pagination" import { normalizeProps, useMachine } from "@zag-js/vue" import { computed } from "vue" import { data } from "./data" const service = useMachine(pagination.machine, { id: "1", count: data.length, }) const api = computed(() => pagination.connect(service, normalizeProps)) </script> <template> <nav v-if="api.totalPages > 1" v-bind="api.getRootProps()"> <ul> <li> <a href="#previous" v-bind="api.getPrevTriggerProps()"> Previous <span class="visually-hidden">Page</span> </a> </li> <li v-for="(page, i) in api.pages" :key="page.type === 'page' ? page.value : `ellipsis-${i}`" > <span v-if="page.type === 'page'"> <a :href="`#${page.value}`" v-bind="api.getItemProps(page)"> {{page.value}} </a></span > <span v-else> <span v-bind="api.getEllipsisProps({ index: i })">&#8230;</span> </span> </li> <li> <a href="#next" v-bind="api.getNextTriggerProps()"> Next <span class="visually-hidden">Page</span> </a> </li> </ul> </nav> </template>
const api = connect(service) // You can slice the data, to get data for current page const currentPageData = data.slice(api.pageRange.start, api.pageRange.end) api.page // => 1 api.setPage(3) // page => 3 api.previousPage // => 2 api.nextPage // => 4 api.pages /* [ { "type": "page", "value": 1, }, { "type": "page", "value": 2, }, { "type": "ellipsis", }, { "type": "page", "value": 3, }, { "type": "page", "value": 4, }, ] */ api.pageRange // => { start: 4, end: 13 }

Styling guide

Earlier, we mentioned that each pagination part has a data-part attribute added to them to select and style them in the DOM.

[data-part="root"] { /* styles for the pagination's root */ } [data-part="item"] { /* styles for the pagination's items */ } [data-part="ellipsis"] { /* styles for the pagination's ellipsis */ } [data-part="prev-trigger"] { /* styles for the pagination's previous page trigger */ } [data-part="next-trigger"] { /* styles for the pagination's next page trigger */ } /* We add a data-disabled attribute to the prev/next items when on the first/last page */ [data-part="prev-trigger"][data-disabled] { /* styles for the pagination's previous page trigger when on first page */ } [data-part="next-trigger"][data-disabled] { /* styles for the pagination's next page trigger when on first page */ }

Methods and Properties

Machine Context

The pagination machine exposes the following context properties:

  • idsPartial<{ root: string; ellipsis: (index: number) => string; prevTrigger: string; nextTrigger: string; item: (page: number) => string; }>The ids of the elements in the accordion. Useful for composition.
  • translationsIntlTranslationsSpecifies the localized strings that identifies the accessibility elements and their states
  • countnumberTotal number of data items
  • pageSizenumberThe controlled number of data items per page
  • defaultPageSizenumberThe initial number of data items per page when rendered. Use when you don't need to control the page size of the pagination.
  • siblingCountnumberNumber of pages to show beside active page
  • pagenumberThe controlled active page
  • defaultPagenumberThe initial active page when rendered. Use when you don't need to control the active page of the pagination.
  • onPageChange(details: PageChangeDetails) => voidCalled when the page number is changed
  • onPageSizeChange(details: PageSizeChangeDetails) => voidCalled when the page size is changed
  • type"button" | "link"The type of the trigger element
  • dir"ltr" | "rtl"The document's text/writing direction.
  • idstringThe unique identifier of the machine.
  • getRootNode() => ShadowRoot | Node | DocumentA root node to correctly resolve document in custom environments. E.x.: Iframes, Electron.

Machine API

The pagination api exposes the following methods:

  • pagenumberThe current page.
  • countnumberThe total number of data items.
  • pageSizenumberThe number of data items per page.
  • totalPagesnumberThe total number of pages.
  • pagesPagesThe page range. Represented as an array of page numbers (including ellipsis)
  • previousPagenumberThe previous page.
  • nextPagenumberThe next page.
  • pageRangePageRangeThe page range. Represented as an object with `start` and `end` properties.
  • slice<V>(data: V[]) => V[]Function to slice an array of data based on the current page.
  • setPageSize(size: number) => voidFunction to set the page size.
  • setPage(page: number) => voidFunction to set the current page.
  • goToNextPageVoidFunctionFunction to go to the next page.
  • goToPrevPageVoidFunctionFunction to go to the previous page.
  • goToFirstPageVoidFunctionFunction to go to the first page.
  • goToLastPageVoidFunctionFunction to go to the last page.

Data Attributes

Item
data-scope
pagination
data-part
item
data-index
The index of the item
data-selected
Present when selected
PrevTrigger
data-scope
pagination
data-part
prev-trigger
data-disabled
Present when disabled
NextTrigger
data-scope
pagination
data-part
next-trigger
data-disabled
Present when disabled
Edit this page on GitHub