Skip to main content

Figma Storybook

Pagination

Allows users to navigate through large data sets split across multiple pages. Use when a list or table contains more items than can be shown in a single view. Don't use for continuous scroll interfaces.

Figma Storybook Docs

Description

What it does

Divides a long list or table into discrete pages and provides controls for moving between them, showing the user their current position within the full data set.

Where it appears

Below tables and lists in Open Point — stakeholder registers, consultation submission lists, activity logs, and search results. In Social Point, below community comment feeds and submission indexes on public-facing project pages.

Why it exists

Loading hundreds of rows at once degrades performance and overwhelms users. Pagination keeps page weight low and gives users a clear sense of progress through a data set, which is important in government workflows where lists can run to thousands of stakeholder records or submissions.

Dependencies

Table, List View, Select

Anatomy

PartRequired?Notes
Previous button Required Navigates to the preceding page. Disabled on the first page. Contains a left-arrow icon and a visible label for accessibility.
Next button Required Navigates to the following page. Disabled on the last page. Contains a right-arrow icon and a visible label for accessibility.
Page number buttons Required Clickable page numbers. The current page is visually distinguished (variant="neutral" appearance="accent" — solid fill, aria-current='page'). Inactive pages use appearance="outlined" so they still read as pressable. Never use appearance="filled" for either — its fill has no border and fails contrast (WCAG 1.4.11) against every surface in this theme.
Ellipsis indicator Recommended A non-interactive '...' element shown when the page range is truncated. Must not be keyboard-focusable. Appears between the first/last page and the windowed range.
First page shortcut Optional Always-visible link to page 1. Recommended when the total page count exceeds 10.
Last page shortcut Optional Always-visible link to the final page. Recommended when the total page count exceeds 10.
Page count summary Recommended Plain text showing context such as 'Page 3 of 47' or 'Showing 41–60 of 930 results'. Assists screen reader users and sighted users scanning quickly.
Items-per-page selector Optional A Select component letting the user choose how many rows appear per page (e.g. 20, 50, 100). Position above or below the pagination bar, aligned to the opposite side.

Variants

Full (with first/last shortcuts and ellipsis)

Shows page 1, an ellipsis, a window of pages around the current page, another ellipsis, and the last page.

Data sets with more than 10 pages — common in stakeholder registers or large submission lists.

Compact (window only)

Shows only the windowed page range without first/last shortcuts. Suitable when total page count is low.

Tables with 2–10 pages where shortcuts add no value.

Simple (previous / next only)

No numbered page buttons; just Previous and Next with a page count summary.

Mobile breakpoints, or when exact page jumping is not required (e.g. chronological activity feeds).

Mini

Reduced-height version using icon-only Previous/Next buttons and a minimal 'X of Y' label. No page number buttons.

Tight layouts such as embedded card-level pagination or drawer content.

States

State Behaviour
Default All applicable page buttons and Previous/Next buttons are interactive. Current page button shows filled --op-color-interactive-default background with white label.
Previous disabled Previous button has pointer-events: none, opacity reduced to --op-color-text-disabled, and aria-disabled='true'. Occurs on page 1.
Next disabled Next button has pointer-events: none, opacity reduced to --op-color-text-disabled, and aria-disabled='true'. Occurs on the last page.
Page button hover Background transitions to --op-color-interactive-hover at 150ms ease. Cursor: pointer.
Page button focus 3px solid focus ring using --op-color-interactive-focus, 2px offset. Visible on keyboard navigation.
Current page Filled background --op-color-interactive-default, text --op-color-text-on-interactive, aria-current='page'.
Loading All buttons disabled and aria-busy='true' on the nav element while a new page of results is fetching. A wa-spinner can appear adjacent to the summary text.

Usage guidelines

When to use

  • A table or list contains more rows than the chosen page size (typically 20–50 rows for dense government data tables).
  • Users need to navigate to a specific page — for example, to find a stakeholder record they remember was on page 4 of an alphabetically sorted register.
  • Server-side or API-driven data sets where loading all records at once is not feasible.

When not to use

  • Continuous scroll interfaces such as a social activity feed — use infinite scroll or a 'Load more' button instead.
  • Data sets with fewer than two pages — hiding pagination entirely is cleaner than rendering a disabled single-page control.
  • Wizard or multi-step forms — use a Step Indicator component instead.
  • Image galleries or media carousels — use a Carousel component with its own navigation pattern.

Do / Don't

Do

Show a page count summary ('Page 3 of 47') so users always know where they are.

Don't

Show page numbers alone without any context about the total number of pages.

Do

Preserve the current page in the URL query string (e.g. ?page=3) so users can bookmark or share a specific page and the browser back button works correctly.

Don't

Manage page state in JavaScript memory only, which breaks the browser back button and makes links unshareable.

Do

Disable (not hide) the Previous button on page 1 and the Next button on the last page.

Don't

Hide Previous/Next when they are unavailable — this causes layout shift and confuses users about the control's purpose.

Do

Keep the items-per-page selector close to the pagination bar and label it clearly (e.g. 'Rows per page').

Don't

Place items-per-page in a settings panel separate from the table — users won't find it.

Do

Announce page changes to screen readers by moving focus to the top of the updated content region or using an aria-live region.

Don't

Let the page update silently — screen reader users will not know the content has changed.

Was this page helpful?

Updated 9 September 2026