useCombobox
Build a keyboard-navigable autocomplete or combobox easily.
Features
- Fully controlled input
- Keyboard arrow navigation
- Highlighted index handling
Usage
1const { 2 query, setQuery, filtered, 3 highlightedIndex, handleKeyDown 4} = useCombobox(countries, c => c.name) 5 6<input 7 value={query} 8 onChange={e => setQuery(e.target.value)} 9 onKeyDown={handleKeyDown} 10/> 11 12<ul> 13 {filtered.map((c, i) => ( 14 <li key={c.code} className={i === highlightedIndex ? 'bg-gray-200' : ''}> 15 {c.name} 16 </li> 17 ))} 18</ul>
📋 Source Code
This is the full implementation of useCombobox
1import { useState } from 'react'
2
3export function useCombobox<T>(items: T[], keyFn: (item: T) => string) {
4 const [query, setQuery] = useState('')
5 const [highlightedIndex, setHighlightedIndex] = useState(0)
6
7 const filtered = items.filter(item => keyFn(item).toLowerCase().includes(query.toLowerCase()))
8
9 const select = () => filtered[highlightedIndex]
10
11 const handleKeyDown = (e: React.KeyboardEvent) => {
12 if (e.key === 'ArrowDown') {
13 setHighlightedIndex(i => (i + 1) % filtered.length)
14 } else if (e.key === 'ArrowUp') {
15 setHighlightedIndex(i => (i - 1 + filtered.length) % filtered.length)
16 }
17 }
18
19 return {
20 query,
21 setQuery,
22 highlightedIndex,
23 filtered,
24 handleKeyDown,
25 select,
26 }
27}
28