Progress Overview

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.

Examples Default progress (Linear)

The default progress indicator displays as a horizontal bar showing determinate progress:

<dap-ds-progress value="60"></dap-ds-progress>
Progress with label

Add descriptive labels to provide context about what is being tracked:

<dap-ds-stack>
<dap-ds-progress value="25" label="Uploading document.pdf"></dap-ds-progress>
<dap-ds-progress value="60" label="Processing images"></dap-ds-progress>
<dap-ds-progress value="100" label="Upload complete"></dap-ds-progress>
</dap-ds-stack>
Circular progress variant

Use circular progress for compact spaces or to emphasize the completion percentage:

<dap-ds-stack direction="row">
<dap-ds-progress variant="circular" value="25"></dap-ds-progress>
<dap-ds-progress variant="circular" value="50"></dap-ds-progress>
<dap-ds-progress variant="circular" value="75"></dap-ds-progress>
<dap-ds-progress variant="circular" value="100"></dap-ds-progress>
</dap-ds-stack>
Circular progress with percentage

Display the percentage value in the center of circular progress indicators:

<dap-ds-stack direction="row">
<dap-ds-progress
  variant="circular"
  value="45"
  show-percentage>
</dap-ds-progress>
<dap-ds-progress
  variant="circular"
  value="75"
  show-percentage
  label="Upload">
</dap-ds-progress>
<dap-ds-progress
  variant="circular"
  value="90"
  show-percentage
  label="Processing">
</dap-ds-progress>
</dap-ds-stack>
Indeterminate progress

Use indeterminate mode for operations where the completion time is unknown:

<dap-ds-stack>
<dap-ds-progress indeterminate label="Loading..."></dap-ds-progress>
<dap-ds-progress
  variant="circular"
  indeterminate
  label="Processing">
</dap-ds-progress>
</dap-ds-stack>
Color variants

Different color variants communicate different states or types of operations:

<dap-ds-stack>
<dap-ds-progress value="60" color="neutral" label="Neutral"></dap-ds-progress>
<dap-ds-progress value="60" color="brand" label="Brand"></dap-ds-progress>
<dap-ds-progress value="60" color="positive" label="Success"></dap-ds-progress>
<dap-ds-progress value="60" color="negative" label="Error"></dap-ds-progress>
</dap-ds-stack>
Size variants

Progress indicators come in six sizes to fit different layouts:

<dap-ds-stack>
<dap-ds-progress value="60" size="xs" label="Extra Small"></dap-ds-progress>
<dap-ds-progress value="60" size="sm" label="Small"></dap-ds-progress>
<dap-ds-progress value="60" size="md" label="Medium"></dap-ds-progress>
<dap-ds-progress value="60" size="lg" label="Large"></dap-ds-progress>
<dap-ds-progress value="60" size="xl" label="Extra Large"></dap-ds-progress>
<dap-ds-progress value="60" size="xxl" label="Extra Extra Large"></dap-ds-progress>
</dap-ds-stack>
Circular size variants
<dap-ds-stack direction="row">
<dap-ds-progress variant="circular" value="60" size="xs" show-percentage></dap-ds-progress>
<dap-ds-progress variant="circular" value="60" size="sm" show-percentage></dap-ds-progress>
<dap-ds-progress variant="circular" value="60" size="md" show-percentage></dap-ds-progress>
<dap-ds-progress variant="circular" value="60" size="lg" show-percentage></dap-ds-progress>
<dap-ds-progress variant="circular" value="60" size="xl" show-percentage></dap-ds-progress>
<dap-ds-progress variant="circular" value="60" size="xxl" show-percentage></dap-ds-progress>
</dap-ds-stack>
Real-World Patterns File Upload Progress
<dap-ds-stack>
<h3>Uploading files...</h3>
<dap-ds-progress
  value="33"
  color="brand"
  label="document1.pdf (5 MB)">
</dap-ds-progress>
<dap-ds-progress
  value="67"
  color="brand"
  label="document2.pdf (8 MB)">
</dap-ds-progress>
<dap-ds-progress
  value="100"
  color="positive"
  label="document3.pdf (3 MB) - Complete">
</dap-ds-progress>
</dap-ds-stack>
System Status Dashboard
<dap-ds-stack direction="row" style={{ gap: '40px', justifyContent: 'center' }}>
<dap-ds-progress
  variant="circular"
  value="45"
  color="neutral"
  size="xl"
  show-percentage
  label="CPU Usage">
</dap-ds-progress>
<dap-ds-progress
  variant="circular"
  value="78"
  color="brand"
  size="xl"
  show-percentage
  label="Memory">
</dap-ds-progress>
<dap-ds-progress
  variant="circular"
  value="92"
  color="negative"
  size="xl"
  show-percentage
  label="Disk">
</dap-ds-progress>
</dap-ds-stack>
Multi-Step Form Progress
<dap-ds-stack>
<h3>Account Setup Progress</h3>
<dap-ds-progress
  value="75"
  color="brand"
  size="lg"
  label="Step 3 of 4: Verification">
</dap-ds-progress>
</dap-ds-stack>
Custom Max Value

Progress indicators support custom maximum values for non-percentage tracking:

<dap-ds-stack>
<dap-ds-progress
  value="500"
  max="1000"
  label="500 / 1000 MB downloaded">
</dap-ds-progress>
<dap-ds-progress
  variant="circular"
  value="7"
  max="10"
  show-percentage
  size="lg"
  label="7 of 10 tasks">
</dap-ds-progress>
</dap-ds-stack>
Updating Progress Dynamically Basic progress updates
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);
Monitoring upload progress
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);
});
Accessibility Features

Progress indicators automatically include appropriate ARIA attributes:

  • Role: Uses progressbar role for determinate progress and status role for indeterminate
  • ARIA attributes: Includes aria-valuenow, aria-valuemin, aria-valuemax for determinate states
  • Live regions: Progress changes are announced to screen readers
  • Labels: Support for aria-label and visible labels for context
  • Keyboard accessible: All interactive states are keyboard navigable
Implementation Notes Choosing Between Linear and Circular

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
Determinate vs Indeterminate

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
Performance Considerations
  • 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
Best Practices
  1. Always provide context: Use labels to explain what is progressing
  2. Match colors to meaning: Use positive for success, negative for errors
  3. Show completion state: Change color or label when progress reaches 100%
  4. Handle errors gracefully: Update color and label on failures
  5. Consider mobile: Use appropriate sizes for touch targets
  6. Test with screen readers: Ensure progress updates are announced clearly
Custom Styling

The progress component supports extensive customization through CSS custom properties and parts.

Quick Customization with CSS Custom Properties
<dap-ds-progress
value="65"
style={{
  '--dds-progress-track-color': 'var(--dds-neutral-100)',
  '--dds-progress-fill-color-brand': 'var(--dds-violet-600)',
}}
label="Custom colored progress">
</dap-ds-progress>
Advanced Styling with CSS 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:

Gradient FillStriped PatternNeon EffectBold Label
☀️ Light🌙 Dark
CopyFormatReset
CSS Editor
Live Preview
Importing
import { DapDSProgress } from 'dap-design-system'
Importing React
import { DapDSProgressReact } from 'dap-design-system/react'
Tree-Shakeable Imports

For optimal bundle sizes, use the tree-shakeable import syntax:

import { DapDSProgress } from 'dap-design-system/components'
Attributes
PropertyTypeDefaultDescription
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.
valuenumber, undefinedCurrent progress value (0-100 for percentage, or 0-max).
maxnumber100Maximum value for the progress indicator.
indeterminatebooleanfalseWhether to show the progress as indeterminate (loading animation).
showPercentagebooleanfalseWhether to show percentage text in the center (circular variant only).
labelstring, undefinedLabel text for the progress indicator.
ariaLive"polite", "assertive" , "off"'polite'The aria-live politeness level for screen readers.
Slots
NameDescription
labelCustom label content for the progress indicator.
Events

No custom events available.

CSS Parts
Part NameDescription
baseThe main progress container.
trackThe progress track (background).
fillThe progress fill (bar for linear, circle for circular).
labelThe progress label text.
percentageThe percentage text (circular variant only).
backgroundThe background circle (circular variant only).
How to Use CSS Parts

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.

CSS Custom Properties
Property NameDescription
--dds-progress-track-colorBackground color of the progress track. Default is var(--dds-neutral-200).
--dds-progress-fill-color-neutralFill color for neutral variant. Default is var(--dds-icon-neutral-base).
--dds-progress-fill-color-brandFill color for brand variant. Default is var(--dds-icon-brand-subtle).
--dds-progress-fill-color-negativeFill color for negative variant. Default is var(--dds-icon-negative-subtle).
--dds-progress-fill-color-positiveFill color for positive variant. Default is var(--dds-icon-positive-subtle).
--dds-progress-fill-color-invertedFill color for inverted variant. Default is var(--dds-icon-neutral-inverted).
--dds-progress-height-xsHeight for extra small linear progress. Default is var(--dds-spacing-50).
--dds-progress-height-smHeight for small linear progress. Default is var(--dds-spacing-100).
--dds-progress-height-mdHeight for medium linear progress. Default is var(--dds-spacing-150).
--dds-progress-height-lgHeight for large linear progress. Default is var(--dds-spacing-200).
--dds-progress-height-xlHeight for extra large linear progress. Default is var(--dds-spacing-300).
--dds-progress-height-xxlHeight for extra extra large linear progress. Default is var(--dds-spacing-400).
--dds-progress-diameter-xsDiameter for extra small circular progress. Default is var(--dds-spacing-600).
--dds-progress-diameter-smDiameter for small circular progress. Default is var(--dds-spacing-800).
--dds-progress-diameter-mdDiameter for medium circular progress. Default is var(--dds-spacing-1200).
--dds-progress-diameter-lgDiameter for large circular progress. Default is var(--dds-spacing-1600).
--dds-progress-diameter-xlDiameter for extra large circular progress. Default is var(--dds-spacing-2000).
--dds-progress-diameter-xxlDiameter for extra extra large circular progress. Default is var(--dds-spacing-2400).
--dds-progress-stroke-widthStroke width for circular progress. Default is var(--dds-spacing-200).
--dds-progress-animation-durationDuration of indeterminate animation. Default is 1.5s.
How to Use CSS Custom Properties

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.