Staaarter

Stats With Progress Bars

A stacked list of metrics where each row shows a label, a 'current / target' value pair, and a horizontal progress bar filled to the percentage of the goal reached. Built with plain divs (no chart library) and exposes the percentage to assistive tech via role="progressbar".

By Staaarter Team
Stats
Docs
Live preview

Docs

Installation

A real shadcn registry command, not a copy-paste stand-in: it fetches this block plus its dependencies and any missing npm packages, and installs them straight into your project.

npx shadcn add https://staaarter.com/r/stats-with-progress-bars.json

Prefer not to use the CLI? Copy the source from the Code toggle above into src/components/blocks/stats/stats4.tsx instead.

Usage

The file also exports stats4Demo, the exact props behind the preview above. Spread it to get a working section in one line, then replace it with your own data.

import { Stats4, stats4Demo } from "@/components/blocks/stats/stats4";

export default function Page() {
  return <Stats4 {...stats4Demo} />;
}

Props

PropTypeDefaultDescription
headingstringundefinedOptional heading above the list.
descriptionstringundefinedOptional supporting text under the heading.
statsProgressStat[]noneThe stat rows, each rendered with its own progress bar.
classNamestringnoneExtra classes for the outer section element.

Types

type ProgressStat = {
  label: string;
  current: number;
  target: number;
  prefix?: string; // e.g. "$"
  suffix?: string; // e.g. "%"
};

Behavior notes

  • Fully static: bar widths are computed once at render time from the current/target props via plain arithmetic (Math.round/Math.min/Math.max), never from Math.random or a live timer, so the same props always render the same bar width across the Code tab's static HTML and every card thumbnail.
  • The percentage is clamped to the 0-100 range, so a current value that exceeds target still renders a full bar instead of overflowing.
  • Each bar carries role="progressbar" with aria-valuenow/aria-valuemin/aria-valuemax and an aria-label stating the percentage, so the value is available to assistive tech even though the bar itself is purely visual (a div sized with inline width, not a native <progress> element).
  • There is no animation on the bar fill; it renders at its final width immediately, matching this block's Server Component (static widths, no client-side effects) description.