Skip to content

AnimateCounter

A number counted up to its value. The one animation in the library whose subject is the content rather than the box around it: a value being interpolated and formatted on every frame, which is not something a keyframe can do.

tsx
import { AnimateCounter, Statistic } from 'neba';

<Statistic label="Monthly active" value={<AnimateCounter value={128400} />} />;

Props

PropTypeDefaultDescription
value * numberWhere it lands
fromnumber0Where it starts
durationsharednumber1200How long the count takes, in milliseconds
delaysharednumber0How long before it starts, in milliseconds
formatIntl.NumberFormatOptionsHow the number is written: Intl.NumberFormat options, so a currency, a percentage or a compact 1.2M is a prop rather than a callback
localestringWhich language it is written in
triggershared'mount' | 'visible' | 'hover' | 'manual''mount'What starts the count. Before it does, the number sits at from
playbooleanRuns it when trigger is manual
oncesharedbooleantrueWith trigger="visible", whether it counts only the first time
thresholdsharednumber0.2With trigger="visible", how much of it has to be on screen
renderuseRender.RenderPropRenders something other than a div (render={<strong />}). Base UI's own escape hatch

Every other <div> attribute passes through to the root. It has no easing, repeat or alternate: a number may only ever approach its value from one side, so the curve is a fixed ease-out and there is no version of a count that loops.

It pairs with Statistic, whose value takes a node for exactly this. A dashboard that draws its numbers instantly and animates everything around them has the emphasis backwards.

Examples

format and locale

Intl.NumberFormat options, so a currency, a percentage or a compact 1.2M is a prop rather than a format callback: the same prop Statistic and the progress indicators take.

trigger

trigger="visible" is the one worth reaching for on a dashboard below the fold: a count that has already finished by the time it is scrolled to has not been seen. Before it starts, the number sits at from rather than at its answer.

tsx
<AnimateCounter value={128400} trigger="visible" />

Accessibility

  • The finished number is in the document from the first frame, in a clipped box for a screen reader; what counts is a visible copy that is aria-hidden. A reader who cannot see the count is told the answer rather than a hundred intermediate ones.
  • A reduced-motion preference shows the answer straight away.

Released under the MIT License