Progress indicators are visual components that show the completion status of ongoing operations or tasks. They provide users with feedback about the system's state, helping manage expectations during loading processes, file uploads, downloads, or any task that takes time to complete.
The default progress indicator displays as a horizontal bar showing determinate progress:
Add descriptive labels to provide context about what is being tracked:
Use circular progress for compact spaces or to emphasize the completion percentage:
Display the percentage value in the center of circular progress indicators:
Use indeterminate mode for operations where the completion time is unknown:
Different color variants communicate different states or types of operations:
Progress indicators come in six sizes to fit different layouts:
Progress indicators support custom maximum values for non-percentage tracking:
const progress = document.querySelector('dap-ds-progress');
// Update progress value
progress.value = 50;
// Simulate progress
let currentProgress = 0;
const interval = setInterval(() => {
currentProgress += 10;
progress.value = currentProgress;
if (currentProgress >= 100) {
clearInterval(interval);
progress.color = 'positive';
progress.label = 'Complete!';
}
}, 500);
const progress = document.querySelector('dap-ds-progress');
const fileInput = document.querySelector('input[type="file"]');
fileInput.addEventListener('change', async (e) => {
const file = e.target.files[0];
const xhr = new XMLHttpRequest();
xhr.upload.addEventListener('progress', (event) => {
if (event.lengthComputable) {
const percentComplete = (event.loaded / event.total) * 100;
progress.value = percentComplete;
progress.label = `Uploading ${file.name}`;
}
});
xhr.addEventListener('load', () => {
progress.value = 100;
progress.color = 'positive';
progress.label = 'Upload complete!';
});
xhr.addEventListener('error', () => {
progress.color = 'negative';
progress.label = 'Upload failed';
});
xhr.open('POST', '/upload');
xhr.send(file);
});
Progress indicators automatically include appropriate ARIA attributes:
- Role: Uses
progressbarrole for determinate progress andstatusrole for indeterminate - ARIA attributes: Includes
aria-valuenow,aria-valuemin,aria-valuemaxfor determinate states - Live regions: Progress changes are announced to screen readers
- Labels: Support for
aria-labeland visible labels for context - Keyboard accessible: All interactive states are keyboard navigable
Use Linear Progress when:
- Displaying progress in lists or tables
- Space allows for horizontal layout
- Multiple progress indicators are shown vertically
- Progress is the primary focus of the interface
Use Circular Progress when:
- Space is limited or you need a compact indicator
- Displaying system metrics or status
- Progress is supplementary information
- You want to emphasize the percentage value
Use Determinate Progress when:
- You know the total amount of work
- You can calculate the percentage complete
- Users benefit from seeing exact progress
Use Indeterminate Progress when:
- The total work is unknown
- Operation time varies significantly
- You cannot accurately track progress
- Initial loading state before determinate tracking begins
- Avoid updating progress values too frequently (throttle to 100-200ms)
- Use
aria-live="polite"for non-critical updates - Consider using
aria-live="assertive"only for critical progress updates - Batch multiple progress updates when possible
- Always provide context: Use labels to explain what is progressing
- Match colors to meaning: Use positive for success, negative for errors
- Show completion state: Change color or label when progress reaches 100%
- Handle errors gracefully: Update color and label on failures
- Consider mobile: Use appropriate sizes for touch targets
- Test with screen readers: Ensure progress updates are announced clearly
The progress component supports extensive customization through CSS custom properties and parts.
Experiment with custom progress styling using CSS parts and custom properties. The progress component exposes several CSS parts for advanced styling: base, track, fill, label, and percentage. Try the presets below or create your own styles:
import { DapDSProgress } from 'dap-design-system'
import { DapDSProgressReact } from 'dap-design-system/react'
For optimal bundle sizes, use the tree-shakeable import syntax:
import { DapDSProgress } from 'dap-design-system/components'
| Property | Type | Default | Description |
|---|---|---|---|
variant | "linear", "circular" | 'linear' | The variant of the progress indicator. |
color | "neutral", "brand" , "negative" , "positive" , "inverted" | 'brand' | The color variant of the progress indicator. |
size | "xxl", "xl" , "lg" , "md" , "sm" , "xs" | 'md' | The size of the progress indicator. |
value | number, undefined | Current progress value (0-100 for percentage, or 0-max). | |
max | number | 100 | Maximum value for the progress indicator. |
indeterminate | boolean | false | Whether to show the progress as indeterminate (loading animation). |
showPercentage | boolean | false | Whether to show percentage text in the center (circular variant only). |
label | string, undefined | Label text for the progress indicator. | |
ariaLive | "polite", "assertive" , "off" | 'polite' | The aria-live politeness level for screen readers. |
| Name | Description |
|---|---|
label | Custom label content for the progress indicator. |
No custom events available.
| Part Name | Description |
|---|---|
base | The main progress container. |
track | The progress track (background). |
fill | The progress fill (bar for linear, circle for circular). |
label | The progress label text. |
percentage | The percentage text (circular variant only). |
background | The background circle (circular variant only). |
You can style CSS parts using the ::part() pseudo-element selector:
/* Target a specific part */
.my-custom-dap-ds-progress::part(base) {
/* Your custom styles */
}
/* Target multiple parts */
.my-custom-dap-ds-progress::part(base),
.my-custom-dap-ds-progress::part(track) {
/* Shared styles */
}
Example usage:
<dap-ds-progress class="my-custom-dap-ds-progress">
Progress
</dap-ds-progress>
.my-custom-dap-ds-progress::part(base) {
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
CSS parts allow you to style internal elements of the component while maintaining encapsulation. Learn more in our styling guide.
| Property Name | Description |
|---|---|
--dds-progress-track-color | Background color of the progress track. Default is var(--dds-neutral-200). |
--dds-progress-fill-color-neutral | Fill color for neutral variant. Default is var(--dds-icon-neutral-base). |
--dds-progress-fill-color-brand | Fill color for brand variant. Default is var(--dds-icon-brand-subtle). |
--dds-progress-fill-color-negative | Fill color for negative variant. Default is var(--dds-icon-negative-subtle). |
--dds-progress-fill-color-positive | Fill color for positive variant. Default is var(--dds-icon-positive-subtle). |
--dds-progress-fill-color-inverted | Fill color for inverted variant. Default is var(--dds-icon-neutral-inverted). |
--dds-progress-height-xs | Height for extra small linear progress. Default is var(--dds-spacing-50). |
--dds-progress-height-sm | Height for small linear progress. Default is var(--dds-spacing-100). |
--dds-progress-height-md | Height for medium linear progress. Default is var(--dds-spacing-150). |
--dds-progress-height-lg | Height for large linear progress. Default is var(--dds-spacing-200). |
--dds-progress-height-xl | Height for extra large linear progress. Default is var(--dds-spacing-300). |
--dds-progress-height-xxl | Height for extra extra large linear progress. Default is var(--dds-spacing-400). |
--dds-progress-diameter-xs | Diameter for extra small circular progress. Default is var(--dds-spacing-600). |
--dds-progress-diameter-sm | Diameter for small circular progress. Default is var(--dds-spacing-800). |
--dds-progress-diameter-md | Diameter for medium circular progress. Default is var(--dds-spacing-1200). |
--dds-progress-diameter-lg | Diameter for large circular progress. Default is var(--dds-spacing-1600). |
--dds-progress-diameter-xl | Diameter for extra large circular progress. Default is var(--dds-spacing-2000). |
--dds-progress-diameter-xxl | Diameter for extra extra large circular progress. Default is var(--dds-spacing-2400). |
--dds-progress-stroke-width | Stroke width for circular progress. Default is var(--dds-spacing-200). |
--dds-progress-animation-duration | Duration of indeterminate animation. Default is 1.5s. |
CSS custom properties (CSS variables) can be set directly on the component or in your stylesheet:
Method 1: Inline styles (Quick customization)
<dap-ds-progress
style="--dds-progress-track-color: value; --dds-progress-fill-color-neutral: value;">
Progress
</dap-ds-progress>
Method 2: CSS classes (Reusable styles)
.my-custom-dap-ds-progress {
--dds-progress-track-color: value;
--dds-progress-fill-color-neutral: value;
--dds-progress-fill-color-brand: value;
}
<dap-ds-progress class="my-custom-dap-ds-progress">
Progress
</dap-ds-progress>
Method 3: Global theme customization
/* Apply to all instances */
dap-ds-progress {
--dds-progress-track-color: value;
--dds-progress-fill-color-neutral: value;
}
CSS custom properties inherit through the Shadow DOM, making them perfect for theming. Changes apply immediately without rebuilding.