zeroUI

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

terminal
# 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/counter

Examples

Credits

12,480cr

counter-credits.tsx
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

PropTypeDefaultDescription
valuenumber—The number.
formatIntl.NumberFormatOptions—How to write it.
localestring"en-US"Whose way of writing numbers.
deltaboolean—Throw each change off the number.