codefast/ui

Command Palette

Search for a command to run...

Source
Feedback

Progress Circle

Circular progress indicator with optional value label and animation. Multiple sizes.

Examples

Animated

Press Start — the ring fills over time with the value shown in the centre.

0%
56 lines
import { Button } from "@codefast/ui/button";
import { ProgressCircle } from "@codefast/ui/progress-circle";
import { useEffect, useState } from "react";

export function ProgressCircleAnimated() {
  const [value, setValue] = useState(0);
  const [running, setRunning] = useState(false);

  useEffect(() => {
    if (!running) {
      return;
    }

    const id = setInterval(() => {
      setValue((previous) => Math.min(100, previous + 5));
    }, 150);

    return () => {
      clearInterval(id);
    };
  }, [running]);

  useEffect(() => {
    if (value >= 100) {
      setRunning(false);
    }
  }, [value]);

  return (
    <div className="flex flex-col items-center gap-4">
      <ProgressCircle value={value} showValue />
      <div className="flex gap-2">
        <Button
          size="sm"
          variant="outline"
          onClick={() => {
            setValue(0);
            setRunning(true);
          }}
        >
          Start
        </Button>
        <Button
          size="sm"
          variant="ghost"
          onClick={() => {
            setRunning(false);
            setValue(0);
          }}
        >
          Reset
        </Button>
      </div>
    </div>
  );
}

Fixed values

Any value 0–100; toggle showValue to print the number inside.

100%
12 lines
import { ProgressCircle } from "@codefast/ui/progress-circle";

export function ProgressCircleValues() {
  return (
    <div className="flex flex-wrap items-center justify-center gap-6">
      <ProgressCircle value={25} />
      <ProgressCircle value={50} />
      <ProgressCircle value={75} />
      <ProgressCircle value={100} showValue />
    </div>
  );
}

Labeled metrics

Group circles into a compact metrics dashboard.

38%
CPU
64%
Memory
82%
Disk
20 lines
import { ProgressCircle } from "@codefast/ui/progress-circle";

const METRICS = [
  { label: "CPU", value: 38 },
  { label: "Memory", value: 64 },
  { label: "Disk", value: 82 },
];

export function ProgressCircleDashboard() {
  return (
    <div className="flex flex-wrap items-center justify-center gap-6">
      {METRICS.map(({ label, value }) => (
        <div key={label} className="flex flex-col items-center gap-2">
          <ProgressCircle value={value} showValue />
          <span className="text-xs text-ui-muted">{label}</span>
        </div>
      ))}
    </div>
  );
}

Usage

The minimal import and composition — see Examples below for styled, real-world variants.

5 lines
import { ProgressCircle } from "@codefast/ui/progress-circle";

export function ProgressCircleUsage() {
  return <ProgressCircle showValue value={66} />;
}

Anatomy

How the parts nest — every slot the component exposes, in composition order.

ProgressCircle

Features

  • Five preset sizes (sm/md/lg/xl/2xl, 32–128px) or an exact sizeInPixels override; stroke width scales with size unless set explicitly via strokeWidth.
  • Three thickness presets (thin/regular/thick) computed as a percentage of the circle's diameter, not a fixed pixel value.
  • Animates value changes over animationDuration (default 1000ms); disable with animated={false} for an instant jump.
  • renderLabel({ value }) replaces the default "N%" center text with your own render.

API reference

Props for each part of the component. All native element props are also forwarded.

ProgressCircle

A circular determinate progress indicator.

valuenumber

Progress from 0 to 100.

Default0

showValueboolean

Render the numeric value in the centre.

Defaultfalse

sizenumber

Diameter in pixels (overrides the size variant).

renderLabel({ value }) => JSX.Element

Render your own centre label instead of the number.

Accessibility

Built to be keyboard-navigable and screen-reader friendly out of the box.

  • Has role=progressbar with the value mirrored for assistive tech.
  • If showValue is off, describe progress nearby so it isn’t only visual.
  • Use a Spinner for indeterminate waits where there’s no percentage.

Guidelines

Conventions that keep usage consistent across an app.

Do

  • Use in compact spots — cards, avatars, dashboards.
  • Show the value for precise, glanceable feedback.

Don’t

  • Don’t use for indeterminate progress.
  • Don’t rely on colour alone to signal a threshold.

Explore further

Ready to integrate?

Follow the Getting Started guide to install @codefast/ui, or browse the full component gallery.