Capítulo 18 de 43
A form primitive built directly on the native browser Constraint Validation API, wiring label/control/error-message association and accessible announcement automatically, with support for both client-side and server-side validation.
Root → Field (name-scoped) → Label + Control + Message + ValidityState, plus top-level Message/Submit.Message's match prop: matches against the native ValidityState keys (e.g. "valueMissing", "typeMismatch") or a custom sync/async function (value, formData) => boolean.data-invalid/data-valid: automatically applied to Field/Label/Control for validity-based styling, no manual state tracking.Field's serverInvalid prop plus Message's forceMatch let you reuse client-defined messages for server errors; Root's onClearServerErrors clears them on resubmit/reset.ValidityState render prop: exposes the raw native validity object when you need custom logic beyond what Message covers (e.g. driving a third-party input component's visual state).<Form.Field name="email" serverInvalid={serverErrors.email}>
<Form.Label>Email address</Form.Label>
<Form.Control type="email" required />
<Form.Message match="valueMissing">Please enter your email.</Form.Message>
<Form.Message match="typeMismatch" forceMatch={serverErrors.email}>
Please provide a valid email.
</Form.Message>
</Form.Field>
valueMissing) plus one message reused for both client (typeMismatch) and server (forceMatch={serverErrors.email}) validation on the same field.| Part | Key props |
|---|---|
Field | name*, serverInvalid |
Message | match (ValidityState key or function), forceMatch, name (required if used outside Field) |
Root | onClearServerErrors |
Form.Control directly with other Radix form primitives (Checkbox, Select): not supported as of this doc — those need separate wiring, not asChild composition with Form.Control.Form.Message match="valueMissing" renders a sensible built-in message — pass children only when you need custom copy or i18n.Message/match pair for both client and server validation via forceMatch instead of maintaining two separate error-rendering paths.Form.Control — treat as a known limitation, not a bug in your integration.