Field
A component that provides labeling and validation for form controls. Pair it with Form when you need submit-time errors. color tints the control wash. inline makes that wash transparent. Labels are Regular, descriptions and errors are Light.
Visible on your profile
Focus the name field and leave it empty to see the valueMissing error. The description stays visible underneath.
Usage guidelines
- Accessible name: Use
UiFieldLabel. It is associated with the control automatically. - When to validate: Standalone fields default to
onBlur. Inside Form they default toonSubmit, then re-validate on change after submit. - Other controls: Omit
UiFieldControland use Input, Checkbox, or Select. Field still wires the label, description, and error. - External validity: Set
invalidand showUiFieldErrorwithmatchtruewhen another library owns the error.
Anatomy
<UiFieldRoot>
<UiFieldLabel />
<UiFieldControl />
<UiFieldDescription />
<UiFieldItem />
<UiFieldError />
<UiFieldValidity />
</UiFieldRoot>
You can omit UiFieldControl and use Input, Checkbox, or Select instead. They work with Field out of the box.
Examples
Disabled
disabled on Root ignores interaction and sets data-disabled on every part. It takes precedence over disabled on Control.
Visible on your profile
Invalid
Set invalid when an external library owns validity. UiFieldError with match true always shows, so the library can control visibility.
We’ll never share this
Custom validation
Pass validate to return a string (or array of strings) when the value is invalid. Returning nothing, null, an empty string, or an empty array means the value is valid. Pair UiFieldError match="customError" with native matches such as valueMissing.
Used to sign in
<UiFieldRoot :validate="(value) => String(value).length < 3 ? 'Use at least 3 characters' : undefined">
<UiFieldLabel>Username</UiFieldLabel>
<UiFieldControl required />
<UiFieldError match="valueMissing">Please choose a username</UiFieldError>
<UiFieldError match="customError" />
</UiFieldRoot>
Validation mode
Standalone fields default to onBlur. Inside Form they default to onSubmit, then re-validate on change after submit. Set validationMode on Root to override:
onSubmit— validate when the form is submitted, then re-validate on changeonBlur— validate when the control loses focusonChange— validate on every change
validationDebounceTime delays onChange validate callbacks, in milliseconds.
Validates on every change
Pattern
Native pattern sets patternMismatch after blur (or according to validationMode).
Four letters, A–Z
Field items
UiFieldItem groups a checkbox or radio with its own label and description. Item disabled ignores that row; Root disabled still wins. Prefer native-button on the checkbox when the label is a sibling (for / id).
Crisp and extra sweet
Mild and aromatic
Tart, good for baking
<UiFieldRoot name="apple">
<UiFieldLabel :native-label="false">Apples</UiFieldLabel>
<UiCheckboxGroup>
<UiFieldItem>
<UiCheckboxRoot native-button value="fuji">
<UiCheckboxIndicator />
</UiCheckboxRoot>
<UiFieldLabel>Fuji</UiFieldLabel>
<UiFieldDescription>Crisp and extra sweet</UiFieldDescription>
</UiFieldItem>
</UiCheckboxGroup>
</UiFieldRoot>
Validity
UiFieldValidity takes a scoped slot with { validity, error, errors, value, initialValue } so you can render a custom message from ValidityState.
filled: no · valid: —
<UiFieldValidity v-slot="{ validity, error }">
<p v-if="validity.valid === false">{{ error }}</p>
</UiFieldValidity>
Other controls
Omit Control and drop in Input (or Checkbox, Select, …). Field still wires the label, description, and error.
You can omit Control and use Input instead
<UiFieldRoot>
<UiFieldLabel>Name</UiFieldLabel>
<UiInput required placeholder="e.g. Colm Tuite" />
<UiFieldError match="valueMissing">Please enter your name</UiFieldError>
</UiFieldRoot>
Native label
nativeLabel defaults to true and renders a <label>. Set it false for Select and Combobox triggers so hovering or clicking the label does not fire on the trigger button.
nativeLabel false avoids label behavior on triggers
<UiFieldLabel :native-label="false">Country</UiFieldLabel>
API reference
Parts receive data-disabled, data-valid, data-invalid, data-dirty, data-touched, data-filled, and data-focused from Root.
Root
Groups all parts of the field. Renders a <div>. Call validate() on a template ref to run the same checks as submit or blur.
| Prop | Type | Default | Description |
|---|---|---|---|
name | string | — | Identifies the field when a form is submitted. Takes precedence over name on Control. |
disabled | boolean | false | Ignore interaction. Takes precedence over Control disabled. |
invalid | boolean | — | Force invalid when an external library owns state. |
dirty | boolean | — | Controlled dirty. Uncontrolled: value differs from the initial value. |
touched | boolean | — | Controlled touched. Uncontrolled: set on blur. |
validate | (value, formValues) => string | string[] | void | null | Promise<…> | — | Custom validation. Return a message (or array) when invalid. Async results do not block onSubmit. |
validationMode | 'onSubmit' | 'onBlur' | 'onChange' | 'onBlur' standalone, 'onSubmit' in Form | When to validate. Takes precedence over Form. |
validationDebounceTime | number | 0 | Milliseconds to wait between onChange validate calls. |
| Attribute | Description |
|---|---|
data-disabled | Present when the field is disabled. |
data-valid | Present when the field is valid. |
data-invalid | Present when the field is invalid. |
data-dirty | Present when the value has changed from its initial value. |
data-touched | Present when the field has been touched. |
data-filled | Present when the field has a value. |
data-focused | Present when the control is focused. |
Label
Accessible label associated with the control. Renders a <label> by default.
| Prop | Type | Default | Description |
|---|---|---|---|
nativeLabel | boolean | true | Set false to render a <span> instead of <label> (for Select / Combobox triggers). |
for | string | control id | Override the labelled control. |
| Attribute | Description |
|---|---|
data-disabled | Present when the field is disabled. |
data-valid | Present when the field is in a valid state. |
data-invalid | Present when the field is in an invalid state. |
data-dirty | Present when the field’s value has changed. |
data-touched | Present when the field has been touched. |
data-filled | Present when the field is filled. |
data-focused | Present when the field control is focused. |
Control
Native <input>. Extra attributes such as type, required, pattern, min, max, and maxlength pass through. You can omit this part and use Input, Checkbox, or Select instead.
| Prop | Type | Default | Description |
|---|---|---|---|
defaultValue | string | number | — | Uncontrolled initial value. |
value | string | — | Controlled value (v-model:value). |
disabled | boolean | false | Ignore this control. Root disabled still wins. |
name | string | Root name | Submitted name. Root name takes precedence. |
| Attribute | Description |
|---|---|
data-disabled | Present when the field is disabled. |
data-valid | Present when the field is in a valid state. |
data-invalid | Present when the field is in an invalid state. |
data-dirty | Present when the field’s value has changed. |
data-touched | Present when the field has been touched. |
data-filled | Present when the field is filled. |
data-focused | Present when the field control is focused. |
Description
Supporting text. Renders a <p>. Referenced by aria-describedby.
| Attribute | Description |
|---|---|
data-disabled | Present when the field is disabled. |
data-valid | Present when the field is in a valid state. |
data-invalid | Present when the field is in an invalid state. |
data-dirty | Present when the field’s value has changed. |
data-touched | Present when the field has been touched. |
data-filled | Present when the field is filled. |
data-focused | Present when the field control is focused. |
Item
Groups a checkbox or radio with its own label and description. Renders a <div>.
| Prop | Type | Default | Description |
|---|---|---|---|
disabled | boolean | false | Ignore this item. Root disabled takes precedence. |
| Attribute | Description |
|---|---|
data-disabled | Present when the field or item is disabled. |
data-valid | Present when the field is in a valid state. |
data-invalid | Present when the field is in an invalid state. |
data-dirty | Present when the field’s value has changed. |
data-touched | Present when the field has been touched. |
data-filled | Present when the field is filled. |
data-focused | Present when the field control is focused. |
Error
Shown after validation. Renders a <div role="alert">. Animate with data-starting-style / data-ending-style. Omit match to show whenever the field is invalid. Empty content uses the native or form message.
| Prop | Type | Default | Description |
|---|---|---|---|
match | boolean | 'valid' | 'badInput' | 'customError' | 'patternMismatch' | 'rangeOverflow' | 'rangeUnderflow' | 'stepMismatch' | 'tooLong' | 'tooShort' | 'typeMismatch' | 'valueMissing' | — | true always shows (for external libraries). A ValidityState key shows when that flag is set. |
| Attribute | Description |
|---|---|
data-disabled | Present when the field is disabled. |
data-valid | Present when the field is in a valid state. |
data-invalid | Present when the field is in an invalid state. |
data-dirty | Present when the field’s value has changed. |
data-touched | Present when the field has been touched. |
data-filled | Present when the field is filled. |
data-focused | Present when the field control is focused. |
data-starting-style | Present when the error message begins animating in. |
data-ending-style | Present when the error message is animating out. |
Validity
Scoped slot for a custom message from field validity.
<UiFieldValidity v-slot="{ validity, error, errors, value, initialValue }">
…
</UiFieldValidity>
| Field | Description |
|---|---|
validity | Native ValidityState plus valid: boolean | null. |
error | Current error string. |
errors | All current error strings. |
value | Current control value. |
initialValue | Value when the control registered. |