Components

Input

An input element to enter text.

Usage

Use the v-model directive to control the value of the Input.

<script setup lang="ts">
const value = ref('')
</script>

<template>
  <UInput v-model="value" />
</template>

Type

Use the type prop to change the input type. Defaults to text.

Some types have been implemented in their own components such as Checkbox, Radio, etc. and others have been styled like file for example.

<template>
  <UInput type="number" />
</template>
You can check all the available types on the MDN Web Docs.

Placeholder

Use the placeholder prop to set a placeholder text.

<template>
  <UInput placeholder="Search..." />
</template>

Color

Use the color prop to change the ring color when the Input is focused.

<template>
  <UInput color="gray" highlight placeholder="Search..." />
</template>
The highlight prop is used here to show the focus state. It's used internally when a validation error occurs.

Variant

Use the variant prop to change the variant of the Input.

<template>
  <UInput color="gray" variant="subtle" placeholder="Search..." />
</template>

Size

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

<template>
  <UInput size="xl" placeholder="Search..." />
</template>

Icon

Use the icon prop to show an Icon inside the Input.

<template>
  <UInput icon="i-heroicons-magnifying-glass" placeholder="Search..." />
</template>

Use the leading and trailing props to set the icon position or the leading-icon and trailing-icon props to set a different icon for each position.

<template>
  <UInput
    trailing-icon="i-heroicons-at-symbol"
    placeholder="Enter your email"
  />
</template>

Loading

Use the loading prop to show a loading icon on the Input.

<template>
  <UInput loading placeholder="Search..." />
</template>

Loading Icon

Use the loading-icon prop to customize the loading icon. Defaults to i-heroicons-arrow-path-20-solid.

<template>
  <UInput loading loading-icon="i-heroicons-arrow-path-rounded-square" placeholder="Search..." />
</template>
You can customize this icon globally in your app.config.ts under ui.icons.loading key.

Disabled

Use the disabled prop to disable the Input.

<template>
  <UInput disabled placeholder="Search..." />
</template>

API

Props

Prop Default Type
modelValue

string | number

id

string

name

string

type

"text"

"number" | "reset" | "submit" | "color" | "image" | "button" | "date" | "time" | string & {} | "text" | "search" | "checkbox" | "datetime-local" | "email" | "file" | "hidden" | "month" | "password" | "radio" | "range" | "tel" | "url" | "week"

placeholder

string

The placeholder text when the input is empty.

color

primary

"error" | "primary" | "red" | "orange" | "amber" | "yellow" | "lime" | "green" | "emerald" | "teal" | "cyan" | "sky" | "blue" | "indigo" | "violet" | "purple" | "fuchsia" | "pink" | "rose" | "gray"

variant

outline

"outline" | "soft" | "subtle" | "ghost" | "none"

size

md

"md" | "xs" | "sm" | "lg" | "xl"

required

boolean

autocomplete

"off"

string

autofocus

boolean

autofocusDelay

0

number

disabled

boolean

highlight

boolean

Highlight the ring color like a focus state.

icon

string

Display an icon based on the leading and trailing props.

leading

boolean

When true, the icon will be displayed on the left side.

leadingIcon

string

Display an icon on the left side.

trailing

boolean

When true, the icon will be displayed on the right side.

trailingIcon

string

Display an icon on the right side.

loading

boolean

When true, the loading icon will be displayed.

loadingIcon

appConfig.ui.icons.loading

string

The icon when the loading prop is true.

ui

PartialString<{ root: string; base: string[]; leading: "absolute inset-y-0 start-0 flex items-center"; leadingIcon: string; leadingAvatar: string; trailing: "absolute inset-y-0 end-0 flex items-center"; trailingIcon: string; }>

Slots

Slot Type
leading

{}

default

{}

trailing

{}

Emits

Event Type
blur

[event: FocusEvent]

change

[event: Event]

update:modelValue

[modelValue: string | number]

Expose

When accessing the component via a template ref, you can use the following:

NameType
inputRefRef<HTMLInputElement | null>

Theme

app.config.ts
export default defineAppConfig({
  ui: {
    input: {
      slots: {
        root: 'relative inline-flex items-center',
        base: [
          'w-full rounded-md border-0 focus:outline-none disabled:cursor-not-allowed disabled:opacity-75',
          'transition-colors'
        ],
        leading: 'absolute inset-y-0 start-0 flex items-center',
        leadingIcon: 'shrink-0 text-gray-400 dark:text-gray-500',
        leadingAvatar: 'shrink-0',
        trailing: 'absolute inset-y-0 end-0 flex items-center',
        trailingIcon: 'shrink-0 text-gray-400 dark:text-gray-500'
      },
      variants: {
        buttonGroup: {
          horizontal: {
            root: 'group',
            base: 'group-not-only:group-first:rounded-e-none group-not-only:group-last:rounded-s-none group-not-last:group-not-first:rounded-none'
          },
          vertical: {
            root: 'group',
            base: 'group-not-only:group-first:rounded-b-none group-not-only:group-last:rounded-t-none group-not-last:group-not-first:rounded-none'
          }
        },
        size: {
          xs: {
            base: 'px-2 py-1 text-xs gap-1',
            leading: 'pl-2',
            trailing: 'pr-2',
            leadingIcon: 'size-4',
            trailingIcon: 'size-4'
          },
          sm: {
            base: 'px-2.5 py-1.5 text-xs gap-1.5',
            leading: 'pl-2.5',
            trailing: 'pr-2.5',
            leadingIcon: 'size-4',
            trailingIcon: 'size-4'
          },
          md: {
            base: 'px-2.5 py-1.5 text-sm gap-1.5',
            leading: 'pl-2.5',
            trailing: 'pr-2.5',
            leadingIcon: 'size-5',
            trailingIcon: 'size-5'
          },
          lg: {
            base: 'px-3 py-2 text-sm gap-2',
            leading: 'pl-3',
            trailing: 'pr-3',
            leadingIcon: 'size-5',
            trailingIcon: 'size-5'
          },
          xl: {
            base: 'px-3 py-2 text-base gap-2',
            leading: 'pl-3',
            trailing: 'pr-3',
            leadingIcon: 'size-6',
            trailingIcon: 'size-6'
          }
        },
        variant: {
          outline: 'text-gray-900 dark:text-white bg-white dark:bg-gray-900 ring ring-inset ring-gray-300 dark:ring-gray-700',
          soft: 'text-gray-900 dark:text-white bg-gray-50 hover:bg-gray-100 focus:bg-gray-100 disabled:bg-gray-50 dark:bg-gray-800/50 dark:hover:bg-gray-800 dark:focus:bg-gray-800 dark:disabled:bg-gray-800/50',
          subtle: 'text-gray-900 dark:text-white bg-gray-100 dark:bg-gray-800 ring ring-inset ring-gray-300 dark:ring-gray-700',
          ghost: 'text-gray-900 dark:text-white hover:bg-gray-100 focus:bg-gray-100 disabled:bg-transparent dark:hover:bg-gray-800 dark:focus:bg-gray-800 dark:disabled:bg-transparent',
          none: 'text-gray-900 dark:text-white'
        },
        color: {
          primary: '',
          error: '',
          red: '',
          orange: '',
          amber: '',
          yellow: '',
          lime: '',
          green: '',
          emerald: '',
          teal: '',
          cyan: '',
          sky: '',
          blue: '',
          indigo: '',
          violet: '',
          purple: '',
          fuchsia: '',
          pink: '',
          rose: '',
          gray: ''
        },
        leading: {
          true: ''
        },
        trailing: {
          true: ''
        },
        loading: {
          true: ''
        },
        highlight: {
          true: ''
        },
        type: {
          file: 'file:mr-1.5 file:font-medium file:text-gray-500 dark:file:text-gray-400 file:outline-none'
        }
      },
      compoundVariants: [
        {
          color: 'primary',
          variant: [
            'outline',
            'subtle'
          ],
          class: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary-500 dark:focus-visible:ring-primary-400'
        },
        {
          color: 'primary',
          highlight: true,
          class: 'ring ring-inset ring-primary-500 dark:ring-primary-400'
        },
        {
          color: 'gray',
          variant: [
            'outline',
            'subtle'
          ],
          class: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-gray-900 dark:focus-visible:ring-white'
        },
        {
          color: 'gray',
          highlight: true,
          class: 'ring ring-inset ring-gray-900 dark:ring-white'
        },
        {
          leading: true,
          size: 'xs',
          class: 'pl-7'
        },
        {
          leading: true,
          size: 'sm',
          class: 'pl-8'
        },
        {
          leading: true,
          size: 'md',
          class: 'pl-9'
        },
        {
          leading: true,
          size: 'lg',
          class: 'pl-10'
        },
        {
          leading: true,
          size: 'xl',
          class: 'pl-11'
        },
        {
          trailing: true,
          size: 'xs',
          class: 'pr-7'
        },
        {
          trailing: true,
          size: 'sm',
          class: 'pr-8'
        },
        {
          trailing: true,
          size: 'md',
          class: 'pr-9'
        },
        {
          trailing: true,
          size: 'lg',
          class: 'pr-10'
        },
        {
          trailing: true,
          size: 'xl',
          class: 'pr-11'
        },
        {
          loading: true,
          leading: true,
          class: {
            leadingIcon: 'animate-spin'
          }
        },
        {
          loading: true,
          leading: false,
          trailing: true,
          class: {
            trailingIcon: 'animate-spin'
          }
        }
      ],
      defaultVariants: {
        size: 'md',
        color: 'primary',
        variant: 'outline'
      }
    }
  }
})
Some colors in compoundVariants are omitted for readability. Check out the source code on GitHub.