Counter
An animated number counter for React: it rolls to each new value and throws the change off it, the way a game counts gold.
Install
# once per project: where @zeroui items come frompnpm dlx shadcn@latest registry add @zeroui=https://zeroui.catforest.dev/r/{name}.jsonpnpm dlx shadcn@latest add @zeroui/counterExamples
Credits
12,480cr
import { useState } from "react";import { Button } from "@/components/zero/button";import { Counter } from "@/components/zero/counter";export default function CounterCredits() { const [credits, setCredits] = useState(12480); return ( <div className="grid justify-items-start gap-5"> <p className="flex items-baseline gap-2"> <Counter value={credits} delta className="text-zero-2xl" /> <span className="font-black font-zero text-zero-accent text-zero-md italic"> cr </span> </p> <div className="flex flex-wrap gap-3"> <Button size="sm" onClick={() => setCredits((c) => c + 3100)}> Deliver the crate </Button> <Button variant="secondary" size="sm" onClick={() => setCredits((c) => c - 450)} > Pay for repairs </Button> </div> </div> );}Behaviour
Set in the display face, leaning, with figures of one width so it does not shake as it counts. It rolls on the roll transition; with delta, each change rises off it and fades, in the accent when it grows and red when it shrinks.
Screen readers get the final value, not the count. Under reduced motion it jumps and the change does not rise. It writes numbers in en-US unless given a locale, so the server and the browser agree.
Props
Counter
| Prop | Type | Default | Description |
|---|---|---|---|
| value | number | — | The number. |
| format | Intl.NumberFormatOptions | — | How to write it. |
| locale | string | "en-US" | Whose way of writing numbers. |
| delta | boolean | — | Throw each change off the number. |