Components

Textarea

A textarea element to input multi-line text.

Usage

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

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

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

Placeholder

Use the placeholder prop to set a placeholder text.

<template>
  <UTextarea placeholder="Type something..." />
</template>

Color

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

<template>
  <UTextarea color="gray" highlight placeholder="Type something..." />
</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 Textarea.

<template>
  <UTextarea color="gray" variant="subtle" placeholder="Type something..." />
</template>

Size

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

<template>
  <UTextarea size="xl" placeholder="Type something..." />
</template>

Disabled

Use the disabled prop to disable the Textarea.

<template>
  <UTextarea disabled placeholder="Type something..." />
</template>

Rows

Use the rows prop to set the number of rows. Defaults to 3.

<template>
  <UTextarea :rows="12" />
</template>

Autoresize

Use the autoresize prop to enable autoresizing the height of the Textarea.

<script setup lang="ts">
const value = ref('This is a long text that will autoresize the height of the Textarea.')
</script>

<template>
  <UTextarea v-model="value" autoresize />
</template>

Use the maxrows prop to set the maximum number of rows when autoresizing. If set to 0, the Textarea will grow indefinitely.

<script setup lang="ts">
const value = ref('This is a long text that will autoresize the height of the Textarea with a maximum of 4 rows.')
</script>

<template>
  <UTextarea v-model="value" :maxrows="4" autoresize />
</template>

API

Props

Prop Default Type
modelValue

string | number

id

string

name

string

placeholder

string

The placeholder text when the textarea 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

autofocus

boolean

autofocusDelay

0

number

disabled

boolean

rows

3

number

maxrows

0

number

autoresize

boolean

highlight

boolean

Highlight the ring color like a focus state.

ui

Partial<{ 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
default

{}

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
textareaRefRef<HTMLTextAreaElement | null>

Theme

app.config.ts
export default defineAppConfig({
  ui: {
    textarea: {
      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.