Combobox
A field for picking one option: typing filters the list, or searches a server.
Import
import { Combobox } from '@k8ordo/ui';Usage
Typing opens the list, and the value changes only when an option is picked with a click or Enter. Leaving half-typed text puts the chosen label back; leaving the field empty clears the choice. ↓ / ↑ open the list and move through it (Alt+↓ only opens it), Escape closes it and, pressed again, drops what was typed. To pick several, use Autocomplete.
<Combobox aria-label="Prefecture" name="prefecture" options={prefectures} />Searching a server
With search, each keystroke calls it for the options. Typing again aborts the previous call’s signal, so pass it on to fetch. While a search runs the list is busy, and a failure or an empty result is shown and announced. options becomes what is shown before anything is typed.
<Combobox
aria-label="City"
name="city"
search={async (query, { signal }) => {
const response = await fetch(
`/api/cities?q=${encodeURIComponent(query)}`,
{ signal },
);
return response.json();
}}
/>With @k8ordo/form
Spread the input derived from z.enum() as is. The choice submits through a hidden <select>, so required, rules, reset, and moving focus after a failed submission all work on it.
// schema.ts
export const addressSchema = z.object({
prefecture: z.enum(['hokkaido', 'tokyo', 'osaka']),
});
// address-form.tsx
const prefecture = form.field('prefecture');
<FormControl
errorText={prefecture.error}
invalid={prefecture.invalid}
label="Prefecture"
required={prefecture.required}
renderInput={(props) => (
<Combobox {...props} {...prefecture.input} options={prefectures} />
)}
/>Props
defaultValue?- Type:
string - Default: -
invalid?- Type:
boolean - Default:
false onChange?- Type:
(value: string) => void - Default: -
options?- Type:
readonly Option[] - Default: -
ref?- Type:
Ref<HTMLInputElement> - Default: -
search?- Type:
ComboboxSearch - Default: -
type?- Type:
string - Default: -
value?- Type:
string - Default: -
| Prop | Type | Default |
|---|---|---|
defaultValue? | string | - |
invalid? | boolean | false |
onChange? | (value: string) => void | - |
options? | readonly Option[] | - |
ref? | Ref<HTMLInputElement> | - |
search? | ComboboxSearch | - |
type? | string | - |
value? | string | - |
Type base (some attrs are managed internally): InputHTMLAttributes<HTMLInputElement>
Wording this component renders (labels, placeholders, and the like) comes from the message dictionary when no prop sets it. To change it, see: i18n