Selection
Select
A native-feeling dropdown select over a list of items.
<UiSelect :items="..." />Options
One block per prop — what it does, and what it looks like set.
Items
requireditems is the list of options. A bare string or number is the shorthand — it becomes both the label and the value — while the long form is { label, value } with an optional icon and disabled. Two entries aren't options at all: { type: 'label' } prints a group heading and { type: 'divider' } draws a rule, which is how a long list gets sectioned.
Options can be plain strings or { label, value } objects in the same items array.
Model value
modelValue is the selected value — the value of an option, not its label, and an array of them once multiple is set. Pass it to control the selection yourself; bind it with v-model for the usual case where the reader's choice should flow back.
Default value
defaultValue is what's selected on first render while the select still owns its own state. It's the right tool for a sensible starting choice — a default currency, the most common option — where you don't otherwise need to hold the value yourself.
Multiple
multiple allows more than one option to be selected, which also switches modelValue from a single value to an array. The trigger then lists the choices instead of showing one.
multiple changes the trigger to show a comma-joined summary rather than tags — use Combobox if you want removable tag chips for multi-select.
Placeholder
placeholder is what the trigger reads while nothing is selected. Phrase it as the instruction it is — “Select a fruit” rather than “Fruit” — since unlike a FormField label it disappears as soon as there's a value to show.
Icon
icon sits at the start of the trigger while nothing is selected — once an option with its own icon is chosen, that one takes over. It's a way to mark 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 select. 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 trigger: side, align and sideOffset. Reach for it when the select 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 — opening it from a keyboard shortcut, closing it when a step finishes — and bind it with v-model:open so the reader's own clicks still register. Omit it and the select manages that itself.
Default open
defaultOpen starts the dropdown expanded on mount while leaving the open state uncontrolled. It's a narrow tool — a step that exists only to be answered — and wrong wherever the select is one field among several.
Wrapped in `FormField`
Grouped `items`, and a divider entry
API Reference
Generated from the component's source — props, slots and emits as the component actually declares them.
Props
itemsrequiredSelectItem[]string | number | (string | number)[]"outline" | "subtle" | "soft" | "ghost"'outline'SelectContentProps{ align: 'start', side: 'bottom', sideOffset: 8 }booleanEmits
update:modelValue[value: string | number | (string | number)[] | undefined]update:open[value: boolean]Types
type Variant = "outline" | "subtle" | "soft" | "ghost";type SelectItem = SelectOption | SelectLabelItem | SelectDividerItem | string | number;interface SelectOption {
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;
}interface SelectLabelItem {
type: "label";
label: string;
}interface SelectDividerItem {
type: "devider" | "divider" | "separator";
}interface SelectContentProps {
align?: "start" | "center" | "end";
side?: "bottom" | "top";
sideOffset?: number;
}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;
}