Skip to main content
U.S. Flag

An official website of the United States government

Step List

A step list represents a user's progression through an application or multi-page form. It serves as a table of contents and a way to quickly see where they are and what they should be working on next.


The StepList component is the preferred method for building a step list, since it handles all the state logic necessary to produce its markup. A step is represented by an object with text, progress, and routing information and can optionally include an array of substeps as well as a description.




<StepList> component

React Properties Documentation
stepsrequiredStepObject[]An array of step objects that contain text, state, link/button URLs and other info needed to render steps.
componentkeyof IntrinsicElements | ComponentType<StepLinkComponentProps>When provided, this will render the passed in component for all link elements. This is useful when integrating with React Router's <Link> or using your own custom component. If more specific control is needed, each step object also accepts a component prop.
showSubSubStepsbooleanfalseWhether or not to render a substep's substeps.
onStepLinkClick(href?: string, stepId?: string) => anyFunction called when a step's Edit, Start, or Resume button/link is clicked. The step's href property will be passed as a parameter.
actionsLabelTextstringPrimary actions for %{step}A template string for the aria-label describing a step's actions where the substring %{step} is replaced with that step's heading.
substepsLabelTextstringSecondary actions for %{step}A template string for the aria-label describing a step's substeps where the substring %{step} is replaced with that step's heading.

<Step> component


The following CSS variables can be overridden to customize StepList patterns:

CSS variables for steplist
VariableDefault Core Theme Value
--steplist__colorhex value: #5a5a5a--color-gray
--steplist__color--currenthex value: #0071bc--color-primary
--steplist__background-color--currenthex value: #0071bc--color-primary
--steplist-step__colorhex value: #5a5a5a--color-gray
--steplist-step__border-colorhex value: #d9d9d9--color-border
--steplist-step__border-color--defaulthex value: #5a5a5a--color-gray
--steplist-step__color--currenthex value: #ffffff--color-white
--steplist-step__color--completedhex value: #262626--color-base
--steplist-step__background-color--completedhex value: #262626--color-base

Step Object

completedboolWhether the step has been completed
componentelement, funcWhen provided, this will render the passed in component for link elements in this Step. This is useful when integrating with React Router's <Link> or using your own custom component.
descriptionstringAdditional text to dsiplay under (only rendered for top-level steps)
heading RequiredstringText to display as the step heading
headingLevel'1', '2', '3', '4', '5'Heading type to override default <h2>.
href RequiredstringURL or partial URL that routes to the step. Will be passed to onStepLinkClick as first parameter
idstringUnique string representing the step. WIll be passed to onStepLinkClick as second parameter
isNextStepboolWhether this is the next unstarted step
linkTextstringAlternative text for the link or button for this step. Will override the defaults
onClickfunconClick handler for this specific step's link/button
startedboolWhether the step has been started
stepsStepObject[]Array of substeps


A user interacts with the steps through "Start", "Resume", and "Edit" links.

In the React component, the links' href properties are determined by the step object's href property. One can also optionally pass an onStepLinkClick function that will cancel the default link behavior and call onStepLinkClick with href as a parameter for apps that handle routing with JavaScript.

When a step has substeps and is incomplete, the href property should be set to match the href of the current substep—that is, the first incomplete substep. The "Edit" button will only appear on substeps that have been completed.

Managing list state


The <StepList> component takes an array of step objects. From there steps can be broken down infinitely into sub-steps. This allows us to have unique URLs for each part of a step; however, by default we only display two levels of this tree —the step and substep. This default behavior should remain unchanged except for special circumstances. It is better not to overwhelm the user with showing all the substeps and giving them names.

We do, nonetheless, encourage the use of sub-substeps that are not visible where these substeps span multiple pages and have their own unique URLs. If, for example, the user completes the first page of the household > overall substep where they list the household members but has not completed the second page where they define those members' relationships to each other, we want the "Resume" button to take them back to the relationships page and not the first page where they entered their names. This, of course, requires an extra steps-building process to update a top-level steps' href property by traversing the substep tree to find the first incomplete step. See the Completed, started, and isNextStep section below for an example JavaScript function that can change the href of steps based on their substeps.

Completed, started, and isNextStep

The state of a step object will be defined for these purposes as the values of its completed, started, and isNextStep properties. These correspond to different visual states when rendered by the <StepList>, showing "Completed", "Resume", or "Start" respectively. For steps with substeps, the state should be representative of the collective states of its substeps. For example, if a step has substeps that have completed: false, that step should not have completed: true because not all of its substeps have been completed. Similarly a step can only be started if at least one of its substeps has been started. This should be true for each of the substep's substeps and so on. Below is an example function that can propagate this state information up from the smallest substep to the largest step before passing the steps array to the <StepList> component.

function propagateSubstepState(step) {
  if (step.steps) {
    const steps =;
    const newStep = {
      started: steps.some((s) => s.started),
      completed: steps.every((s) => s.completed),
    if (!newStep.completed) {
      const nextStep = steps.find((s) => !s.completed);
      newStep.href = nextStep.href;
    return newStep;
  } else {
    return step;

// ...
// Render function:

const steps =;
return <StepList steps={steps} />;

Component maturity

For more information about how we tested and validated our work for each checklist item, read our component maturity documentation.


  • Color

    Meets AA color contrast standards for accessibility and color blindness.
  • Forced Colors Mode (FCM)

    While using FCM the components text is legible and improves readability.
  • WCAG 2.1 Level AA Conformance

    All Axe checks for WCAG AA compliance have passed.
  • Screen readers

    VoiceOver, NVDA, and JAWS screen readers provide concise communication and interaction.
  • Keyboard navigation

    Component is fully navigable with a keyboard.


  • Storybook

    Component has stories to cover all defined props.
  • Responsive

    Component designed to work in all responsive breakpoints.
  • Spanish translations

    Includes Spanish translations for default text content.


  • Code

    Tokens implemented in code.
  • Design

    Tokens implemented in the Sketch.