Skip to content

Combobox ​

A single-select that opens a searchable list, sized to the field it came from.

Open in demo
Open in demo

Usage ​

Bind one value with v-model and pass options as FieldOption[], which is { label, value, disabled? }. The value may be a string or a number, and the control compares by string, so 1 and '1' both select the same option.

A plain select is right while the whole list is visible at once. Past that, scrolling a popup to find one entry is the wrong interaction, which is what this control replaces. The form engine picks between the two by option count, so the data decides rather than the schema author. See Schema.

Examples ​

Disabled options ​

An option carrying disabled stays in the list, grayed and unselectable, which is how you show a tier someone has to ask for rather than hiding it.

Disabled ​

disabled blocks the whole control. The current selection still reads.

Invalid, required and described ​

invalid, required and describedBy are props rather than attributes. The component's root is a popover root, which renders no element of its own, so a fallthrough aria-* would have nowhere to land. Passing them by name puts them on the trigger.

API ​

Source: src/shared/components/common/SaCombobox.vue

Props ​

PropTypeDefaultDescription
modelValuestring | number—The selected value. Compared to each option as a string.
optionsFieldOption[]required{ label, value, disabled? }. A label that is a translation key is translated.
placeholderstring'field.selectPrompt'The trigger text while nothing is selected. The default renders as "Select".
searchPlaceholderstring'field.searchPrompt'The search box text. The default renders as "Search…".
emptyTextstring'field.nothingFound'Shown when the search matches nothing. The default renders as "Nothing found".
disabledbooleanfalseBlocks the trigger.
idstring—Put on the trigger, so a <Label for> points at it.
invalidbooleanfalseSets aria-invalid on the trigger.
requiredboolean—Sets aria-required on the trigger.
describedBystring—Sets aria-describedby on the trigger, for an error or hint element.

The three text defaults are translation keys, not English. They resolve at render, so they follow the language switcher, and a string you pass wins over them.

Emits ​

EventPayloadDescription
update:modelValuevalue: string | number | undefinedFires on select. The popover closes with it.

Slots ​

None.

Accessibility ​

  • The trigger is a button with role="combobox" and aria-expanded, and carries aria-invalid, aria-required and aria-describedby when you pass them.
  • The list is a command list: typing filters it, ArrowUp and ArrowDown move the active item, Enter selects and Escape closes.
  • The selected option is marked with a check, so the state does not rest on color.
  • The popover is sized with the trigger's own width, so it reads as the field's list rather than a stray floating menu.