Form
Form provides a small, validator-neutral composition layer for existing Typlog controls. It connects labels, descriptions, and errors to a control, while preserving native controls and browser constraint validation behavior. Valid submissions emit submit after field validation; FormRoot prevents the browser's default navigation so the application can handle the result.
It does not manage nested values, field arrays, or schema state. Validation can come from the browser, a field callback, a server response, or an external schema library such as Zod.
Examples
Validation
Native validation
Native constraints such as required and type continue to work. Invalid events update the field state, associate the message with the control, and focus the first invalid field when submission is blocked.
Server errors
Pass an error map to FormRoot, keyed by each FieldRoot name. New input clears the matching visible error; a later server response can provide a new error map. Form-level errors remain application-owned.
Zod
Run schema validation in application code, normalize issues into the controlled error map, and use the parsed output on success. Zod is used only by this example and is not a runtime dependency of @typlog/ui.
Controls
Use FieldControl with native elements or compose it through as-child with TextField, TextArea, Select, Combobox, Checkbox, Radio Group, Switch, and Pin Input. Compound controls keep their existing submission behavior.
API Reference
Form
FormRoot
The form container. It coordinates field validation, controlled errors, submission, reset, and focus movement after an invalid submission. It prevents the browser's default submit navigation and emits submit only when every registered field is valid.
It accepts native <form> attributes and events. Use errors to provide a controlled error map keyed by field name; native attributes are omitted here.
Field
FieldRoot
Provides the field name, generated IDs, validation state, and shared context for the remaining field parts. Use validate for a validator-neutral synchronous or asynchronous field callback.
FieldLabel
Labels the field control using the generated or explicit control ID.
FieldControl
Applies the field's ID, name, required and disabled state, and ARIA attributes to a native element or an existing component through as-child.
FieldDescription
Provides persistent supporting text for the control. It remains visible when an error is present because descriptions and errors serve different purposes.
FieldError
Renders the current native, field-validator, or controlled error messages. The part is omitted when the field has no visible errors.
Behavior
Error lifecycle
Errors become visible after native invalid events, field validation, or a controlled error update. New input immediately clears the field's visible local, native, and controlled error state. Blur or the next submission validates the field again.
FieldDescription remains visible alongside FieldError. Both IDs are included in aria-describedby while they are rendered.
Reset
Native form.reset() restores native control defaults and clears field touched, dirty, validity, and local error state.
Accessibility
Generated IDs associate labels, descriptions, and visible errors with the field control. Pass an explicit id to FieldControl when an application needs a stable ID. Invalid controls receive aria-invalid="true", and keyboard focus moves to the first invalid control after a blocked submission.