75%
Complete
Installation
Usage
import { ProgressCircle } from "@/components/ui/circular-progress";
const CircularProgressDemo = () => {
return (
<ProgressCircle
percent={75}
size={120}
stroke={8}
progressClass="stroke-blue-500"
duration={2}
>
<div className="text-center">
<div className="text-2xl font-bold">75%</div>
<div className="text-xs text-muted-foreground">Complete</div>
</div>
</ProgressCircle>
);
};
export default CircularProgressDemo;Examples
Custom Colors
<ProgressCircle
percent={85}
size={120}
stroke={8}
progressClass="stroke-emerald-500"
trackClass="stroke-emerald-100"
>
<div className="text-center">
<div className="text-xl font-bold text-emerald-600">85%</div>
<div className="text-xs text-muted-foreground">Success Rate</div>
</div>
</ProgressCircle>Multiple Sizes
<div className="flex items-end gap-6">
<ProgressCircle percent={75} size={80} stroke={6}>
<span className="text-sm font-medium">75%</span>
</ProgressCircle>
<ProgressCircle percent={75} size={120} stroke={8}>
<span className="text-xl font-bold">75%</span>
</ProgressCircle>
<ProgressCircle percent={75} size={160} stroke={10}>
<div className="text-center">
<div className="text-2xl font-bold">75%</div>
<div className="text-sm text-muted-foreground">Complete</div>
</div>
</ProgressCircle>
</div>Skills Dashboard
function SkillsDashboard() {
const skills = [
{ name: "React", level: 90, color: "stroke-blue-500" },
{ name: "TypeScript", level: 85, color: "stroke-cyan-500" },
{ name: "Node.js", level: 80, color: "stroke-green-500" },
{ name: "Design", level: 75, color: "stroke-purple-500" },
];
return (
<div className="grid grid-cols-2 md:grid-cols-4 gap-6">
{skills.map((skill, index) => (
<div key={skill.name} className="text-center">
<ProgressCircle
percent={skill.level}
size={100}
stroke={6}
progressClass={skill.color}
duration={1.5 + index * 0.2}
>
<div className="text-center">
<div className="text-lg font-bold">{skill.level}%</div>
</div>
</ProgressCircle>
<h3 className="mt-3 font-medium text-sm">{skill.name}</h3>
</div>
))}
</div>
);
}Loading State
import { useState, useEffect } from "react";
function LoadingExample() {
const [progress, setProgress] = useState(0);
useEffect(() => {
const timer = setInterval(() => {
setProgress((prev) => {
if (prev >= 100) {
clearInterval(timer);
return 100;
}
return prev + 1;
});
}, 50);
return () => clearInterval(timer);
}, []);
return (
<ProgressCircle
percent={progress}
size={140}
stroke={10}
progressClass="stroke-blue-500"
duration={0.1}
>
<div className="text-center">
<div className="text-2xl font-bold">{progress}%</div>
<div className="text-sm text-muted-foreground">
{progress < 100 ? "Loading..." : "Complete!"}
</div>
</div>
</ProgressCircle>
);
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
percent | number | Required | Progress percentage (0-100) |
size | number | 120 | Circle diameter in pixels |
stroke | number | 8 | Stroke width in pixels |
trackClass | string | "stroke-muted" | CSS class for background track |
progressClass | string | "stroke-primary" | CSS class for progress arc |
children | React.ReactNode | undefined | Content to display in center |
className | string | "" | Additional CSS classes for container |
duration | number | 1.5 | Animation duration in seconds |