The Steps component displays a visual progress indicator with connected steps. It supports vertical and horizontal layouts, animated progress transitions, and customizable step indicators.
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>First step
Second step
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>Cart
Shipping
Payment
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>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>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>Use a function for the indicator prop to render custom content based on the step index.
Step A
Step B
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>Neutral
Status
Primary
Status
Success
Status
Danger
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>| Name | Type | Default | Description |
|---|---|---|---|
children | JSXElement | Step components to render within the Steps container | |
status | Status | '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 |
progress | number | 0 | Progress value controlling which steps are complete. Each step represents 100 units (0-100 for first step, 100-200 for second, etc.) |
horizontal | boolean | false | If true, renders steps in a horizontal layout instead of vertical |
| Name | Type | Default | Description |
|---|---|---|---|
children | JSXElement | Content to render for this step | |
status | null | 'active' | 'completed' | 'disabled' | null | Status of the individual step |
aside | boolean | false | If true, positions the step content on the opposite side of the indicator (left for vertical, top for horizontal) |
indicator | null | '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 |
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
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 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.
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>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>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>
);
}| Name | Type | Default | Description |
|---|---|---|---|
children | JSXElement | Step components to render within the container | |
status | Status | '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 |
horizontal | boolean | false | If true, renders steps in a horizontal layout instead of vertical |
triggerPosition | number | 0.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. |
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.