Selection

Combobox

A searchable, richer alternative to `Select`, supporting icons/avatars and multi-select.

vue
<UiCombobox :items="..." />

Options

One block per prop — what it does, and what it looks like set.

Items

required

items is the list of options, and unlike Select it's searchable by default — typing in the field filters it client-side. A bare string or number is the shorthand for an option whose label and value match; the long form is { label, value } with an optional icon and disabled. Mixing in { type: 'label' } and { type: 'divider' } entries is how a long list gets grouped.

Unlike Select, this is searchable by default — typing filters items client-side.

items can mix plain options with { type: 'label', label } and { type: 'divider' } entries to group the list — both just delimit groups rather than becoming selectable rows themselves, and searching drops any group whose options no longer match.

Model value

modelValue is the selected value — the option's value, not its label, and an array of them once multiple is set. Pass it to control the selection yourself; v-model is the usual binding, so the reader's choice flows back.

Selected: nothing

Default value

defaultValue is what's selected on first render while the combobox still owns its own state. Reach for it when a starting choice is genuinely sensible — the reader's own country, the most common option — and you don't otherwise need to hold the value.

Multiple

multiple lets more than one option be selected, and turns the selected set into removable tags inside the field.

multiple renders selected values as removable tag chips inside the trigger, which grows the trigger's height.

Placeholder

placeholder is what the trigger reads while nothing is selected — distinct from searchPlaceholder, which belongs to the filter box inside the open list. Phrase it as the instruction it is, since it disappears the moment there's a value to show.

Search placeholder

searchPlaceholder is the hint inside the search box at the top of the open list, defaulting to “Search…”. Worth naming what's being searched when the list holds something less obvious than its label suggests.

Icon

icon sits at the start of the trigger while nothing is selected; once an option carrying its own icon is chosen, that one replaces it. It's a way to say what the field is for without spending a label on it.


Examples

The component in real use: compositions that answer "how do I build X with this", rather than one prop at a time.

`icon` as an object on an option

icon is usually just a name, but it also takes { name, color, fill }. color tints an option's own icon, independent of whether that option is selected — use it to flag a choice at a glance, like a status dot or a severity level, without coloring the label along with it. fill draws the icon's filled variant, for the icons that ship one.

Disabled

disabled locks the whole input. Individual options can opt out on their own with a per-item disabled instead.

Clearable

clearable shows a button to clear the current selection.

Variant

outline is the ringed field on the page background, and the right default wherever the control stands on its own. subtle is that same ring on a raised surface, matching a Card's own subtle, so the control belongs to the card it sits on. soft drops the ring for a plain fill. ghost shows nothing until hover, for a control sitting in a toolbar — it's the only one with a hover state, since without a resting fill it would otherwise give no sign it can be clicked.

Content

content positions the dropdown relative to the field: side, align and sideOffset. Reach for it when the combobox sits near an edge the list would otherwise open across.

Open

open controls whether the dropdown is showing. Pass it to drive the list from your own state and bind it with v-model:open so the reader's clicks still register; omit it and the combobox manages that itself.

Default open

defaultOpen starts the dropdown expanded on mount while leaving the open state uncontrolled — reasonable for a step whose only purpose is the choice, wrong wherever the field is one of several.

Select a country

Grouped `items` — label and divider entries

Wrapped in `FormField`


API Reference

Generated from the component's source — props, slots and emits as the component actually declares them.

Props

Prop
Type
Default
Description
itemsrequired
ComboboxItem[]
—
The list of selectable options, optionally grouped with label and divider items.
string | number | (string | number)[]
—
The selected value(s). Pass this to fully control the selection yourself.
string | number | (string | number)[]
—
The initial selected value(s) when uncontrolled.
boolean
false
Allows selecting more than one option.
string
—
Placeholder text shown in the trigger when nothing is selected.
string
'Search…'
Placeholder text shown in the search input.
string
—
Icon displayed at the start of the trigger when no option is selected.
boolean
false
Disables the select, preventing interaction.
boolean
false
Shows a button to clear the current selection.
"outline" | "subtle" | "soft" | "ghost"
'outline'
The visual style of the field. `outline` is the ringed field on the page background; `subtle` is that same ring on a raised surface, matching a `Card`'s own `subtle`; `soft` drops the ring for a plain fill; `ghost` shows nothing until hover, for a combobox sitting in a toolbar.
ComboboxContentProps
{ align: 'start', side: 'bottom', sideOffset: 8 }
Positioning options for the dropdown list.
boolean
—
Controls whether the dropdown list is open. Omit to let the component manage its own open state.
boolean
false
Whether the dropdown list is open by default when uncontrolled.

Emits

Event
Payload
Description
update:modelValue
[value: string | number | (string | number)[] | undefined]
—
update:open
[value: boolean]
—

Types

ts
type Variant = "outline" | "subtle" | "soft" | "ghost";
ts
type ComboboxItem = ComboboxOption | ComboboxLabelItem | ComboboxDividerItem | string | number;
ts
interface ComboboxOption {
    label: string;
    value: string | number;
    /**
     * The row's icon: an icon name, or `{ name, color, fill }` to also tint just the icon
     * (independent of whether the row is selected) or render its filled variant.
     */
    icon?: string | MenuItemIcon;
    disabled?: boolean;
}
ts
interface ComboboxLabelItem {
    type: "label";
    label: string;
}
ts
interface ComboboxDividerItem {
    type: "devider" | "divider" | "separator";
}
ts
interface ComboboxContentProps {
    align?: "start" | "center" | "end";
    side?: "bottom" | "top";
    sideOffset?: number;
}
ts
interface MenuItemIcon {
    /**
     * Name of the icon to render, same as the `icon` prop of `UiIcon`.
     */
    name: string;

    /**
     * Colors just the icon, independent of the item's `color` (which tints the whole row) or, in a
     * select, of whether the option is selected.
     */
    color?: "error" | "primary" | "secondary" | "success" | "info" | "warning" | "pending" | "neutral";

    /**
     * Render the icon's filled variant. Only some icons ship one — the rest ignore this.
     */
    fill?: boolean;
}