Prepared Docs

Prepared Docs

⌘K

    Loading navigation…

User

  1. Blocks
  2. Forms
  3. API and Development

Forms

API and Development

View Source
Submit Issue

@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.

Import

Architecture

Hooks

useZodForm

useForm preconfigured with zodResolver(schema) and default mode: "onBlur". Infers values from z.infer<S>.

NameDefaultDescription
schemarequiredZod schema for parsing and field validation.
options—Same as useForm except resolver (always set from schema).

useFormLocalizedErrors

Returns (err?: FieldError) => string | undefined — formats RHF messages via TranslationContext.formatMessage.

useDebouncedFieldSubmit

Watches one field, debounces (default 500 ms), calls onSubmit with the new value. Returns { isSaving, error, clearError }.

NameDefaultDescription
formrequiredUseFormReturn instance.
namerequiredField path to watch.
onSubmitrequiredAsync save handler.
debounceMs500Debounce interval.

useStableHtmlId

Stable DOM id from React useId (strips :), optional prefix.

useModalOpenSync

Syncs @prepared911/ui-core modal open state to a boolean open prop. Requires ModalProvider.

Form

Low-level FormProvider + native <form> with handleSubmit.

NameDefaultDescription
formrequiredUseFormReturn from useZodForm or useForm.
onValidrequiredSubmit handler when validation succeeds.
onInvalid—Handler when validation fails.
childrenrequiredFields; descendants may use useFormContext.
id—Root <form> id.
className—Root class names.
noValidatetrueDisables native browser validation ahead of RHF.

StandardForm

Form with Save/Cancel footer. Submit disabled when pristine or submitting.

NameDefaultDescription
formrequiredRHF instance.
onSubmitrequiredValid submit handler.
intentFormActionIntent.DefaultDefault or Destructive primary button styling.
onCancel—When set, renders Cancel button.
submitLabellocalized "Save"Primary button label.
cancelLabellocalized "Cancel"Cancel button label.
isSubmittingform.formState.isSubmittingDisables actions while true.
footerdefault footerCustom footer or "hidden".
className—Root class names.
childrenrequiredField content.

SectionedForm and FormSection

StandardForm with accordion-grouped sections. FormSection derives status dots from field errors unless state is overridden.

SectionedForm props

Inherits StandardFormProps plus:

NameDefaultDescription
typeAccordionType.SingleAccordion behavior for sections.
defaultOpen—Initially open section id(s).

FormSection props

NameDefaultDescription
idrequiredAccordion item value and DOM id.
titlerequiredHeader label beside status dot.
description—Helper copy below header.
fieldsrequiredField paths for automatic error status.
statederivedOverride SectionStatus (Default, Error, Complete).
childrenrequiredFields inside the panel.

ModalForm

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).

NameDefaultDescription
openrequiredControlled visibility.
handleCloserequiredClose callback from local state or registry hide.
formrequiredRHF instance.
onSubmitrequiredValid submit handler; awaited before close.
headingrequiredModal title.
confirmLabellocalized "Save"Primary action label.
cancelLabellocalized "Cancel"Cancel label.
confirmDisabled—Additional confirm disable beyond isSubmitting.
intentFormActionIntent.DefaultDefault or Destructive primary styling.
childrenrequiredForm fields.

DrawerForm

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.

NameDefaultDescription
openrequiredControlled drawer visibility.
onOpenChangerequiredOpen/close callback.
formrequiredRHF instance.
onSubmitrequiredValid submit handler; resets with submitted values then closes.
headingrequiredDrawer title.
confirmLabellocalized "Save"Primary action label.
cancelLabellocalized "Cancel"Cancel label.
width—CSS width for the panel.
intentFormActionIntent.DefaultDefault or Destructive primary styling.
childrenrequiredForm fields.

UnsavedChangesModal

Exported for reuse; DrawerForm owns the usual instance. Heading + Keep editing / Discard actions only (empty ModalContent). Requires ui-core ModalProvider.

NameDefaultDescription
modalIdrequiredStable id for useModalOpenSync / Modal.
openrequiredControlled visibility.
onDiscardrequiredDiscard edits and complete close.
onKeepEditingrequiredDismiss modal and return to the drawer.

Modal context

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.

ExportDescription
ModalContextProviderRenders registered modals; wraps trees that call useModal.
useModal(Component, options?)Returns { show, hide, registryId }. Must run under the provider.
ModalConfigOptionsregistryId?, onShow?, onHide?, defaultProps?.
MODAL_REGISTRY_ID_PREFIXPrefix for auto-generated registry ids (ui-forms-modal).
RequiredModalPropsopen + handleClose required on registered modal components (e.g. ModalForm).

SettingsSection and SettingsRow

Grouped settings with debounced per-row autosave. Wrap in Form + useZodForm — SettingsRow requires form context.

SettingsSection props

NameDefaultDescription
titlerequiredSection heading.
description—Supporting copy.
childrenrequiredSettingsRow elements.

SettingsRow props

NameDefaultDescription
namerequiredRegistered field path.
labelrequiredPrimary label.
description—Helper under label.
tooltip—Info icon tooltip.
controlrequiredSettingsControlType (Switch, Checkbox, Input, Select, Segmented).
onSave—Persists value; rolls back on reject.
debounceMs500Debounce before onSave.
selectItems[]Options when control is Select.
selectLabel""Accessible label for the select trigger.
segmentedItems[]Options when control is Segmented.

FormActionIntent

ValueUse when
FormActionIntent.DefaultStandard save/create commits.
FormActionIntent.DestructiveDelete, revoke, or irreversible commits.

Field wrappers

All single-field wrappers extend FormControlProps<T, N>:

NameDefaultDescription
namerequiredRegistered field path.
controlnearest FormProviderOptional 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 map

Wrapperui-core primitiveNotes
FormInputInputSupports masked + maskType.
FormEmailInputInputEmail mask preset.
FormPhoneInputInputE.164 phone mask.
FormZipCodeInputInputUS zip mask.
FormCurrencyInputInputCurrency mask.
FormUrlInputInputURL mask.
FormDateInputInputDate mask.
FormSecretSecretPassword-style input.
FormInputWithSelectInputWithSelectDual paths: inputName, selectName.
FormTextAreaTextAreaerror + errorMessage props.
FormCheckboxCheckboxFormHelperText for errors.
FormRadioGroupRadioGroup
FormSwitchSwitch
FormSliderSlider
FormRangeSliderRangeSlider
FormSelectSelect
FormComboboxComboboxAlways multi-select (string[]).
FormCheckboxCardGroupCheckboxCardGroupstring[] value.
FormSegmentedControlSegmentedControl
FormToggleGroupToggleGroupRoot
FormRadioCardGroupRadioCardGroup
FormIconToggleIconToggleClick toggles boolean.
FormFileUploadFileUploadAreaFile array value.

FormInput

Masked inputs

Use typed wrappers with matching schema builders.

FormSelect

FormCheckbox and FormSwitch

FormCombobox

Forces multi-select; value is string[].

FormField and FormHelperText

Use FormField for custom renderers; FormHelperText for standalone error/helper copy below controls without built-in helper slots.

Zod schema builders

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.

BuilderOptionsValidates
emailSchemarequired, requiredMessage, invalidMessageTrimmed email.
phoneSchemarequired, requiredMessage, invalidMessage, allowExtensionE.164 (+ optional *extension).
zipCodeSchemarequired, requiredMessage, invalidMessage, requirePlusFourUS ZIP (##### or #####-####).
currencySchemarequired, requiredMessage, invalidMessage, min, maxCurrency amount string.
urlSchemarequired, requiredMessage, invalidMessage, requireHttpsURL.
dateSchemarequired, requiredMessage, invalidMessage, min, maxMM/dd/yyyy display string; bounds compared by UTC calendar date.

Form* vs manual register

ApproachWhen
FormInput + useZodFormDefault for all new Prepared forms.
register + raw InputLegacy only; migrate call sites incrementally.
FormField custom childrenOne-off controls without a Form* wrapper yet.

Related packages

  • @prepared911/ui-core — primitives and ModalProvider.
  • @prepared911/ui-drawer — DrawerForm panel and DrawerPortal.
  • @prepared911/tool-localization — TranslationProvider for localized labels and Zod messages.

Previous

Forms / Usage

Next

Forms / Accessibility

On this page

Import
Architecture
Hooks
useZodForm
useFormLocalizedErrors
useDebouncedFieldSubmit
useStableHtmlId
useModalOpenSync
Form
StandardForm
SectionedForm and FormSection
SectionedForm props
FormSection props
ModalForm
DrawerForm
UnsavedChangesModal
Modal context
SettingsSection and SettingsRow
SettingsSection props
SettingsRow props
FormActionIntent
Field wrappers
Wrapper map
FormInput
Masked inputs
FormSelect
FormCheckbox and FormSwitch
FormCombobox
FormField and FormHelperText
Zod schema builders
Form* vs manual register
Related packages