suiss/uim · React Native 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 mobile component from suiss/uim for React Native and Expo, with SwiftUI and Jetpack Compose versions built from the same design tokens. The @esuiss/uim CLI copies its source into your project, so you own the code.

iOS
Page Indicator on iOS in light mode

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 label color for the active dot and accent uses the accent color.

Installation

$ pnpm dlx @esuiss/uim@latest add page-indicator

Manual

  1. Install the dependencies:
npx expo install cn react-native-reanimated react-native-worklets
  1. Add the pieces it builds on: the primitives components/primitives/haptics.tsx.

  2. Copy the source into components/ui/page-indicator.tsx:

uniwind/components/ui/page-indicator.tsx
import { cn } from "cn"
import * as React from "react"
import {
  type AccessibilityActionEvent,
  Pressable,
  View,
  type ViewProps,
} from "react-native"
import {
  Easing,
  ReduceMotion,
  useAnimatedStyle,
  useSharedValue,
  withTiming,
} from "react-native-reanimated"
import { useHaptics } from "@/components/primitives/haptics"
  1. Update the import paths to match your project.

Usage

import { PageIndicator } from "@/components/ui/page-indicator"
<PageIndicator count={5} index={1} />

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.

iOS
Page Indicator (sizes) on iOS in light mode

Accent

The accent variant.

iOS
Page Indicator (accent) on iOS in light mode

Many pages

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

iOS
Page Indicator (many pages) on iOS in light mode

Interactive

Pressable dots that change the page through onIndexChange.

iOS
Page Indicator (interactive) on iOS in light mode

API Reference

PageIndicator

ExtendsViewProps
PropType
About
Total number of pages. Nothing renders when it is 0.
Type
number
Default
required
About
Zero-based index of the current page.
Type
number
Default
required
About
Called with the new index when a dot is pressed or an accessibility action is used.
Type
(index: number) => void
Default
—
About
Dot size: default or sm.
Type
PageIndicatorSize
Default
"default"
About
Active dot color: default or accent.
Type
PageIndicatorVariant
Default
"default"
About
Most dots shown at once. Defaults to 7, minimum 3.
Type
number
Default
7

Accessibility

  • The indicator is a single element with the adjustable role, and the dots are not focusable on their own.
  • Its value is announced as "2 of 5".
  • When onIndexChange is 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-label or bg-accent for the active dot and bg-label-quaternary for the others; colors follow the system appearance.