# Rolling number

> A number whose digits roll in the direction of change, with digits that open and close in place and currency signs that glide instead of jumping.

- Type: Component (data)
- Access: Free, open source (MIT)
- Page: https://goodui.dev/native/components/rolling-number
- Markdown: https://goodui.dev/native/components/rolling-number.md
- Registry item: https://goodui.dev/native/r/rolling-number.json
- Dependencies: react-native-reanimated
- Keywords: react native animated number, rolling digits, odometer, animated price, number ticker, number flow react native

## When to use

- Prices that change with a plan or billing period.
- Totals, balances, counters and scores that update in place.

## When not to use

- Static numbers that never change: use Text with tabular digits.
- Values that update many times a second: use a plain Text.

## Installation

With the shadcn CLI (needs a components.json in the Expo app), then `npx expo install --fix` so native dependencies match your Expo SDK. The foundation comes along the first time.

```bash
npx shadcn@latest add https://goodui.dev/native/r/rolling-number.json
npx expo install --fix
```

The component lands in `components/goodui-native/rolling-number/` and imports the foundation from `components/goodui-native/foundation/` with relative paths.

## Usage

```tsx
import { View } from "react-native";
import { Text } from "@/components/goodui-native/foundation";
import { RollingNumber } from "@/components/goodui-native/rolling-number/rolling-number";

<View style={{ flexDirection: "row", alignItems: "flex-end", gap: 8 }}>
  <RollingNumber
    value={yearly ? 79.99 : 9.99}
    size="largeTitle"
    weight="medium"
    locale="en-US"
    format={{ style: "currency", currency: "USD" }}
  />
  <Text tone="secondary" style={{ marginBottom: 6 }}>
    {yearly ? "/ year" : "/ month"}
  </Text>
</View>
```

## API reference

### RollingNumber

`import { RollingNumber } from "@/components/goodui-native/rolling-number/rolling-number";`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `value` (required) | `number` | – | The number to show. Changes roll the digits. |
| `format` | `Intl.NumberFormatOptions` | – | Intl options, for example `{ style: "currency", currency: "EUR" }`. |
| `locale` | `string` | – | BCP 47 locale for separators and currency placement, for example `de-DE`. Defaults to the device locale. |
| `size` | `"caption" \| "footnote" \| "subhead" \| "body" \| "title3" \| "title2" \| "title1" \| "largeTitle"` | `"body"` | Type size from the theme scale. |
| `weight` | `"regular" \| "medium"` | `"regular"` | Regular or medium. |
| `tone` | `"success" \| "warning" \| "default" \| "danger" \| "accent" \| "secondary" \| "tertiary"` | `"default"` | Text color from the theme. |
| `trend` | `"auto" \| "up" \| "down"` | `"auto"` | Which way digits roll. `auto` rolls up when the value grows and down when it shrinks, even across a 9 to 0 boundary. |
| `style` | `StyleProp<ViewStyle>` | – | Style for the outer container. |
| `testID` | `string` | – | Identifier for end-to-end tests. |

## Accessibility

- Read as one piece of text with the fully formatted value as its label; the individual digits are hidden.
- On the web the number is visually hidden text and the digit strips are aria-hidden.

## Motion

- Each digit is a strip that rolls on the morph spring; increases roll up and decreases roll down, even across 9 and 0.
- A digit that joins opens from zero width and one that leaves closes, so text beside the number reflows smoothly.
- A new currency or locale morphs: the old sign closes while the new one opens.
- Reduced motion: values change in place without rolling.

## Performance

- One Text node per digit. Rolling runs on the UI thread; joining and leaving digits animate their real width.

## Notes for AI

- Pass a number, not a string. Format with the format and locale props (Intl.NumberFormat options).
- It sizes to its content; place labels beside it in a row and they move with it.
- It is a View, so alignItems: 'baseline' does not line it up with neighboring text. Use a row with alignItems: 'flex-end' and give a smaller label a marginBottom of about 6 pt at largeTitle (see the usage example).
- Use the same size and weight tokens as Text.

## Related

- [Segmented control](https://goodui.dev/native/components/segmented-control.md): Two to five views of the same thing with an elastic highlight that stretches toward the new segment, can be dragged, and ticks at every boundary. Includes a billing toggle.

## Guidance for AI tools

Rolling number: A number whose digits roll in the direction of change, with digits that open and close in place and currency signs that glide instead of jumping. Use only the documented props. Keep accessibility, reduced motion and both color schemes intact when adapting it.

Full library index: https://goodui.dev/native/llms.txt
