Form schema
Yield
Learn how the yield element is used in the schema.
Usage
The yield element is used to yield values when navigating between steps. When values are yielded the onYield
callback of the Formity
component will be called.
To understand how it is used let's look at this example.
import type { Schema, Form, Return, Yield } from "@formity/react";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import {
Step,
Layout,
Row,
TextField,
NumberField,
YesNo,
NextButton,
BackButton,
} from "./components";
import { MultiStep } from "./multi-step";
export type Values = [
Form<{ name: string; surname: string; age: number }>,
Yield<{
next: [{ name: string; surname: string; age: number }];
back: [];
}>,
Form<{ softwareDeveloper: boolean }>,
Yield<{
next: [{ softwareDeveloper: boolean }];
back: [];
}>,
Return<{
name: string;
surname: string;
age: number;
softwareDeveloper: boolean;
}>,
];
export const schema: Schema<Values> = [
{
form: {
values: () => ({
name: ["", []],
surname: ["", []],
age: [20, []],
}),
render: ({ values, onNext, onBack }) => (
<MultiStep onNext={onNext} onBack={onBack}>
<Step
key="main"
defaultValues={values}
resolver={zodResolver(
z.object({
name: z
.string()
.min(1, { message: "Required" })
.max(20, { message: "Must be at most 20 characters" }),
surname: z
.string()
.min(1, { message: "Required" })
.max(20, { message: "Must be at most 20 characters" }),
age: z
.number()
.min(18, { message: "Minimum of 18 years old" })
.max(99, { message: "Maximum of 99 years old" }),
}),
)}
>
<Layout
heading="Tell us about yourself"
description="We would want to know about you"
fields={[
<Row
key="nameSurname"
items={[
<TextField key="name" name="name" label="Name" />,
<TextField key="surname" name="surname" label="Surname" />,
]}
/>,
<NumberField key="age" name="age" label="Age" />,
]}
button={<NextButton>Next</NextButton>}
/>
</Step>
</MultiStep>
),
},
},
{
yield: {
next: ({ name, surname, age }) => [{ name, surname, age }],
back: () => [],
},
},
{
form: {
values: () => ({
softwareDeveloper: [true, []],
}),
render: ({ values, onNext, onBack }) => (
<MultiStep onNext={onNext} onBack={onBack}>
<Step
key="softwareDeveloper"
defaultValues={values}
resolver={zodResolver(
z.object({
softwareDeveloper: z.boolean(),
}),
)}
>
<Layout
heading="Are you a software developer?"
description="We would like to know if you are a software developer"
fields={[
<YesNo
key="softwareDeveloper"
name="softwareDeveloper"
label="Software Developer"
/>,
]}
button={<NextButton>Next</NextButton>}
back={<BackButton />}
/>
</Step>
</MultiStep>
),
},
},
{
yield: {
next: ({ softwareDeveloper }) => [{ softwareDeveloper }],
back: () => [],
},
},
{
return: ({ name, surname, age, softwareDeveloper }) => ({
name,
surname,
age,
softwareDeveloper,
}),
},
];
We need to use the Yield
type and define the types of the values to be yielded when navigating to the next and previous steps.
export type Values = [
// ...
Yield<{
next: [{ name: string; surname: string; age: number }];
back: [];
}>,
// ...
Yield<{
next: [{ softwareDeveloper: boolean }];
back: [];
}>,
// ...
];
Then, in the schema we need to create an object with the following structure.
export const schema: Schema<Values> = [
// ...
{
yield: {
next: ({ name, surname, age }) => [{ name, surname, age }],
back: () => [],
},
},
// ...
{
yield: {
next: ({ softwareDeveloper }) => [{ softwareDeveloper }],
back: () => [],
},
},
// ...
];
The next
function takes the input values and returns an array with the values to be yielded. Each array element will trigger the onYield
callback function.
The back
function works the same way with the difference that the values will be yielded when navigating to the previous steps.