API and Development
@prepared911/ui-forms exports form shells, Form* field wrappers, hooks, and Zod schema builders. Every field routes through FormField (Controller) and maps RHF state to @prepared911/ui-core primitives. Consumers define their own Zod schemas; the package wires validation, localization, and layout.
useForm preconfigured with zodResolver(schema) and default mode: "onBlur". Infers values from z.infer<S>.
| Name | Default | Description |
|---|---|---|
schema | required | Zod schema for parsing and field validation. |
options | — | Same as useForm except resolver (always set from schema). |
Returns (err?: FieldError) => LocalizedMessage | undefined. Known ui-forms.schema.* keys (from the schema builders) are resolved through useTranslation(). Any other message is shown as given, so translate your own schema messages with formatMessage where the schema is built.
Watches one field, debounces (default 500 ms), calls onSubmit with the new value. Returns { isSaving, error, clearError }.
| Name | Default | Description |
|---|---|---|
form | required | UseFormReturn instance. |
name | required | Field path to watch. |
onSubmit | required | Async save handler. |
debounceMs | 500 | Debounce interval. |
Stable DOM id from React useId (strips :), optional prefix.
Syncs @prepared911/ui-core modal open state to a boolean open prop. Requires ModalProvider.
Low-level FormProvider + native <form> with handleSubmit.
| Name | Default | Description |
|---|---|---|
form | required | UseFormReturn from useZodForm or useForm. |
onValid | required | Submit handler when validation succeeds. |
onInvalid | — | Handler when validation fails. |
children | required | Fields; descendants may use useFormContext. |
id | — | Root <form> id. |
className | — | Root class names. |
noValidate | true | Disables native browser validation ahead of RHF. |
Form with Save/Cancel footer. Submit disabled when pristine or submitting.
| Name | Default | Description |
|---|---|---|
form | required | RHF instance. |
onSubmit | required | Valid submit handler. |
intent | FormActionIntent.Default | Default or Destructive primary button styling. |
onCancel | — | When set, renders Cancel button. |
submitLabel | localized "Save" | Primary button label. |
cancelLabel | localized "Cancel" | Cancel button label. |
isSubmitting | form.formState.isSubmitting | Disables actions while true. |
footer | default footer | Custom footer or "hidden". |
className | — | Root class names. |
children | required | Field content. |
StandardForm with accordion-grouped sections. FormSection derives status dots from field errors unless state is overridden.
Inherits StandardFormProps plus:
| Name | Default | Description |
|---|---|---|
type | AccordionType.Single | Accordion behavior for sections. |
defaultOpen | — | Initially open section id(s). |
| Name | Default | Description |
|---|---|---|
id | required | Accordion item value and DOM id. |
title | required | Header label beside status dot. |
description | — | Helper copy below header. |
fields | required | Field paths for automatic error status. |
state | derived | Override SectionStatus (Default, Error, Complete). |
children | required | Fields inside the panel. |
Modal with embedded Form; closes after successful submit. Requires ModalProvider and ModalPortal from @prepared911/ui-core. Uses noDismiss — Escape and outside click do not close; only Cancel or a successful submit does. Confirm is not gated on isDirty (unlike StandardForm / DrawerForm).
| Name | Default | Description |
|---|---|---|
open | required | Controlled visibility. |
handleClose | required | Close callback from local state or registry hide. |
form | required | RHF instance. |
onSubmit | required | Valid submit handler; awaited before close. |
heading | required | Modal title. |
confirmLabel | localized "Save" | Primary action label. |
cancelLabel | localized "Cancel" | Cancel label. |
confirmDisabled | — | Additional confirm disable beyond isSubmitting. |
intent | FormActionIntent.Default | Default or Destructive primary styling. |
children | required | Form fields. |
Side drawer with Form, unsaved-change guard, and Save/Cancel footer. Pair with DrawerPortal from @prepared911/ui-drawer. Also requires ui-core ModalProvider / ModalPortal because discard confirmation uses UnsavedChangesModal. Save disables when !form.formState.isDirty or while submitting; close while dirty opens the unsaved-changes modal.
| Name | Default | Description |
|---|---|---|
open | required | Controlled drawer visibility. |
onOpenChange | required | Open/close callback. |
form | required | RHF instance. |
onSubmit | required | Valid submit handler; resets with submitted values then closes. |
heading | required | Drawer title. |
confirmLabel | localized "Save" | Primary action label. |
cancelLabel | localized "Cancel" | Cancel label. |
width | — | CSS width for the panel. |
intent | FormActionIntent.Default | Default or Destructive primary styling. |
children | required | Form fields. |
Exported for reuse; DrawerForm owns the usual instance. Heading + Keep editing / Discard actions only (empty ModalContent). Requires ui-core ModalProvider.
| Name | Default | Description |
|---|---|---|
modalId | required | Stable id for useModalOpenSync / Modal. |
open | required | Controlled visibility. |
onDiscard | required | Discard edits and complete close. |
onKeepEditing | required | Dismiss modal and return to the drawer. |
Register modal components for imperative show / hide. Alias: ModalFormContextProvider === ModalContextProvider. This is separate from ui-core's useModal() (open / close / isOpen), which useModalOpenSync uses internally.
| Export | Description |
|---|---|
ModalContextProvider | Renders registered modals; wraps trees that call useModal. |
useModal(Component, options?) | Returns { show, hide, registryId }. Must run under the provider. |
ModalConfigOptions | registryId?, onShow?, onHide?, defaultProps?. |
MODAL_REGISTRY_ID_PREFIX | Prefix for auto-generated registry ids (ui-forms-modal). |
RequiredModalProps | open + handleClose required on registered modal components (e.g. ModalForm). |
Grouped settings with debounced per-row autosave. Wrap in Form + useZodForm — SettingsRow requires form context.
| Name | Default | Description |
|---|---|---|
title | required | Section heading. |
description | — | Supporting copy. |
children | required | SettingsRow elements. |
| Name | Default | Description |
|---|---|---|
name | required | Registered field path. |
label | required | Primary label. |
description | — | Helper under label. |
tooltip | — | Info icon tooltip. |
control | required | SettingsControlType (Switch, Checkbox, Input, Select, Segmented). |
onSave | — | Persists value; rolls back on reject. |
debounceMs | 500 | Debounce before onSave. |
selectItems | [] | Options when control is Select. |
selectLabel | "" | Accessible label for the select trigger. |
segmentedItems | [] | Options when control is Segmented. |
| Value | Use when |
|---|---|
FormActionIntent.Default | Standard save/create commits. |
FormActionIntent.Destructive | Delete, revoke, or irreversible commits. |
All single-field wrappers extend FormControlProps<T, N>:
| Name | Default | Description |
|---|---|---|
name | required | Registered field path. |
control | nearest FormProvider | Optional explicit Control. |
defaultValue | — | Initial value when form has none. |
Each wrapper omits RHF-controlled props from the underlying ui-core component (value, onChange, name, ref, etc.) and forwards the rest.
| Wrapper | ui-core primitive | Notes |
|---|---|---|
FormInput | Input | Supports masked + maskType. |
FormEmailInput | Input | Email mask preset. |
FormPhoneInput | Input | E.164 phone mask. |
FormZipCodeInput | Input | US zip mask. |
FormCurrencyInput | Input | Currency mask. |
FormUrlInput | Input | URL mask. |
FormDateInput | Input | Date mask. |
FormSecret | Secret | Password-style input. |
FormInputWithSelect | InputWithSelect | Dual paths: inputName, selectName. |
FormTextArea | TextArea | error + errorMessage props. |
FormCheckbox | Checkbox | FormHelperText for errors. |
FormRadioGroup | RadioGroup | |
FormSwitch | Switch | |
FormSlider | Slider | |
FormRangeSlider | RangeSlider | |
FormSelect | Select | |
FormCombobox | Combobox | Always multi-select (string[]). |
FormCheckboxCardGroup | CheckboxCardGroup | string[] value. |
FormSegmentedControl | SegmentedControl | |
FormToggleGroup | ToggleGroupRoot | |
FormRadioCardGroup | RadioCardGroup | |
FormIconToggle | IconToggle | Click toggles boolean. |
FormFileUpload | FileUploadArea | File array value. |
Use typed wrappers with matching schema builders.
Forces multi-select; value is string[].
Use FormField for custom renderers; FormHelperText for standalone error/helper copy below controls without built-in helper slots.
Exported builders return default ui-forms.schema.* keys (e.g. ui-forms.schema.email.required); override via *Message options. useFormLocalizedErrors / field wrappers resolve those ui-forms.schema.* keys at render, to an English default even with no translations loaded. Any other message is shown as given, so pass already-translated text to *Message options. Values are .trim()'d; whitespace-only becomes empty.
| Builder | Options | Validates |
|---|---|---|
emailSchema | required, requiredMessage, invalidMessage | Trimmed email. |
phoneSchema | required, requiredMessage, invalidMessage, allowExtension | E.164 (+ optional *extension). |
zipCodeSchema | required, requiredMessage, invalidMessage, requirePlusFour | US ZIP (##### or #####-####). |
currencySchema | required, requiredMessage, invalidMessage, min, max | Currency amount string. |
urlSchema | required, requiredMessage, invalidMessage, requireHttps | URL. |
dateSchema | required, requiredMessage, invalidMessage, min, max | MM/dd/yyyy display string; bounds compared by UTC calendar date. |
| Approach | When |
|---|---|
FormInput + useZodForm | Default for all new Prepared forms. |
register + raw Input | Legacy only; migrate call sites incrementally. |
FormField custom children | One-off controls without a Form* wrapper yet. |
@prepared911/ui-core — primitives and ModalProvider.@prepared911/ui-drawer — DrawerForm panel and DrawerPortal.@prepared911/tool-localization — TranslationProvider for localized labels and Zod messages.On this page