Skip to content
HooksPro

useAnimatedNumber

A number that counts from its previous value to the new one, for chart headlines and KPI values.

Returns the value to show while it counts. The count uses the token and the entrance curve by default; pass another duration token as the second argument. When the value changes mid-count (a pointer sliding across a chart), it turns towards the new target instead of starting over. The component wraps the hook with a formatter.

See alsoChart CardMetric Card

Import

tsx
import { useAnimatedNumber } from "@wunderui/react/charts"

Comes with WunderUI Core and Pro, in the entry of the package from your plan. See the plans.

Signature

ts
useAnimatedNumber(value: number | null | undefined, token?: string): number | null

Parameters

ParameterTypeDefault
valuenumber | null | undefined—
token?string"--duration-slow"

Returns

Examples

The value of the hovered point

tsx
import { ChartCard, LineChart } from "@wunderui/react/charts"

export function Revenue({ data }: { data: { month: string; revenue: number }[] }) {
  const [active, setActive] = React.useState<number | null>(null)
  const value = data[active ?? data.length - 1].revenue
  return (
    <ChartCard title="Revenue" value={value} valueFormatter={(v) => `$${Math.round(v).toLocaleString("en-US")}`}>
      <LineChart data={data} index="month" series={[{ key: "revenue" }]} onActiveIndexChange={setActive} label="Revenue by month" />
    </ChartCard>
  )
}

The hook on its own

tsx
import { useAnimatedNumber } from "@wunderui/react/charts"

function Total({ value }: { value: number }) {
  const shown = useAnimatedNumber(value, "--duration-base")
  return (
    <p className="text-3xl font-semibold tabular-nums">
      <span aria-hidden="true">{Math.round(shown ?? 0).toLocaleString("en-US")}</span>
      <span className="sr-only">{value.toLocaleString("en-US")}</span>
    </p>
  )
}

Notes

  • Under reduced motion the number changes at once, without counting.
  • Screen readers should get the final value only: hides the counting digits from them and adds the final value as visually hidden text. Do the same when you use the hook directly.
  • and values that are not finite are passed through, so a missing value shows as your placeholder.