Components
Stepper

Stepper

The Stepper component is a sequential step-by-step navigation interface that offers a structured, user-friendly way to guide users through a series of steps in a process. It ensures clarity and ease of use with visual progress indicators and interactive controls, helping users understand their progress and navigate each step effortlessly.

Step 1
Step 2
Step 3

Step 1

Additional Examples

Change Orientation

Step 1

Step 1

Step 2
Step 3

We can pass the orientation prop to the Stepper component to change the orientation from "vertical" to "horizontal".

With Descriptions

Step 1Description 1
Step 2Description 2
Step 3Description 3

Step 1

We can add optional description text to provide additional context.

Make Steps Optional

Step 1
Step 2
Step 3

Step 1

If you want to make a step optional, you can add optional: true in the array of steps.

In this example, the second step is optional. You can visualize the change of the label in the Next button

Legend Variants

  • circle: allows you to display each step as a circular shape. The label and description are positioned horizontally next to the button of each step.
  • circle-alt: same circular design as the circle variant but the label and description are positioned vertically below the button of each step and applies a centered effect.
  • line: this variant enables a modern line design with titles and descriptions positioned below the line.
Step 1
Step 2
Step 3

Step 1

Label Sizes

Step 1
Step 2
Step 3

Step 1

Steps can be set to one of 3 sizes: sm, md, and lg which can be set using the size prop.

Mobile Breakpoints (Responsive behavior)

By using the orientation prop you are able to switch between horizontal (default) and vertical orientations. By default, when in mobile view the Steps component will switch to vertical orientation. You can also customize the mobile breakpoint behavior by using the mobileBreakpoint prop.

Status Feedback

Step 1
Step 2
Step 3

Step 1

When communicating with a user, colors, and visuals can play a considerable part; by using color as feedback, we can effectively communicate status messages to users without overcomplicating with words. We can use the state prop to display a loading or error indicator with the values of loading | error.

This prop can be used globally within the Stepper component or locally in the Step component affected by this state.

Custom Icons

Step 1
Step 2
Step 3

Step 1

If you want to use custom icons instead of the default numerical indicators, you can do so by using the icon prop on the Step component.

Clickable Step Indicators

Step 1
Step 2
Step 3

Step 1

If you need the step indicator to be clickable and to be able to set a custom logic for the onClick event, we can use the onClickStep prop in the Stepper component globally or in Step locally.

In this example we have placed a global alert when any step is clicked. Try clicking on any step to see the result.

Step 1

Step 1

Step 2
Step 3

When using the vertical orientation, we may want to have the footer buttons inside each step and not located at the end. To achieve this, we can simply move our footer below all the steps inside the Stepper component.

Automatic Scrolling

Step 1

Step 1

Step 2
Step 3
Step 4
Step 5
Step 6

To enable automatic scrolling as a user progresses through steps use the scrollTracking prop on the Stepper component.

With Forms

Step 1Description 1
Step 2Description 2

This is your public display name.

To use Form components within the Stepper component, use the useStepper hook to control the component.

This example uses the Form component and the react-hook-form hooks to create a form with ZOD validations.

You can also use the component with server actions.

Custom Styling

Step 1
Step 2
Step 3

Step 1

In this example we will change the style of the steps and the separator. In addition, we will also change the variables that define the size and gap of the icon for each step.

...
  <Stepper
    initialStep={0}
    steps={steps}
    styles={{
      "step-button-container": cn(
        "text-purple-700 rounded-none",
        "data-[current=true]:border-purple-500 data-[current=true]:bg-purple-50",
        "data-[active=true]:bg-purple-500 data-[active=true]:border-purple-500"
      ),
      "horizontal-step":
        "data-[completed=true]:[&:not(:last-child)]:after:bg-purple-500",
    }}
    variables={{
      "--step-icon-size": "60px",
      "--step-gap": "20px",
    }}
  >
  // Rest of the code
  </Stepper>
...

To customize the styles of the Steps component, Stepper provides a set of CSS variables for each part of the component. You can use these variables to override default styles:

  • main-container: The main container of the stepper.
  • horizontal-step: Outer wrapper for each step in horizontal layout
  • horizontal-step-container: Inner wrapper for each step in horizontal layout
  • vertical-step: Outer wrapper for each step in vertical layout
  • vertical-step-container: Inner wrapper for each step in vertical layout
  • vertical-step-content: Content wrapper for each step in vertical layout
  • step-button-container: Wrapper for the step button
  • step-label-container: Wrapper for the label and description
  • step-label: The label of the step
  • step-description: The description of the step

State specific variables:

  • data-active: The active step
  • data-invalid: The step with an error
  • data-loading: The step in loading state
  • data-clickable: The step that is clickable
  • data-completed: The step that is completed
  • data-optional: The step that is optional

Sure, here's the rephrased version:

Finally, the variables prop lets you define values for the CSS variables used to position the separator lines. This is particularly useful when custom elements of varying sizes need to be set beyond the default options provided by the component:

  • --step-icon-size: defines the width of the step icon. It is important to define this value in pixels. By default it has the values of the width of a button depending if the style is default (36px, 40px, 44px).
  • --step-gap: defines the gap between the separator and the elements that follow it. The default value is 8px.

Configurable Props

<Stepper>

Prop

Type

Default/ Options

Description

initialStep

number

Currently active step

steps

StepItem[]

An array of objects with the label and description of each step.

orientation

"horizontal" | "vertical"

"horizontal"

The orientation of the stepper.

size

"sm" | "md" | "lg"

"md"

The size of the stepper.

state

"loading" | "error"

The state of the stepper (global).

icon

object

The custom icon to be displayed in the step button.

checkIcon

object

The custom icon to be displayed when the step is completed.

errorIcon

object

The custom icon to be displayed when the step has an error.

responsive

boolean

true

If the stepper should be responsive.

mobileBreakpoint

number

768px

The breakpoint at which the stepper switches to vertical orientation.

scrollTracking

boolean

false

Scroll to the active step when scrolling forward or backward.

styles

{ [key: string]: string }

Custom styles for the stepper.

variables

{ [key: string]: string }

Custom css variables values for the stepper.

onClickStep

(index: number, setStep: (index: number) => void) => void

The function to be executed when a step is clicked.

variant

"circle" | "circle-alt" | "line"

"circle"

The design variant of the stepper.

expandVerticalSteps

boolean

false

Control whether or not the vertical steps should collapse.

<Step>

Prop

Type

Default/ Options

Description

id

string

The id of the step.

label

string

The label of the step.

description

string

The description of the step.

optional

boolean

If the step is optional.

icon

object

The custom icon to be displayed in the step button.

state

"loading" | "error"

The state of the step (local).

isCompletedStep

boolean

Individually control each step state, defaults to active step.

isKeepError

boolean

Individually control if each step should keep showing the error state.

checkIcon

object

The custom icon to be displayed when the step is completed.

errorIcon

object

The custom icon to be displayed when the step has an error.

onClickStep

(index: number, setStep: (index: number) => void) => void

The function to be executed when a step is clicked.

useStepper

In order to use the hook, we simply have to import it and use it inside the <Stepper /> component as a wrapper.

import { useStepper } from "@/components/ui/stepper"
 
export funcion UseStepperDemo() {
  { ... } = useStepper();
 
  return (
    <div>
      { ... }
    </div>
  )
}

The hook returns the following values:

Prop

Type

Default/ Options

Description

activeStep

number

The current active step.

isLastStep

boolean

If the current step is the last step.

isOptionalStep

boolean

If the current step is optional.

isDisabledStep

boolean

If the current step is disabled.

isError

boolean

If the stepper has an error.

isLoading

boolean

If the stepper is loading.

isVertical

boolean

If the stepper is vertical.

expandVerticalSteps

boolean

If the vertical steps should be expanded.

nextStep

() => void

Function to go to the next step.

prevStep

() => void

Function to go to the previous step.

setStep

(index: number) => void

Function to set a specific step.

resetSteps

() => void

Function to reset the stepper.

stepCount

number

The total number of steps.

initialStep

number

The initial active step.

clickable

boolean

If the steps are clickable.

hasCompletedAllSteps

boolean

If all steps have been completed.

currentStep

StepItem

The current step object.