ProgressBar

ProgressBar is a process status indicator.

Usage#

import { ProgressBar } from 'primereact/progressbar';
<ProgressBar value={50}>
    <ProgressBar.Track>
        <ProgressBar.Indicator>
            <ProgressBar.Label>
                <ProgressBar.Value />
            </ProgressBar.Label>
        </ProgressBar.Indicator>
    </ProgressBar.Track>
</ProgressBar>

Examples#

Basic#

Use the value property to define the progress.

50%
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>
    );
}

Dynamic#

Value is reactive so updating it dynamically changes the bar as well.

0%
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>
    );
}

Formatter#

Custom formatter function to format the display value.

50/100
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>
    );
}

Template#

Place ProgressBar.Value where you want the progress value to be displayed inside the ProgressBar and customize formatter prop to display in different format.

Basic Percentage0.0%
File Size Progress0.00 B / 4.88 KB
Time Remaining0% (25s remaining)
Upload Status StepsPreparing file...
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>
    );
}

Indeterminate#

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>
    );
}

As Steps#

Steps are used to display a progress with multiple steps.

Order Placed
25%
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>
    );
}

Accessibility#

Screen Reader#

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" />

Keyboard Support#

Not applicable.