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.
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.
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.
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.
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.
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.
valuenumberProgress from 0 to 100.
Default
0showValuebooleanRender the numeric value in the centre.
Default
falsesizenumberDiameter in pixels (overrides the size variant).
renderLabel({ value }) => JSX.ElementRender 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.