React Dropdown Component with TypeScript
This challenge asks you to build a reusable dropdown component in React using TypeScript. Dropdowns are fundamental UI elements for selecting options from a list, and creating a well-structured, type-safe component will enhance your React skills and provide a valuable building block for more complex applications.
Problem Description
You need to create a Dropdown component that renders a selectable list of options. The component should accept a list of options, each with a label and a value, and allow the user to select one option. Upon selection, the component should display the selected value and provide a visual cue to indicate that an option is selected. The component should also handle the case where no options are provided gracefully.
Key Requirements:
- Type Safety: Utilize TypeScript to ensure type safety for the options and the selected value.
- Props: The component should accept the following props:
options: An array of objects, where each object has alabel(string) and avalue(any).onChange: A function that is called when an option is selected, passing the selected value as an argument.selectedValue: (Optional) The initially selected value. If not provided, no option is initially selected.
- UI: The component should display a button or similar element that, when clicked, reveals a list of options.
- Selection: Clicking an option should update the
selectedValuestate and call theonChangefunction with the selected value. - Visual Indication: The component should visually indicate which option is currently selected.
- No Options Handling: If the
optionsarray is empty, the component should display a message indicating that no options are available.
Expected Behavior:
- When the component mounts, it should render the dropdown button/element.
- Clicking the button/element should toggle the visibility of the options list.
- Clicking an option should update the component's state with the selected value and trigger the
onChangecallback. - The selected option should be visually highlighted.
- If no options are provided, a message like "No options available" should be displayed.
Edge Cases to Consider:
- Empty
optionsarray. selectedValuenot matching any of theoptionsvalues.- Handling potential errors during state updates.
- Accessibility (consider ARIA attributes for screen readers).
Examples
Example 1:
Input:
options: [{ label: "Option 1", value: 1 }, { label: "Option 2", value: 2 }]
onChange: (value: number) => console.log(value)
selectedValue: null
Output:
Initially, a dropdown button displaying "Select an option". Clicking the button reveals a list with "Option 1" and "Option 2". Selecting "Option 2" updates the button to display "Option 2" and calls the onChange function with the value 2.
Explanation: The component renders the dropdown, allows selection, and updates the displayed value and calls the callback.
Example 2:
Input:
options: [{ label: "Red", value: "red" }, { label: "Green", value: "green" }, { label: "Blue", value: "blue" }]
onChange: (color: string) => setChosenColor(color)
selectedValue: "green"
Output:
Initially, a dropdown button displaying "Green". Clicking the button reveals a list with "Red", "Green", and "Blue". Selecting "Blue" updates the button to display "Blue" and calls the onChange function with the value "blue".
Explanation: The component renders with a pre-selected value and allows changing it.
Example 3:
Input:
options: []
onChange: (value: any) => console.log(value)
selectedValue: null
Output:
A message "No options available" is displayed.
Explanation: Handles the edge case of an empty options array.
Constraints
- The component should be implemented as a functional component using React Hooks.
- The component should be styled using CSS (inline styles, CSS modules, or a CSS-in-JS library are acceptable). Focus on functionality over elaborate styling.
- The component should be reusable and accept different types of values for the
valueproperty of the options. - The component should be performant; avoid unnecessary re-renders.
Notes
- Consider using the
useStatehook to manage the selected value and the visibility of the options list. - Think about how to efficiently update the state when an option is selected.
- Pay attention to accessibility best practices.
- Focus on creating a clean, well-structured, and type-safe component. Don't overcomplicate the styling. The primary goal is to demonstrate the core functionality and type safety.