React Autocomplete Component with TypeScript
This challenge asks you to build a reusable autocomplete component in React using TypeScript. Autocomplete is a common UI feature that suggests possible completions as the user types, improving user experience and reducing input errors. This component will take a list of suggestions and filter them based on the user's input, displaying relevant options.
Problem Description
You need to create a React component called Autocomplete that provides an autocomplete functionality. The component should accept a list of strings as a prop (suggestions) and display a dropdown list of suggestions that match the user's input in a text field.
Key Requirements:
- Input Field: The component must include a text input field where the user can type.
- Suggestion Filtering: As the user types, the component should filter the
suggestionsprop to only show those that start with the current input. - Dropdown Display: Filtered suggestions should be displayed in a dropdown list below the input field.
- Selection Handling: When the user clicks on a suggestion in the dropdown, the input field should be populated with the selected suggestion, and the dropdown should disappear.
- Empty State: If no suggestions match the input, the dropdown should be hidden.
- Clear Input: When the dropdown is closed (either by selection or by clicking outside), the input field should remain unchanged.
- TypeScript: The component must be written in TypeScript, with appropriate type definitions for props and state.
Expected Behavior:
- The component renders an input field and a hidden dropdown list.
- As the user types in the input field, the component updates the dropdown list to display suggestions that start with the input.
- If the input field is empty, the dropdown list should be hidden.
- Clicking on a suggestion in the dropdown list populates the input field with that suggestion and hides the dropdown.
- Clicking outside the component should hide the dropdown.
Edge Cases to Consider:
- Empty
suggestionsarray: The component should handle this gracefully and not render a dropdown. - Case-insensitive matching: The filtering should be case-insensitive.
- Large
suggestionsarray: Consider performance implications when filtering a very large array. - Special characters in suggestions: Ensure special characters are handled correctly in filtering and display.
Examples
Example 1:
Input: suggestions = ["apple", "banana", "apricot", "orange"]
Input: User types "ap"
Output: Dropdown displays: ["apple", "apricot"]
Explanation: The component filters the suggestions to only show those starting with "ap".
Example 2:
Input: suggestions = ["cat", "dog", "bird"]
Input: User types "zebra"
Output: Dropdown is hidden.
Explanation: No suggestions start with "zebra", so the dropdown is hidden.
Example 3:
Input: suggestions = ["Apple", "banana", "Apricot"]
Input: User types "ap" (lowercase)
Output: Dropdown displays: ["Apple", "Apricot"]
Explanation: Filtering should be case-insensitive.
Constraints
- The component should be reusable and accept the
suggestionsprop dynamically. - The component should be reasonably performant, even with a large number of suggestions (consider using techniques like debouncing).
- The component should be styled simply for demonstration purposes; elaborate styling is not required.
- The
suggestionsprop will always be an array of strings. - The component should not rely on external libraries beyond React and TypeScript.
Notes
- Consider using React's
useStatehook to manage the input value and the visibility of the dropdown. - Debouncing the filtering logic can improve performance when the user types quickly. This prevents excessive re-renders.
- You can use a simple CSS class to hide/show the dropdown.
- Focus management (handling clicks outside the component to close the dropdown) is an important aspect of the user experience. Consider using a ref and event listener for this.
- Think about how to handle the case where the user selects a suggestion and then immediately starts typing again.