Progress
freeProgress shows how far a task or value has advanced, as a line or a circular gauge.
Preview
Dark
Storage used62 GB of 100 GB
import Progress from '@/components/ui/Progress';
export default function UsageDemo() {
return (
<div className="w-full max-w-sm rounded-card border border-border bg-card p-4 shadow-card">
<div className="flex items-center justify-between">
<span className="text-sm font-semibold text-foreground">
Storage used
</span>
<span className="text-xs text-muted-foreground">62 GB of 100 GB</span>
</div>
<div className="mt-4">
<Progress percent={62} />
</div>
</div>
);
}Installation
Add this component with the NateUI CLI.
npx nateui@latest add ProgressExamples
Basic
Preview
Dark
import Progress from '@/components/ui/Progress';
export default function BasicDemo() {
return (
<div className="w-full max-w-sm">
<Progress percent={45} />
</div>
);
}Circle
Preview
Dark
80%
import Progress from '@/components/ui/Progress';
export default function CircleDemo() {
return (
<Progress variant="circle" percent={80} />
);
}Size
Preview
Dark
50%
import Progress from '@/components/ui/Progress';
export default function SizeDemo() {
return (
<div className="flex flex-col gap-8">
<Progress size="md" percent={50} />
<Progress variant="circle" percent={50} width={80} />
</div>
);
}Color
Preview
Dark
import Progress from '@/components/ui/Progress';
export default function ColorDemo() {
return (
<div className="flex w-full max-w-sm flex-col gap-4">
<Progress strokeClass="bg-destructive" percent={38} />
<Progress strokeClass="bg-warning" percent={74} />
<Progress strokeClass="bg-success" percent={92} />
</div>
);
}Custom Info
Preview
Dark
68%
completed
import { PiCheckCircle, PiWarning } from 'react-icons/pi'
import Progress from '@/components/ui/Progress';
export default function CustomInfoDemo() {
return (
<div className="flex flex-wrap items-center gap-8">
<div className="flex w-full max-w-xs flex-col gap-4">
<Progress
strokeClass="bg-success"
percent={100}
customInfo={<PiCheckCircle className="text-lg text-success" />}
/>
<Progress
strokeClass="bg-warning"
percent={70}
customInfo={<PiWarning className="text-lg text-warning" />}
/>
<Progress percent={40} showInfo={false} />
</div>
<div className="flex justify-center items-center">
<Progress
variant="circle"
percent={68}
width={140}
customInfo={
<div className="text-center">
<div className="text-xl font-semibold text-foreground">68%</div>
<div className="text-xs text-muted-foreground">completed</div>
</div>
}
/>
</div>
</div>
);
}Gap
Preview
Dark
75%
import Progress from '@/components/ui/Progress';
export default function GapDemo() {
return (
<Progress
variant="circle"
percent={75}
gapDegree={70}
gapPosition="bottom"
strokeWidth={8}
/>
);
}Controlled
Preview
Dark
40%
import { useState } from 'react';
import { PiMinus, PiPlus } from 'react-icons/pi'
import Button from '@/components/ui/Button';
import Progress from '@/components/ui/Progress';
export default function ControlledDemo() {
const [percent, setPercent] = useState(40);
const step = (amount: number) => {
setPercent((current) => Math.min(100, Math.max(0, current + amount)));
};
return (
<div className="flex w-full max-w-sm flex-col gap-4">
<div className="flex items-center gap-8">
<Progress percent={percent} />
<Progress variant="circle" percent={percent} width={80} />
</div>
<div className="flex items-center gap-2">
<Button
shape="circle"
size="sm"
icon={<PiMinus />}
disabled={percent === 0}
onClick={() => step(-10)}
/>
<Button
shape="circle"
size="sm"
icon={<PiPlus />}
disabled={percent === 100}
onClick={() => step(10)}
/>
</div>
</div>
);
}API
Progress renders a line or circle indicator driven by percent. The line variant grows a bar and places its label beside it; the circle variant draws a gauge and centers its label. size applies to the line; width, gapDegree, gapPosition, strokeWidth, and strokeLinecap shape the circle.
| Prop | Description | Type | Default |
|---|---|---|---|
variant | Indicator shape to render. | 'line' | 'circle' | 'line' |
percent | Completion value from 0 to 100. | number | 0 |
showInfo | Whether the percentage label is shown. | boolean | true |
customInfo | Replaces the default ${percent}% label. | string | ReactNode | - |
size | Line thickness. Applies to the line variant only. | 'sm' | 'md' | 'md' |
strokeClass | Class applied to the filled indicator. Defaults to the primary color. | string | - |
trailClass | Class applied to the unfilled track. | string | - |
width | Diameter of the circle, in pixels or a CSS size. Circle only. | string | number | 120 |
gapDegree | Size of the gap in the circle ring, in degrees (0–360). Circle only. | number | 0 |
gapPosition | Where the ring gap sits. Circle only. | GapPosition | 'top' |
strokeWidth | Thickness of the circle ring stroke. Circle only. | number | 6 |
strokeLinecap | Shape of the circle stroke ends. Circle only. | StrokeLinecap | 'round' |
className | Class names applied to the progress root. | string | - |
ref | Ref forwarded to the root element. | Ref<HTMLDivElement> | - |
...nativeProps | Native div props applied to the root element. | ComponentProps<'div'> | - |
Types
type GapPosition = 'top' | 'right' | 'bottom' | 'left';
type StrokeLinecap = 'round' | 'square';