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 the error prop. Disabled uses the disabled attribute. Filled is a chosen value. Needs label or aria-label.
  • Compose with: combobox-option.
  • Storybook: Inputs/Combobox.

Props

PropTypeNotes
size"sm" | "md"Default "md"
labelReactNode
helperTextReactNode
placeholdernative attribute
errorReactNode
disablednative attribute
openboolean
options requiredComboboxOptionData[]
aria-labelstring
aria-labelledbystring

Other props

PropTypeWhat it does
filter(option: ComboboxOptionData, query: string) => booleanDecides which options match what was typed. Default: case-insensitive "contains" on the label.
emptyMessagestringShown when nothing matches.
formatResults(count: number) => stringAnnounced when the list opens or changes, for translation.
defaultOpenboolean
onOpenChange(open: boolean) => void
toggleLabelstringAccessible name of the chevron button.
namestringName for a form: submits the chosen option's value.
valuestring | nullThe chosen option's value (controlled). null is none.
defaultValuestring | 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.tertiary

Related

inputs 12 Figma variants Try it in the live demo