> For AI agents: the complete documentation index is available at https://wallarm.github.io/design-system/llms.txt, the full documentation bundle is available at https://wallarm.github.io/design-system/llms-full.txt.

# Pagination

Page-through navigation for a bounded set — previous and next, numbered pages with automatic ellipsis, and an optional rows-per-page selector. Infinite scroll is the house default for long data, so this is the deliberate alternative: reach for it when knowing and controlling your position genuinely helps — jumping to a page, coming back to page two, choosing a page size. “Lots of rows” on its own is not the cue. It is compound, so render only the parts you want, in the order you want.

[Source](https://github.com/wallarm/design-system/tree/main/packages/design-system/src/components/Pagination) · [Storybook](https://wallarm.github.io/design-system/storybook/?path=/docs/navigation-pagination--overview)

```tsx
import { Pagination, PaginationList, PaginationNext, PaginationPrevious } from '@wallarm-org/design-system/Pagination';

export const Full = () => (
  <Pagination count={120} pageSize={10} defaultPage={2} align='center' aria-label='Search results'>
    <PaginationPrevious />
    <PaginationList />
    <PaginationNext />
  </Pagination>
);
```

## Usage

```tsx
import { Pagination, PaginationList, PaginationNext, PaginationPrevious } from '@wallarm-org/design-system/Pagination';
```

## Examples

### Simple

Numbers only. Fine where the reader is scanning to a known page rather than stepping through.

```tsx
import { Pagination, PaginationList } from '@wallarm-org/design-system/Pagination';

export const Simple = () => (
  <Pagination count={120} pageSize={10} defaultPage={2} align='center'>
    <PaginationList />
  </Pagination>
);
```

### Links only

Previous and next with no numbers, for a set whose page count means nothing to the reader.

```tsx
import { Pagination, PaginationNext, PaginationPrevious } from '@wallarm-org/design-system/Pagination';

export const LinksOnly = () => (
  <Pagination count={120} pageSize={10} defaultPage={2} align='center'>
    <PaginationPrevious />
    <PaginationNext />
  </Pagination>
);
```

### With page size

`PaginationPageSize` puts rows-per-page in the same row. Offering it is the strongest reason to choose pagination over infinite scroll.

```tsx
import { Pagination, PaginationList, PaginationNext, PaginationPageSize, PaginationPrevious } from '@wallarm-org/design-system/Pagination';

export const WithPageSize = () => (
  <Pagination count={120} defaultPageSize={25} defaultPage={2} align='right'>
    <PaginationPageSize options={[10, 25, 50]} />
    <PaginationPrevious />
    <PaginationList />
    <PaginationNext />
  </Pagination>
);
```

### Sizes

`medium` and `small`. Small is the one to use in a `Table` footer, where the pager should not outweigh the data.

```tsx
import { Pagination, PaginationList, PaginationNext, PaginationPrevious } from '@wallarm-org/design-system/Pagination';
import { VStack } from '@wallarm-org/design-system/Stack';

export const Sizes = () => (
  <VStack gap={24}>
    <Pagination count={120} pageSize={10} defaultPage={2} size='medium' align='center'>
      <PaginationPrevious />
      <PaginationList />
      <PaginationNext />
    </Pagination>
    <Pagination count={120} pageSize={10} defaultPage={2} size='small' align='center'>
      <PaginationPrevious />
      <PaginationList />
      <PaginationNext />
    </Pagination>
  </VStack>
);
```

### Alignment

`align` places the row left, centre or right — right for a table footer, centre for a standalone list.

```tsx
import { Pagination, PaginationList } from '@wallarm-org/design-system/Pagination';
import { VStack } from '@wallarm-org/design-system/Stack';

export const Alignment = () => (
  <VStack gap={24} className='w-600'>
    {(['left', 'center', 'right'] as const).map(align => (
      <Pagination key={align} count={120} pageSize={10} defaultPage={2} align={align}>
        <PaginationList />
      </Pagination>
    ))}
  </VStack>
);
```

### Many pages

`siblingCount` and `boundaryCount` decide how much of a 50-page set stays visible; the ellipsis is inserted for you.

```tsx
import { Pagination, PaginationList, PaginationNext, PaginationPrevious } from '@wallarm-org/design-system/Pagination';

export const ManyPages = () => (
  <Pagination
    count={500}
    pageSize={10}
    defaultPage={6}
    siblingCount={1}
    boundaryCount={1}
    align='center'
  >
    <PaginationPrevious />
    <PaginationList />
    <PaginationNext />
  </Pagination>
);
```

### Playground

Controlled mode with both `page` and `pageSize` held outside, which is how it behaves against a real query.

```tsx
import { useState } from 'react';
import { Pagination, PaginationList, PaginationNext, PaginationPageSize, PaginationPrevious } from '@wallarm-org/design-system/Pagination';

export const Playground = () => {
  const [page, setPage] = useState(1);
  const [pageSize, setPageSize] = useState(10);
  return (
    <Pagination
      count={120}
      page={page}
      pageSize={pageSize}
      align='left'
      onPageChange={({ page }) => setPage(page)}
      onPageSizeChange={({ pageSize }) => setPageSize(pageSize)}
    >
      <PaginationPageSize options={[10, 25, 50]} />
      <PaginationPrevious />
      <PaginationList />
      <PaginationNext />
    </Pagination>
  );
};
```

### In table

The pager below a `Table`, sharing its state through `useClientPagination` — the composition to copy for a paged grid.

```tsx
import { useClientPagination, Pagination, PaginationList, PaginationNext, PaginationPageSize, PaginationPrevious } from '@wallarm-org/design-system/Pagination';
import { VStack } from '@wallarm-org/design-system/Stack';
import { Table } from '@wallarm-org/design-system/Table';

export const InTable = () => {
  const { pageData, ...pagination } = useClientPagination(apiEndpoints, 10);

  return (
    <div className='w-800'>
      <VStack gap={12}>
        <Table data={pageData} columns={endpointColumns} getRowId={row => row.id} />
        <Pagination {...pagination} align='right' aria-label='API endpoints'>
          <PaginationPageSize options={[5, 10, 25]} />
          <PaginationPrevious />
          <PaginationList />
          <PaginationNext />
        </Pagination>
      </VStack>
    </div>
  );
};
```

## Props

| Prop             | Type                                                                | Default  | Description                               |
| ---------------- | ------------------------------------------------------------------- | -------- | ----------------------------------------- |
| count            | `number \| undefined`                                               |          | Total number of data items (Ark `count`). |
| page             | `number \| undefined`                                               |          | Controlled current page (1-based).        |
| defaultPage      | `number \| undefined`                                               |          | Uncontrolled initial page.                |
| pageSize         | `number \| undefined`                                               |          | Controlled items-per-page.                |
| defaultPageSize  | `number \| undefined`                                               |          | Uncontrolled initial items-per-page.      |
| siblingCount     | `number \| undefined`                                               |          | Pages shown beside the active page.       |
| boundaryCount    | `number \| undefined`                                               |          | Pages shown at the start/end.             |
| onPageChange     | `((details: PaginationPageChangeDetails) => void) \| undefined`     |          |                                           |
| onPageSizeChange | `((details: PaginationPageSizeChangeDetails) => void) \| undefined` |          |                                           |
| type             | `"button" \| "link" \| undefined`                                   |          | Trigger element type.                     |
| getPageUrl       | `((details: PaginationPageChangeDetails) => string) \| undefined`   |          |                                           |
| size             | `PaginationSize \| undefined`                                       | `medium` | Visual size.                              |
| align            | `PaginationAlign \| undefined`                                      | `left`   | Horizontal alignment of the row.          |
| aria-label       | `string \| undefined`                                               |          |                                           |
| data-testid      | `string \| undefined`                                               |          |                                           |

### PaginationEllipsis

| Prop           | Type                                                 | Default | Description                                                      |
| -------------- | ---------------------------------------------------- | ------- | ---------------------------------------------------------------- |
| index \*       | `number`                                             |         | Index of this ellipsis within the pages array (required by Ark). |
| defaultChecked | `boolean \| undefined`                               |         |                                                                  |
| defaultValue   | `string \| number \| readonly string[] \| undefined` |         |                                                                  |
| autoFocus      | `boolean \| undefined`                               |         |                                                                  |
| id             | `string \| undefined`                                |         |                                                                  |
| tabIndex       | `number \| undefined`                                |         |                                                                  |
| title          | `string \| undefined`                                |         |                                                                  |
| rel            | `string \| undefined`                                |         |                                                                  |
| onChange       | `ChangeEventHandler<T, Element> \| undefined`        |         |                                                                  |

### PaginationItem

| Prop           | Type                                                 | Default | Description          |
| -------------- | ---------------------------------------------------- | ------- | -------------------- |
| value \*       | `number`                                             |         | 1-based page number. |
| disabled       | `boolean \| undefined`                               |         |                      |
| name           | `string \| undefined`                                |         |                      |
| type           | `"button" \| "submit" \| "reset" \| undefined`       |         |                      |
| defaultChecked | `boolean \| undefined`                               |         |                      |
| defaultValue   | `string \| number \| readonly string[] \| undefined` |         |                      |
| autoFocus      | `boolean \| undefined`                               |         |                      |
| id             | `string \| undefined`                                |         |                      |
| tabIndex       | `number \| undefined`                                |         |                      |
| title          | `string \| undefined`                                |         |                      |
| rel            | `string \| undefined`                                |         |                      |
| onChange       | `ChangeEventHandler<T, Element> \| undefined`        |         |                      |

### PaginationNext

| Prop           | Type                                                 | Default | Description |
| -------------- | ---------------------------------------------------- | ------- | ----------- |
| disabled       | `boolean \| undefined`                               |         |             |
| name           | `string \| undefined`                                |         |             |
| type           | `"button" \| "submit" \| "reset" \| undefined`       |         |             |
| value          | `string \| number \| readonly string[] \| undefined` |         |             |
| defaultChecked | `boolean \| undefined`                               |         |             |
| defaultValue   | `string \| number \| readonly string[] \| undefined` |         |             |
| autoFocus      | `boolean \| undefined`                               |         |             |
| id             | `string \| undefined`                                |         |             |
| tabIndex       | `number \| undefined`                                |         |             |
| title          | `string \| undefined`                                |         |             |
| rel            | `string \| undefined`                                |         |             |
| onChange       | `ChangeEventHandler<T, Element> \| undefined`        |         |             |

### PaginationPageSize

| Prop        | Type                  | Default                      | Description                       |
| ----------- | --------------------- | ---------------------------- | --------------------------------- |
| options \*  | `number[]`            |                              | Selectable items-per-page values. |
| label       | `string \| undefined` | `PAGINATION_PAGE_SIZE_LABEL` | Leading label.                    |
| data-testid | `string \| undefined` |                              |                                   |

### PaginationPrevious

| Prop           | Type                                                 | Default | Description |
| -------------- | ---------------------------------------------------- | ------- | ----------- |
| disabled       | `boolean \| undefined`                               |         |             |
| name           | `string \| undefined`                                |         |             |
| type           | `"button" \| "submit" \| "reset" \| undefined`       |         |             |
| value          | `string \| number \| readonly string[] \| undefined` |         |             |
| defaultChecked | `boolean \| undefined`                               |         |             |
| defaultValue   | `string \| number \| readonly string[] \| undefined` |         |             |
| autoFocus      | `boolean \| undefined`                               |         |             |
| id             | `string \| undefined`                                |         |             |
| tabIndex       | `number \| undefined`                                |         |             |
| title          | `string \| undefined`                                |         |             |
| rel            | `string \| undefined`                                |         |             |
| onChange       | `ChangeEventHandler<T, Element> \| undefined`        |         |             |

## Explorer

