Navigation / React + CSS
Progress stepper
A connected step indicator with animated progress and clear next actions.
- 1Brief
- 2Design
- 3Review
Step 1: Brief
"use client";
import styles from "./ProgressStepper.module.css";
import { useState } from "react";
export default function ProgressStepper({
steps = ["Brief", "Design", "Review"],
onComplete,
}) {
const [step, setStep] = useState(0);
const complete = step === steps.length;
return (
<div className={styles.root}>
<ol>
{steps.map((label, index) => (
<li
key={label}
data-done={index < step}
aria-current={index === step ? "step" : undefined}
>
<span>{index < step ? "✓" : index + 1}</span>
<small>{label}</small>
</li>
))}
</ol>
<div className={styles.track} aria-hidden="true">
<i style={{ width: `${(step / Math.max(steps.length, 1)) * 100}%` }} />
</div>
<p role="status">
{complete
? "You’re ready for the next chapter."
: `Step ${step + 1}: ${steps[step]}`}
</p>
<div className={styles.actions}>
<button
type="button"
disabled={step === 0}
onClick={() => setStep(step - 1)}
>
Back
</button>
<button
type="button"
onClick={() => {
if (complete) {
setStep(0);
return;
}
const next = step + 1;
setStep(next);
if (next === steps.length) onComplete?.();
}}
>
{complete
? "Start again"
: step === steps.length - 1
? "Finish"
: "Continue"}{" "}
<span aria-hidden="true">→</span>
</button>
</div>
</div>
);
}
Make it yours
Use for a short, linear task. This standalone example manages step state; connect validation and actual task content before using it for a real workflow. Pass at least one step.
- Use a React project with CSS Modules support, such as Next.js or Vite.
- Save the JSX as
ProgressStepper.jsxand the CSS asProgressStepper.module.cssin the same folder. - Import
ProgressStepperand connect its props to your application. Controlled components need parent state and change handlers.
No third-party component or animation package is required. Use the theme controls to adjust accent, corners, spacing, and type. Copy the Theme CSS into your stylesheet and wrap your components in <div className="tdp-components">. The theme applies to every component inside that wrapper. TDP defaults work without a theme file.
Props
| Prop | Type | Use |
|---|---|---|
steps | string[] | Nonempty list of unique step labels. |
onComplete | function | Called when the final step is finished. |
Accessibility & behavior
An ordered list describes the sequence and aria-current marks the active step. Progress changes are announced in a status region. Navigation uses native buttons.
Visible focus styles and reduced-motion support are included. Check labels, contrast, keyboard behavior, and screen-reader output again after adapting the component to your product.