Manual UI Templates Field

Field

elements man ui/templates/field

A label, a control, a description and an error wired together, with native validation that never moves the layout.

Example
import { Field, FieldLabel, FieldDescription, FieldError, FieldContent, FieldTitle, FieldSet, FieldLegend, FieldGroup, FieldSeparator, } from "@elements/ui/field"; import { Input } from "@elements/ui/input"; import { Checkbox } from "@elements/ui/checkbox"; <Field label="Email" description="We never share it." required> <Input type="email" value={form.email} /> </Field> <Field label="Username" validate={checkUsername} validationMode="onBlur"> <Input value={form.username} attrs={{ minlength: 3 }} /> <div slot="error"> <FieldError match="tooShort">At least 3 characters.</FieldError> </div> </Field> <Field orientation="horizontal" label="Email me updates"> <Checkbox checked={form.updates} /> </Field>

Parts

Part What it is
FieldLabel <label class="label field-label">. Wired to the control by the field. Wrapping a Field, it makes a choice card.
FieldDescription <p class="hint field-description">, added to aria-describedby.
FieldError <div class="error field-error-part">: a message shown by match.
FieldContent A column for a label and description beside a control.
FieldTitle Label-styled text that is not a <label>, for choice cards.
FieldSet / FieldLegend A native fieldset and legend with the box removed.
FieldGroup A column of fields, and the container a responsive field measures.
FieldSeparator A rule between groups, with optional text.
.field-message The reserved line: the description and the error share it.

Attributes

Field

Attribute Type Default Description
label string "" The label, wired to the control. Or use a FieldLabel part.
description string "" Help text under the control, wired with aria-describedby. Or use FieldDescription.
error string "" A message from elsewhere (the server). Shows at once and makes the field invalid.
errors string[] [] Several messages from elsewhere; render as a list.
invalid boolean false Force the invalid state with no message.
disabled boolean false Disables every control inside and dims the field.
required boolean false Required on the control, and a marker on the label.
name string "" Form name for the control.
orientation "vertical" | "horizontal" | "responsive" "vertical" Label above; control first with the label beside it; or a column that becomes a row in a wide FieldGroup.
validationMode "onSubmit" | "onBlur" | "onChange" "onSubmit" When errors first show. After that they follow every change.
validationDebounceTime number 0 onChange: wait this many ms after typing.
validate (value: string, control: HTMLElement, formValues: FormValues) => string | string[] | null | Promise<string | string[] | null> () => null Your rule. Return a message (or several) when invalid, or a Promise of them for a server check. It blocks a native submit (a pending Promise does not).
reserveError boolean true Keep the message line even with no description, so an error never moves anything.
dirty boolean undefined Controls the dirty state when another library owns it; unset, the field tracks it.
touched boolean undefined Controls the touched state when another library owns it; unset, the field tracks it.
class string "" Extra classes on the field.
onValidityChange (state: { valid, errors, error, value, initialValue, validity }) => void () => {} After every validation and a form reset, with the ValidityState flags.

FieldLabel

Attribute Type Default Description
required boolean false Draws the required marker.
attrs Record<string, string | number | boolean | undefined> {} Attributes for the <label>.

FieldError

Attribute Type Default Description
match ValidityKey | "always" | "" "" Show when this ValidityState flag is set (valueMissing, typeMismatch, tooShort...). Empty shows whenever the field is invalid; valid shows when it passes.

FieldSet

Attribute Type Default Description
disabled boolean false Native fieldset disabled: disables every control inside.

FieldLegend

Attribute Type Default Description
variant "legend" | "label" "legend" label sizes the legend like a field label, for nested sets.

Slots

Slot Part Content
default Field The control, and any parts: FieldLabel, FieldDescription, FieldContent.
error Field FieldError parts, in one wrapper element: they share the reserved message line.
default FieldSet Fields, a FieldLegend and a FieldDescription.
default FieldSeparator Optional text in the middle of the rule.

Keyboard

Keys Action
Click on the label Focuses or toggles the control.
Enter (in a form) Submits; an invalid field shows its error and takes focus instead.

Data attributes

Attribute Values On Description
data-orientation "vertical" | "horizontal" | "responsive" field
data-invalid present while an error shows field
data-valid present once validated and passing field
data-disabled present while disabled field
data-required present when required field
data-dirty present when the value differs from the first one field
data-touched present after focus has left once field
data-filled present while the control has a value field
data-focused present while focus is inside field
data-error-shown present while an error message is on screen field
data-visible present while this error is shown FieldError
data-field-control present a custom control Set by a template that is not a native control on its focusable element: the label, description and aria-invalid go there.
data-field-input present a custom control's value input An input beside the control that carries its form value (Select). Field validates it, names it and marks it required.
data-custom-validity the message a control's input The control's own custom validity (NumberInput's step check). Field keeps it and shows it as an error.

Accessibility

  • The field finds its control and wires it: label for (or aria-labelledby for a radio group), aria-describedby to the description and the shown error, aria-invalid while invalid.
  • The field is role="group" named by its label; FieldSet and FieldLegend group related fields natively.
  • Validation is the browser's constraint validation plus validate() through setCustomValidity, so an invalid form does not submit and the first invalid control takes focus.
  • Errors are in an aria-live region and take the description's line, so nothing on the page moves when one appears.

See also