Components / inputs
Combobox
A text field with a filterable list of options.
import { Combobox } from '@basiiik/ui';
The snippet an agent gets
From get_component_snippet, with the required props filled in from the spec. Every snippet is type-checked against the library before it is shipped.
import { Combobox } from '@basiiik/ui';
<Combobox options={[{ value: 'lis', label: 'Lisbon' }, { value: 'osl', label: 'Oslo' }]} label="City" />- Example values were filled in for the required props options, label: replace them with your own.
- Values in braces are your own variables, handlers or data, such as const [open, setOpen] = useState(false).
- Hover and Focused are CSS. Open is
open/defaultOpen. Error is theerrorprop. Disabled uses the disabled attribute. Filled is a chosenvalue. Needslabeloraria-label. - Compose with: combobox-option.
- Storybook: Inputs/Combobox.
Props
| Prop | Type | Notes |
|---|---|---|
size | "sm" | "md" | Default "md" |
label | ReactNode | |
helperText | ReactNode | |
placeholder | native attribute | |
error | ReactNode | |
disabled | native attribute | |
open | boolean | |
options required | ComboboxOptionData[] | |
aria-label | string | |
aria-labelledby | string |
Other props
| Prop | Type | What it does |
|---|---|---|
filter | (option: ComboboxOptionData, query: string) => boolean | Decides which options match what was typed. Default: case-insensitive "contains" on the label. |
emptyMessage | string | Shown when nothing matches. |
formatResults | (count: number) => string | Announced when the list opens or changes, for translation. |
defaultOpen | boolean | |
onOpenChange | (open: boolean) => void | |
toggleLabel | string | Accessible name of the chevron button. |
name | string | Name for a form: submits the chosen option's value. |
value | string | null | The chosen option's value (controlled). null is none. |
defaultValue | string | null | |
onValueChange | (value: string | null) => void |
States. Hover and Focused are CSS. Open is open / defaultOpen. Error is the error prop. Disabled uses the disabled attribute. Filled is a chosen value. Needs label or aria-label.
Native attributes such as className, id and data-* are forwarded to the root element.
Use it when
- Long lists where people need to search, roughly more than 15 options
- A searchable select (autocomplete, typeahead, filterable dropdown): pick one option from a long list by typing to filter it
Do not use it when
- Fewer than 5 options (use Radio)
- 5 to 15 options without search (use Select)
- Free text with suggestions (use Text Field)
- More than one option can be chosen (use Multi Combobox)
Rules for agents
- Every Combobox has a visible label
- Pass options as { value, label } data; the chosen value is always one of the option values, never the typed text
- Use emptyMessage to say what to try when nothing matches
- Pass formatResults (and toggleLabel) when the interface is not in English
Avoid
- A Combobox for a short list that fits on screen (use Select or Radio)
- Treating the typed text as the value, or accepting free text (use Text Field)
- Moving DOM focus into the list instead of keeping it in the input
- Leaving the list empty with no message when nothing matches
Writing the content
- Labels are short nouns: 'City', 'Assignee'
- Placeholders hint at search: 'Search cities'
- The empty message suggests a next step: 'No cities match. Check the spelling.'
Keyboard
- ArrowDown opens the list and moves to the next option; ArrowUp moves back
- Typing filters the options
- Enter chooses the highlighted option
- Escape closes the list; a second Escape clears the text
- Home and End move within the list; Tab closes it and keeps the typed text only if it matches
Accessibility
- aria-expanded, aria-controls and aria-autocomplete="list" on the input
- aria-activedescendant points at the highlighted option
- aria-invalid and aria-describedby for Error and helper text
- Result count announced through a polite live region; "No results" is shown when empty
Colour tokens it reads
color.bg.brand.subtlecolor.bg.disabledcolor.bg.subtlecolor.bg.surfacecolor.border.dangercolor.border.focuscolor.border.inputcolor.border.subtlecolor.icon.primarycolor.text.brandcolor.text.dangercolor.text.disabledcolor.text.primarycolor.text.secondarycolor.text.tertiaryRelated
inputs 12 Figma variants Try it in the live demo