Github

Progress

Displays an indicator showing the completion progress of a task, typically as a progress bar.

x
"use client";
import * as React from "react";
import { Progress } from "@/components/ui/progress";
export function ProgressDemo() {	const [progress, setProgress] = React.useState(13);
	React.useEffect(() => {		const timer = setTimeout(() => setProgress(66), 500);		return () => clearTimeout(timer);	}, []);
	return <Progress value={progress} className="w-[60%]" />;}

Installation

pnpm dlx shadcn@latest add @herocn/progress

Usage

import {  Progress,  ProgressLabel,  ProgressValue,} from "@/components/ui/progress"
<Progress value={33} />

Composition

Use ProgressLabel and ProgressValue as optional children for a header row; the track and indicator are rendered automatically inside Progress.

Progress├── ProgressLabel├── ProgressValue└── ProgressTrack    └── ProgressIndicator

Examples

Label

Use ProgressLabel and ProgressValue to show a title and formatted percentage.

Upload progress
x
import {	Progress,	ProgressLabel,	ProgressValue,} from "@/components/ui/progress";
export function ProgressLabelExample() {	return (		<Progress value={56} className="w-full max-w-sm">			<ProgressLabel>Upload progress</ProgressLabel>			<ProgressValue />		</Progress>	);}

Variants

Use the variant prop to match semantic status colors (default uses the neutral foreground on the track).

Default

x

Primary

x

Success

x

Warning

x

Destructive

x
import { Progress } from "@/components/ui/progress";
export function ProgressVariants() {	return (		<div className="flex w-full max-w-sm flex-col gap-4">			<div className="space-y-1">				<p className="text-muted-foreground text-xs">Default</p>				<Progress value={45} variant="default" className="w-full" />			</div>			<div className="space-y-1">				<p className="text-muted-foreground text-xs">Primary</p>				<Progress value={50} variant="primary" className="w-full" />			</div>			<div className="space-y-1">				<p className="text-muted-foreground text-xs">Success</p>				<Progress value={72} variant="success" className="w-full" />			</div>			<div className="space-y-1">				<p className="text-muted-foreground text-xs">Warning</p>				<Progress value={38} variant="warning" className="w-full" />			</div>			<div className="space-y-1">				<p className="text-muted-foreground text-xs">Destructive</p>				<Progress value={88} variant="destructive" className="w-full" />			</div>		</div>	);}

Sizes

Use the size prop to change the track height (sm, default, or lg).

Small
x
Default
x
Large
x
import {	Progress,	ProgressLabel,	ProgressValue,} from "@/components/ui/progress";
export function ProgressSizes() {	return (		<div className="flex w-full max-w-sm flex-col gap-6">			<Progress value={40} size="sm" className="w-full">				<ProgressLabel>Small</ProgressLabel>				<ProgressValue />			</Progress>			<Progress value={55} size="default" className="w-full">				<ProgressLabel>Default</ProgressLabel>				<ProgressValue />			</Progress>			<Progress value={70} size="lg" className="w-full">				<ProgressLabel>Large</ProgressLabel>				<ProgressValue />			</Progress>		</div>	);}

Controlled

Drive the bar from another control, such as a slider.

x
"use client";
import * as React from "react";
import { Progress } from "@/registry/new-york-v4//ui/progress";import { Slider } from "@/registry/new-york-v4//ui/slider";
export function ProgressControlled() {	const [value, setValue] = React.useState(50);
	return (		<div className="flex w-full max-w-sm flex-col gap-4">			<Progress size="lg" value={value} className="w-full" />			<Slider				value={value}				onValueChange={(value) => setValue(value as number)}				min={0}				max={100}				step={1}			/>		</div>	);}

RTL

To enable RTL support in shadcn/ui, see the RTL configuration guide.

تقدم الرفع
x
"use client";
import {	type Translations,	useTranslation,} from "@/components/language-selector";import {	Progress,	ProgressLabel,	ProgressValue,} from "@/components/ui/progress";
const translations: Translations = {	en: {		dir: "ltr",		values: {			label: "Upload progress",		},	},	ar: {		dir: "rtl",		values: {			label: "تقدم الرفع",		},	},	he: {		dir: "rtl",		values: {			label: "התקדמות העלאה",		},	},};
function toArabicNumerals(num: number): string {	const arabicNumerals = ["٠", "١", "٢", "٣", "٤", "٥", "٦", "٧", "٨", "٩"];	return num		.toString()		.split("")		.map((digit) => arabicNumerals[Number.parseInt(digit, 10)] ?? digit)		.join("");}
export function ProgressRtl() {	const { dir, t, language } = useTranslation(translations, "ar");
	const formatNumber = (num: number): string => {		if (language === "ar") {			return toArabicNumerals(num);		}		return num.toString();	};
	return (		<div className="w-full max-w-sm" lang={language} dir={dir}>			<Progress value={56} className="w-full">				<ProgressLabel>{t.label}</ProgressLabel>				<ProgressValue>					{(_formatted, value) => (						<span className="ms-auto">{formatNumber(value ?? 0)}%</span>					)}				</ProgressValue>			</Progress>		</div>	);}

API Reference

Progress

Progress wraps Base UI Progress.Root and sets variant and size on the root for styling the built-in track and indicator.

PropTypeDefault

ProgressLabel

PropTypeDefault

ProgressValue

PropTypeDefault

ProgressTrack & ProgressIndicator

These parts are rendered by default. They are exported if you need to build a fully custom layout alongside the same primitives.

For the full root API (locale, getAriaValueText, etc.), see the Base UI Progress documentation.