RollingNumber
RollingNumber animates changing digits in a numeric readout.
Source
LLM docs
Package
Examples
5
Properties
37
Playground
Basics
A counter whose digits roll to their new positions. Only the columns that changed move.
Loading demo…
import { useState } from 'react';
import { Button, Flex, RollingNumber } from '@plocks/ui';
export function Demo() {
const [value, setValue] = useState(1234);
return (
<Flex direction="column" align="center" gap="md">
<RollingNumber value={value} size={48} fw="bold" />
<Button variant="outline" onPress={() => setValue((current) => current + 1)}>+1</Button>
</Flex>
);
}Currency
prefix, suffix and the decimal options cover currency formatting without an external formatter. Copying the value on web yields the formatted string, not the digit strips.Loading demo…
import { useState } from 'react';
import { Button, Flex, RollingNumber } from '@plocks/ui';
export function Demo() {
const [total, setTotal] = useState(1299.99);
return (
<Flex direction="column" align="center" gap="md">
<RollingNumber
value={total}
prefix="$ "
suffix=" USD"
decimalScale={2}
fixedDecimalScale
thousandSeparator
size={36}
fw="semibold"
/>
<Button variant="outline" onPress={() => setTotal((current) => current + 149.5)}>
Add item
</Button>
</Flex>
);
}Timing
transitionDuration, timingFunction and stagger shape the roll. Stagger delays each column right-to-left, so the carries trail the ones place the way an odometer does.Loading demo…
import { useState } from 'react';
import { Button, Flex, RollingNumber, Text } from '@plocks/ui';
export function Demo() {
const [value, setValue] = useState(407219);
return (
<Flex direction="column" gap="lg">
<Flex direction="column" gap="xs">
<Text size="xs" c="muted">Snappy — 200ms, no stagger</Text>
<RollingNumber value={value} transitionDuration={200} size={32} thousandSeparator />
</Flex>
<Flex direction="column" gap="xs">
<Text size="xs" c="muted">Odometer — 900ms, 60ms stagger</Text>
<RollingNumber
value={value}
transitionDuration={900}
timingFunction="ease-out"
stagger={60}
size={32}
thousandSeparator
/>
</Flex>
<Button variant="outline" onPress={() => setValue(Math.floor(Math.random() * 999999))}>
Shuffle
</Button>
</Flex>
);
}Trend
By default the digits roll up when the number grows and down when it shrinks, so 19 → 20 carries the ones column forward like an odometer.
trend={1} or trend={-1} fix the direction, trend={0} moves each digit straight to its new value, and a function (previous, value) => number decides per change.Loading demo…
import { useState } from 'react';
import { Button, Flex, RollingNumber, Text } from '@plocks/ui';
export function Demo() {
const [value, setValue] = useState(19);
return (
<Flex direction="column" gap="lg">
<Flex gap="xl">
<Flex direction="column" align="center" gap="xs">
<Text size="xs" c="muted">Auto</Text>
<RollingNumber value={value} size={32} />
</Flex>
<Flex direction="column" align="center" gap="xs">
<Text size="xs" c="muted">Always up</Text>
<RollingNumber value={value} trend={1} size={32} />
</Flex>
<Flex direction="column" align="center" gap="xs">
<Text size="xs" c="muted">Per digit</Text>
<RollingNumber value={value} trend={0} size={32} />
</Flex>
</Flex>
<Flex gap="sm" justify="center">
<Button variant="outline" onPress={() => setValue((current) => current - 1)}>−1</Button>
<Button variant="outline" onPress={() => setValue((current) => current + 1)}>+1</Button>
</Flex>
</Flex>
);
}Live metric
A ticking live metric. Values that change faster than the roll retarget mid-flight rather than snapping.
Loading demo…
import { useEffect, useState } from 'react';
import { Flex, RollingNumber, Text } from '@plocks/ui';
export function Demo() {
const [requests, setRequests] = useState(84213);
useEffect(() => {
const timer = setInterval(() => {
setRequests((current) => current + Math.floor(Math.random() * 40));
}, 1200);
return () => clearInterval(timer);
}, []);
return (
<Flex direction="column" gap="xs">
<Text size="xs" c="muted" tt="uppercase">Requests today</Text>
<RollingNumber
value={requests}
thousandSeparator
size={40}
fw="bold"
transitionDuration={500}
stagger={40}
/>
</Flex>
);
}React Native design for iOS, Android, and Web.
Quick Links
Resources