Nuxt UI v3-alpha has been released!

Try it out
Components

Select

Display a select field.

Usage

The Select component is a wrapper around the native <select> HTML element. For more advanced use cases like searching or multiple selection, consider using the SelectMenu component.

Use a v-model to make the Select reactive alongside the options prop to pass an array of strings or objects.

<script setup lang="ts">
const countries = ['United States', 'Canada', 'Mexico']

const country = ref(countries[0])
</script>

<template>
  <USelect v-model="country" :options="countries" />
</template>

When using objects, you can configure which field will be used for display through the option-attribute prop that defaults to label and which field will be used for comparison through the value-attribute prop that defaults to value.

Adding a disabled key to the objects will control the disabled state of the option.

<script setup lang="ts">
const countries = [{
  name: 'United States',
  value: 'US'
}, {
  name: 'Canada',
  value: 'CA',
  disabled: true
}, {
  name: 'Mexico',
  value: 'MX'
}]

const country = ref('CA')
</script>

<template>
  <USelect v-model="country" :options="countries" option-attribute="name" />
</template>

Style

Use the color and variant props to change the visual style of the Select.

<template>
  <USelect
    color="primary"
    variant="outline"
    :options="['United States', 'Canada', 'Mexico']"
  />
</template>

Besides all the colors from the ui.colors object, you can also use the white (default) and gray colors with their pre-defined variants.

White

<template>
  <USelect
    color="white"
    variant="outline"
    :options="['United States', 'Canada', 'Mexico']"
  />
</template>

Gray

<template>
  <USelect
    color="gray"
    variant="outline"
    :options="['United States', 'Canada', 'Mexico']"
  />
</template>

Size

Use the size prop to change the size of the Select.

<template>
  <USelect size="sm" :options="['United States', 'Canada', 'Mexico']" />
</template>

Placeholder

Use the placeholder prop to set a placeholder text.

<template>
  <USelect
    placeholder="Search..."
    :options="['United States', 'Canada', 'Mexico']"
  />
</template>

Icon

Use any icon from Iconify by setting the icon prop by using this pattern: i-{collection_name}-{icon_name}.

Use the trailing-icon prop to set a different icon or change it globally in ui.select.default.trailingIcon. Defaults to i-heroicons-chevron-down-20-solid.

<template>
  <USelect
    icon="i-heroicons-magnifying-glass-20-solid"
    color="white"
    size="sm"
    :options="['United States', 'Canada', 'Mexico']"
    placeholder="Search..."
  />
</template>

Disabled

Use the disabled prop to disable the Select.

<template>
  <USelect
    disabled
    :options="['United States', 'Canada', 'Mexico']"
    placeholder="Search..."
  />
</template>

Add a disabled key with a truthy value to the options array of object to disable a single option.

Loading

Use the loading prop to show a loading icon and disable the Input.

Use the loading-icon prop to set a different icon or change it globally in ui.select.default.loadingIcon. Defaults to i-heroicons-arrow-path-20-solid.

<template>
  <USelect
    loading
    icon="i-heroicons-magnifying-glass-20-solid"
    :options="['United States', 'Canada', 'Mexico']"
    placeholder="Search..."
  />
</template>

Padded

Use the padded prop to remove the padding of the Select.

<template>
  <USelect
    :padded="false"
    placeholder="Search..."
    :options="['United States', 'Canada', 'Mexico']"
    variant="none"
    class="w-full"
  />
</template>

Slots

leading

Use the #leading slot to set the content of the leading icon.

<template>
  <USelect
    :options="['United States', 'Canada', 'Mexico']"
    placeholder="Search..."
  >
    <template #leading>
      <UIcon name="i-heroicons-flag" class="w-5 h-5" />
    </template>
  </USelect>
</template>

trailing

Use the #trailing slot to set the content of the trailing icon.

<template>
  <USelect placeholder="Search...">
    <template #trailing>
      <UIcon name="i-heroicons-arrows-up-down-20-solid" class="w-5 h-5" />
    </template>
  </USelect>
</template>

Props

name
string
null
size
SelectSize
null
"md""2xs""xs""sm""lg""xl"
color
string
config.default.color
icon
string
null
ui
{ form?: string; placeholder?: string; default?: DeepPartial<{ size: string; color: string; variant: string; loadingIcon: string; trailingIcon: string; }, any>; wrapper?: string; base?: string; ... 9 more ...; icon?: DeepPartial<...>; } & { ...; } & { ...; }
{}
id
string
null
modelValue
string | number | object
""
variant
SelectVariant
config.default.variant
"outline""none"
placeholder
string
null
loadingIcon
string
config.default.loadingIcon
leadingIcon
string
null
trailingIcon
string
config.default.trailingIcon
options
unknown[]
[]
optionAttribute
string
"label"
valueAttribute
string
"value"
selectClass
string
null
required
boolean
false
disabled
boolean
false
leading
boolean
false
trailing
boolean
false
loading
boolean
false
padded
boolean
true

Config

{
  wrapper: 'relative',
  base: 'relative block w-full disabled:cursor-not-allowed disabled:opacity-75 focus:outline-none border-0',
  form: 'form-select',
  rounded: 'rounded-md',
  placeholder: 'text-gray-400 dark:text-gray-500',
  file: {
    base: 'file:mr-1.5 file:font-medium file:text-gray-500 dark:file:text-gray-400 file:bg-transparent file:border-0 file:p-0 file:outline-none'
  },
  size: {
    '2xs': 'text-xs',
    xs: 'text-xs',
    sm: 'text-sm',
    md: 'text-sm',
    lg: 'text-sm',
    xl: 'text-base'
  },
  gap: {
    '2xs': 'gap-x-1',
    xs: 'gap-x-1.5',
    sm: 'gap-x-1.5',
    md: 'gap-x-2',
    lg: 'gap-x-2.5',
    xl: 'gap-x-2.5'
  },
  padding: {
    '2xs': 'px-2 py-1',
    xs: 'px-2.5 py-1.5',
    sm: 'px-2.5 py-1.5',
    md: 'px-3 py-2',
    lg: 'px-3.5 py-2.5',
    xl: 'px-3.5 py-2.5'
  },
  leading: {
    padding: {
      '2xs': 'ps-7',
      xs: 'ps-8',
      sm: 'ps-9',
      md: 'ps-10',
      lg: 'ps-11',
      xl: 'ps-12'
    }
  },
  trailing: {
    padding: {
      '2xs': 'pe-7',
      xs: 'pe-8',
      sm: 'pe-9',
      md: 'pe-10',
      lg: 'pe-11',
      xl: 'pe-12'
    }
  },
  color: {
    white: {
      outline: 'shadow-sm bg-white dark:bg-gray-900 text-gray-900 dark:text-white ring-1 ring-inset ring-gray-300 dark:ring-gray-700 focus:ring-2 focus:ring-primary-500 dark:focus:ring-primary-400'
    },
    gray: {
      outline: 'shadow-sm bg-gray-50 dark:bg-gray-800 text-gray-900 dark:text-white ring-1 ring-inset ring-gray-300 dark:ring-gray-700 focus:ring-2 focus:ring-primary-500 dark:focus:ring-primary-400'
    }
  },
  variant: {
    outline: 'shadow-sm bg-transparent text-gray-900 dark:text-white ring-1 ring-inset ring-{color}-500 dark:ring-{color}-400 focus:ring-2 focus:ring-{color}-500 dark:focus:ring-{color}-400',
    none: 'bg-transparent focus:ring-0 focus:shadow-none'
  },
  icon: {
    base: 'flex-shrink-0 text-gray-400 dark:text-gray-500',
    color: 'text-{color}-500 dark:text-{color}-400',
    loading: 'animate-spin',
    size: {
      '2xs': 'h-4 w-4',
      xs: 'h-4 w-4',
      sm: 'h-5 w-5',
      md: 'h-5 w-5',
      lg: 'h-5 w-5',
      xl: 'h-6 w-6'
    },
    leading: {
      wrapper: 'absolute inset-y-0 start-0 flex items-center',
      pointer: 'pointer-events-none',
      padding: {
        '2xs': 'px-2',
        xs: 'px-2.5',
        sm: 'px-2.5',
        md: 'px-3',
        lg: 'px-3.5',
        xl: 'px-3.5'
      }
    },
    trailing: {
      wrapper: 'absolute inset-y-0 end-0 flex items-center',
      pointer: 'pointer-events-none',
      padding: {
        '2xs': 'px-2',
        xs: 'px-2.5',
        sm: 'px-2.5',
        md: 'px-3',
        lg: 'px-3.5',
        xl: 'px-3.5'
      }
    }
  },
  default: {
    size: 'sm',
    color: 'white',
    variant: 'outline',
    loadingIcon: 'i-heroicons-arrow-path-20-solid',
    trailingIcon: 'i-heroicons-chevron-down-20-solid'
  }
}