ProgressBar is a process status indicator.
import { ProgressBar } from 'primereact/progressbar';
<ProgressBar value={50}>
<ProgressBar.Track>
<ProgressBar.Indicator>
<ProgressBar.Label>
<ProgressBar.Value />
</ProgressBar.Label>
</ProgressBar.Indicator>
</ProgressBar.Track>
</ProgressBar>
Use the value
property to define the progress.
import { ProgressBar } from 'primereact/progressbar';
export default function BasicDemo() {
const value = 50;
return (
<div className="card">
<ProgressBar value={value}>
<ProgressBar.Track>
<ProgressBar.Indicator>
<ProgressBar.Label>
<ProgressBar.Value />
</ProgressBar.Label>
</ProgressBar.Indicator>
</ProgressBar.Track>
</ProgressBar>
</div>
);
}
Value is reactive so updating it dynamically changes the bar as well.
import { ProgressBar } from 'primereact/progressbar';
import * as React from 'react';
export default function DynamicDemo() {
const [value, setValue] = React.useState(0);
const interval = React.useRef<NodeJS.Timeout | undefined>(undefined);
React.useEffect(() => {
interval.current = setInterval(() => {
setValue((prevValue) => {
const newValue = prevValue + Math.random() * 10 + 1;
if (newValue >= 100) {
clearInterval(interval.current);
return 100;
}
return newValue;
});
}, 2000);
return () => {
if (interval.current) {
clearInterval(interval.current);
interval.current = undefined;
}
};
}, []);
return (
<div className="card">
<ProgressBar value={value}>
<ProgressBar.Track>
<ProgressBar.Indicator>
<ProgressBar.Label>
<ProgressBar.Value />
</ProgressBar.Label>
</ProgressBar.Indicator>
</ProgressBar.Track>
</ProgressBar>
</div>
);
}
Custom formatter function to format the display value.
import { ProgressBar } from 'primereact/progressbar';
export default function FormatterDemo() {
return (
<div className="card">
<ProgressBar value={50} formatter={(value: number) => `${value}/100`}>
<ProgressBar.Track>
<ProgressBar.Indicator>
<ProgressBar.Label>
<ProgressBar.Value />
</ProgressBar.Label>
</ProgressBar.Indicator>
</ProgressBar.Track>
</ProgressBar>
</div>
);
}
Place ProgressBar.Value
where you want the progress value to be displayed inside the ProgressBar
and customize formatter
prop to display in different format.
import { ProgressBar } from 'primereact/progressbar';
import * as React from 'react';
export default function TemplateDemo() {
const [uploadedFileSize, setUploadedFileSize] = React.useState(0);
const maxFileSize = 5000;
React.useEffect(() => {
const interval = setInterval(() => {
setUploadedFileSize((prevValue) => {
const newValue = prevValue + Math.floor(Math.random() * 200) + 1;
return newValue >= maxFileSize ? maxFileSize : newValue;
});
}, 500);
return () => clearInterval(interval);
}, []);
const formatFileSize = (bytes: number) => {
if (bytes < 1024) return bytes.toFixed(2) + ' B';
else if (bytes < 1048576) return (bytes / 1024).toFixed(2) + ' KB';
else return (bytes / 1048576).toFixed(2) + ' MB';
};
return (
<div className="card">
<div className="max-w-sm mx-auto space-y-8">
{/* Basic percentage formatter */}
<ProgressBar value={uploadedFileSize} max={maxFileSize} formatter={(value: number) => `${value.toFixed(1)}%`}>
<div className="flex items-center justify-between mb-3">
<span className="font-medium">Basic Percentage</span>
<ProgressBar.Value />
</div>
<ProgressBar.Track className="rounded-full h-1.5">
<ProgressBar.Indicator className="bg-blue-600 rounded-full" />
</ProgressBar.Track>
</ProgressBar>
{/* File size formatter */}
<ProgressBar
value={uploadedFileSize}
max={maxFileSize}
formatter={(value: number) => {
const currentSize = (value / 100) * maxFileSize;
return `${formatFileSize(currentSize)} / ${formatFileSize(maxFileSize)}`;
}}
>
<div className="flex items-center justify-between mb-3">
<span className="font-medium">File Size Progress</span>
<ProgressBar.Value />
</div>
<ProgressBar.Track className="rounded-full h-1.5">
<ProgressBar.Indicator className="bg-emerald-600 rounded-full" />
</ProgressBar.Track>
</ProgressBar>
{/* Time remaining formatter */}
<ProgressBar
value={uploadedFileSize}
max={maxFileSize}
formatter={(value: number) => {
const remaining = ((maxFileSize - uploadedFileSize) / 200).toFixed(0);
return `${value.toFixed(0)}% (${remaining}s remaining)`;
}}
>
<div className="flex items-center justify-between mb-3">
<span className="font-medium">Time Remaining</span>
<ProgressBar.Value />
</div>
<ProgressBar.Track className="rounded-full h-1.5">
<ProgressBar.Indicator className="bg-purple-600 rounded-full" />
</ProgressBar.Track>
</ProgressBar>
{/* Status Steps formatter */}
<ProgressBar
value={uploadedFileSize}
max={maxFileSize}
formatter={(value: number) => {
if (value < 40) return 'Preparing file...';
else if (value < 60) return 'Uploading file...';
else if (value < 99) return 'Finalizing...';
else return 'Upload complete';
}}
>
<div className="flex items-center justify-between mb-3">
<span className="font-medium">Upload Status Steps</span>
<ProgressBar.Value />
</div>
<ProgressBar.Track className="rounded-full h-1.5">
<ProgressBar.Indicator className="bg-orange-600 rounded-full" />
</ProgressBar.Track>
</ProgressBar>
</div>
</div>
);
}
For progresses with no value to track, set the mode
property to indeterminate
.
import { ProgressBar } from 'primereact/progressbar';
export default function IndeterminateDemo() {
return (
<div className="card">
<ProgressBar mode="indeterminate">
<ProgressBar.Track className="h-1.5">
<ProgressBar.Indicator />
</ProgressBar.Track>
</ProgressBar>
</div>
);
}
Steps are used to display a progress with multiple steps.
import { cn } from '@primeuix/utils';
import { Button } from 'primereact/button';
import { ProgressBar } from 'primereact/progressbar';
import * as React from 'react';
const orderProgress = [
{
status: 'Place Order'
},
{
status: 'Order Placed',
colors: {
track: 'bg-blue-500/20',
indicator: 'bg-blue-600 dark:bg-blue-400'
}
},
{
status: 'Processing',
colors: {
track: 'bg-yellow-500/20',
indicator: 'bg-amber-600 dark:bg-amber-400'
}
},
{
status: 'Shipped',
colors: {
track: 'bg-purple-500/20',
indicator: 'bg-violet-600 dark:bg-violet-400'
}
},
{
status: 'Delivered',
colors: {
track: 'bg-green-500/20',
indicator: 'bg-green-600 dark:bg-green-400'
}
}
];
export default function StepsDemo() {
const [step, setStep] = React.useState(1);
const nextStep = () => setStep(Math.min(step + 1, orderProgress.length));
const prevStep = () => setStep(Math.max(step - 1, 0));
return (
<div className="card">
<div className="max-w-sm mx-auto">
<div className="mb-3 font-medium">{orderProgress[step].status}</div>
<ProgressBar value={step} min={0} max={4}>
{() => {
const { colors } = orderProgress[step] ?? {};
return (
<ProgressBar.Track className={cn(colors?.track, 'transition-all duration-300 ease-linear')}>
<ProgressBar.Indicator className={cn(colors?.indicator, 'transition-[width,_background-color] duration-300 ease-linear')}>
<ProgressBar.Label>
<ProgressBar.Value />
</ProgressBar.Label>
</ProgressBar.Indicator>
</ProgressBar.Track>
);
}}
</ProgressBar>
<div className="flex items-center justify-between mt-6">
<Button onClick={prevStep} disabled={step === 0} rounded variant="text" severity="contrast">
Previous
</Button>
<Button onClick={nextStep} disabled={step === orderProgress.length - 1} rounded variant="text" severity="contrast">
Next
</Button>
</div>
</div>
</div>
);
}
ProgressBar components uses progressbar role along with aria-valuemin, aria-valuemax and aria-valuenow attributes. Value to describe the component can be defined using aria-labelledby and aria-label props.
<span id="label_status" />
<ProgressBar aria-labelledby="label_status" />
<ProgressBar aria-label="Status" />
Not applicable.