Implementing a Multi-Step Wizard Flow in React with TypeScript
Wizard flows are a common UI pattern used to guide users through a series of steps to complete a task, such as onboarding, form filling, or configuration. This challenge asks you to build a reusable wizard component in React using TypeScript, allowing users to navigate sequentially through a defined set of steps. This is a valuable skill for building complex user interfaces and improving user experience.
Problem Description
You need to create a Wizard component that displays a series of steps, allowing users to navigate between them using "Next" and "Previous" buttons. The wizard should maintain the current step and render the appropriate content for that step. The content for each step is provided as a prop.
Key Requirements:
- Step Definition: The wizard should accept an array of step objects. Each step object should have a
title(string) andcontent(React.ReactNode) property. - Navigation: "Next" and "Previous" buttons should be rendered, enabling users to move between steps. The "Next" button should be disabled when on the last step, and the "Previous" button should be disabled when on the first step.
- Current Step Display: The wizard should clearly indicate the current step number to the user (e.g., "Step 2 of 5").
- Content Rendering: The
contentproperty of the current step should be rendered within the wizard. - State Management: The component should manage its internal state to track the current step.
- Reusability: The component should be designed to be reusable with different sets of steps and content.
Expected Behavior:
- Clicking "Next" should move the user to the next step, if available.
- Clicking "Previous" should move the user to the previous step.
- The UI should update to reflect the current step, including the step number and the displayed content.
- The "Next" button should be disabled on the last step.
- The "Previous" button should be disabled on the first step.
Edge Cases to Consider:
- Empty step array: The wizard should gracefully handle an empty array of steps (e.g., render a message indicating no steps are defined).
- Invalid step content: The
contentproperty of a step should be able to accept any valid React node. - Initial step: The wizard should start at the first step by default.
Examples
Example 1:
Input: steps = [{ title: "Step 1", content: <h1>Welcome!</h1> }, { title: "Step 2", content: <p>Please enter your details.</p> }]
Output: A wizard displaying "Step 1 of 2" and the content "Welcome!". A "Next" button is present and enabled. Clicking "Next" displays "Step 2 of 2" and the content "Please enter your details.". The "Next" button is disabled.
Explanation: The wizard correctly renders the first step and allows navigation to the second.
Example 2:
Input: steps = [{ title: "Step 1", content: <input type="text" /> }, { title: "Step 2", content: <button>Submit</button> }]
Output: A wizard displaying "Step 1 of 2" and an input field. Clicking "Next" displays "Step 2 of 2" and a submit button.
Explanation: Demonstrates rendering different types of React content within the steps.
Example 3: (Edge Case)
Input: steps = []
Output: A message "No steps defined."
Explanation: Handles the edge case of an empty steps array.
Constraints
- The component should be written in TypeScript.
- The component should be functional.
- The component should be reasonably performant (avoid unnecessary re-renders).
- The
contentproperty of each step can be any valid React node. - The number of steps will be between 1 and 10 (inclusive).
Notes
- Consider using React's
useStatehook for managing the current step. - Think about how to make the component configurable and reusable.
- You can use CSS or a CSS-in-JS library to style the wizard. Styling is not the primary focus of this challenge, but a clean and understandable layout is appreciated.
- Focus on the core logic of the wizard flow and state management.
- Error handling for invalid input is not required for this challenge.