Hone logo
Hone
Problems

React Autocomplete Component Challenge

Build an intelligent and user-friendly autocomplete component for a React application. This component will allow users to type into an input field and receive real-time suggestions based on a provided list of data. This is a common and highly useful feature for enhancing user experience in search bars, forms, and selection inputs.

Problem Description

Your task is to create a reusable React component named Autocomplete that takes a list of options and a callback function for handling selection. The component should:

  1. Display an Input Field: Render a standard HTML <input type="text" /> element.
  2. Filter Options: As the user types, dynamically filter the provided list of options to show only those that match the current input value (case-insensitive).
  3. Show Suggestions: Display the filtered suggestions in a dropdown list below the input field.
  4. Handle Selection: When a user clicks on a suggestion, update the input field with the selected suggestion and trigger a callback function (provided as a prop) with the selected value.
  5. Handle Keyboard Navigation: Allow users to navigate through suggestions using the Up and Down arrow keys and select a highlighted suggestion by pressing Enter.
  6. Close Suggestions: The suggestion list should close when the user clicks outside the component or after a selection is made.

Examples

Example 1:

  • Input (Props):
    • options: ['Apple', 'Banana', 'Cherry', 'Date', 'Elderberry', 'Fig']
    • onSelect: (value) => console.log('Selected:', value)
  • User Interaction:
    1. User types "a" into the input.
    2. User types "ap" into the input.
  • Expected Behavior:
    • Initially, the input is empty, and no suggestions are shown.
    • After typing "a", the suggestions ['Apple'] are displayed.
    • After typing "ap", the suggestions ['Apple'] are still displayed.
    • If the user clicks on "Apple", the input shows "Apple", and onSelect is called with "Apple".

Example 2:

  • Input (Props):
    • options: ['United States', 'Canada', 'Mexico', 'Brazil', 'Argentina', 'Chile']
    • onSelect: (value) => console.log('Selected:', value)
  • User Interaction:
    1. User types "u" into the input.
    2. User types "un" into the input.
    3. User types "uni" into the input.
    4. User presses the Down arrow key twice.
    5. User presses the Enter key.
  • Expected Behavior:
    • After typing "u", suggestions ['United States'] appear.
    • After typing "un", suggestions ['United States'] appear.
    • After typing "uni", suggestions ['United States'] appear.
    • If a suggestion like ['Canada'] was visible and highlighted, pressing Down arrow twice might select ['Mexico'].
    • Pressing Enter should select the currently highlighted suggestion, update the input, and call onSelect.

Example 3: Case Insensitivity and Empty Input

  • Input (Props):
    • options: ['React', 'Vue', 'Angular', 'Svelte']
    • onSelect: (value) => console.log('Selected:', value)
  • User Interaction:
    1. User types "r" into the input.
    2. User types "R" into the input.
    3. User clears the input.
  • Expected Behavior:
    • Typing "r" shows ['React'].
    • Typing "R" also shows ['React'] (case-insensitive matching).
    • Clearing the input hides all suggestions.

Constraints

  • The options prop will be an array of strings.
  • The onSelect prop will be a function that accepts a single string argument.
  • The component should be built using React and TypeScript.
  • For simplicity, assume there are no more than 1000 options.
  • The filtering should be reasonably efficient, aiming for a response time under 100ms for typical user typing speeds.

Notes

  • Consider how you will manage the state for the input value, the filtered suggestions, and the currently highlighted suggestion for keyboard navigation.
  • Styling is not a primary concern for this challenge, but the suggestions should be visually distinct from the input and positioned correctly. You can use basic CSS or inline styles.
  • Think about how to handle the scenario where no options match the input.
  • Consider using event handlers like onChange, onKeyDown, and onClick effectively.
  • Debouncing the input change event might be a good optimization to avoid excessive filtering on every keystroke, especially for larger datasets or more complex filtering logic.
Loading editor...
typescript