Wrap any form component with a FormField. Used in a Form, it provides validation and error handling.
Use the label prop to set the label for the form control.
<template>
<UFormField label="Email">
<UInput placeholder="Enter your email" />
</UFormField>
</template>
for attribute and the form control are associated with a unique id if not provided.When using the required prop, an asterisk is added next to the label.
<template>
<UFormField label="Email" required>
<UInput placeholder="Enter your email" />
</UFormField>
</template>
Use the description prop to provide additional information below the label.
We'll never share your email with anyone else.
<template>
<UFormField label="Email" description="We'll never share your email with anyone else.">
<UInput placeholder="Enter your email" class="w-full" />
</UFormField>
</template>
Use the hint prop to display a hint message next to the label.
<template>
<UFormField label="Email" hint="Optional">
<UInput placeholder="Enter your email" />
</UFormField>
</template>
Use the help prop to display a help message below the form control.
<template>
<UFormField label="Email" help="Please enter a valid email address.">
<UInput placeholder="Enter your email" class="w-full" />
</UFormField>
</template>
You can pass an array of names to the name prop to track errors for multiple fields. This is useful when you have a complex field that is composed of multiple inputs.
Make sure you're passing manually name to fields inside the form field to link fields to state (and then errors accordingly).
Error messages of fields inside the form field will be displayed in the form field itself.
<template>
<UFormField label="Duration" :name="['duration.value', 'duration.unit']">
<div class="flex gap-2">
<UInput name="duration.value" type="number" />
<USelect name="duration.unit" :items="['min', 'h']" />
</div>
</UFormField>
</template>
Use the error prop to display an error message below the form control. When used together with the help prop, the error prop takes precedence.
When used inside a Form, this is automatically set when a validation error occurs.
<template>
<UFormField label="Email" error="Please enter a valid email address.">
<UInput placeholder="Enter your email" class="w-full" />
</UFormField>
</template>
Use the size prop to change the size of the FormField, the size is proxied to the form control.
We'll never share your email with anyone else.
<template>
<UFormField
label="Email"
description="We'll never share your email with anyone else."
hint="Optional"
help="Please enter a valid email address."
size="xl"
>
<UInput placeholder="Enter your email" class="w-full" />
</UFormField>
</template>
| Prop | Default | Type |
|---|---|---|
as | 'div' | anyThe element or component this component should render as. |
name | string | string[]The name of the FormField. Also used to match form errors. | |
errorPattern | RegExpA regular expression to match form error names. | |
label | string | |
description | string | |
help | string | |
error | string | false | true | |
hint | string | |
size | 'md' | "md" | "xs" | "sm" | "lg" | "xl" |
required | boolean | |
eagerValidation | boolean If true, validation on input will be active immediately instead of waiting for a blur event. | |
validateOnInputDelay | `300` | numberDelay in milliseconds before validating the form on input events. |
ui | { root?: ClassNameValue; wrapper?: ClassNameValue; labelWrapper?: ClassNameValue; label?: ClassNameValue; container?: ClassNameValue; description?: ClassNameValue; error?: ClassNameValue; hint?: ClassNameValue; help?: ClassNameValue; } |
| Slot | Type |
|---|---|
label | { label?: string | undefined; } |
hint | { hint?: string | undefined; } |
description | { description?: string | undefined; } |
help | { help?: string | undefined; } |
error | { error?: string | boolean | undefined; } |
default | { error?: string | boolean | undefined; } |
export default defineAppConfig({
ui: {
formField: {
slots: {
root: '',
wrapper: '',
labelWrapper: 'flex content-center items-center justify-between',
label: 'block font-medium text-default',
container: 'mt-1 relative',
description: 'text-muted',
error: 'mt-2 text-error',
hint: 'text-muted',
help: 'mt-2 text-muted'
},
variants: {
size: {
xs: {
root: 'text-xs'
},
sm: {
root: 'text-xs'
},
md: {
root: 'text-sm'
},
lg: {
root: 'text-sm'
},
xl: {
root: 'text-base'
}
},
required: {
true: {
label: "after:content-['*'] after:ms-0.5 after:text-error"
}
}
},
defaultVariants: {
size: 'md'
}
}
}
})
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/ui/vite'
export default defineConfig({
plugins: [
vue(),
ui({
ui: {
formField: {
slots: {
root: '',
wrapper: '',
labelWrapper: 'flex content-center items-center justify-between',
label: 'block font-medium text-default',
container: 'mt-1 relative',
description: 'text-muted',
error: 'mt-2 text-error',
hint: 'text-muted',
help: 'mt-2 text-muted'
},
variants: {
size: {
xs: {
root: 'text-xs'
},
sm: {
root: 'text-xs'
},
md: {
root: 'text-sm'
},
lg: {
root: 'text-sm'
},
xl: {
root: 'text-base'
}
},
required: {
true: {
label: "after:content-['*'] after:ms-0.5 after:text-error"
}
}
},
defaultVariants: {
size: 'md'
}
}
}
})
]
})