Skip to contentSkip to navigationSkip to topbar
Paste assistant Assistant
Figma
Star

Progress Bar

Version 1.1.0GithubStorybook

A Progress Bar communicates the completion status of a process or task.

// See storybook for full code
<Box maxWidth="400px">
  {value >= 100 ? (
    <Box marginBottom="space90" display="flex" alignItems="center" columnGap="space30">
      <AcceptIcon decorative size="sizeIcon30" color="colorTextSuccess" />
      Your submission has been approved!
    </Box>
  ) : (
    <Box marginBottom="space90">
      <ProgressBarLabel htmlFor={progressBarId} valueLabel={Math.round(value)%}>
        Reviewing submission
      </ProgressBarLabel>
      <ProgressBar
        id={progressBarId}
        aria-describedby={helpTextId}
        value={value}
        valueLabel={Math.round(value)%}
      />
      <HelpText id={helpTextId}>Automatically reviewing your submission with our AI agents.</HelpText>
    </Box>
  )}
  <Button
    variant="primary"
    onClick={() => {
      setRerun(1);
      setValue(0);
    }}
    disabled={rerun === 1}
  >
    Restart Progress
  </Button>
</Box>

Guidelines

Guidelines page anchor

About Progress Bar

About Progress Bar page anchor

A Progress Bar communicates the completion status of a process, like downloads and data processing, or a task, like filling out a form. A Progress Bar enhances user understanding of where they are in a task or where the system is in a process.

A Progress Bar represents only completion progress, like a file upload or filling out a form. If you're not displaying progress, use a Meter.

One way to check if you need a Progress Bar or a Meter is to ask yourself: Could you substitute your UI element for Progress Steps? Would it communicate roughly the same intent? If yes, then Progress Bar is probably the right element to use.

Progress Bar vs. Progress Steps

Progress Bar vs. Progress Steps page anchor

Use Progress Bar for tasks that are short, straightforward, and linear that don't need the extra layer of information that Progress Steps provides. Example: A sign-up flow that a customer can reasonably complete without leaving the flow.

In contrast, Progress Steps are a visual representation of a complex task broken up into multiple steps. They indicate what has and what needs to be done to fully complete the task. Use Progress Steps when the task is nonlinear or can't be completed in one sitting. Example: A task that requires a customer to go to a third-party application to configure their settings before returning to Twilio to complete the full task.

  • A label is required when using Progress Bar. Use one of these options:
    • Visible label using ProgressBarLabel, with htmlFor set equal to the id of the Progress Bar (preferred)
    • Visible label that's associated to the Progress Bar with aria-labelledby
    • Label directly using aria-label
  • A numerical value is required, between 0 and any maximum value provided.

Use a Progress Bar to communicate the completion status of a process or task. Use the valueLabel prop to show a visible value.

If you don't show a visible value, communicate what kind of process is happening through ProgressBarLabel. For example, the Progress Bar Label should say “Uploading filename.png…” not just “filename.png” if you don't show the completion percentage. If the label starts with a verb and the Progress Bar is not disabled, use an ellipsis at the end of the label.

// See storybook for full code
<Box maxWidth="400px">
  {value >= 100 ? (
    <Box marginBottom="space90" display="flex" alignItems="center" columnGap="space30">
      <AcceptIcon decorative size="sizeIcon30" color="colorTextSuccess" />
      Your submission has been approved!
    </Box>
  ) : (
    <Box marginBottom="space90">
      <ProgressBarLabel htmlFor={progressBarId} valueLabel={Math.round(value)%}>
        Reviewing submission
      </ProgressBarLabel>
      <ProgressBar
        id={progressBarId}
        aria-describedby={helpTextId}
        value={value}
        valueLabel={Math.round(value)%}
      />
      <HelpText id={helpTextId}>Automatically reviewing your submission with our AI agents.</HelpText>
    </Box>
  )}
  <Button
    variant="primary"
    onClick={() => {
      setRerun(1);
      setValue(0);
    }}
    disabled={rerun === 1}
  >
    Restart Progress
  </Button>
</Box>

When the process or task is complete, swap the Progress Bar out with an element that represents the completed process or task. For example, for a file upload, that could be a card representing the file.

By default, Progress Bar has a value of 0 (represented as a percentage) and range of 0 to 100. Pass maxValue to Progress Bar to set a custom max value. The min value is always 0.

To show a visible max value, use the valueLabel prop to show “[current value] of [max value]”. Consider what type of value would be most useful for a user. For example, choose either “50%” or “5,000 of 10,000”, not both.

<ProgressBarLabel htmlFor={progressBarId} valueLabel="688KB of 834KB">
  mtn_sunrise.png
</ProgressBarLabel>
<ProgressBar id={progressBarId} value={688} maxValue={834} />

Use an indeterminate Progress Bar when progress is being made, but you can't calculate how much progress or you don't know the value. This is common when computing the progress value interferes with showing an accurate value, or when connection is lost but the process is still continuing.

For indeterminate states, communicate what kind of process is happening through ProgressBarLabel. If the label starts with a verb, use an ellipsis at the end of the label. For example, the Progress Bar Label should say “Uploading filename.png…” not just “filename.png”.

<ProgressBarLabel htmlFor={progressBarIdA}>Uploading sunrise_video.mov...</ProgressBarLabel>
<ProgressBar id={progressBarIdA} aria-describedby={helpTextId} isIndeterminate />
<Separator orientation="horizontal" verticalSpacing="space60" />
<ProgressBarLabel htmlFor={progressBarIdB}>Converting files...</ProgressBarLabel>
<ProgressBar id={progressBarIdB} aria-describedby={helpTextId} isIndeterminate />
<HelpText id={helpTextId}>
  Connection lost. Check your connection and refresh the page to get up-to-date information.
</HelpText>

Use the error state to show a process has stopped, and the user must do something to continue it.

Use error Help Text to describe the error and what needs to be done to fix it. For additional guidance on how to compose error messages, refer to the error state pattern.

<ProgressBarLabel htmlFor={progressBarId} valueLabel="50%">
  mtn_sunrise.png
</ProgressBarLabel>
<ProgressBar id={progressBarId} aria-describedby={helpTextId} value={50} valueLabel="50%" hasError />
<HelpText variant="error" id={helpTextId}>
  Upload failed. <Anchor href="#">Retry upload</Anchor>
</HelpText>

Use a disabled Progress Bar to show a task has stopped, and the system needs to do something before the user can continue the task. Let users know when they can expect their next steps.

Do not include an ellipsis on a disabled Progress Bar.

<ProgressBarLabel disabled htmlFor={progressBarId} valueLabel="50%">
  Campaign registration
</ProgressBarLabel>
<ProgressBar id={progressBarId} aria-describedby={helpTextId} value={80} disabled />
<HelpText variant="default" id={helpTextId}>
  Your profile is in review. You will receive an email about your application status in 3-5 business days.
</HelpText>

The Progress Bar label should communicate what the Progress Bar is measuring. Where possible, avoid a label that wraps onto two lines.

A Progress Bar can include a numerical value through valueLabel. When using a custom value label, consider what type of value would be most useful for a user to see (for example, “50%” vs. “5000 of 10,000”).

If you don't show a visible value through valueLabel, or if the Progress Bar is indeterminate, communicate what kind of process is happening through ProgressBarLabel. If the label starts with a verb and the Progress Bar is not disabled, use an ellipsis at the end of the label. For example, the Progress Bar Label should say “Uploading filename.png…” not just “filename.png”.

Use Help Text to offer additional information to contextualize or help the user understand the Progress Bar, especially if the process is complex or has a long wait time to better communicate current status with users.

When to use Progress Bar

When to use Progress Bar page anchor
Do

Use a Progress Bar when you want to represent the status of an ongoing task (like downloading files, setting up an account, etc.) within a fixed 0-100% range. It’s especially useful when you don’t need to communicate the details of each step.

Don't

Don’t use a Progress Bar when you need a user to navigate between different steps of a task. Use Progress Steps instead when the task is nonlinear or can’t be completed in one sitting.

Do

Use a Progress Bar to show real-time feedback to users as tasks are completed, or when they need to wait for a process to finish.

Don't

Don’t use a Progress Bar for entire page loads. In this case, use a Spinner or Skeleton Loader instead.

Do

Use a Progress Bar when you need to display the completion percentage of a task.

Don't

Don’t use Progress Bar if you’re communicating capacity. Use Meter instead.