Hone logo
Hone
Problems

Implement a Searchable Dropdown Component in React

Create a reusable React component that functions as a searchable dropdown. This component should allow users to select an option from a list, with the ability to filter that list by typing into an input field. This is a common UI pattern found in many web applications for selecting from a large set of options.

Problem Description

Your task is to build a SearchableDropdown component in React using TypeScript. This component will receive a list of options and render an input field. When the user types into the input field, the list of displayed options should dynamically filter to show only those that match the user's input (case-insensitive search).

Key Requirements:

  • Display Options: Render a list of selectable options.
  • Input Field: Provide an input field for users to type into.
  • Filtering: The displayed options should update in real-time as the user types, based on a case-insensitive match against the option's label.
  • Selection: When a user clicks on an option, it should be selected, and the dropdown should close, displaying the selected option in the input field.
  • No Selection: If the user clears the input field or there are no matches, the full list of options should be displayed (or an appropriate "no results" message).
  • Accessibility: Basic accessibility considerations should be kept in mind (e.g., keyboard navigation is a plus, but not strictly required for this core implementation).

Expected Behavior:

  1. The SearchableDropdown component is rendered with an initial list of options.
  2. An input field is displayed, initially showing a placeholder or no value.
  3. Clicking on the input field (or a dedicated button/icon, which you can choose to implement or omit) reveals the dropdown list of options.
  4. As the user types in the input field:
    • If the input is "apple", only options containing "apple" (e.g., "Apple Pie", "Granny Smith Apple") are shown.
    • If the input is cleared, the full list of options reappears.
    • If no options match the input, a "No results found" message should be displayed.
  5. Clicking on an option from the filtered list:
    • Updates the input field's value to the selected option's label.
    • Closes the dropdown list.
    • (Optional but recommended) Triggers a callback function to inform the parent component about the selected option.

Edge Cases:

  • Empty Options List: The component should gracefully handle an empty array of options.
  • No Matches: The component should clearly indicate when no options match the current search query.
  • Case Sensitivity: The search must be case-insensitive.
  • Special Characters: The search should handle common characters.

Examples

Example 1:

Input:
Props passed to SearchableDropdown:
{
  options: [
    { id: 1, label: "Apple" },
    { id: 2, label: "Banana" },
    { id: 3, label: "Cherry" },
    { id: 4, label: "Date" },
    { id: 5, label: "Elderberry" }
  ],
  placeholder: "Select a fruit..."
}

User interaction:
1. Component mounts. Input shows "Select a fruit...". Dropdown is hidden.
2. User clicks the input. Dropdown appears showing all 5 fruits.
3. User types "a".

Output:
Input field shows: (empty, or the current selection if one was made)
Dropdown shows:
- Apple
- Banana
- Date

Example 2:

Input:
Following up on Example 1, user types "er".

Output:
Input field shows: (empty)
Dropdown shows:
- Cherry
- Elderberry

Example 3:

Input:
Following up on Example 2, user types "xyz".

Output:
Input field shows: (empty)
Dropdown shows:
- No results found.

Constraints

  • The options prop will be an array of objects, each having at least an id (string or number) and a label (string).
  • The component must be built using React and TypeScript.
  • Styling is optional but recommended for usability. For the core challenge, focus on functionality.
  • Consider performance for a moderate number of options (e.g., up to 1000). Avoid overly complex or inefficient search algorithms.

Notes

  • You will need to manage the state of the input field's value, the currently displayed options (filtered list), and whether the dropdown is open or closed.
  • Consider how you'll handle selecting an option and updating the parent component. An onSelect prop (a callback function) is a good pattern for this.
  • For simplicity, you can assume the initial state of the dropdown is closed.
  • Focus on the core filtering and selection logic. Fancy animations or complex styling are secondary.
  • Think about how to handle user interaction for opening/closing the dropdown – a simple click on the input field is sufficient.
Loading editor...
typescript