CyclingNumber

Animate a formatted number from zero to its value when it scrolls into view.

CyclingNumber is a client component that renders NumberFlow from @number-flow/react inside a Text span and updates it to value once the element is at least half visible. Use it for headline statistics and counters. It requires @number-flow/react and motion, and should render inside DesignSystemProvider.

Revenue this year$0

Import#

typescript
import { CyclingNumber } from "@reactberry/system/blocks";

Usage#

typescript
import { CyclingNumber } from "@reactberry/system/blocks";
import { Box, Text } from "@reactberry/system/elements";

export default function RevenueStat() {
  return (
    <Box display="flex" flexDirection="column" gap="xs">
      <Text color="secondary">Revenue this year</Text>
      <Text fontSize="xxl" fontWeight="bold">
        <CyclingNumber value={1250000} />
      </Text>
    </Box>
  );
}

Examples#

Formats, prefix and suffix#

format takes Intl.NumberFormat options. Add text around the number with prefix and suffix.

Uptime0%
Active users~0

Changing value#

Changing value animates from the current number to the new one. delay={0} updates without waiting.

Orders today0

API#

CyclingNumber#

PropTypeDefaultDescription
value
number
0

Target number. The display starts at 0 and animates to it once in view.

delay
number
500

Milliseconds to wait after entering the viewport before updating to value.

format
Format
{…

Intl.NumberFormat options passed to NumberFlow.

suffix
string
—

Text rendered after the number.

prefix
string
—

Text rendered before the number.

value is required in the type but defaults to 0 in code. format is a Format from @number-flow/react; the default is { style: "currency", currency: "USD", trailingZeroDisplay: "stripIfInteger" }. No other props are accepted and nothing is spread.

Notes#

  • The number starts at 0 and updates once at least 50% of the element is in view. It is not reset when the element leaves the viewport, so later entries do not replay the animation; changing value animates to the new value.
  • The default format is US dollar currency. Pass format for any other output.
  • Transitions use a 2 second spring when useCanAnimate() from @number-flow/react returns true, and an instant tween otherwise (for example, when the browser cannot animate the number or the user prefers reduced motion).
  • The wrapper Text uses color="primary" and display: inline-flex; font size and weight are inherited from the parent.