Smart typeahead
Debounced search input with keyboard navigation, loading states, and result highlighting.
Ingredients
- Controlled input with debounce hook
- AbortController for in-flight requests
- Arrow-key + Enter navigation
- Highlight matched substring in results
- Empty, loading, and error states
Steps
- Create a
useDebouncehook wrappingsetTimeout. - Wire the input value through debounce, firing a fetch when the debounced value changes.
- Store an
AbortControllerref and call.abort()before each new request. - Track
activeIndexfor keyboard navigation; clamp withMath.min/max. - Split result text on the query substring and wrap matches in a highlighted
<mark>element. - Render a spinner while loading, a message when empty, and an inline error banner on failure.
Tip: Keep the debounce window between 200–350 ms. Shorter feels jittery; longer feels sluggish on fast typists.