Hone logo
Hone
Problems

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 a label (string) and a value (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 selectedValue state and call the onChange function with the selected value.
  • Visual Indication: The component should visually indicate which option is currently selected.
  • No Options Handling: If the options array 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 onChange callback.
  • 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 options array.
  • selectedValue not matching any of the options values.
  • 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 value property of the options.
  • The component should be performant; avoid unnecessary re-renders.

Notes

  • Consider using the useState hook 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.
Loading editor...
typescript