Prodular UI

Inputs

FormPro

Forms on React Hook Form and Zod: fields wired to labels and errors, conditional fields, an error summary, server errors per field, and autosave with a status line.

npx prodular-ui add form

Part of Prodular UI Pro. Preview and read the docs freely, install with a license. See pricing

Billing details

Submit it empty to see the error summary. VAT shows for EU countries, PO and terms for invoices. DE000000000 comes back as a server error on its field.

Invoices and receipts go here.

Shown for EU countries. Try DE000000000 to see a server error.

Autosave

Valid changes save after a pause in typing, with no button. Invalid ones wait. Turn on the network failure to see the retry.

Profile

Changes save automatically

Shown on your approvals and comments.

Anatomy

const form = useAppForm(schema, { defaultValues })
<Form form={form} onSubmit={save}>  <FormErrorSummary />  <FormField name="email" label="Billing email">    {(field) => <Input {...field} type="email" />}  </FormField>  <FormWhen name="payment" is="invoice">    <FormField name="po" label="PO number">{(field) => <Input {...field} />}</FormField>  </FormWhen>  <FormSubmit /></Form>

Guidance

Use it when

  • Any form with more than two fields, validation or server errors: settings, billing, onboarding, create and edit dialogs.
  • autosave for settings pages where every field stands on its own; a submit button where changes only make sense together.

Avoid

  • One field edited in place. Use Inline edit.
  • Autosave on forms that start something irreversible, like payments or invites. Submit those.

Rules for AI agents

Published in llms-full.txt and the registry, so coding agents follow them when they build with this component.

  • Define the schema with Zod and create the form with useAppForm(schema, { defaultValues }). Give every field a default value.
  • Put fields that depend on another field in a z.discriminatedUnion and show them with FormWhen, so hidden fields are never validated.
  • Render each control through FormField: spread field onto Input and Textarea; for Select, Switch, Number input and other value APIs map value and onChange by hand, and pass field.ref so the error summary can focus it.
  • Return { errors: { field: message } } from onSubmit for server validation and { formError } for anything else. Do not show toasts for field errors.
  • Put FormErrorSummary at the top of long forms and FormSubmit at the end. Write error messages that say how to fix the value.

API

useAppForm

PropTypeDefaultDescription
(schema, { defaultValues, mode })UseFormReturn<T>React Hook Form with a Zod resolver. mode defaults to onTouched.

Form

PropTypeDefaultDescription
formUseFormReturn<T>The form from useAppForm.
onSubmit(values) => void | { errors?, formError? }Runs with valid values. Return errors to show them on fields or for the whole form.
autosave{ onSave(values), delay? }Saves valid changes after delay ms (800). Throw to show a retry.

FormField

PropTypeDefaultDescription
name / label / descriptionpath / ReactNode / ReactNodeThe field's path in the values and its copy. The error replaces the description.
children(field, state) => ReactNodeRenders the control. field has value, onChange, onBlur, ref, name and aria-invalid.

FormWhen

PropTypeDefaultDescription
name / is / whenpath / value or values / (value) => booleanShows its children while the watched field matches.

FormErrorSummary

PropTypeDefaultDescription
titlestring"Fix these to continue"Listed after a failed submit. Each item focuses its field.

FormStatus

PropTypeDefaultDescription
--Autosave state: saving, saved at a time, what to fix, or retry.

FormSubmit

PropTypeDefaultDescription
...propsButton propsSubmit button with loading while onSubmit runs.