Skip to main content

Overview

The FormField component wraps form inputs to provide consistent labeling, descriptions, help text, and error message display. It automatically integrates with parent Form components for validation.

Basic Usage

<script setup lang="ts">
import { ref } from 'vue'

const state = ref({
  email: ''
})
</script>

<template>
  <UFormField
    label="Email Address"
    name="email"
    description="We'll never share your email"
    help="Enter a valid email address"
  >
    <UInput v-model="state.email" type="email" />
  </UFormField>
</template>

With Form Validation

<script setup lang="ts">
import { z } from 'zod'
import { ref } from 'vue'

const schema = z.object({
  email: z.string().email('Invalid email address'),
  password: z.string().min(8, 'Password must be at least 8 characters')
})

const state = ref({
  email: '',
  password: ''
})
</script>

<template>
  <UForm :schema="schema" :state="state">
    <UFormField 
      label="Email" 
      name="email"
      required
    >
      <UInput v-model="state.email" />
    </UFormField>
    
    <UFormField 
      label="Password" 
      name="password"
      required
      help="Must be at least 8 characters"
    >
      <UInput v-model="state.password" type="password" />
    </UFormField>
  </UForm>
</template>

Custom Error Messages

Override form validation errors with custom messages:
<template>
  <UFormField
    label="Username"
    name="username"
    error="This username is already taken"
  >
    <UInput v-model="state.username" />
  </UFormField>
  
  <!-- Conditionally show error -->
  <UFormField
    label="Email"
    name="email"
    :error="customError || undefined"
  >
    <UInput v-model="state.email" />
  </UFormField>
</template>

Error Pattern Matching

Match multiple error fields with a regular expression:
<script setup lang="ts">
// This field will show errors for addresses.home, addresses.work, etc.
const addressPattern = /^addresses\./
</script>

<template>
  <UFormField
    label="Addresses"
    name="addresses"
    :error-pattern="addressPattern"
  >
    <!-- nested address inputs -->
  </UFormField>
</template>

Eager Validation

Enable immediate validation without waiting for blur event:
<template>
  <UFormField
    label="Username"
    name="username"
    eager-validation
  >
    <UInput v-model="state.username" />
  </UFormField>
</template>

Sizes

<template>
  <UFormField label="Small" size="sm">
    <UInput />
  </UFormField>
  
  <UFormField label="Medium" size="md">
    <UInput />
  </UFormField>
  
  <UFormField label="Large" size="lg">
    <UInput />
  </UFormField>
</template>

Horizontal Orientation

<template>
  <UFormField
    label="Name"
    orientation="horizontal"
  >
    <UInput v-model="state.name" />
  </UFormField>
</template>

Custom Slots

<template>
  <UFormField name="terms">
    <template #label="{ label }">
      <div class="flex items-center gap-2">
        <UIcon name="i-heroicons-information-circle" />
        <span>{{ label }}</span>
      </div>
    </template>
    
    <template #description="{ description }">
      <p class="italic">{{ description }}</p>
    </template>
    
    <template #error="{ error }">
      <div class="flex items-center gap-1">
        <UIcon name="i-heroicons-exclamation-triangle" />
        <span>{{ error }}</span>
      </div>
    </template>
    
    <UCheckbox />
  </UFormField>
</template>

Props

name
string
The name of the FormField. Used to match form errors.
label
string
Label text displayed above the field.
description
string
Description text displayed below the label.
help
string
Help text displayed below the input when there’s no error.
hint
string
Hint text displayed next to the label.
error
boolean | string
Custom error message. Set to false to hide errors, or provide a string to override.
errorPattern
RegExp
A regular expression to match form error names.
required
boolean
Mark the field as required (visual indicator).
size
'sm' | 'md' | 'lg' | 'xl'
default:"md"
Size variant of the form field.
orientation
'vertical' | 'horizontal'
default:"vertical"
Layout orientation of the form field.
eagerValidation
boolean
If true, validation on input will be active immediately instead of waiting for a blur event.
validateOnInputDelay
number
default:"300"
Delay in milliseconds before validating on input events.
as
any
default:"div"
The element or component this component should render as.
class
any
Additional CSS classes.
ui
object
UI customization object for styling slots (root, wrapper, labelWrapper, label, hint, description, container, error, help).

Slots

default
{ error?: boolean | string }
Default slot for the input component. Receives current error state.
label
{ label?: string }
Custom label content.
hint
{ hint?: string }
Custom hint content.
description
{ description?: string }
Custom description content.
help
{ help?: string }
Custom help text content.
error
{ error?: boolean | string }
Custom error message content.

Build docs developers (and LLMs) love