Components / Forms

Field

Field is the form-field orchestrator. It generates a stable id, derives the help and error ids from it, and broadcasts them — plus the invalid, disabled, and required state — to every control inside through context.

Loading playground…
Updated 3 days agoEdit on GitHubWeb & native

What it is

A <Box> that renders a context provider. The provider carries a fieldId, a helpId, an errorId, and the three state flags. Child primitives — Label, Input, FieldHelp, FieldError — subscribe through useFieldContext and wire their own attributes from it.

Install

Field is exported from usemotif. No separate install.

example.tsx
import { Field } from 'usemotif';

Anatomy

A Field holds a Label, a control, and optionally help and error text. Order is up to you — the wiring is id-based, not position-based.

example.tsx
<Field>
<Label>…</Label>
<Input />
<FieldHelp>…</FieldHelp>
<FieldError>…</FieldError>
</Field>

API

Field

stable
function Field(props: FieldProps): JSX.Element
invalidboolean= false

Marks the field invalid. The control inside picks up `aria-invalid`; the error text becomes the announced description.

disabledboolean= false

Disables the field. The control inside renders disabled and greys out.

requiredboolean= false

Marks the field required. The Label renders a required marker; the control picks up `aria-required`.

idstring

Explicit field id. When omitted, Field generates a stable one with React's `useId`.

…BoxPropsBoxProps

Every prop Box accepts. Field lays its children out as a flex column with a small gap.

State flows to the children

The three state flags are defaults the children read, not locks. Set invalid on the Field and the Input inside picks up aria-invalid — but an Input can still pass its own invalid prop to override the inherited value. The Field value wins only when the child does not specify its own.

Accessibility

Field is the reason the form is accessible — it generates the id graph, but it asserts nothing on its own. The contract is split across the children:

  • Label resolves htmlFor to the field id, so clicking the label focuses the control.
  • The control claims the field id and an aria-describedby list pointing at the help and error ids.
  • FieldError carries role="alert", so a newly shown error is announced.

Field's responsibility is to generate consistent ids; the children's responsibility is to consume them. Keep the Label, the control, and any help or error text inside the same Field.

Examples

A field with help text:

example.tsx
<Field>
<Label>Display name</Label>
<Input />
<FieldHelp>Shown on your public profile.</FieldHelp>
</Field>

An invalid, required field:

example.tsx
<Field invalid required>
<Label>Email</Label>
<Input type="email" />
<FieldError>Enter a valid email address.</FieldError>
</Field>