20 / 59 · Structured output
Number ticker
Digits that roll into place as a count updates in real time.
01234567890123456789,012345678901234567890123456789tokens generated
Installation
npx shadcn@latest add "@assistant-ui/elements-number-ticker"
Usage
import { NumberTicker } from "@/components/elements/number-ticker";
<NumberTicker value={1284} label="tokens / sec" />Props
value*numberNumeric value whose digits roll into place as it changes.
label*stringMono caption rendered under the rolling number.
classNamestringExtra classes merged onto the root.
Source
number-ticker.tsx"use client";
import { cn } from "@/lib/utils";
import { mono } from "./surfaces";
function RollingDigit({ digit }: { digit: number }) {
return (
<span className="inline-flex h-[1.15em] overflow-hidden">
<span
className="flex flex-col transition-transform duration-500 ease-[cubic-bezier(0.32,0.72,0,1)] motion-reduce:transition-none"
style={{ transform: `translateY(-${digit * 1.15}em)` }}
>
{Array.from({ length: 10 }, (_, i) => (
<span key={i} className="h-[1.15em] leading-[1.15]">
{i}
</span>
))}
</span>
</span>
);
}
export function NumberTicker({
value,
label,
className,
}: {
value: number;
label: string;
className?: string;
}) {
const formatted = value.toLocaleString("en-US");
return (
<div className={cn("flex flex-col items-center gap-2.5", className)}>
<span
className="flex text-3xl font-medium tracking-tight tabular-nums"
aria-label={formatted}
>
{formatted.split("").map((char, i) =>
/\d/.test(char) ? (
<RollingDigit key={i} digit={Number(char)} />
) : (
<span key={i} className="h-[1.15em] leading-[1.15]">
{char}
</span>
),
)}
</span>
<span className={cn(mono, "text-foreground/35")}>{label}</span>
</div>
);
}