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) => string | undefined — formats RHF messages via TranslationContext.formatMessage.
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 i18n keys (e.g. ui-forms.schema.email.required); override via *Message options. useFormLocalizedErrors / field wrappers format keys at render. 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