HomeDocsComponentsBlocksForm contractValidation
Validation / Two modes

Batteries included, removable

Drop a field in with no form library and it validates itself. Put it in one and it gets out of the way.

Standalone

// No schema, no resolver, no onBlur handler, no useState for the error.
// The field renders its own message, once, after the first blur.
<CurrencyInput label="Budget" required positive max={100000} currency="GBP" />

Managed

// aria-invalid is supplied, so the field detects managed mode and renders
// no message of its own. Your <FormMessage> is the only one on screen.
<Controller
  name="budget"
  control={control}
  render={({ field, fieldState }) => (
    <CurrencyInput label="Budget" {...field} aria-invalid={fieldState.invalid} />
  )}
/>

How the mode is chosen

SIGNALRESULTNOTE
mode prop suppliedThat modeEscape hatch; rarely needed
aria-invalid suppliedManagedYour form library is already deciding
aria-describedby suppliedManagedSomething else owns the description
react-hook-form contextManagedDetected from the form context
none of the aboveStandaloneThe field owns its own error