A circular indicator used to show task or loading progress.
1'use client'
2
3import React, { useEffect, useState } from 'react'
4
5import CircularProgress from '@/components/ui/circular-progress'
6
7export function CircularProgressDemo() {
8 const [v1, setV1] = useState(0)
9 const [v2, setV2] = useState(5)
10
11 useEffect(() => {
12 const i1 = setInterval(() => {
13 setV1((n) => (n >= 100 ? 0 : n + 1))
14 }, 80)
15 const i2 = setInterval(() => {
16 setV2((n) => (n >= 75 ? 0 : n + 3))
17 }, 500)
18
19 return () => {
20 clearInterval(i1)
21 clearInterval(i2)
22 }
23 }, [])
24 return (
25 <div className="space-y-8">
26 <div className="grid grid-cols-2 items-center gap-6 sm:grid-cols-3">
27 <div className="flex flex-col items-center gap-2">
28 <CircularProgress
29 value={v1}
30 label={`${v1}%`}
31 classNames={{
32 svg: 'drop-shadow-md',
33 indicator: 'stroke-success',
34 track: 'stroke-success/20',
35 value: 'text-sm font-semibold text-success',
36 }}
37 size={64}
38 strokeWidth={6}
39 />
40 </div>
41 <div className="flex flex-col items-center gap-2">
42 <CircularProgress
43 value={v2}
44 label={`${v2}%`}
45 classNames={{
46 svg: 'drop-shadow-md',
47 indicator: 'stroke-yellow',
48 track: 'stroke-yellow/20',
49 value: 'text-sm font-semibold text-primary',
50 }}
51 size={56}
52 strokeWidth={5}
53 />
54 </div>
55 <div className="flex flex-col items-center gap-2">
56 <CircularProgress
57 value={30}
58 label={`${30}%`}
59 classNames={{
60 svg: 'drop-shadow-md',
61 indicator: 'stroke-danger',
62 track: 'stroke-gray/30',
63 value: 'text-sm font-semibold text-danger',
64 }}
65 />
66 </div>
67 </div>
68 </div>
69 )
70}
71Install the following dependencies:
1import React from 'react'
2
3import CircularProgress from '@/components/ui/circular-progress'
4
5export function CircularProgressIndeterminate() {
6 return (
7 <div className="space-y-8">
8 <div className="grid grid-cols-2 items-center gap-6 sm:grid-cols-5">
9 <div className="flex flex-col items-center gap-2">
10 <CircularProgress
11 indeterminate
12 size="default"
13 className="text-blue"
14 />
15 <div className="text-muted-foreground text-xs">Default</div>
16 </div>
17 <div className="flex flex-col items-center gap-2">
18 <CircularProgress
19 indeterminate
20 size="sm"
21 className="text-warning"
22 />
23 <div className="text-muted-foreground text-xs">Small</div>
24 </div>
25 <div className="flex flex-col items-center gap-2">
26 <CircularProgress
27 indeterminate
28 size="md"
29 className="text-danger"
30 />
31 <div className="text-muted-foreground text-xs">Medium</div>
32 </div>
33 <div className="flex flex-col items-center gap-2">
34 <CircularProgress
35 indeterminate
36 size="lg"
37 className="text-secondary"
38 />
39 <div className="text-muted-foreground text-xs">Large</div>
40 </div>
41 <div className="flex flex-col items-center gap-2">
42 <CircularProgress
43 indeterminate
44 size={72}
45 className="text-secondary"
46 />
47 <div className="text-muted-foreground text-xs">
48 Custom Size
49 </div>
50 </div>
51 </div>
52 </div>
53 )
54}
551'use client'
2
3import React, { useEffect, useState } from 'react'
4
5import CircularProgress from '@/components/ui/circular-progress'
6
7export function CircularProgressStrokewidth() {
8 const [v1, setV1] = useState(0)
9
10 useEffect(() => {
11 const i1 = setInterval(() => {
12 setV1((n) => (n >= 300 ? 0 : n + 20))
13 }, 400)
14
15 return () => {
16 clearInterval(i1)
17 }
18 }, [])
19 return (
20 <div className="space-y-8">
21 <div className="grid grid-cols-2 items-center gap-6 sm:grid-cols-3">
22 <div className="flex flex-col items-center gap-2">
23 <CircularProgress
24 indeterminate
25 size="md"
26 className="text-danger"
27 />
28 </div>
29 <div className="flex flex-col items-center gap-2">
30 <CircularProgress
31 indeterminate
32 size="lg"
33 strokeWidth={6}
34 className="text-secondary"
35 />
36 </div>
37 <div className="flex flex-col items-center gap-2">
38 <CircularProgress
39 value={(v1 / 500) * 100}
40 size={72}
41 strokeWidth={8}
42 className="text-secondary"
43 />
44 </div>
45 </div>
46 </div>
47 )
48}
49
501import React from 'react'
2
3import CircularProgress from '@/components/ui/circular-progress'
4
5export function CircularProgressIndeterminate() {
6 return (
7 <div className="space-y-8">
8 <div className="grid grid-cols-1 items-center gap-6 sm:grid-cols-2">
9 <div className="flex flex-col items-center gap-2">
10 <CircularProgress
11 value={70}
12 label={`70km`}
13 ariaLabel="Speed"
14 size={64}
15 />
16 </div>
17 <div className="flex flex-col items-center gap-2">
18 <CircularProgress
19 value={70}
20 label={`70km`}
21 ariaLabel="Speed"
22 size={72}
23 className="text-primary"
24 classNames={{
25 svg: 'drop-shadow-md',
26 indicator: 'stroke-success',
27 track: 'stroke-success/20',
28 value: 'text-sm font-semibold text-success',
29 caption:
30 'border border-success px-3 py-1 rounded-full text-md font-medium text-success bg-success/20',
31 }}
32 strokeWidth={6}
33 />
34 </div>
35 </div>
36 </div>
37 )
38}
39| Prop | Type | Default |
|---|---|---|
| value | number | 0 |
| size | number, sm, md, lg, default | default |
| strokeWidth | number | 4 |
| indeterminate | boolean | false |
| label | string | - |
| classNames | { svg?: string; track?: string; indicator?: string; value?: string, caption?: string } | - |