Installation
Usage
The usage consists of the following steps:
- Define Zod schema for form validation
- Use the
useFormhook provided by Pure UI or Conform - Use
Formcomponent - Utilize
*Fieldcomponents or manually handle form fields - Use Conform’s
parseWithZodin the server action
useForm
The useForm hook is a React hook that integrates Zod schema validation with form handling using the Conform library.
It’s designed for use with RSC, specifically leveraging useActionState. It accepts a Zod schema, an optional submission result, and an action. The hook ensures validation happens on blur and revalidation occurs on input, preventing the default form reset behavior while keeping the last submission result in sync.
Essentially, it's a wrapper around the Conform useForm hook, which removes some boilerplate and provides a more convenient API and sensible defaults. You can use Conform hook instead if you prefer.
The hook returns a tuple containing form and fields metadata that you can use to enhance a HTML form by using Form and *Field components with the provided metadata.
Form
Uses Conform’s getFormProps and sets all props required to make a form element accessible. To function properly, pass the form metadata returned by useForm hook as the validate prop.
Form Fields
To enhance the developer experience, additional form field components are provided that wrap inputs, adding styling, error messages, labels, and Conform’s meta binding.
To ensure proper functionality, pass the appropriate field from the fields metadata returned by the useForm hook as the validate prop.
Checkbox Field
| Prop | Type | Default |
|---|---|---|
size | enum | "default" |
radius | enum | ― |
invalid | boolean | ― |
reduceMotion | boolean | false |
validate | FieldMetadata<string | boolean | undefined> | ― |
label | ReactNode | string | ― |
Input Field
| Prop | Type | Default |
|---|---|---|
type | enum | "text" |
size | enum | "default" |
radius | enum | ― |
invalid | boolean | ― |
reduceMotion | boolean | false |
validate | FieldMetadata<string | boolean | undefined> | ― |
label | ReactNode | string | ― |
Textarea Field
| Prop | Type | Default |
|---|---|---|
size | enum | "default" |
radius | enum | ― |
invalid | boolean | ― |
reduceMotion | boolean | false |
minRows | number | 2 |
maxRows | number | ― |
resize | enum | ― |
validate | FieldMetadata<string | boolean | undefined> | ― |
label | ReactNode | string | ― |
Radio Group Field
| Prop | Type | Default |
|---|---|---|
size | enum | "default" |
invalid | boolean | ― |
reduceMotion | boolean | false |
options* | RadioOption[] | ― |
validate | FieldMetadata<string | boolean | undefined> | ― |
label | ReactNode | string | ― |
Select Field
| Prop | Type | Default |
|---|---|---|
options* | OptionDataProps[] | ― |
groupedOptions* | GroupedOptionDataProps[] | ― |
size | enum | "default" |
radius | enum | ― |
reduceMotion | boolean | false |
indicator | ReactNode | ― |
animation | AnimationProps | ― |
animationPreset | enum | ― |
transition | Transition | ― |
transitionPreset | enumTransitionPreset | ― |
placeholder | ReactNode | ― |
icon | ReactNode | ― |
invalid | boolean | ― |
validate | FieldMetadata<string | boolean | undefined> | ― |
label | ReactNode | string | ― |
Switch Field
| Prop | Type | Default |
|---|---|---|
size | enum | "default" |
invalid | boolean | ― |
elastic | boolean | ― |
reduceMotion | boolean | false |
validate | FieldMetadata<string | boolean | undefined> | ― |
label | ReactNode | string | ― |
Custom Field
You’re not limited to using only *Field components. If you need more control over component rendering, you can use any input component with validation:
Native Inputs
You can even use native HTML inputs:
Conform Wrappers
If you don’t need Label, FormField, or error messages, you can use form inputs wrapped with Conform directly.
CheckboxConform
| Prop | Type | Default |
|---|---|---|
size | enum | "default" |
radius | enum | ― |
invalid | boolean | ― |
reduceMotion | boolean | false |
validate | FieldMetadata<string | boolean | undefined> | ― |
InputConform
| Prop | Type | Default |
|---|---|---|
type | enum | "text" |
size | enum | "default" |
radius | enum | ― |
invalid | boolean | ― |
reduceMotion | boolean | false |
validate | FieldMetadata<string | boolean | undefined> | ― |
RadioGroupConform
| Prop | Type | Default |
|---|---|---|
size | enum | "default" |
invalid | boolean | ― |
reduceMotion | boolean | false |
options* | RadioOption[] | ― |
validate | FieldMetadata<string | boolean | undefined> | ― |
SelectConform
| Prop | Type | Default |
|---|---|---|
options* | OptionDataProps[] | ― |
groupedOptions* | GroupedOptionDataProps[] | ― |
size | enum | "default" |
radius | enum | ― |
reduceMotion | boolean | false |
indicator | ReactNode | ― |
animation | AnimationProps | ― |
animationPreset | enum | ― |
transition | Transition | ― |
transitionPreset | enumTransitionPreset | ― |
placeholder | ReactNode | ― |
icon | ReactNode | ― |
invalid | boolean | ― |
validate | FieldMetadata<string | boolean | undefined> | ― |
SwitchConform
| Prop | Type | Default |
|---|---|---|
size | enum | "default" |
invalid | boolean | ― |
elastic | boolean | ― |
reduceMotion | boolean | false |
validate | FieldMetadata<string | boolean | undefined> | ― |
TextareaConform
| Prop | Type | Default |
|---|---|---|
size | enum | "default" |
radius | enum | ― |
invalid | boolean | ― |
reduceMotion | boolean | false |
minRows | number | 2 |
maxRows | number | ― |
resize | enum | ― |
validate | FieldMetadata<string | boolean | undefined> | ― |
API Reference
Form
| Prop | Type | Default |
|---|---|---|
validate* | FormMetadata<input<T>, string[]> | ― |
invalidAnimation | enum | ― |
FormFieldSet
| Prop | Type | Default |
|---|---|---|
legend | ReactNode | string | ― |
messages | string[] | ― |
size | enum | "default" |
FormField
| Prop | Type | Default |
|---|---|---|
messages | string[] | ― |
size | enum | "default" |
FormFieldMessages
| Prop | Type | Default |
|---|---|---|
messages | string[] | ― |
size | enum | "default" |