Overview
The Select component provides a customizable dropdown menu for selecting one or multiple items from a list, with support for icons, avatars, descriptions, and grouping.
Basic Usage
<script setup lang="ts">
import { ref } from 'vue'
const selected = ref(null)
const items = [
'Apple',
'Banana',
'Cherry',
'Date',
'Elderberry'
]
</script>
<template>
<USelect v-model="selected" :items="items" placeholder="Select a fruit" />
</template>
With Objects
<script setup lang="ts">
import { ref } from 'vue'
const selected = ref(null)
const items = [
{ value: 1, label: 'Wade Cooper', description: 'Software Engineer' },
{ value: 2, label: 'Arlene Mccoy', description: 'Product Manager' },
{ value: 3, label: 'Devon Webb', description: 'Designer' }
]
</script>
<template>
<USelect
v-model="selected"
:items="items"
placeholder="Select a person"
/>
</template>
With Icons and Avatars
<script setup lang="ts">
const items = [
{
label: 'Profile',
icon: 'i-heroicons-user',
value: 'profile'
},
{
label: 'Settings',
icon: 'i-heroicons-cog',
value: 'settings'
},
{
label: 'Team',
avatar: { src: 'https://i.pravatar.cc/150?img=1' },
value: 'team'
}
]
</script>
<template>
<USelect v-model="selected" :items="items" />
</template>
Multiple Selection
<script setup lang="ts">
import { ref } from 'vue'
const selected = ref([])
const items = ['React', 'Vue', 'Angular', 'Svelte', 'Solid']
</script>
<template>
<USelect
v-model="selected"
:items="items"
multiple
placeholder="Select frameworks"
/>
</template>
Grouped Items
<script setup lang="ts">
const items = [
[
{ type: 'label', label: 'Fruits' },
{ label: 'Apple', value: 'apple' },
{ label: 'Banana', value: 'banana' }
],
[
{ type: 'label', label: 'Vegetables' },
{ label: 'Carrot', value: 'carrot' },
{ label: 'Potato', value: 'potato' }
]
]
</script>
<template>
<USelect v-model="selected" :items="items" />
</template>
With Separators
<script setup lang="ts">
const items = [
{ label: 'Profile', value: 'profile' },
{ label: 'Settings', value: 'settings' },
{ type: 'separator' },
{ label: 'Logout', value: 'logout' }
]
</script>
<template>
<USelect v-model="selected" :items="items" />
</template>
Colors
<template>
<USelect :items="items" color="primary" placeholder="Primary" />
<USelect :items="items" color="secondary" placeholder="Secondary" />
<USelect :items="items" color="success" placeholder="Success" />
<USelect :items="items" color="warning" placeholder="Warning" />
<USelect :items="items" color="error" placeholder="Error" />
<USelect :items="items" color="neutral" placeholder="Neutral" />
</template>
Variants
<template>
<USelect :items="items" variant="outline" placeholder="Outline" />
<USelect :items="items" variant="soft" placeholder="Soft" />
<USelect :items="items" variant="ghost" placeholder="Ghost" />
<USelect :items="items" variant="none" placeholder="None" />
</template>
Sizes
<template>
<USelect :items="items" size="xs" placeholder="Extra Small" />
<USelect :items="items" size="sm" placeholder="Small" />
<USelect :items="items" size="md" placeholder="Medium" />
<USelect :items="items" size="lg" placeholder="Large" />
<USelect :items="items" size="xl" placeholder="Extra Large" />
</template>
States
<template>
<!-- Disabled -->
<USelect :items="items" disabled placeholder="Disabled" />
<!-- Required -->
<USelect :items="items" required placeholder="Required" />
<!-- Highlighted -->
<USelect :items="items" highlight placeholder="Highlighted" />
<!-- Loading -->
<USelect :items="items" loading placeholder="Loading..." />
</template>
With Icons
<template>
<!-- Leading icon -->
<USelect
:items="items"
leading-icon="i-heroicons-user"
placeholder="Select user"
/>
<!-- Custom trailing icon -->
<USelect
:items="items"
trailing-icon="i-heroicons-chevron-up-down"
placeholder="Select option"
/>
</template>
<script setup lang="ts">
import { z } from 'zod'
import { ref } from 'vue'
const schema = z.object({
country: z.string().min(1, 'Please select a country'),
role: z.string().min(1, 'Please select a role')
})
const state = ref({
country: '',
role: ''
})
const countries = [
{ value: 'us', label: 'United States' },
{ value: 'ca', label: 'Canada' },
{ value: 'mx', label: 'Mexico' }
]
const roles = [
{ value: 'admin', label: 'Admin' },
{ value: 'user', label: 'User' },
{ value: 'guest', label: 'Guest' }
]
</script>
<template>
<UForm :schema="schema" :state="state">
<UFormField label="Country" name="country">
<USelect v-model="state.country" :items="countries" />
</UFormField>
<UFormField label="Role" name="role">
<USelect v-model="state.role" :items="roles" />
</UFormField>
</UForm>
</template>
Custom Slots
<template>
<USelect v-model="selected" :items="items">
<template #item="{ item }">
<div class="flex items-center gap-2">
<UBadge :color="item.color">{{ item.status }}</UBadge>
<span>{{ item.label }}</span>
</div>
</template>
</USelect>
</template>
Props
The controlled value. Can be bound with v-model.
The default value when initially rendered.
Array of items or nested arrays for grouped items.
Field to use as the value when items are objects.
Field to use as the label when items are objects.
descriptionKey
string
default:"description"
Field to use as the description when items are objects.
Placeholder text when no item is selected.
Allow multiple items to be selected.
Icon displayed at the start.
Icon displayed at the end (chevron by default).
Icon shown for selected items.
Highlight the ring color.
Automatically focus on mount.
portal
boolean | string | HTMLElement
default:"true"
Render the menu in a portal.
Content props (side, sideOffset, etc.).
Display an arrow alongside the menu.
Events
Emitted when the selected value changes.
Emitted when the value is committed.
@blur
(event: FocusEvent) => void
Emitted when focus is lost.
@focus
(event: FocusEvent) => void
Emitted when focused.
Slots
leading
{ modelValue: any, open: boolean, ui: object }
Custom leading content.
default
{ modelValue: any, open: boolean, ui: object }
Custom trigger content.
trailing
{ modelValue: any, open: boolean, ui: object }
Custom trailing content.
item
{ item: any, index: number, ui: object }
Custom item rendering.
item-leading
{ item: any, index: number, ui: object }
Custom item leading content.
item-trailing
{ item: any, index: number, ui: object }
Custom item trailing content.
Exposed
Reference to the trigger button.
Reference to the viewport element.