Skip to main content

Field

Composes labels, descriptions, validation, and errors around a form control.

import { Field } from "@/fragments/ui";Source

Preview

<Field name="email">
  <Field.Label>Email address</Field.Label>
  <Field.Control>
    <Input type="email" placeholder="jane@example.com" />
  </Field.Control>
  <Field.Description>We will never share your email.</Field.Description>

Installation

npx @usefragments/cli add field

Writes src/fragments/ui/components/Field plus what it imports, the globals stylesheet, and .fragments/registry-lock.json, then prints the packages to add. No account, no key.

Your own registry: publish from Fragments Cloud and add --registry org/name. Connect a workspace.

Anatomy

Field is a compound: import the root and reach its parts through dot notation.

  • Field.Label
  • Field.Control
  • Field.Description
  • Field.Error
  • Field.Validity
  • Field.Required

Label, control and description wired together automatically.

<Field name="email">
  <Field.Label>Email address</Field.Label>
  <Field.Control>
    <Input type="email" placeholder="jane@example.com" />
  </Field.Control>
  <Field.Description>We will never share your email.</Field.Description>
</Field>

Examples

Two-column layout

Grid places two short fields side by side and one full-width.

<Grid columns={2} gap="md">
  <Field name="firstName">
    <Field.Label>First Name</Field.Label>
    <Field.Control>
      <Input placeholder="Jane" />
    </Field.Control>

Invalid

invalid marks the field failed and reveals Field.Error.

<Field name="username" invalid>
  <Field.Label>Username</Field.Label>
  <Field.Control>
    <Input value="ada lovelace" error />
  </Field.Control>
  <Field.Error match>Usernames cannot contain spaces</Field.Error>

Custom validation

validate runs on change and feeds Field.Error.

<Field
  name="age"
  validate={(value) => {
    const num = Number(value);
    if (isNaN(num) || num < 18) return 'Must be 18 or older';
    return null;

API

Component props
Prop
Type
Default
Description
childrenRequirednodeNot setField content (Label, Control, Description, Error)
namestringNot setField name, used for error distribution from Form
disabledbooleanNot setDisables the field and its control
invalidbooleanNot setMarks the field as invalid
validatefunctionNot setCustom validation function returning error string(s) or null
validationModeenumonSubmitonBluronChangeNot setWhen to trigger validation
validationDebounceTimenumberNot setDebounce time in ms for onChange validation
sizeenumsmmdlgNot set

Accessibility

  • Label links to the control via aria-labelledby
  • Description links via aria-describedby
  • Errors are announced when they appear
  • data-disabled and data-invalid are available for styling

Guidance

Use when

  • One error message per failure reason, not one catch-all
  • A custom control needs a real label and description
  • Server errors must land on the field that caused them
  • You need dirty and touched tracking

Avoid when

  • A plain input with a label and helper text (use Input's own props)
  • A Select or Textarea whose built-in error display is enough
  • InputalternativeUse Input for simple fields with built-in label/error
  • FormparentWrap in Form for server-side error distribution
  • FieldsetsiblingUse Fieldset to group related fields

Next steps