---
title: Pagination
description: Pagination shows how many pages there are and which one is current, as three dots or as numbers. Appetite UI component for Figma, iOS and Android.
group: Components
source: https://www.appetiteui.com/docs/pagination
dateModified: 2026-10-08
---

# Pagination

Updated: October 8, 2026.

Pagination shows how many pages or slides there are, and which one someone is on. Dots report a swipe, numbers let people jump.

## Preview

Where you are in a paged sequence. Dots for carousels and onboarding, Numbered for lists and tables. On mobile, prefer scrolling wherever the content allows.

Specimen: Pagination, Style Numbered, Active Center. 356 x 36, nine 36 targets at gap 4.

Every width here is arithmetic: nine 36 targets and eight 4 gaps make 356, seven targets make 276. 356 does not fit a 390 screen once you add a page margin.

## When should I use Pagination dots?

Use dots where the user swipes and the indicator only reports: a carousel or onboarding. Three dots, 26 by 24, and the only thing that moves is which one is big.

Specimen: Active First, Center, Last. current 8 on brand/base, the others 5, gap 4.

Three is what the component ships, and the idea holds to about six dots, past which they stop being countable. The current dot is 8 and the others 5, so size carries the state as well as color, readable without telling blue from gray.

The inactive dots are one value in both modes, so they do not lift in dark.

## Numbered

Two arrows and a run of numbers with the middle truncated. The three variants are three positions in the sequence, each truncating differently.

Specimen: Active First, Center, Last. 276, 356 and 276, arrows disabled at the ends.

First disables the back arrow, Last the forward one, Center enables both and pays with two ellipses. The ellipsis is the Disabled state of the same 36 target and looks pressable, so give it no tap handler.

The numbers are placeholders in the file.

## Which states does a page number have?

Four, on the private target behind every number: Default and Pressed on a rounded square, Active on the brand circle, and the ellipsis.

Specimen: Default, Pressed, Active, Disabled. 36 x 36, 14/20 at ls .1, radius 16 or full.

Default and Pressed targets are a rounded square at radius 16. Active is the only state drawn as a full circle.

Default has no fill, Pressed takes `bg/weak-50`, Active takes `brand/base` and turns the label Semi Bold, Disabled is the ellipsis. Active is the only state that changes the weight.

The chevrons are their own component with one boolean and no pressed state.

## How does Pagination differ on iOS and Material 3?

iOS has a page control of dots and no numbered pager. The Material 3 pages in the file have no pagination component at all.

| Appetite UI component | iOS counterpart | Material 3 counterpart | What differs |
| --- | --- | --- | --- |
| Pagination, Style Dots | iOS / Page Control, dots only, at Pages 3, 5 and 8 | No counterpart | Same job: report the position in a swipe. Appetite UI sizes the current dot 8 and the others 5 |
| Pagination, Style Numbered, 36 targets | No counterpart | No counterpart | Neither platform ships a numbered pager, so this one is Appetite UI's own |

Dots only report, so no touch target applies. In code, build them as the page indicator of a TabView on iOS and a HorizontalPager indicator on Android.

A Numbered target is 36, under the 44 minimum on iOS and the 48 on Android from `platform/min-touch-target`. Keep the drawn target at 36 and extend each hit area to 44 or 48 in code, or use Dots, a Load more button or plain scrolling where the user does not need to jump.

See [Platform Bridge](https://www.appetiteui.com/docs/platform-bridge).

## Properties

Two axes on the published component, six variants. The three private blocks behind it carry their own.

| Property | Type | Default |
| --- | --- | --- |
| `Style` | Dots \| Numbered | Dots |
| `Active` | First \| Center \| Last | First |
| `State` | Active \| Default \| Pressed \| Disabled, on _Page | Default |
| `Disabled` | False \| True, on _Chevron | False |
| `Active`, `Background` | True \| False, Dark \| Light, on _Dot | False, Light |

There are no text properties: the numbers are baked into each variant, so real page numbers mean overriding the text on each instance.

The widths do not change. A 36 target holds two digits comfortably and three at a squeeze.

## Tokens

Every value the component reads, resolved to its primitive.

| Token | Light | Dark | Applied to |
| --- | --- | --- | --- |
| `brand/base` | #155DFC | #2B7FFF | Active page, active dot |
| `text/on-color/strong` | #FFFFFF | #FFFFFF | Active page label, one value both modes |
| `bg/weak-50` | #F4F5F5 | #242427 | Pressed page |
| `text/strong-950` | #0E0E0F | #FFFFFF | Every other page number |
| `text/disabled-400` | #AEAEB2 | #8E8E93 | Ellipsis |
| `fg/sub-700` | #48484A | #C7C7CC | Enabled chevron |
| `fg/disabled-400` | #AEAEB2 | #8E8E93 | Disabled chevron |
| `colors/alpha/gray/alpha-16` | #6A7282 at 16% | #6A7282 at 16% | Inactive dot, one value both modes |

The inactive dot is a single mode Foundations primitive, so it does not theme. A page runs on `dimensions/radius/xl` 16 at Default and Pressed and on `dimensions/radius/full` at Active.

## Guidelines

- Do: Use Dots where the user swipes and the indicator only reports. Nothing to press, nothing to read, and it survives any width.

- Avoid: Do not put nine 36 targets across a phone.

On mobile the default is to skip pagination. Infinite scroll or a Load more button beats a row of small round targets.

Reach for Numbered when the user needs to jump to a page. If they only ever go forward, one arrow and a count is the whole control.

[Mobile onboarding screen patterns for iOS and Android](https://www.appetiteui.com/blog/mobile-onboarding-screen-patterns).
