Form schema
Form
Learn how the Form element is used in the schema.
Usage
The Form element is used to define a form in the multi-step form.
To understand how it is used let's look at this example:
import type { Schema, Form, Return } from "@formity/react";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import { FormView, FormLayout, TextField, Next } from "./components";
import { Controller } from "./controller";
export type Values = [
Form<{ name: string; surname: string }>,
Return<{ name: string; surname: string }>,
];
export const schema: Schema<Values> = [
{
form: {
values: () => ({
name: ["", []],
surname: ["", []],
}),
render: ({ values, onNext, onBack, getState, setState }) => (
<Controller
step="name-surname"
onNext={onNext}
onBack={onBack}
getState={getState}
setState={setState}
>
<FormView
defaultValues={values}
resolver={zodResolver(
z.object({
name: z.string(),
surname: z.string(),
}),
)}
>
<FormLayout
heading="What is your name?"
description="We would like to know what is your name"
fields={[
<TextField key="name" name="name" label="Name" />,
<TextField key="surname" name="surname" label="Surname" />,
]}
button={<Next>Next</Next>}
/>
</FormView>
</Controller>
),
},
},
{
return: ({ name, surname }) => ({
name,
surname,
}),
},
];
We need to use the Form
type and define the types of the values of the form:
export type Values = [
Form<{ name: string; surname: string }>,
// ...
];
Then, in the schema we need to create an object with the following structure:
export const schema: Schema<Values> = [
{
form: {
values: () => ({
name: ["", []],
surname: ["", []],
}),
render: ({ values, onNext, onBack, getState, setState }) => (
<Controller
step="name-surname"
onNext={onNext}
onBack={onBack}
getState={getState}
setState={setState}
>
<FormView
defaultValues={values}
resolver={zodResolver(
z.object({
name: z.string(),
surname: z.string(),
}),
)}
>
<FormLayout
heading="What is your name?"
description="We would like to know what is your name"
fields={[
<TextField key="name" name="name" label="Name" />,
<TextField key="surname" name="surname" label="Surname" />,
]}
button={<Next>Next</Next>}
/>
</FormView>
</Controller>
),
},
},
// ...
];
The values
function is used to define the values of the form. It takes the values generated in the previous steps, and returns an object where each property corresponds to a form value. Each property is a tuple containing two elements, the first is the default value, and the second is an array of strings or numbers.
export const schema: Schema<Values> = [
{
form: {
values: () => ({
name: ["", []],
surname: ["", []],
}),
// ...
},
},
// ...
];
When the user navigates between steps and returns to the same one, if the array remains unchanged, the default value will be the value previously entered. This feature is particularly useful when working with loops in the form.
The render
function is used to render the form, and it takes as argument an object with the following properties:
inputs
: Values generated in the previous steps.values
: Default values of the form.params
: Values that are passed in theparams
prop ofFormity
.onNext
: Function used to navigate to the next step. It receives the current values of the form as argument.onBack
: Function used to navigate to the previous step. It receives the current values of the form as argument.getState
: Function used to get the current state of the multi-step form. It receives the current values of the form as argument.setState
: Function used to set the current state of the multi-step form. It receives an object of typeState
as argument.
export const schema: Schema<Values> = [
{
form: {
// ...
render: ({ values, onNext, onBack, getState, setState }) => (
<Controller
step="name-surname"
onNext={onNext}
onBack={onBack}
getState={getState}
setState={setState}
>
<FormView
defaultValues={values}
resolver={zodResolver(
z.object({
name: z.string(),
surname: z.string(),
}),
)}
>
<FormLayout
heading="What is your name?"
description="We would like to know what is your name"
fields={[
<TextField key="name" name="name" label="Name" />,
<TextField key="surname" name="surname" label="Surname" />,
]}
button={<Next>Next</Next>}
/>
</FormView>
</Controller>
),
},
},
// ...
];
A key
prop must be defined for each form to ensure the form's state updates correctly when navigating between steps. In this example, the Controller
component manages the key
prop internally, using the value from the step
prop.