Skip to content
Ndop UI

Combobox primitive

Headless Combobox: the behavior, keyboard support and ARIA of the WAI-ARIA Editable combobox with list autocomplete pattern, with no styles.

Import

Primitives ship in the @ndop/primitives package and have no styles. Their state is on data attributes for you to style. The styled Combobox is built on this one.

import {
  NdCombobox,
  NdComboboxGroup,
  NdComboboxLabel,
  NdComboboxSeparator,
  NdComboboxChip,
  NdComboboxChipRemove,
  NdComboboxChips,
  NdComboboxClear,
  NdComboboxContent,
  NdComboboxEmpty,
  NdComboboxInput,
  NdComboboxItem,
  NdComboboxItemIndicator,
  NdComboboxList,
  NdComboboxTrigger,
} from '@ndop/primitives/combobox';

Accessibility

Implements the Editable combobox with list autocomplete pattern of the WAI-ARIA Authoring Practices.

Keyboard

Keys the component handles.

Key Action
aTypes into the field, opening the popup and filtering its options.
ArrowDownOpens the popup and highlights the chosen option or the first; while open, highlights the next option.
ArrowUpOpens the popup and highlights the last option; while open, highlights the previous option.
Alt+ArrowDownOpens the popup without highlighting an option.
EnterChooses the highlighted option. Without multiple the popup closes; with it, the option toggles and it stays open.
EscapeCloses the popup; if it's closed, clears the field and, without multiple, the value.
BackspaceWith multiple, in an empty field, removes the last chosen value.
HomeorEndMove the caret in the field, as in any text field.
TabCloses the popup and moves focus on.

Focus

  • Focus stays in the field; aria-activedescendant points at the highlighted option, which scrolls into view.
  • Clicking an option, the trigger, the clear button or a chip's remove button keeps focus in the field.
  • Focus leaving the combobox closes the popup and marks a bound field touched.

Right-to-left

start and end alignments are logical and swap in right-to-left layouts. The listbox is vertical, so its arrow keys don't change.

API reference

NdCombobox

[ndCombobox]from @ndop/primitives/combobox

Root of a combobox: the WAI-ARIA editable combobox pattern with list autocomplete, a text field that filters a popup listbox of options. Focus stays in the field while aria-activedescendant points at the highlighted option, on the CDK's ActiveDescendantKeyManager; the popup is written in place and opening moves it into a CDK overlay. With multiple, chosen options show as chips. Put it on an ng-container, and bind forms on the NdComboboxInput.

NdCombobox binding Type Default
[multiple]
Lets several options be chosen, shown as chips.
booleanfalse
[filter]
Tests whether an option matches what was typed; null shows every option, for lists filtered elsewhere.
NdFilter | nullndContainsFilter
[autoHighlight]
Highlights the first shown option as the user types.
booleanfalse
[disabled]
Disables the field. A disabled bound field does too.
booleanfalse
[required]
Marks the combobox required: aria-required="true" on the field.
booleanfalse
[invalid]
Marks the combobox invalid when no forms library is bound; with one, the field's state decides.
booleanfalse
[(value)]
The chosen option's value, or null, without multiple. Two-way bindable with [(value)].
string | nullnull
[(values)]
The chosen options' values, with multiple. Two-way bindable with [(values)].
readonly string[][]
[(search)]
The field's text. Two-way bindable with [(search)].
string''
[(open)]
Whether the popup is open. Two-way bindable with [(open)].
booleanfalse

NdComboboxGroup

[ndComboboxGroup]role groupfrom @ndop/primitives/combobox

Groups options (role="group"), named by its NdComboboxLabel. It's hidden while none of its options is shown.

Manages aria-labelledby, hidden.

NdComboboxLabel

[ndComboboxLabel]from @ndop/primitives/combobox

The heading of a NdComboboxGroup, which names the group.

Manages id.

NdComboboxSeparator

[ndComboboxSeparator]from @ndop/primitives/combobox

A decorative line between groups of options.

Manages aria-hidden.

NdComboboxChip

[ndComboboxChip]from @ndop/primitives/combobox

One chosen value, shown as a chip.

NdComboboxChip binding Type Default
[value]required
The chosen value it shows.
string—
Data attribute Values
data-disabled —

NdComboboxChipRemove

button[ndComboboxChipRemove]from @ndop/primitives/combobox

A button that removes its chip's value with the pointer, keeping focus in the field, as Backspace does from it. It's out of the tab order and hidden from assistive technology.

Manages aria-hidden, tabindex.

NdComboboxChips

[ndComboboxChips]from @ndop/primitives/combobox

Holds the chips and the field of a combobox with multiple; the popup sits below it. Clicking its empty space focuses the field.

NdComboboxClear

button[ndComboboxClear]from @ndop/primitives/combobox

A button that empties the field and the value with the pointer, keeping focus in the field, as Escape does from it. It's out of the tab order, hidden from assistive technology, and has the hidden attribute while there is nothing to clear.

Manages aria-hidden, tabindex, hidden.

NdComboboxContent

[ndComboboxContent]from @ndop/primitives/combobox

The popup. Write it after the field: it has the hidden attribute while closed, and opening moves it into an overlay below the chips, or else the field. data-empty marks it while no option is shown.

Manages hidden.

NdComboboxContent binding Type Default
[side]
Side of the anchor it opens on, before flipping.
'start' | 'end' | 'bottom' | 'top''bottom'
[align]
Alignment along that side.
'start' | 'end' | 'center''start'
[sideOffset]
Gap between the anchor and the popup, in pixels.
number6
Data attribute Values
data-state —
data-side —
data-align —
data-empty —

NdComboboxEmpty

[ndComboboxEmpty]from @ndop/primitives/combobox

What shows while no option matches the field's text. It has the hidden attribute otherwise.

Manages hidden.

NdComboboxInput

input[ndComboboxInput]role comboboxfrom @ndop/primitives/combobox

The text field (role="combobox"), on a native input. Typing filters the popup's options; the arrow keys, Enter and Escape work from here while focus stays in it. The combobox owns its value, so this is a ControlValueAccessor: bind Signal Forms ([formField]), reactive or template-driven forms here (ADR-0004, amendments 1 and 4).

Manages aria-autocomplete, aria-expanded, aria-controls, aria-activedescendant, aria-required, aria-invalid, aria-describedby.

Data attribute Values
data-state —
data-disabled —
data-invalid —

NdComboboxItem

[ndComboboxItem]role optionfrom @ndop/primitives/combobox

One option (role="option"). Clicking it, or Enter while it's highlighted, chooses it. It's hidden while the field's text doesn't match it.

Manages aria-selected, aria-disabled, id, hidden.

NdComboboxItem binding Type Default
[value]required
The value choosing it gives the combobox.
string—
[disabled]
Makes it unchoosable; the arrow keys skip it.
booleanfalse
[label]
Its text, when it differs from what it renders.
string | nullnull
Data attribute Values
data-highlighted —
data-selected —
data-disabled —

NdComboboxItemIndicator

[ndComboboxItemIndicator]from @ndop/primitives/combobox

The check of an option. It has the hidden attribute unless its option is chosen.

Manages hidden.

NdComboboxList

[ndComboboxList]role listboxfrom @ndop/primitives/combobox

The listbox of options (role="listbox"), named after the field's labels unless it has its own aria-label.

Manages aria-labelledby, aria-label, aria-multiselectable, id.

Data attribute Values
data-empty —

NdComboboxTrigger

button[ndComboboxTrigger]from @ndop/primitives/combobox

A button that opens and closes the popup with the pointer, keeping focus in the field. It's out of the tab order and hidden from assistive technology, which use Alt+ArrowDown from the field.

Manages aria-hidden, tabindex.

Data attribute Values
data-state —