Create a Responsive React Stepper Component
Develop a reusable and accessible stepper component in React using TypeScript. This component will guide users through a multi-step process, visually indicating the current step and allowing navigation between them.
Problem Description
Your task is to build a functional stepper component. This component should display a series of steps, with the current step clearly highlighted. Users should be able to navigate forward and backward through the steps. The component should be responsive, adapting gracefully to different screen sizes.
Key Requirements:
- Step Display: Render a visual representation of each step. This could be a circle with a number, a label, or a combination.
- Active Step Indication: Clearly highlight the currently active step.
- Navigation: Implement functionality to move to the next and previous steps.
- Step Completion: Optionally, visually indicate completed steps.
- Accessibility: Ensure the component is accessible, using appropriate ARIA attributes and keyboard navigation.
- Responsiveness: The component should look and function well on various screen sizes.
- TypeScript: The entire implementation must be in TypeScript.
Expected Behavior:
- When the component mounts, the first step should be active.
- Clicking a "Next" button should advance the active step.
- Clicking a "Previous" button should move back to the previous step.
- Navigation should be disabled when at the first or last step.
- Completed steps should have a distinct visual style.
- Keyboard navigation (e.g., using arrow keys or Tab) should be supported.
Edge Cases to Consider:
- What happens if the
stepsarray is empty? - What happens if
initialActiveStepis out of bounds? - How does the component behave with a very large number of steps?
Examples
Example 1:
Input Props:
interface StepperProps {
steps: string[];
initialActiveStep?: number;
onStepChange?: (step: number) => void;
}
const stepLabels = ["Personal Info", "Contact Details", "Payment", "Confirmation"];
Expected Visual Output (Conceptual):
- On desktop, steps are laid out horizontally.
- Step 1 (Personal Info) is active and highlighted (e.g., blue circle with "1").
- Steps 2, 3, and 4 are inactive (e.g., gray circle with "2", "3", "4").
- "Previous" button is disabled.
- "Next" button is enabled.
Explanation: The stepper is initialized with 4 steps, and the initialActiveStep is 0 (the first step). The current step is visually indicated, and navigation controls are present and appropriately enabled/disabled.
Example 2:
Input Props:
const stepLabels = ["Step A", "Step B", "Step C"];
User Interaction: User clicks "Next" twice.
Expected Visual Output (Conceptual):
- Step 1 (Step A) is now completed (e.g., green circle with "A").
- Step 2 (Step B) is active and highlighted (e.g., blue circle with "B").
- Step 3 (Step C) is inactive (e.g., gray circle with "C").
- "Previous" button is enabled.
- "Next" button is enabled.
Explanation: After navigating to Step C and then pressing "Previous" once, the stepper should show Step B as active, Step A as completed, and Step C as the next step.
Example 3: Responsive Behavior
Input Props:
const stepLabels = ["One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight"];
Expected Visual Output (Conceptual):
- On small screens (e.g., mobile): Steps might stack vertically or display as a compact horizontal list with only an indicator and label, perhaps using ellipsis for too many steps. Navigation might be through swipe gestures or dedicated buttons.
- On larger screens (e.g., desktop): Steps are displayed clearly horizontally with numbers and labels.
Explanation: The layout and interaction of the stepper should adapt to the available screen space, ensuring usability across devices.
Constraints
- The stepper component should accept an array of strings for step labels.
- The
initialActiveStepprop should be a number representing the index of the first active step. - An optional
onStepChangecallback function should be provided, which is called with the new active step index whenever the step changes. - The component should not rely on external UI libraries (like Material UI or Ant Design) for its core functionality and styling, though you can use basic CSS for styling.
Notes
- Consider how you will visually represent completed steps (e.g., different color, checkmark icon).
- Think about how to handle the styling and layout for responsiveness. CSS Grid or Flexbox would be excellent choices.
- For accessibility, use appropriate ARIA roles (e.g.,
role="tablist",role="tab",aria-selected) and ensure keyboard focus management. - You can define custom CSS classes or use inline styles for visual presentation.
- The
stepsarray should be treated as read-only within the component.