<Form />
Form is the first item in the array returned by setupForm.
Form is used throughout this documentation, but since setupForm() returns an array, you can name it anything.
Form bound to field mapping
When a Form is created, it is bound to a specific field mapping. This mapping defines which field types are available and how they are rendered.
By default, BlueForm provides a set of built-in structural field types (inline, section, array, hidden). Calling setupForm() with no arguments creates a form system that only includes these built-in types.
To extend the form with custom fields while keeping all built-in ones available, use defineMapping:
Any unknown field type will be caught at compile time.
Form bound to a data model
Form is generic. Field keys must match the data model, and onSubmit always receives fully typed data.
Form props
config
The field configuration object that defines the structure of the form. Each key maps to one field entry, including its type, label, rules, render behavior, and any extra props.
See Field config below.
onSubmit
Called when the form is submitted and passes validation. Receives the typed form data, the full React Hook Form methods, and the optional submit event:
Use this for submit-time effects such as API calls, persistence, navigation, or analytics. If you need to derive field values while the user is typing, use onFieldChange instead.
onSubmitSuccess
Called after onSubmit resolves successfully. Receives the same arguments as onSubmit.
This is a good place for post-submit side effects such as reset(), toast notifications, or closing a dialog after a successful save.
onSubmitError
Called when submission fails due to validation errors. Receives the RHF errors object.
Use this when you need to react to invalid submission attempts, for example by scrolling to the first error or showing a summary banner.
defaultValues
Initial values for the form. These are passed into RHF useForm and always take precedence over formOptions.defaultValues.
Use this for initial edit-state data, server-provided defaults, or sensible empty-state values.
formOptions
Options passed to RHF useForm for this specific form instance. These merge over formOptions defined in setupForm and per-form values always win.
Common use cases:
resolverfor schema validationmodeto override the default validation triggershouldUnregisterto control hidden or unmounted field retention
Use formOptions when you want BlueForm to keep handling rendering and field wiring, but still need lower-level RHF behavior control.
readOnly
When true, all fields in the form receive readOnly: true.
This is a form-level hint for your field components. BlueForm passes the flag down, but each renderer is still responsible for deciding how read-only mode should look and behave.
onFormChange
Called whenever any field value changes. Receives the current full form values and the full RHF form methods.
This is most useful for autosave, external state sync, analytics, or debugging. Because it fires on every change, consider combining it with debounceMs for anything non-trivial.
onFieldChange
Called when a single field value changes. Receives a typed context object plus the full RHF form methods:
The first argument contains:
Derived fields and side effects like title -> slug can be handled with this API, but use it carefully once many fields start depending on each other - update loops can shoot you in the foot.
debounceMs
Delay in milliseconds before onFormChange and onFieldChange fire. Useful for debouncing side effects such as autosave, remote lookups, or expensive synchronization work. Set to 0 or omit to disable.
This affects the change hooks only. It does not change how RHF validation itself works.
renderRoot
Controls the outer form shell, usually the <form> element and any wrappers around it.
Can be provided per-form to override the value set in setupForm.
If neither setupForm nor the <Form /> instance provides renderRoot, an error will be thrown at run time.
i18nConfig
Controls how labels, descriptions, and validation messages are translated.
Can be provided per-form to override the value set in setupForm.
The only option that cannot be overridden is fieldMapping - it is fixed at setup time to preserve compile-time type safety.
Form accepts children
children accepts either a ReactNode or a render function that receives form methods - useful when rendering dynamic UI that depends on form state. It is rendered after the config-driven content, so it usually appears at the end of the form. Both the generated fields and this children content are passed together as the children of renderRoot.
The render function receives the same curated set of form methods as renderRoot - see renderRoot for the full list.
Field config
Each entry in config describes a single field. All fields share a common set of options:
visible and disabled can also be functions. In that case they receive the current form values and are evaluated reactively on every change:
For the full runtime behavior - including hidden-from-start fields, defaultValue, and shouldUnregister - see conditional rendering.
rules uses standard React Hook Form validation rules. These are automatically disabled when formOptions.resolver is provided, so schema-driven forms should keep validation in the resolver instead.

