Skip to contentSkip to navigationSkip to topbar
Figma
Star

Progress Steps

Progress Steps can be a presentational or interactive component and shows users an outline of a complex multi-step task.

Version 2.0.1
Github

Component preview theme
const ProgressStepsExample = () => {
return (
<ProgressSteps>
<ProgressStepComplete as="button" onClick={() => {}}>Sign up</ProgressStepComplete>
<ProgressStepSeparator />
<ProgressStepError as="button" onClick={() => {}}>Validate email</ProgressStepError>
<ProgressStepSeparator />
<ProgressStepCurrent as="button" onClick={() => {}}>Complete profile</ProgressStepCurrent>
<ProgressStepSeparator />
<ProgressStepIncomplete as="button" onClick={() => {}}>Add friends</ProgressStepIncomplete>
<ProgressStepSeparator />
<ProgressStepIncomplete as="button" onClick={() => {}} disabled>
Start event
</ProgressStepIncomplete>
</ProgressSteps>
);
};
render(<ProgressStepsExample />);

Guidelines

Guidelines page anchor

About Progress Steps

About Progress Steps page anchor

Progress Steps are a visual representation of a complex task broken up into multiple steps, ideally 3–5. They indicate what has and what needs to be done to fully complete the task. Use Progress Steps to show a clear path to completion, especially when the task is nonlinear or can’t be completed in one sitting.

Not all multi-step tasks need Progress Steps. Tasks that are short, straightforward, and linear probably don’t need the extra layer of information that Progress Steps provides.

Each step can communicate one of these statuses:

  • Complete: The user has completed this step with no more action needed.
  • Incomplete: The user has interacted with this step but there is still more action needed.
  • Current: The user is currently on this step.
  • Error: The user has interacted with this step but more action is required that will prevent completing the full task.
  • Incomplete + Disabled: This step is not yet reached by a user.
  • Give each step a concise label describing what the goal of that step is.
  • Each step icon has a title prop whose value is the current status of that step (e.g. complete, incomplete, etc.) to inform screen readers of a step's status. This label is adjustable for internationalization.
  • The ProgressStep has role=list and each step has role=listitem for screen readers.
  • The ProgressStep has aria-current set to step for the current step.

Progress Steps as buttons

Progress Steps as buttons page anchor

Use Progress Steps as buttons when each step triggers an in-page action and doesn’t have a unique URL. We recommend using this button action to save information in each step.

Only button steps may be disabled.

Component preview theme
const ProgressStepsExample = () => {
return (
<ProgressSteps>
<ProgressStepComplete as="button" onClick={() => {}}>Sign up</ProgressStepComplete>
<ProgressStepSeparator />
<ProgressStepError as="button" onClick={() => {}}>Validate email</ProgressStepError>
<ProgressStepSeparator />
<ProgressStepCurrent as="button" onClick={() => {}}>Complete profile</ProgressStepCurrent>
<ProgressStepSeparator />
<ProgressStepIncomplete as="button" onClick={() => {}}>Add friends</ProgressStepIncomplete>
<ProgressStepSeparator />
<ProgressStepIncomplete as="button" onClick={() => {}} disabled>
Start event
</ProgressStepIncomplete>
</ProgressSteps>
);
};
render(<ProgressStepsExample />);

Progress Steps as anchors

Progress Steps as anchors page anchor

Use Progress Steps as anchors when each step links to other pages and has a unique URL.

Component preview theme
const ProgressStepsExample = () => {
return (
<ProgressSteps>
<ProgressStepComplete as="a" href="#">Sign up</ProgressStepComplete>
<ProgressStepSeparator />
<ProgressStepError as="a" href="#">Validate email</ProgressStepError>
<ProgressStepSeparator />
<ProgressStepCurrent as="a" href="#">Complete profile</ProgressStepCurrent>
<ProgressStepSeparator />
<ProgressStepIncomplete as="a" href="#">Add friends</ProgressStepIncomplete>
</ProgressSteps>
);
};
render(<ProgressStepsExample />);

Non-interactive Progress Steps

Non-interactive Progress Steps page anchor

Use Progress Steps as divs when steps have no need for user interaction.

Component preview theme
const ProgressStepsExample = () => {
return (
<ProgressSteps>
<ProgressStepComplete as="div">Sign up</ProgressStepComplete>
<ProgressStepSeparator />
<ProgressStepError as="div">Validate email</ProgressStepError>
<ProgressStepSeparator />
<ProgressStepCurrent as="div">Complete profile</ProgressStepCurrent>
<ProgressStepSeparator />
<ProgressStepIncomplete as="div">Add friends</ProgressStepIncomplete>
</ProgressSteps>
);
};
render(<ProgressStepsExample />);

Progress Steps represented vertically

Progress Steps represented vertically page anchor

Use vertical Progress Steps when you’re constrained on vertical space in your layout.

Component preview theme
const ProgressStepsExample = () => {
return (
<ProgressSteps orientation="vertical">
<ProgressStepComplete as="div">Sign up</ProgressStepComplete>
<ProgressStepSeparator />
<ProgressStepError as="div">Validate email</ProgressStepError>
<ProgressStepSeparator />
<ProgressStepCurrent as="div">Complete profile</ProgressStepCurrent>
<ProgressStepSeparator />
<ProgressStepIncomplete as="div">Add friends</ProgressStepIncomplete>
</ProgressSteps>
);
};
render(<ProgressStepsExample />);

Each step within the Progress Step component has a label which can be set to adjust the icon's title for internationalization.

Component preview theme
const ProgressStepsExample = () => {
return (
<ProgressSteps>
<ProgressStepComplete i18nCompleteLabel="Complété" as="div">S'inscrire</ProgressStepComplete>
<ProgressStepSeparator />
<ProgressStepError i18nErrorLabel="Erreur" as="div">Email validé</ProgressStepError>
<ProgressStepSeparator />
<ProgressStepCurrent i18nCurrentLabel="Actuelle" as="div">Complétez votre profil</ProgressStepCurrent>
<ProgressStepSeparator />
<ProgressStepIncomplete i18nIncompleteLabel="Incomplet" as="div">Ajouter des amis</ProgressStepIncomplete>
</ProgressSteps>
);
};
render(<ProgressStepsExample />);

  • Each step must have a label. Keep the label concise with fewer than 5 words per label.
  • Skip articles like “a” or “the” to shorten the step.
  • Generally, start each step with a verb to keep the user grounded in the task at hand.
  • If the process has 5 steps and describing each one with a verb + noun is too long, consider shortening the step labels to just a verb, and using the in-page step label to clarify the full scope of the task. For example, use “Add” as a step label, but include “Add entry step” as the page label.
  • If the process does not fit into a mental model of performing tasks, make sure each step is phrased consistently. For example, “Business profile” and “Brand registration.”
  • Keep the placement of Progress Steps consistent between different pages (steps).

When to use an error step

When to use an error step page anchor

Show the error status on a step when it’s not the current step they’re on. When a user navigates to the step that has errors, use ProgressStepCurrent to set the status of the step to current, and use in-page validation to then communicate the errors in the current page. Check out the Error state pattern for more guidance.

CompletedCreate profile
CurrentRegister brand
IncompleteRegister campaign
Do

Use Progress Steps for complex tasks with 3–5 steps that can't be completed in one session.

CompletedName
CurrentEmail
IncompletePassword
Don't

Don’t use Progress Steps for every single kind of task that has multiple steps. A line of text can be used as an alternative to show progression (e.g., “Step 1 of 2”)

CompletedCreate profile
CurrentRegister brand
IncompleteRegister campaign
Do

Make the labels of each step short, descriptive, and consistent. Use fewer than 5 words for each step label.

CompletedBusiness profile for your primary business account
CurrentA2P brand
IncompleteFinalize campaign registration
Don't

Don’t use long or inconsistent labels with mismatched parts of speech.

Do

Keep Progress Steps in a consistent location between steps or pages.

Don't

Don’t change the placement of Progress Steps between steps or pages.

Do

Include only one Progress Steps component per task or page.

Don't

Don’t embed a Progress Steps component within a task that’s already being tracked with another Progress Steps component. Don’t use multiple Progress Steps per page.


Installation

Installation page anchor
yarn add @twilio-paste/progress-steps - or - yarn add @twilio-paste/core
import {
  ProgressSteps,
  ProgressStepIncomplete,
  ProgressStepComplete,
  ProgressStepCurrent,
  ProgressStepError,
  ProgressStepSeparator,
} from '@twilio-paste/core/progress-steps';

const PopoverExample: React.FC = () => {
  return (
    <ProgressSteps>
      <ProgressStepComplete as="button" onClick={() => {}}>
        Sign up
      </ProgressStepComplete>
      <ProgressStepSeparator />
      <ProgressStepError as="button" onClick={() => {}}>
        Validate email
      </ProgressStepError>
      <ProgressStepSeparator />
      <ProgressStepCurrent as="button" onClick={() => {}}>
        Complete profile
      </ProgressStepCurrent>
      <ProgressStepSeparator />
      <ProgressStepIncomplete as="button" onClick={() => {}}>
        Add friends
      </ProgressStepIncomplete>
      <ProgressStepSeparator />
      <ProgressStepIncomplete as="button" onClick={() => {}} disabled>
        Start event
      </ProgressStepIncomplete>
    </ProgressSteps>
  );
};
ProgressSteps
ProgressSteps page anchor
PropTypeDescriptionDefault
orientation?'horizontal' \| 'vertical'Sets the orientation for the progress steps component.'horizontal'
element?stringOverrides the default element name to apply unique styles with the Customization Provider'PROGRESS_STEPS'
PropTypeDescriptionDefault
element?stringOverrides the default element name to apply unique styles with the Customization Provider'PROGRESS_STEP_SEPARATOR'
PropTypeDescriptionDefault
as'div', 'button', 'a'Sets the HTML element to render the component as.'div'
href?stringSets the URL for the anchor tag. Only used when as is set to a.undefined
onClick?() => voidSets the onClick for the button tag. Only used when as is set to button.undefined
i18nCompleteLabel?stringSets the title for the complete step icon.'Completed'
element?stringOverrides the default element name to apply unique styles with the Customization Provider'PROGRESS_STEPS_COMPLETE'
PropTypeDescriptionDefault
as'div', 'button', 'a'Sets the HTML element to render the component as.'div'
href?stringSets the URL for the anchor tag. Only used when as is set to a.undefined
onClick?() => voidSets the onClick for the button tag. Only used when as is set to button.undefined
i18nCurrentLabel?stringSets the title for the complete step icon.'Current'
element?stringOverrides the default element name to apply unique styles with the Customization Provider'PROGRESS_STEPS_CURRENT'
PropTypeDescriptionDefault
as'div', 'button', 'a'Sets the HTML element to render the component as.'div'
href?stringSets the URL for the anchor tag. Only used when as is set to a.undefined
onClick?() => voidSets the onClick for the button tag. Only used when as is set to button.undefined
i18nErrorLabel?stringSets the title for the complete step icon.'Error'
element?stringOverrides the default element name to apply unique styles with the Customization Provider'PROGRESS_STEPS_ERROR'
PropTypeDescriptionDefault
as'div', 'button', 'a'Sets the HTML element to render the component as.'div'
href?stringSets the URL for the anchor tag. Only used when as is set to a.undefined
onClick?() => voidSets the onClick for the button tag. Only used when as is set to button.undefined
i18nIncompleteLabel?stringSets the title for the complete step icon.'Incomplete'
disabled?booleanSets the disabled state for the button tag. Only used when as is set to button.undefined
element?stringOverrides the default element name to apply unique styles with the Customization Provider'PROGRESS_STEPS_INCOMPLETE'