Progress
Linear progress bar indicating completion status of a process or task.
progress.tsx
Progress bar built with Radix Primitive supporting colors, sizes, indeterminate state, and labels.
ReactRadix UITailwindUI ComponentProgress
"use client";
import * as React from "react";
import * as ProgressPrimitive from "@radix-ui/react-progress";
import { cn } from "@/lib/utils";
import { designColors } from "@/lib/design-system";
export interface ProgressProps
extends React.ComponentPropsWithoutRef<typeof ProgressPrimitive.Root> {
value?: number;
size?: "sm" | "md" | "lg";
color?: keyof typeof designColors;
isIndeterminate?: boolean;
label?: string;
showValueLabel?: boolean;
}
const progressSizes = {
sm: "h-1.5",
md: "h-2.5",
lg: "h-4",
};
const progressColors = {
default: "bg-foreground",
primary: "bg-primary",
secondary: "bg-secondary",
accent: "bg-accent",
success: "bg-emerald-500",
warning: "bg-amber-500",
danger: "bg-rose-500",
};
const Progress = React.forwardRef<
React.ElementRef<typeof ProgressPrimitive.Root>,
ProgressProps
>(
(
{
className,
value = 0,
size = "md",
color = "primary",
isIndeterminate = false,
label,
showValueLabel = false,
...props
},
ref
) => {
const clampedValue = Math.min(100, Math.max(0, value));
return (
<div className="w-full space-y-1.5">
{(label || showValueLabel) && (
<div className="flex items-center justify-between text-sm font-medium text-foreground">
{label ? <span>{label}</span> : <span />}
{showValueLabel && !isIndeterminate && (
<span className="text-xs text-muted-foreground">{Math.round(clampedValue)}%</span>
)}
</div>
)}
<ProgressPrimitive.Root
ref={ref}
aria-label={label || "Progress bar"}
value={isIndeterminate ? undefined : clampedValue}
className={cn(
"relative w-full overflow-hidden rounded-full bg-muted/60 shrink-0",
progressSizes[size],
className
)}
{...props}
>
<ProgressPrimitive.Indicator
className={cn(
"h-full w-full flex-1 transition-all duration-300 ease-in-out rounded-full",
progressColors[color],
isIndeterminate && "animate-progress-indeterminate origin-left"
)}
style={
isIndeterminate
? undefined
: { transform: `translateX(-${100 - clampedValue}%)` }
}
/>
</ProgressPrimitive.Root>
</div>
);
}
);
Progress.displayName = "Progress";
export { Progress };
Basic Usage
Displays a progress bar with a numeric percentage value from 0 to 100.
value: number
Colors
Apply custom color themes using the color prop.
color:
default | primary | secondary | accent | success | warning | dangerSizes
Adjust the height scale using sm, md, or lg.
size:
sm | md | lgLabels & Value Display
Combine text description and numeric percentage with label and showValueLabel.
label: stringshowValueLabel: boolean
Uploading file...75%
Storage used100%
Animated Progress (0% to 100%)
Demonstrates a real-time animated progress simulation from 0% to 100% with restart capability.
Simulating download...0%
Indeterminate State
Set isIndeterminate for ongoing processes without a fixed completion percentage.
isIndeterminate: boolean
Fetching server status...
API Reference
Props — Progress
Properties for configuring the Progress component.
| Prop | Type | Default | Description |
|---|---|---|---|
| value | number | 0 | Completion percentage value from 0 to 100. |
| size | 'sm' | 'md' | 'lg' | 'md' | Height dimension of the progress track. |
| color | 'default' | 'primary' | 'secondary' | 'accent' | 'success' | 'warning' | 'danger' | 'primary' | Color theme fill of the indicator bar. |
| isIndeterminate | boolean | false | Enables animated continuous loading mode without fixed value. |
| label | string | — | Optional text label displayed above the progress bar. |
| showValueLabel | boolean | false | Displays formatted percentage text on the top right. |