Steps Component

The Steps component displays a visual progress indicator with connected steps. It supports vertical and horizontal layouts, animated progress transitions, and customizable step indicators.

Usage

Basic Steps

Step 1

Step 2

Step 3

<Steps progress={150}>
  <Step>
    <Text>Step 1</Text>
  </Step>
  <Step>
    <Text>Step 2</Text>
  </Step>
  <Step>
    <Text>Step 3</Text>
  </Step>
</Steps>

Numbered Indicators

1

First step

2

Second step

3

Third step

<Steps progress={100} status="primary">
  <Step indicator="number">
    <Text>First step</Text>
  </Step>
  <Step indicator="number">
    <Text>Second step</Text>
  </Step>
  <Step indicator="number">
    <Text>Third step</Text>
  </Step>
</Steps>

Horizontal Layout

1

Cart

2

Shipping

3

Payment

4

Confirm

<Steps horizontal progress={200} status="success">
  <Step indicator="number">
    <Text>Cart</Text>
  </Step>
  <Step indicator="number">
    <Text>Shipping</Text>
  </Step>
  <Step indicator="number">
    <Text>Payment</Text>
  </Step>
  <Step indicator="number">
    <Text>Confirm</Text>
  </Step>
</Steps>

Dot Alignment

Control the alignment of step indicators relative to content with the dotAlignment prop.

Step Title

This is a longer description

Another Step

With more content here

Final Step

Almost done

<Steps progress={100} dotAlignment="center" status="info">
  <Step>
    <div>
      <Text bold>Step Title</Text>
      <Text.small>This is a longer description</Text.small>
    </div>
  </Step>
  <Step>
    <div>
      <Text bold>Another Step</Text>
      <Text.small>With more content here</Text.small>
    </div>
  </Step>
  <Step>
    <div>
      <Text bold>Final Step</Text>
      <Text.small>Almost done</Text.small>
    </div>
  </Step>
</Steps>

Aside Content

Use the aside prop to position step content on the opposite side of the indicator.

9:00 AM

Meeting started

10:30 AM

Break time

11:00 AM

Resume meeting

<Steps progress={150} status="warning">
  <Step aside>
    <Text.small>9:00 AM</Text.small>
  </Step>
  <Step>
    <Text>Meeting started</Text>
  </Step>
  <Step aside>
    <Text.small>10:30 AM</Text.small>
  </Step>
  <Step>
    <Text>Break time</Text>
  </Step>
  <Step aside>
    <Text.small>11:00 AM</Text.small>
  </Step>
  <Step>
    <Text>Resume meeting</Text>
  </Step>
</Steps>

Custom Indicator Function

Use a function for the indicator prop to render custom content based on the step index.

A

Step A

B

Step B

C

Step C

<Steps progress={100} status="success">
  <Step indicator={(index) => <span>{String.fromCharCode(65 + index)}</span>}>
    <Text>Step A</Text>
  </Step>
  <Step indicator={(index) => <span>{String.fromCharCode(65 + index)}</span>}>
    <Text>Step B</Text>
  </Step>
  <Step indicator={(index) => <span>{String.fromCharCode(65 + index)}</span>}>
    <Text>Step C</Text>
  </Step>
</Steps>

Status Variants

1

Neutral

2

Status

1

Primary

2

Status

1

Success

2

Status

1

Danger

2

Status

<Steps progress={100} status="neutral">...</Steps>
<Steps progress={100} status="primary">...</Steps>
<Steps progress={100} status="success">...</Steps>
<Steps progress={100} status="danger">...</Steps>

Steps Props

NameTypeDefaultDescription
childrenJSXElement

Step components to render within the Steps container

statusStatus'neutral'

Status for color theming (e.g., 'success', 'error', 'primary', 'neutral')

dotAlignment'start' | 'center' | 'end''start'

Alignment of the step indicators relative to step content

progressnumber0

Progress value controlling which steps are complete. Each step represents 100 units (0-100 for first step, 100-200 for second, etc.)

horizontalbooleanfalse

If true, renders steps in a horizontal layout instead of vertical

Step Props

NameTypeDefaultDescription
childrenJSXElement

Content to render for this step

statusnull | 'active' | 'completed' | 'disabled'null

Status of the individual step

asidebooleanfalse

If true, positions the step content on the opposite side of the indicator (left for vertical, top for horizontal)

indicatornull | 'number' | ((index: number) => JSXElement)null

Content to display in the step indicator. Use 'number' to show the step index, or a function for custom content

Progress System

The progress prop uses a numeric scale where each step represents 100 units. The progress value determines which steps are marked as complete and animates the connecting lines:

0 - No steps complete, first step indicator inactive

50 - First step indicator active, line animating to second step

100 - First step complete, second step indicator active

150 - First step complete, line animating to third step

200 - First two steps complete, third step indicator active

Theming

The Steps component uses theme variables for customization. The following theme details control the appearance:

steps_stepSpacing - Gap between steps

steps_gutterSpacing - Gap between indicator and content

steps_lineWidth - Width of the connecting lines

steps_indicatorSize - Size of the step indicators

steps_indicatorBorderRadius - Border radius of indicators

steps_indicatorAnimationTime - Transition duration for indicator state changes

ScrollTrackedSteps

ScrollTrackedSteps is a wrapper component that automatically tracks scroll position and updates the step progress based on which step indicators are visible in the viewport. This is useful for creating scroll-driven progress indicators, like those used in documentation pages or tutorials.

Basic Usage

Wrap your Step components with ScrollTrackedSteps instead of Steps. The progress will automatically update as the user scrolls through the content.

<ScrollTrackedSteps status="success" dotAlignment="center">
  <Step>
    <div style={{ "min-height": "300px" }}>
      <Text.H3>Step 1: Getting Started</Text.H3>
      <Text.body>Introduction content here...</Text.body>
    </div>
  </Step>
  <Step>
    <div style={{ "min-height": "300px" }}>
      <Text.H3>Step 2: Configuration</Text.H3>
      <Text.body>Configuration content here...</Text.body>
    </div>
  </Step>
  <Step>
    <div style={{ "min-height": "300px" }}>
      <Text.H3>Step 3: Implementation</Text.H3>
      <Text.body>Implementation content here...</Text.body>
    </div>
  </Step>
</ScrollTrackedSteps>

Custom Trigger Position

Use the triggerPosition prop to control where in the viewport the progress triggers. A value of 0.3 means the trigger line is at 30% from the top of the viewport.

<ScrollTrackedSteps triggerPosition={0.3} status="primary">
  <Step>...</Step>
  <Step>...</Step>
</ScrollTrackedSteps>

Custom Scroll Container

By default, ScrollTrackedSteps listens to window scroll events. Use the scrollContainer prop to track scroll position within a custom scrollable container.

function MyComponent() {
  let scrollRef: HTMLDivElement | undefined;

  return (
    <div
      ref={scrollRef}
      style={{ height: "400px", overflow: "auto" }}
    >
      <ScrollTrackedSteps
        scrollContainer={() => scrollRef}
        status="info"
      >
        <Step>...</Step>
        <Step>...</Step>
      </ScrollTrackedSteps>
    </div>
  );
}

ScrollTrackedSteps Props

NameTypeDefaultDescription
childrenJSXElement

Step components to render within the container

statusStatus'neutral'

Status for color theming (e.g., 'success', 'error', 'primary', 'neutral')

dotAlignment'start' | 'center' | 'end''start'

Alignment of the step indicators relative to step content

horizontalbooleanfalse

If true, renders steps in a horizontal layout instead of vertical

triggerPositionnumber0.5

Position in the viewport (0-1) that triggers step progress. 0.5 means the middle of the viewport.

scrollContainer() => HTMLElement | undefined

Optional accessor function returning a custom scroll container. Defaults to window scroll.

How Scroll Tracking Works

ScrollTrackedSteps calculates progress by comparing the scroll position to the vertical positions of step indicators (elements with the data-step-indicator attribute). The component:

1. Caches the absolute positions of all step indicators on mount and resize

2. Listens to scroll events (throttled with requestAnimationFrame)

3. Calculates which step the trigger line (viewport position * triggerPosition) has passed

4. Interpolates progress between steps for smooth line animation

The progress value passed to the internal Steps component follows the same 0-100 per step scale described in the Progress System section above.