suiss/ui · Component
Page Indicator
A row of dots that shows the current page in a pager or carousel, with an elongated dot for the active page.
Page Indicator is an open-source component from suiss/ui for React Native, SwiftUI and Jetpack Compose. The @esuiss/ui CLI copies its source into your project, so you own the code.

PageIndicator draws one dot per page and widens the active one into a pill. Width and position changes animate with Reanimated. When count exceeds maxVisible, only a window of dots is shown; the window slides to keep the active dot near the center and the dots at its edges shrink to hint that more pages exist.
It comes in two sizes, default and sm, and two variants: default uses the foreground color for the active dot and accent uses the primary color.
Installation
Manual
- Install the dependencies:
-
Add the pieces it builds on: the primitives
components/primitives/haptics.tsx, and the animated viewcomponents/ui/animated-view.tsxfrom the next step. -
Copy the animated view into
components/ui/animated-view.tsx:
- Copy the source into
components/ui/page-indicator.tsx:
- Update the import paths to match your project.
- Install the dependencies:
-
Add the pieces it builds on: the primitives
components/primitives/haptics.tsx, and the animated viewcomponents/ui/animated-view.tsxfrom the next step. -
Copy the animated view into
components/ui/animated-view.tsx:
- Copy the source into
components/ui/page-indicator.tsx:
- Update the import paths to match your project.
- Install the dependencies:
-
Add the pieces it builds on: the primitives
components/primitives/haptics.tsx, and the animated viewcomponents/ui/animated-view.tsxfrom the next step. -
Copy the animated view into
components/ui/animated-view.tsx:
- Copy the source into
components/ui/page-indicator.tsx:
- Update the import paths to match your project.
-
Target iOS 17 or later.
-
Add the Swift package to your app:
- Copy the theme files every view uses:
- Copy the source and every file it uses:
- Add the files to your app target.
- Set
minSdkto 24 or higher and add the dependencies:
- Copy the theme files every view uses:
- Copy the source and every file it uses:
- Update the
com.esuiss.uipackage names to match your project.
Usage
The component is controlled: pass count and the current index. Pass onIndexChange to make the dots pressable; without it the indicator is display-only. Pressing a dot plays a selection haptic.
The PageIndicatorSize and PageIndicatorVariant types are also exported.
Examples
Sizes
The sm and default sizes.

Accent
The accent variant, which colors the active dot with bg-primary.

Many pages
Twelve pages shown in a sliding window at the start, middle and end.

Interactive
Pressable dots that change the page through onIndexChange.

API Reference
PageIndicator
| Prop | Type | Default | Description |
|---|---|---|---|
count | number | Required | Total number of pages. Nothing renders when it is 0. |
index | number | Required | Zero-based index of the current page. |
onIndexChange | (index: number) => void | - | Called with the new index when a dot is pressed or an accessibility action is used. |
size | PageIndicatorSize | "default" | Dot size: default or sm. |
variant | PageIndicatorVariant | "default" | Active dot color: default or accent. |
maxVisible | number | 7 | Most dots shown at once. Defaults to 7, minimum 3. |
Also accepts the props of ViewProps.
Accessibility
- The indicator is a single element with the
adjustablerole, and the dots are not focusable on their own. - Its value is announced as "2 of 5".
- When
onIndexChangeis set, VoiceOver and TalkBack users swipe up or down to move to the next or previous page. - Animations respect the system reduce motion setting.
Notes
- Uses
bg-foregroundorbg-primaryfor the active dot andbg-borderfor the others; colors follow the system appearance.




