Skip to main content

Combobox

A text field that filters a list of options as the user types and lets them pick one. Use when there are too many options to scan in a plain list. Don't use for short lists (use Select or Radio) or when more than one choice is allowed (use Multi-Select).

OverviewStyleAccessibility

Description

Anatomy

PartRequired?Notes
Label Required Names the field. Always visible, and linked to the input. A required marker can follow it.
Field Required The text input where the user types. Same size, border and fill as Input.
Clear button Optional Empties the field and the current choice. Shown only when there is something to clear.
Toggle button Required The chevron that opens and closes the list for people who don't want to type. Turns to point up while the list is open.
List Required The floating panel of options under the field. Same surface as Select and Dropdown. Scrolls once it reaches its maximum height.
Option Required One choice. Shows a highlight when focused or hovered, and a tick when it is the selected choice.
Section heading Optional Groups related options, for example by region.
Match highlight Optional The part of each option that matches what was typed is shown in a heavier weight.
No results message Required Replaces the options when nothing matches, so the list never just goes blank.
Loading message Optional A spinner and a short message while options are fetched from a server.
Hint and error Optional Helper text below the field, or the error message when the field is invalid.

Variants

States

State Behaviour
Default Shows the placeholder or the current choice, with the toggle button at the right.
Hover A light overlay appears over the field. The border doesn't change.
Focused A focus ring appears around the field. The list opens when the user types or activates the toggle.
Open The list is shown under the field and the chevron points up. Keyboard focus stays in the field; the highlighted option is announced to screen readers.
Invalid The border takes the invalid colour and an error message appears below. The message names the problem and says how to fix it.
Disabled Greyed out and removed from the tab order. It can't be opened or typed in.

Usage guidelines

Do / Don't

Do

Show a clear message when nothing matches ("No results found") and offer a way forward if there is one.

Don't

Don't let the list close or go blank with no explanation. Screen reader users get no signal that anything happened.

Do

Label the field with what the user is choosing ("Council area"), and keep options short so matches are easy to scan.

Don't

Don't use match highlighting as the only cue. It supports scanning but must not carry meaning on its own.

Do

Put the most likely options first, and use section headings only when they genuinely help the user find things.

Don't

Don't hide the toggle button. Some people prefer to open the list and browse it.

Layout & Spacing

Combobox is built from three shared sets of tokens, plus a small set of its own. The field is the same as Input, and the list is the same as Select.

Part Tokens used
Field: height, padding, corner radius, border, fill, text, placeholder, hover overlay, focus ring, hint and error --orbit-form-control-* (the same tokens as Input and Select)
List: surface, border, corner radius, padding, shadow --orbit-menu-*
Options and headings: size, padding, text, highlight, divider --orbit-menu-size-*, --orbit-menu-item-*, --orbit-menu-heading-*
Tick on the selected option --orbit-menu-item-selected-icon
Anything specific to Combobox --orbit-combobox-*
Element Spec
Field height 24 / 32 / 40 / 48 / 56px for XS / S / M / L / XL. M is the default. --orbit-form-control-size-*-height
Field text 12 / 14 / 16 / 16 / 20px for XS / S / M / L / XL. --orbit-form-control-size-*-font-size
List maximum height 320px; longer lists scroll. --orbit-combobox-popup-max-height
Match highlight weight Semibold (600) on the matching letters. --orbit-combobox-match-font-weight
No results text Quiet text colour. --orbit-combobox-empty-text
Loading spinner Quiet icon colour, the same size as the option text. --orbit-combobox-loading-icon
Chevron turn and list open Fast duration, standard easing. --orbit-combobox-transition-duration, -easing

Component tokens

These are the variables that belong to Combobox. The field and list tokens are documented on Input, Select and Popover.

Token What it sets
--orbit-combobox-popup-max-height Maximum height of the open list (320px).
--orbit-combobox-empty-text Colour of the "No results" message.
--orbit-combobox-loading-icon Colour of the loading spinner.
--orbit-combobox-match-font-weight Weight of the matched letters in each option.
`--orbit-combobox-transition-{duration easing}`
--orbit-menu-item-selected-icon Colour of the tick on the selected option. Shared with Select and Dropdown.
Element Token
Field fill (outlined) --orbit-form-control-outlined-background
List surface --orbit-menu-background
Selected tick --orbit-menu-item-selected-icon
No results text --orbit-combobox-empty-text

Engineering notes

  • In the React Aria trial, Combobox is ComboBox with an Input, a Button for the chevron, a Popover and a ListBox of ListBoxItem rows. Each part takes one group of tokens: the input and label use --orbit-form-control-*, the popover and list use --orbit-menu-*, and the extras use --orbit-combobox-*. Treat this mapping as a proposal until Engineering confirms it in the trial.
  • React Aria marks hovered, focused, selected, disabled and invalid parts with state attributes you can style, so each state in the Figma file maps to one rule. Confirm the attribute names against the version used in the trial.
  • Show the no-results message from the list's empty state rather than closing the popover, so the message is announced.
  • Set the list's maximum height from --orbit-combobox-popup-max-height and let the list scroll inside it. Keep the page itself from scrolling when the list is open.
  • Match highlighting should wrap the matched letters in an element styled with --orbit-combobox-match-font-weight. Don't change the option's text; screen readers should hear the full option.
  • The Popover for the list uses the menu surface so Combobox looks the same as Select. Don't switch it to the popover tokens.

Keyboard interaction

KeyAction
Down arrow Opens the list if it is closed and moves the highlight to the next option. Focus stays in the field.
Up arrow Moves the highlight to the previous option.
Enter Chooses the highlighted option and closes the list.
Escape Closes the list. Pressing it again with the list closed clears the field.
Home or End Moves the text cursor within the field, as in any text input.
Tab Moves to the next control. If an option is highlighted it can be accepted first, but never choose an option the user hasn't acted on.

Why it matters

A combobox changes what's on the page as the user types. Screen reader users can't see the list, so the field has to announce that a list exists, which option is highlighted, and how many results there are. Without this, a long list is harder to use than a plain Select.

ARIA

Role or attributeWhen to useExample
role="combobox" On the input. Tells assistive technology this field controls a popup list. Libraries such as React Aria add it for you. <input role="combobox" aria-expanded="true" aria-controls="country-list" aria-autocomplete="list" />
aria-expanded On the input. true while the list is open, false when it is closed. <input role="combobox" aria-expanded="false" />
aria-controls On the input. Points to the id of the list. <input role="combobox" aria-controls="country-list" />
aria-activedescendant On the input. Points to the id of the highlighted option, so focus can stay in the field while the option is announced. <input role="combobox" aria-activedescendant="option-canada" />
role="listbox" and role="option" On the list and its rows. The selected row has aria-selected="true". Disabled rows have aria-disabled="true". <ul role="listbox" id="country-list"><li role="option" id="option-canada" aria-selected="true">Canada</li></ul>
aria-live On a visually hidden status element that announces the number of results, for example "5 results available" or "No results found". Needed so a change in the list is heard (WCAG 4.1.3). <div role="status" aria-live="polite">5 results available</div>

How to apply it

Keep keyboard focus in the field the whole time. The list is operated with the arrow keys, and the highlighted option is announced through aria-activedescendant. Never move focus into the list.

Contrast

Option text, the No results message and the placeholder meet 4.5:1 against the list and field surfaces in Light and Dark. The selected tick, the loading spinner, the chevron and the field border meet 3:1 against their surfaces (WCAG 1.4.11). The token checks in the repository enforce these.

Things to avoid

  • Don't rely on match highlighting, colour or the tick alone to show state. The tick has an accessible name through aria-selected.
  • Don't open the list on page load, and don't open it when the field only receives focus unless the user asked for that.
  • Don't accept text that isn't in the list. A Combobox returns one of its options, or nothing.
  • Don't remove the toggle button to save space. Some people can't type easily.

Was this page helpful?

Updated 2 October 2026