Skip to content
Template Empire / components

Search components

10 results

Browse components

Progress Ring Stats

A free logo and stats section for React: circular progress rings that sweep to their value on scroll.

  • Automated axe check
  • Reduced-motion tested
  • SSR build verified
  • Motion
  • 1 runtime package

Progress Ring Stats is a free animated stats section for Next.js and React, styled with Tailwind. It renders circular progress stats as SVG rings: the first time the section scrolls into view, every ring sweeps from empty to its percentage with Motion while the number in its centre counts up to match, rings starting 100 milliseconds apart.

The final number and the fully drawn ring of every stat are rendered in the server HTML, so crawlers, no-JS visitors and reduced-motion users always see the real values (enhancement-only animation). The sweep writes the stroke offset and the count writes into the DOM through a single Motion value subscription with zero React re-renders per frame, tabular numerals and a reserved width hold layout perfectly stable, and screen readers only ever hear the final value and label.

Measured in production

Uptime: 99 percent
Customer satisfaction: 96 percent
Faster builds: 72 percent
Test coverage: 88 percent

Install

Add the @te registry to your components.json once:

{
  "registries": {
    "@te": "https://templateempire.io/r/{name}.json"
  }
}

Then install the component:

npx shadcn@latest add @te/stat-progress-ring

Usage

import { StatProgressRing } from "@/components/stat-progress-ring";

const stats = [
  { label: "Uptime", value: 99, suffix: "%" },
  { label: "Customer satisfaction", value: 96, suffix: "%" },
  { label: "Faster builds", value: 72, suffix: "%" },
  { label: "Test coverage", value: 88, suffix: "%" },
];

export function Example() {
  return <StatProgressRing stats={stats} />;
}

Props

PropTypeDefaultDescription
stats{ label: string; value: number; suffix?: string }[]required2 to 6 stats; each value is a percent from 0 to 100, rendered final in the SSR HTML.
sizenumber160Ring diameter in pixels; stroke width and radius derive from it.
durationnumber1.2Sweep and count-up duration in seconds per ring (--dur-4).
classNamestringundefinedAdditional classes merged onto the section.

Customisation

Progress Ring Stats deliberately ships without component-level CSS variables. The ring track and progress stroke read the border and foreground tokens, so they follow your theme automatically. Shape each stat through its own entry and tune the section with the props: size sets the ring diameter, duration paces the sweep against your motion system, and className restyles the grid, for example to change the gap or column widths:

<StatProgressRing
  stats={stats}
  size={200}
  duration={2}
  className="max-w-4xl gap-y-14"
/>

Frequently asked questions

Is Progress Ring Stats free for commercial use?
Yes. Progress Ring Stats is MIT licensed, so you can use it in personal and commercial projects without attribution.
Do the rings hurt SEO or accessibility?
No. The server HTML contains every final number and a fully drawn ring, so crawlers and no-JS visitors read the real values without JavaScript. Each ring exposes a single visually hidden string with its value and label to assistive technology, while the SVG and the visible number and label are hidden from it, so screen readers never hear an intermediate frame. With reduced motion enabled nothing sweeps or counts and the final state renders immediately.
How do I change the ring size or the number suffix?
Set the size prop for the ring diameter; the stroke width and radius scale with it. Add a suffix such as a percent sign on each stat to render it after the counting number. Values are percentages from 0 to 100 and the count keeps the same rounding as the final number on every frame.

Related components

Want the full page this belongs to?Template Empire builds complete Next.js templates with this motion system throughout. Browse the paid templates that pair with these free components.Explore Template Empire templates