Overview
Build a robust React Autocomplete component for a fictional Galactic Travel Agency. This problem challenges you to create a dynamic typeahead search experience that suggests space destinations as users type. Focus on efficient client-side data filtering, keyboard navigation, and clear UI feedback for an optimal user experience.
What you need to do / Task
Your primary goal is to implement a functional and accessible Autocomplete React component. Specifically, you need to:
- Implement Filtering: As the user types into the input field, dynamically filter the provided
suggestions (an array of strings) and display matching results in a dropdown list.
- Handle Selection: Allow users to select a suggestion using either a mouse click or keyboard navigation (Up/Down arrow keys and Enter key).
- Update UI: Upon selection, update the input field with the chosen suggestion and hide the suggestion list.
- Manage Visibility: The suggestion list should appear only when the input is focused and there are matches, and hide when the input loses focus, a selection is made, or no matches are found.
- Accessibility: Ensure the component is keyboard navigable and uses appropriate ARIA attributes to be accessible to screen reader users.
UI/UX expectations
- Input Field: A prominent text input where users type their search query.
- Suggestion List: A dropdown list that appears directly below the input field when there are matching suggestions and the input is focused.
- Highlighting: The currently active (hovered or keyboard-navigated) suggestion should be visually distinct.
- Empty State: If the user types a query that yields no matches, display a clear "No matches found" message within the suggestion area.
- Clear State: When the input is empty, the suggestion list should not be shown.
- Responsiveness: The UI should respond quickly to user input and navigation.
Acceptance criteria
- The input field correctly filters and displays suggestions in real-time as the user types (case-insensitive).
- The suggestion list appears only when the input is focused and there are matching results.
- Clicking a suggestion populates the input field with the selected value and hides the suggestion list.
- Pressing
ArrowDown or ArrowUp navigates through the suggestions, visually highlighting the active item.
- Pressing
Enter when a suggestion is highlighted selects it, populates the input, and hides the list.
- Pressing
Escape hides the suggestion list without changing the input value.
- Typing a query that results in no matches displays a "No matches found" message.
- The component is fully navigable and usable via keyboard (tabbing, arrow keys, enter, escape).
- Appropriate ARIA attributes (e.g.,
aria-autocomplete="list", aria-controls, aria-expanded, role="listbox", role="option", aria-selected, aria-activedescendant) are implemented for accessibility.
- Clicking outside the component hides the suggestion list.
Clarifications
- Q: Should I debounce the input? A: For this exercise, assume client-side filtering on a relatively small dataset. Debouncing is not strictly required but would be a good enhancement in a real-world scenario with large datasets or API calls.
- Q: How should I handle case sensitivity? A: The filtering logic should be case-insensitive.
- Q: What about performance with a very large dataset? A: Focus on correctness and UI/UX for a moderate dataset. Optimizations for extremely large datasets (e.g., virtualization of the list) are out of scope.