Angular Typeahead Component
This challenge requires you to build a reusable typeahead (autocomplete) component in Angular. A typeahead component is a common UI pattern that suggests possible matches as a user types into an input field, enhancing user experience by reducing typing and preventing errors.
Problem Description
You need to create an Angular component that functions as a typeahead. This component will:
- Accept an input query: A user will type into an input field associated with this component.
- Fetch suggestions: Based on the user's input, the component should fetch a list of relevant suggestions. For this challenge, we will simulate fetching suggestions using a predefined array.
- Display suggestions: The fetched suggestions should be displayed in a dropdown list below the input field.
- Handle selection: When a user selects a suggestion from the dropdown, the input field should be populated with the selected suggestion, and the dropdown should disappear.
- Handle empty input/no results: If there are no suggestions matching the input, or if the input is cleared, the dropdown should not be displayed or should be hidden.
Key Requirements:
- The component should be implemented using TypeScript and Angular.
- It should accept an array of strings as input, representing the complete list of possible suggestions.
- It should emit an event when a suggestion is selected.
- The component should manage its own internal state (e.g., the currently displayed suggestions, the visibility of the dropdown).
- Basic styling should be applied to make the typeahead functional and visually presentable.
Expected Behavior:
- As the user types in the input field, a filtered list of suggestions should appear in a dropdown.
- The filtering should be case-insensitive and match any part of the suggestion string.
- If the user presses the "Escape" key, the dropdown should close.
- If the user clicks outside the typeahead component (input field or dropdown), the dropdown should close.
- When a suggestion is clicked, the input field should update with the selected suggestion, and the dropdown should close.
Edge Cases:
- Handling rapid typing: Ensure the component doesn't become unresponsive.
- Empty suggestion list: The component should gracefully handle cases where the provided suggestions array is empty.
- Case sensitivity: Filtering should be case-insensitive.
- Special characters in input: The component should handle inputs containing special characters.
Examples
Example 1: Initial state and typing
- Input:
- Component receives
suggestions: ['Apple', 'Banana', 'Cherry', 'Date', 'Elderberry']. - User types "a" into the input field.
- Component receives
- Output:
- A dropdown appears below the input field.
- The dropdown displays:
- Apple
- Banana
- Date
- Explanation: The component filters the
suggestionsarray to find items containing "a" (case-insensitive) and displays them.
Example 2: Selecting a suggestion
- Input:
- Dropdown is currently showing:
- Apple
- Banana
- Date
- User clicks on "Banana".
- Dropdown is currently showing:
- Output:
- The input field is updated to "Banana".
- The dropdown is hidden.
- Explanation: Selecting "Banana" populates the input and closes the suggestion list.
Example 3: No matching suggestions
- Input:
- Component receives
suggestions: ['Apple', 'Banana', 'Cherry']. - User types "z" into the input field.
- Component receives
- Output:
- The dropdown remains hidden, or an empty dropdown is displayed and immediately hidden.
- Explanation: No suggestions match "z", so no results are shown.
Constraints
- The component should be designed for performance, especially when dealing with a large number of suggestions (though for this challenge, assume a maximum of 1000 suggestions).
- Input to the component should be an array of strings (
string[]). - The output should be an event emitting the selected suggestion (a
string).
Notes
- Consider using Angular's
HostListenerto handle clicks outside the component for closing the dropdown. - Debouncing the input event can improve performance by reducing the number of times suggestions are fetched/filtered.
- You can use
[ngClass]or[ngStyle]for basic styling. - The core logic for filtering suggestions should be implemented within the component.