Components
- Accordion
- Alert
- Alert Dialog
- Aspect Ratio
- Autocomplete
- Avatar
- Badge
- Bar List
- Breadcrumb
- Button
- Button Group
- Calendar
- Card
- Carousel
- Checkbox
- Checkbox Group
- Circular Progress
- Collapsible
- Combobox
- Command
- Context Menu
- Currency Input
- Data Table
- Date Picker
- Dialog
- Drawer
- Dropdown Menu
- Empty
- Field
- Hover Card
- Input
- Input Group
- Input OTP
- Item
- Kbd
- Label
- Menubar
- Meter
- Multi Combobox
- Native Select
- Navigation Menu
- Number Field
- Pagination
- Phone Input
- Popover
- Progress
- Progress List
- Prompt
- Radio Group
- Resizable
- Scroll Area
- Select
- Separator
- Sheet
- Sidebar
- Skeleton
- Slider
- Sonner
- Spinner
- Stat
- Switch
- Table
- Tabs
- Textarea
- Toggle
- Toggle Group
- Tooltip
- Typography
Loading...
"use client";
import { useEffect, useState } from "react";
import { CircularProgress } from "@/components/ui/circular-progress";
import { Slider } from "@/components/ui/slider";
export function CircularProgressDemo() {
const [progress, setProgress] = useState(45);
const [autoProgress, setAutoProgress] = useState(false);
useEffect(() => {
if (!autoProgress) {
return;
}
const interval = setInterval(() => {
setProgress((previous) => {
if (previous >= 100) {
setAutoProgress(false);
return 0;
}
return previous + 5;
});
}, 500);
return () => clearInterval(interval);
}, [autoProgress]);
return (
<div className="grid w-full max-w-md gap-6">
<div className="flex items-center justify-center gap-8">
<div className="flex flex-col items-center">
<CircularProgress className="size-24" value={progress} />
<span className="mt-2 text-muted-foreground text-sm">With value</span>
</div>
<div className="flex flex-col items-center">
<CircularProgress className="size-24" hideText value={progress} />
<span className="mt-2 text-muted-foreground text-sm">
Indicator only
</span>
</div>
</div>
<div className="space-y-4">
<Slider
max={100}
min={0}
onValueChange={(value) => {
setProgress(value[0] ?? 0);
}}
step={1}
value={[progress]}
/>
</div>
</div>
);
}Installation
npx shadcn@latest add "https://ui.blode.co/r/styles/default/circular-progress"
Usage
import { CircularProgress } from "@/components/ui/circular-progress";<CircularProgress value={75} />Examples
Basic
Loading...
"use client";
import { useEffect, useState } from "react";
import { CircularProgress } from "@/components/ui/circular-progress";
import { Slider } from "@/components/ui/slider";
export function CircularProgressDemo() {
const [progress, setProgress] = useState(45);
const [autoProgress, setAutoProgress] = useState(false);
useEffect(() => {
if (!autoProgress) {
return;
}
const interval = setInterval(() => {
setProgress((previous) => {
if (previous >= 100) {
setAutoProgress(false);
return 0;
}
return previous + 5;
});
}, 500);
return () => clearInterval(interval);
}, [autoProgress]);
return (
<div className="grid w-full max-w-md gap-6">
<div className="flex items-center justify-center gap-8">
<div className="flex flex-col items-center">
<CircularProgress className="size-24" value={progress} />
<span className="mt-2 text-muted-foreground text-sm">With value</span>
</div>
<div className="flex flex-col items-center">
<CircularProgress className="size-24" hideText value={progress} />
<span className="mt-2 text-muted-foreground text-sm">
Indicator only
</span>
</div>
</div>
<div className="space-y-4">
<Slider
max={100}
min={0}
onValueChange={(value) => {
setProgress(value[0] ?? 0);
}}
step={1}
value={[progress]}
/>
</div>
</div>
);
}Without Text
You can hide the percentage text by using the hideText prop:
<CircularProgress hideText value={75} />Custom Stroke Width
You can customize the thickness of the progress ring:
<CircularProgress strokeWidth={8} value={75} />Dynamic Progress
You can update the value programmatically to show progress:
const [progress, setProgress] = useState(0);
useEffect(() => {
const timer = setInterval(() => {
setProgress((previousProgress) => {
const nextProgress = previousProgress + 5;
if (nextProgress >= 100) {
clearInterval(timer);
return 100;
}
return nextProgress;
});
}, 500);
return () => {
clearInterval(timer);
};
}, []);
return <CircularProgress value={progress} />;Props
| Prop | Type | Default | Description |
|---|---|---|---|
value | number | - | The progress value (0-100) |
strokeWidth | number | 4 | The width of the progress circle stroke |
hideText | boolean | false | Whether to hide the percentage text |
className | string | - | Additional CSS class name |