Forms
ICombobox
A select you can type into. It takes the same items as ISelect and filters them against the query. The field shows the selected option's label; the model holds its value.
A plain string is expanded to { label: value, value }, so a list of names needs no shaping.
Groups
An entry with its own items becomes a labelled run of options. A group disappears once nothing inside it matches — type cir and watch "Recent" go.
Sizes
Empty results
emptyText is the line shown when the query matches nothing. The empty slot replaces that markup entirely and receives the current query.
Create from the query
Set create to offer a row for whatever was typed when nothing matches. Choosing it emits create with the trimmed query and leaves the model alone — add the option and select it yourself.
Virtualized rows
For lists in the thousands, virtual renders only the rows on screen. The field below holds 5,000 options.
virtual cannot be combined with grouped items: groups are flattened and their labels dropped, with a warning in dev. estimateSize is the assumed row height in px, used to size the scrollbar before the rows are measured — set it when you have restyled rows to a different height.
Use virtual for lists in the thousands.
Invalid
Inside an IFormField the field passes its own validity down, so invalid rarely needs setting by hand.
Clearing
clearable turns the dropdown arrow into a clear button as soon as something is selected — the arrow is only useful while the field is empty, and two targets in the same corner of a 36px field is a mis-click waiting to happen.
Clearing empties the query, returns focus to the input and sets the model to null — or to [] when multiple.
Rename it for a non-English app with clearLabel, which is its accessible name.
Multiple
multiple lets the field hold several values. The model becomes an array and chosen rows keep their tick.
Each value is drawn as a removable chip inside the field, and the input stays a query box — so the labels are readable at a glance and there is still somewhere to type. Remove one with its cross, or with ⌫ while the query is empty — the first press marks the last chip and the next removes it, as in ITagsInput. The field wraps and grows rather than clipping, the same trade ITagsInput makes.
The popup stays open as you tick rows, so a run of choices is one visit rather than one visit each.
Reach for ITagsInput instead when the values are free text rather than a fixed list, and for ICheckbox when there are only a handful of options and hiding them behind a popup buys nothing.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
items | (ComboboxItemOption | ComboboxItemGroup | string)[] | — | Options to render |
placeholder | string | — | Shown while the field is empty |
size | 'sm' | 'md' | 'lg' | 'md' | Control scale |
invalid | boolean | — | Red border and ring; inherited from IFormField when unset |
id | string | — | Id for the input; IFormField supplies one |
emptyText | string | 'No results found.' | Line shown when nothing matches |
clearable | boolean | — | Swap the arrow for a clear button once a value is set |
clearLabel | string | 'Clear' | Accessible name for that button |
multiple | boolean | — | Hold several values as chips; the model becomes an array |
removeLabel | (label: string) => string | Remove … | Accessible name for a chip's remove button |
create | boolean | — | Offer a "create" row for an unmatched query |
createLabel | (query: string) => string | Create "…" | Label for that row |
virtual | boolean | — | Render only the rows in view; flattens groups |
estimateSize | number | 32 | Assumed row height in px, before rows are measured |
overscan | number | 12 | Rows rendered beyond the viewport on each side |
unstyled | boolean | — | Drop built-in classes |
class | string | — | Merged with the built-in classes |
ui | { anchor?, input?, trigger?, clear?, tag?, tagText?, tagDelete?, content?, viewport?, item?, empty?, group?, groupLabel? } | — | Per-element class overrides |
disabled, dir and the rest of Reka UI's ComboboxRoot props are forwarded.
Events
| Event | Payload | When |
|---|---|---|
create | query: string | The create row was chosen. The model is left alone |
Reka UI's own ComboboxRoot events are re-emitted unchanged.
Slots
| Slot | Props | When to use it |
|---|---|---|
empty | { query } | Replace the no-results line with your own markup |
create | { query } | Replace the create row's label with your own markup |
tag | { option, remove } | Replace a chip's contents; call remove() to drop that value |
Item shapes
interface ComboboxItemOption {
label: string
value: string
disabled?: boolean
}
interface ComboboxItemGroup {
label: string
items: (ComboboxItemOption | string)[]
}Attributes you set land on the input, so aria-label and friends reach the control the reader types into.