This project implements a ComboBox / Autocomplete component in React + TypeScript, built from scratch without using any UI frameworks or CSS libraries. Styling is implemented using plain CSS (e.g. CSS Modules) to match the provided Figma design.
The component is designed to be:
- Reusable and developer-friendly
- Keyboard accessible
- Compatible with form management libraries, demonstrated using React Hook Form (RHF)
Example usage:
<Autocomplete
name="customer"
label="Customer"
options={options}
control={control}
isLoading={isLoading}
placeholder="Search customer"
/>
-
name: stringField name used for RHF integration.
-
control: Control<TFieldValues>React Hook Form control object (fully typed).
-
options: Option[]Options to display. Options are supplied externally and may change over time.
-
isLoading?: booleanIndicates that options are currently being loaded asynchronously.
-
label?: stringLabel rendered above the input (matches Figma design).
-
placeholder?: string -
disabled?: boolean -
ariaLabel?: stringAccessibility label when a visible label is not provided.
The autocomplete behaviour (filtering, focus handling, keyboard navigation, selection, dropdown visibility) is tightly coupled to the input element. For clarity and readability, this logic is intentionally co-located within a single component rather than split into multiple hooks or abstractions. This avoids unnecessary indirection and keeps state transitions easy to follow.
The component manages explicit UI state such as:
- Input value
- Filtered options
- Dropdown open/closed state
- Highlighted option index
The component is designed to work cleanly with asynchronously loaded options, while remaining agnostic to how data is fetched.
Design principles:
- Options are passed in as props
- Loading state is controlled externally (via an isLoading prop)
- React Hook Form integration continues to work while options update
- The component does not own data fetching (by design)
This separation keeps the component reusable and predictable, and allows it to integrate with different data sources (local data, remote APIs, cached results, etc.) without coupling UI logic to networking concerns.
The component supports standard ComboBox keyboard interactions, including:
ArrowDown/ArrowUpto navigate optionsEnterto select the highlighted optionEscapeto close the dropdown- Natural
Tabbehaviour without focus trapping
The component is integrated with React Hook Form using Controller, allowing it to behave as a fully controlled form field.
A small demo wrapper is included to show:
- Typed RHF integration
- Submission
- Error handling via RHF form state
The component styling is intentionally constrained to match the provided Figma design in terms of height, spacing, typography, and icon placement.
Layout and width, however, are controlled by the parent component, allowing the Autocomplete to be used responsively in different contexts without internal layout assumptions.
In a production design system, these constraints would typically be extended with size variants and theme tokens, but for this challenge the focus is on visual accuracy and predictable layout behaviour.
npm install
npm run dev
Open the local URL shown in the terminal.
npm test
Component tests focus on observable behaviour:
- Rendering and basic interactions
- Filtering behaviour
- Keyboard navigation and selection
- Integration with React Hook Form
Tests avoid implementation details and assert behaviour from a user’s perspective.
If this component were part of a production design system, potential enhancements could include:
- Additional accessibility validation against ARIA combobox guidelines
- Virtualisation for very large option lists
- Standardised async helpers (e.g. debounced remote search utilities)
- Size and layout variants
AI tools were used as a general development aid (e.g. validating edge cases and improving test coverage). All component API design, architectural decisions, and implementation were authored and refined manually.
No proprietary code, confidential information, or internal systems were shared or used during development.