Skip to main content
In progress

ProgressBar

A visual indicator that displays the completion status of a task or process. Supports both determinate (known progress) and indeterminate (unknown duration) states.

Loading
50% complete
Code example
import { ProgressBar } from '@yleisradio/yds-components-react';

<ProgressBar
value={50}
max={100}
label="Loading"
description="50% complete"
/>

Why to use

Use the ProgressBar component to provide visual feedback about the status of ongoing operations such as file uploads, downloads, form submissions, or any process with measurable progress.

When to use

Use ProgressBar when you need to communicate progress of a task to users, helping them understand how much work has been completed and how much remains.

Do
  • File uploads or downloads where size/progress is known
  • Multi-step processes like form submissions or wizards
  • Data processing, importing, or exporting operations
  • Installation, setup, or configuration workflows
  • Media buffering when duration can be calculated
Don't
  • Don't use for instantaneous actions (under ~300ms) — no indicator needed, or use a brief Spinner for visual consistency
  • Don't use when progress cannot be measured and the operation may complete quickly — use a Spinner instead
  • Don't display fabricated progress values — use the indeterminate variant when actual progress is unknown

Anatomy

  1. Label – Optional text above the progress bar describing the operation
  2. Status Icon – Checkmark (success) or alert triangle (error) shown next to label
  3. Track – Background container showing the full extent of progress
  4. Indicator – Filled portion showing current progress
  5. Description – Optional text below the bar with additional context

Key ProgressBar Props

Use these props to configure the ProgressBar component.

variant

Defines whether the progress is measurable or unknown.

ValueExampleDescription
determinate
Shows specific progress percentage
indeterminate
Animated indicator for unknown duration
Code example
<ProgressBar variant="determinate" value={60} max={100} />
<ProgressBar variant="indeterminate" />

status

Indicates the current state of the progress operation.

ValueExampleDescription
active
Operation in progress (turquoise)
success
Done
Operation completed successfully (green)
error
Failed
Operation failed (red)
Code example
<ProgressBar status="active" value={50} max={100} />
<ProgressBar status="success" value={100} max={100} label="Done" />
<ProgressBar status="error" value={75} max={100} label="Failed" />

value and max

Controls the progress percentage. Follows HTML <progress> element convention.

PropsExampleDescription
value, max
Current value (30) out of maximum (100)
Code example
<ProgressBar value={30} max={100} />
<ProgressBar value={3} max={10} />

label

Provides descriptive text above the progress bar.

TypeExampleDescription
string
Uploading files...
Text displayed above the progress bar
Code example
<ProgressBar value={50} max={100} label="Uploading files..." />

description

Provides additional context below the progress bar.

TypeExampleDescription
string
2 of 4 files uploaded
Text displayed below the progress bar
Code example
<ProgressBar value={50} max={100} description="2 of 4 files uploaded" />
<ProgressBar status="error" value={75} max={100} description="Upload failed" />

Behavior

  • Determinate progress smoothly animates as the value changes
  • Indeterminate progress continuously animates with a sliding indicator
  • Success and error states display corresponding icons next to the label
  • Error state changes description text color to red

Implementation examples

File upload simulation

This example demonstrates how to use the ProgressBar component to show upload progress with dynamic state updates, transitioning from active to success or error states.

Ready to upload
Click the button to start upload
Code example
import { useState, useCallback } from 'react';
import { Button, ProgressBar } from '@yleisradio/yds-components-react';

type UploadState = 'idle' | 'uploading' | 'success' | 'error';

export const ProgressBarUploadSimulation = () => {
const [progress, setProgress] = useState(0);
const [uploadState, setUploadState] = useState<UploadState>('idle');

const simulateUpload = useCallback(() => {
setProgress(0);
setUploadState('uploading');

let currentProgress = 0;
const interval = setInterval(() => {
const increment = Math.random() * 15 + 5;
currentProgress = Math.min(currentProgress + increment, 100);
setProgress(Math.round(currentProgress));

if (currentProgress >= 100) {
clearInterval(interval);
setUploadState('success');
}
}, 300);
}, []);

const getStatus = () => {
if (uploadState === 'success') return 'success';
if (uploadState === 'error') return 'error';
return 'active';
};

const getLabel = () => {
switch (uploadState) {
case 'idle': return 'Ready to upload';
case 'uploading': return 'Uploading file...';
case 'success': return 'Upload complete';
case 'error': return 'Upload failed';
}
};

const getDescription = () => {
switch (uploadState) {
case 'idle': return 'Click the button to start upload';
case 'uploading': return `${progress}% complete`;
case 'success': return 'Your file has been uploaded successfully';
case 'error': return 'Network error occurred. Please try again.';
}
};

return (
<div style={{ maxWidth: '400px' }}>
<ProgressBar
value={progress}
max={100}
status={getStatus()}
label={getLabel()}
description={getDescription()}
/>
<div style={{ marginTop: '16px' }}>
{uploadState === 'idle' && (
<Button onClick={simulateUpload}>Start Upload</Button>
)}
{(uploadState === 'success' || uploadState === 'error') && (
<Button onClick={() => { setProgress(0); setUploadState('idle'); }}>
Reset
</Button>
)}
</div>
</div>
);
};

Accessibility

  • Uses role="progressbar" for semantic meaning
  • Includes aria-valuenow, aria-valuemin, aria-valuemax for screen readers
  • Label text is connected via aria-label
  • Color is not the only indicator of status (icons are included)

API Reference

Props

The ProgressBar component accepts all standard HTML <div> attributes in addition to the following props:

PropTypeRequiredDefaultDescription
valuenumberNo0Current progress value
maxnumberNo100Maximum progress value
variant'determinate' | 'indeterminate'No'determinate'Progress bar variant
status'active' | 'success' | 'error'No'active'Current status of the operation
labelstringNoText label above the progress bar
descriptionstringNoDescription text below the progress bar

Type Definitions

export const progressBarStatuses = ['active', 'success', 'error'] as const;
export const progressBarVariants = ['determinate', 'indeterminate'] as const;

export type ProgressBarStatus = (typeof progressBarStatuses)[number];
export type ProgressBarVariant = (typeof progressBarVariants)[number];

export interface ProgressBarDSProps {
value?: number;
max?: number;
variant?: ProgressBarVariant;
status?: ProgressBarStatus;
label?: string;
description?: string;
}

export type ProgressBarProps = ProgressBarDSProps & HTMLAttributes<HTMLDivElement>;
  • Spinner – For loading states without progress tracking
  • Notification – For displaying success/error messages after completion