The page navigation is complete. You may now navigate the page content as you wish.
Skip to main content

Stepper Nav

Added in v4.18.1

Navigates users through a sequential flow allowing them to visually track progress.

Usage

When to use

  • In complex flows that are broken up into multiple steps.
  • To communicate what has and has not been completed in a multi-step flow.
  • For a single page multi-step flow that requires completion.

When not to use

  • For simple flows, use the form pattern on a single page.
  • For simple forms or when progress doesn't need to be tracked, use structured page content.
  • For a progression of tasks that doesn’t require a user to remain on the same page, use the Stepper List.

Interactive vs non-interactive

The Stepper Nav supports both interactive (default) and non-interactive variants.

Interactive steps

Users can navigate backwards within the Stepper Nav steps but cannot navigate forwards unless they have completed the current step. This creates consistency for step flow behavior and the order of operations.

The user's mouse is hovering over step one of four, showing its hover state.

Non-interactive steps

The non-interactive variant is for read-only purposes and does not allow backwards navigation.

Content

The Stepper Nav supports a title and an optional description. Content should be limited to only what is necessary, and long form content should live within the body of the Step.

Title

Titles provide an overview to help users understand what tasks need to be completed. Titles are required and should be brief.

Description

Descriptions provide additional context about the step and are optional. We recommend that all steps either have a description or do not.

Do

Use descriptions consistently.

The stepper with descriptions included in every step.

Don’t

Don't mix and match inclusion of descriptions.

Stepper where steps one and four include descriptions, while steps two and three have only a title.

Number of steps

We recommend a maximum of 4 steps. If that isn’t possible, be mindful of how the content within the title and description will wrap on smaller screens.

Spacing

There should be 32px of spacing above the Stepper Nav and 24px below.

Resizing behavior

Each step scales evenly to fit within the total width of the Stepper Nav. This ensures consistent touch target sizes for hover, active, and focus states. The total width of the Stepper Nav should match the page content width.

Responsive layout

At browser widths of 550px and below, the steps will stack vertically and not display a connecting progress bar.

On small screens, the steps in a Stepper Nav switch from horizontal orientation to vertical.

Composition with other components

Always pair the Stepper Nav with appropriate navigation Buttons such as "Next" and "Previous". Buttons can be wrapped with a Button Set to ensure consistent spacing between them.

If backwards navigation is allowed, use an interactive Stepper Nav, otherwise use the non-interactive variant.

How to use this component

The Stepper Nav component is used to track the linear progress of a user in a given on-page flow.

To use this component, you can either pass in the contextual Step and Panel components, or use the @steps argument to pass in an array of steps.

Using contextual components

The Hds::Stepper::Nav::Step and Hds::Stepper::Nav::Panel are yielded as contextual components.

<Hds::Stepper::Nav @ariaLabel="Basic usage" as |S|>
  <S.Step>
    <:title>Step 1</:title>
  </S.Step>
  <S.Step>
    <:title>Step 2</:title>
  </S.Step>
  <S.Step>
    <:title>Step 3</:title>
  </S.Step>

  <S.Panel>Content 1</S.Panel>
  <S.Panel>Content 2</S.Panel>
  <S.Panel>Content 3</S.Panel>
</Hds::Stepper::Nav>

Using the @steps argument

When using the @steps argument, use the named block <:body> to pass in step content. This can be used if the template for steps content is consistent across steps, or conditionally rendered based on arguments other than the currentStep.

<Hds::Stepper::Nav
  @currentStep={{this.demoCurrentStep}}
  @steps={{array
    (hash title="Step 1")
    (hash title="Step 2")
    (hash title="Step 3")
  }}
  @ariaLabel="Using steps argument"
  @onStepChange={{this.demoOnStepChange}}
>
  <:body>
    {{#if (eq this.demoCurrentStep 0)}}
      Content 1
    {{else if (eq this.demoCurrentStep 1)}}
      Content 2
    {{else}}
      Content 3
    {{/if}}
    {{#if true}}
      Conditional content
    {{/if}}
  </:body>
</Hds::Stepper::Nav>

Step status

The status of steps is controlled automatically through the @currentStep argument. The argument is zero-indexed and sets the active step to the value provided. The status of a step is determined in the following ways in relation to the @currentStep.

  • A step equal to @currentStep is active
  • All steps less than @currentStep are completed
  • All steps greater than @currentStep are incomplete

By default, @currentStep is equal to 0.

<Hds::Stepper::Nav
  @currentStep={{this.demoCurrentStep}}
  @ariaLabel="Status"
  @onStepChange={{this.demoOnStepChange}}
  as |S|
>
  <S.Step>
    <:title>Step 1</:title>
  </S.Step>
  <S.Step>
    <:title>Step 2</:title>
  </S.Step>
  <S.Step>
    <:title>Step 3</:title>
  </S.Step>

  <S.Panel>Content 1</S.Panel>
  <S.Panel>Content 2</S.Panel>
  <S.Panel>Content 3</S.Panel>
</Hds::Stepper::Nav>

Interactivity

The @isInteractive argument controls if navigation between steps is allowed using the steps. By default @isInteractive is true.

Interactive

When @isInteractive is set to true, users can navigate to completed steps by clicking on the step. Users can only navigate to completed steps, not incomplete ones.

When a click on a step occurs, the @onStepChange handler can be used to pass a custom function to update the current step number.

<Hds::Stepper::Nav
  @currentStep={{this.demoCurrentStep}}
  @ariaLabel="Interactive"
  @onStepChange={{this.demoOnStepChange}}
  as |S|
>
  <S.Step>
    <:title>Step 1</:title>
  </S.Step>
  <S.Step>
    <:title>Step 2</:title>
  </S.Step>
  <S.Step>
    <:title>Step 3</:title>
  </S.Step>

  <S.Panel>Content 1</S.Panel>
  <S.Panel>Content 2</S.Panel>
  <S.Panel>Content 3</S.Panel>
</Hds::Stepper::Nav>

Not interactive

When @isInteractive is set to false, the component steps do not allow navigation between steps.

  1. Step 1
  2. Step 2
  3. Step 3
<Hds::Stepper::Nav
  @currentStep={{1}}
  @isInteractive={{false}}
  @ariaLabel="Interactive"
  as |S|
>
  <S.Step>
    <:title>Step 1</:title>
  </S.Step>
  <S.Step>
    <:title>Step 2</:title>
  </S.Step>
  <S.Step>
    <:title>Step 3</:title>
  </S.Step>

  <S.Panel>Content 1</S.Panel>
  <S.Panel>Content 2</S.Panel>
  <S.Panel>Content 3</S.Panel>
</Hds::Stepper::Nav>

Without panels

The component can be used without the [S].Panel contextual component, or <:body> named block. In this use case, the component operates similar to a static list. This can be used if the content of the steps is outside of the component.

Due to accessibility implications, @isInteractive must be set to false when using the component without panels.

  1. Step 1
  2. Step 2
  3. Step 3
Steps content
<Hds::Stepper::Nav
  @isInteractive={{false}}
  @ariaLabel="Standalone contextual components"
  as |S|
>
  <S.Step>
    <:title>Step 1</:title>
  </S.Step>
  <S.Step>
    <:title>Step 2</:title>
  </S.Step>
  <S.Step>
    <:title>Step 3</:title>
  </S.Step>
</Hds::Stepper::Nav>
Steps content

Composition with other components

The Stepper Nav should be paired with appropriate navigation Buttons. Buttons can be wrapped with a Button Set to ensure consistent spacing between them.

<Hds::Stepper::Nav
  @currentStep={{this.demoButtonsCurrentStep}}
  @ariaLabel="Component composition"
  @onStepChange={{this.demoButtonsOnStepChange}}
  as |S|
>
  <S.Step>
    <:title>Step 1</:title>
  </S.Step>
  <S.Step>
    <:title>Step 2</:title>
  </S.Step>
  <S.Step>
    <:title>Step 3</:title>
  </S.Step>
  <S.Panel>
    Content 1
    <Hds::Button @text="Next" {{on "click" this.onNextClickDemo}} />
  </S.Panel>
  <S.Panel>
    Content 2
    <Hds::ButtonSet>
      <Hds::Button
        @text="Previous"
        @color="secondary"
        {{on "click" this.onPreviousClickDemo}}
      />
      <Hds::Button @text="Next" {{on "click" this.onNextClickDemo}} />
    </Hds::ButtonSet>
  </S.Panel>
  <S.Panel>
    Content 3
    <Hds::Button
      @text="Previous"
      @color="secondary"
      {{on "click" this.onPreviousClickDemo}}
    />
  </S.Panel>
</Hds::Stepper::Nav>

Component API

Stepper::Nav

<[S].Step> yielded component
Stepper::Navigation::Step yielded as contextual component (see below).
<[S].Panel> yielded component
Stepper::Navigation::Panel yielded as contextual component (see below).
<:body> named block
A named block where the content of a step is rendered. It is only used when leveraging the @steps argument.
steps array
Array hash that defines each step with key-value properties that describe each step. Options:
title string
Required
The step's title.
description string
The step's description.
currentStep integer
  • 0 (default)
Sets the active step to the base-indexed number provided.
isInteractive boolean
  • true (default)
If set to true, navigation to completed steps is allowed using the nav steps.
titleTag enum
  • div (default)
  • h1
  • h2
  • h3
  • h4
  • h5
  • h6
The HTML tag that wraps the content of each Nav Step title block.
ariaLabel string
Required
The value of the aria-label. If no text value is defined, an error will be thrown.
onStepChange function
Callback function invoked when @isInteractive is set to true and a click occurs on an interactive step. The function receives the DOM event and the steps's index (integer number) as arguments.
…attributes
This component supports use of ...attributes.

Contextual components

[S].Step

The Stepper::Nav::Step component, yielded as contextual component.

<:title> named block
Required
A named block where the title of the step is rendered.
<:description> named block
A named block where the description of the step is rendered.
…attributes
This component supports use of ...attributes.

[S].Panel

The Stepper::Nav::Panel component, yielded as contextual component.

yield
Elements passed as children are yielded as inner content of a <section> HTML element.
…attributes
This component supports use of ...attributes.

Anatomy

Element Usage
Stepper Indicator Required
Progress bar Required
Title Required
Description Optional

States

Non-interactive Stepper Nav steps only have one state. Interactive Stepper Nav steps have multiple: completed steps have default, active, hover, focus states, the current step has default and focus states, and inactive steps only have a default state because they are not interactive.

Conformance rating

Conformant

When used as recommended, there should not be any WCAG conformance issues with this component.

Keyboard navigation

Keyboard navigation with the following keys is only available when @isInteractive is set to true.

Tab

Focus on the active step.

Stepper Nav with 3 steps. The second step, which is active, is focused.

Left arrow
Right arrow

Move between completed and active steps.

If focus is on the first step, left arrow moves focus to the last completed or active step. If focus is on the last completed or active step, right arrow moves focus to the first completed or active step.

Stepper Nav with 3 steps. The left arrow has been pressed moving focus from step 1 to step 2.

Spacebar
Enter

Activate step to display step content.

Stepper Nav showing on spacebar or enter on a completed step, that step is made active

Tab

Move to interactive element within the content area.

Stepper Nav showing on tab press while focus is on a step, focus moves to next interactive element

Applicable WCAG Success Criteria

  • 1.3.1 Info and Relationships (Level A):
    Information, structure, and relationships conveyed through presentation can be programmatically determined or are available in text.
  • 1.3.2 Meaningful Sequence (Level A):
    When the sequence in which content is presented affects its meaning, a correct reading sequence can be programmatically determined.
  • 1.4.1 Use of Color (Level A):
    Color is not used as the only visual means of conveying information, indicating an action, prompting a response, or distinguishing a visual element.
  • 1.4.10 Reflow (Level AA):
    Content can be presented without loss of information or functionality, and without requiring scrolling in two dimensions.
  • 1.4.11 Non-text Contrast (Level AA):
    The visual presentation of the following have a contrast ratio of at least 3:1 against adjacent color(s): user interface components; graphical objects.
  • 1.4.12 Text Spacing (Level AA):
    No loss of content or functionality occurs by setting all of the following and by changing no other style property: line height set to 1.5; spacing following paragraphs set to at least 2x the font size; letter-spacing set at least 0.12x of the font size, word spacing set to at least 0.16 times the font size.
  • 1.4.3 Minimum Contrast (Level AA):
    The visual presentation of text and images of text has a contrast ratio of at least 4.5:1
  • 1.4.4 Resize Text (Level AA):
    Except for captions and images of text, text can be resized without assistive technology up to 200 percent without loss of content or functionality.
  • 2.1.1 Keyboard (Level A):
    All functionality of the content is operable through a keyboard interface.
  • 2.1.2 No Keyboard Trap (Level A):
    If keyboard focus can be moved to a component of the page using a keyboard interface, then focus can be moved away from that component using only a keyboard interface.
  • 2.2.2 Pause, Stop, Hide (Level A):
    If you have moving, blinking, scrolling or auto-updating information, read the guidance because there are a lot of details.
  • 2.4.6 Headings and Labels (Level AA):
    Headings and labels describe topic or purpose.
  • 2.4.7 Focus Visible (Level AA):
    Any keyboard operable user interface has a mode of operation where the keyboard focus indicator is visible.
  • 3.2.1 On Focus (Level A):
    When any user interface component receives focus, it does not initiate a change of context.
  • 3.3.2 Labels or Instructions (Level A):
    Labels or instructions are provided when content requires user input.
  • 4.1.2 Name, Role, Value (Level A):
    For all user interface components, the name and role can be programmatically determined; states, properties, and values that can be set by the user can be programmatically set; and notification of changes to these items is available to user agents, including assistive technologies.

Support

If any accessibility issues have been found within this component, let us know by submitting an issue.

4.18.1

Added new Stepper Nav component


Related