Flow elements
Module
Learn how the module element is used in the flow.
Usage
The module element includes a nested flow that can be defined outside the main flow if needed.
TSX
type Schema = {
render: React.ReactNode;
struct: [
s.Module<{
render: React.ReactNode;
struct: [s.Form<{ name: string; softwareDeveloper: string }>];
inputs: Record<never, never>;
values: Record<never, never>;
params: Record<never, never>;
}>,
s.Module<{
render: React.ReactNode;
struct: [
s.Condition<{
then: [
s.Form<{ expertise: string }>,
s.Return<{
name: string;
softwareDeveloper: true;
expertise: string;
}>,
];
else: [
s.Form<{ interested: string }>,
s.Return<{
name: string;
softwareDeveloper: false;
interested: string;
}>,
];
}>,
];
inputs: Record<never, never>;
values: { name: string; softwareDeveloper: string };
params: Record<never, never>;
}>,
];
inputs: Record<never, never>;
params: Record<never, never>;
};
const flow: Flow<Schema> = [
{
module: [
{
form: {
fields: () => ({ name: ["", []], softwareDeveloper: ["", []] }),
render: ({ fields, next }) => (
<AboutMeForm fields={fields} onNext={next} />
),
},
},
],
},
{
module: [
{
condition: {
if: ({ softwareDeveloper }) => softwareDeveloper === "yes",
then: [
{
form: {
fields: () => ({ expertise: ["", []] }),
render: ({ fields, back, next }) => (
<ExpertiseForm fields={fields} onBack={back} onNext={next} />
),
},
},
{
return: ({ name, expertise }) => ({
name,
softwareDeveloper: true,
expertise,
}),
},
],
else: [
{
form: {
fields: () => ({ interested: ["", []] }),
render: ({ fields, back, next }) => (
<InterestedForm fields={fields} onBack={back} onNext={next} />
),
},
},
{
return: ({ name, interested }) => ({
name,
softwareDeveloper: false,
interested,
}),
},
],
},
},
],
},
];
Each module schema must be compatible with the parent flow:
rendermust match the flow'srender.inputsmust be a subset of the flow'sinputs.valuesmust be a subset of the flow's values at that point.paramsmust be a subset of the flow'sparams.
Separate files
Modules are most useful when defined in separate files, which keeps the flow clean and allows reuse.
modules/about-me.tsx:
TSX
import type { Module, s } from "@formity/react";
export type Schema = {
render: React.ReactNode;
struct: [s.Form<{ name: string; softwareDeveloper: string }>];
inputs: Record<never, never>;
values: Record<never, never>;
params: Record<never, never>;
};
export const module: Module<Schema> = [
{
form: {
fields: () => ({ name: ["", []], softwareDeveloper: ["", []] }),
render: ({ fields, back, next }) => (
<AboutMeForm fields={fields} onBack={back} onNext={next} />
),
},
},
];
modules/condition.tsx:
TSX
import type { Module, s } from "@formity/react";
export type Schema = {
render: React.ReactNode;
struct: [
s.Condition<{
then: [
s.Form<{ expertise: string }>,
s.Return<{
name: string;
softwareDeveloper: true;
expertise: string;
}>,
];
else: [
s.Form<{ interested: string }>,
s.Return<{
name: string;
softwareDeveloper: false;
interested: string;
}>,
];
}>,
];
inputs: Record<never, never>;
values: { name: string; softwareDeveloper: string };
params: Record<never, never>;
};
export const module: Module<Schema> = [
{
condition: {
if: ({ softwareDeveloper }) => softwareDeveloper === "yes",
then: [
{
form: {
fields: () => ({ expertise: ["", []] }),
render: ({ fields, back, next }) => (
<ExpertiseForm fields={fields} onBack={back} onNext={next} />
),
},
},
{
return: ({ name, expertise }) => ({
name,
softwareDeveloper: true,
expertise,
}),
},
],
else: [
{
form: {
fields: () => ({ interested: ["", []] }),
render: ({ fields, back, next }) => (
<InterestedForm fields={fields} onBack={back} onNext={next} />
),
},
},
{
return: ({ name, interested }) => ({
name,
softwareDeveloper: false,
interested,
}),
},
],
},
},
];
Then import and use them in the flow.
TSX
import * as aboutMe from "./modules/about-me";
import * as condition from "./modules/condition";
type Schema = {
render: React.ReactNode;
struct: [s.Module<aboutMe.Schema>, s.Module<condition.Schema>];
inputs: Record<never, never>;
params: Record<never, never>;
};
const flow: Flow<Schema> = [
{ module: aboutMe.module },
{ module: condition.module },
];