Stepper
Stepper displays progress through a multi-step process, allowing users to navigate between steps and track their progress.
Preview
Publication Information
Enter the basic information about your publication
Usage
tsx
import { Stepper, StepperHeader, StepperContent, StepperFooter, useStepper, Button } from '@e-infra/design-system'
// Define your steps
const steps = [
{ label: "Step 1", description: "First step description" },
{ label: "Step 2", description: "Second step description" },
{ label: "Step 3", description: "Third step description" },
]
// Basic usage
<Stepper>
<StepperHeader steps={steps} />
<StepperContent>
<YourStep1Content />
<YourStep2Content />
<YourStep3Content />
</StepperContent>
</Stepper>
// Optional: custom footer actions
function StepperActions() {
const { currentStep, totalSteps, nextStep, previousStep } = useStepper();
const isLastStep = currentStep === totalSteps - 1;
return (
<StepperFooter showDefaultButtons={false}>
<Button variant="outline" onClick={previousStep} disabled={currentStep === 0}>
Back
</Button>
<Button onClick={isLastStep ? () => console.log("Done") : nextStep}>
{isLastStep ? "Submit" : "Continue"}
</Button>
</StepperFooter>
);
}Components
| Component | Description |
|---|---|
Stepper | Container component that manages step state and context |
StepperHeader | Displays progress indicator, current section label, and header navigation |
StepperContent | Displays content for the current step |
StepperFooter | Optional footer area for default or custom actions |
Props
Stepper
| Prop | Type | Default | Description |
|---|---|---|---|
| children | React.ReactNode | - | Step content and child components |
| initialStep | number | 0 | Starting step index |
| totalSteps | number | - | Total number of steps. If omitted, it is inferred from Stepper direct children, so pass explicitly when your content count differs. |
| onStepChange | (step: number) => void | - | Callback when step changes |
StepperHeader
| Prop | Type | Default | Description |
|---|---|---|---|
| steps | Step[] | - | Array of step definitions with label and optional description |
| className | string | - | Additional CSS classes |
StepperContent
| Prop | Type | Default | Description |
|---|---|---|---|
| children | React.ReactNode | - | Content for each step |
| className | string | - | Additional CSS classes |
StepperFooter
| Prop | Type | Default | Description |
|---|---|---|---|
| children | React.ReactNode | - | Custom footer content (overrides default buttons) |
| className | string | - | Additional CSS classes |
| showDefaultButtons | boolean | true | Show default Previous/Next/Finish buttons |
| nextLabel | string | "Next" | Label for Next button |
| previousLabel | string | "Previous" | Label for Previous button |
| finishLabel | string | "Finish" | Label for Finish button on last step |
| onFinish | () => void | - | Callback when Finish button is clicked |
Controlled vs Uncontrolled
The Stepper works as an uncontrolled component by default, managing its own internal state. You can also use it in a controlled manner by managing the step externally:
tsx
function ControlledStepper() {
const [currentStep, setCurrentStep] = React.useState(0);
return (
<Stepper initialStep={currentStep} onStepChange={setCurrentStep}>
<StepperHeader steps={steps} />
<StepperContent>{/* Your step content */}</StepperContent>
<StepperFooter
onFinish={() => console.log("Finished")}
showDefaultButtons={false}
>
{/* Custom controls using currentStep */}
</StepperFooter>
</Stepper>
);
}Accessibility
The Stepper component includes built-in accessibility features:
- ARIA labels on navigation buttons
- Keyboard navigation support via clickable step indicators
- Screen reader announcements for current step changes via a polite live region
- Semantic HTML structure with proper landmark roles
Examples
With Initial Step
Start the stepper at a specific step:
tsx
<Stepper initialStep={2}>
<StepperHeader steps={steps} />
<StepperContent>{/* Your step content */}</StepperContent>
<StepperFooter onFinish={() => console.log("Done")} />
</Stepper>Custom Footer
Provide custom navigation controls by using useStepper() inside a child component:
tsx
function CustomFooterActions() {
const { currentStep, totalSteps, nextStep, previousStep } = useStepper();
const isLastStep = currentStep === totalSteps - 1;
return (
<StepperFooter showDefaultButtons={false}>
<Button
variant="outline"
onClick={previousStep}
disabled={currentStep === 0}
>
Back
</Button>
<Button onClick={isLastStep ? () => submit() : nextStep}>
{isLastStep ? "Submit" : "Continue"}
</Button>
</StepperFooter>
);
}
<Stepper totalSteps={steps.length}>
<StepperHeader steps={steps} />
<StepperContent>{/* Your step content */}</StepperContent>
<CustomFooterActions />
</Stepper>;On Step Change Callback
Track or validate before step changes:
tsx
<Stepper
onStepChange={(step) => {
console.log(`Moving to step ${step}`);
// Perform validation or analytics here
}}
>
{/* Your stepper content */}
</Stepper>