Component Variants
Component variants allows you to change all aspects of a form component based on the state of the rest of the form.
While rules allows you to show and hide different component based on the form state, variants lets you customize everything.
Here's a simple example where we make the form component required or not, depending on the form state:
- Code
- Example
import * as React from "react";
import {
textAreaField,
booleanField,
exists,
createForm,
StatefulFormView,
} from "@fab4m/fab4m";
const form = createForm({
likeBio: booleanField({ label: "Do you like to talk about yourself?" }),
bio: [
// This variant is defined like a rule. If the rule is true,
// then the variant is activated.
[
"likeBio",
exists(),
textAreaField({
label: "You have to write your bio now!",
required: true,
}),
],
// You can also provide a component without a rule. If you reach this point,
// then the component will be rendered.
textAreaField({ label: "Biography" }),
],
});
export default function RequiredWhenPresent() {
return <StatefulFormView form={form} hideSubmit={true} />;
}
Variant selection
A variant array is evaluated in order, and the first variant where the rule passes is selected. If you provide a component without a rule, it will always be selected.
- Code
- Example
import * as React from "react";
import {
booleanField,
textField,
equals,
content,
createForm,
StatefulFormView,
selectWidget,
} from "@fab4m/fab4m";
const form = createForm({
city: textField({
label: "Select your city",
widget: selectWidget(["London", "Paris", "New york"]),
}),
attractions: [
// This variant is defined like a rule. If the rule is true,
// then the variant is activated.
[
"city",
equals("Paris"),
booleanField({
label: "I visited the eiffel tower",
required: true,
}),
],
[
"city",
equals("London"),
booleanField({
label: "I visited Buckinghamn palace",
required: true,
}),
],
[
"city",
equals("New york"),
booleanField({
label: "I visited the statue of liberty",
required: true,
}),
],
content(
{},
() => "Select a city to tell us if you visited a popular attraction!"
),
],
});
export default function VariantSelection() {
return <StatefulFormView form={form} hideSubmit={true} />;
}
A note about variants and JSON Schema
When you use variants, you need to provide the data you want to validate when you generate your JSON Schema, for example:
- Code
- Example
import * as React from "react";
import * as beautify from "json-beautify";
import {
textField,
equals,
createForm,
StatefulFormView,
selectWidget,
group,
generateSchema,
} from "@fab4m/fab4m";
import { Schema } from "ajv";
const form = createForm({
transport: textField({
label: "How do you get to work?",
required: true,
widget: selectWidget(["Car", "Public transport"]),
}),
questions: [
[
"transport",
equals("Car"),
group(
{ label: "Questions" },
{
car: textField({
label: "What type of car do you have?",
required: true,
}),
},
),
],
[
"transport",
equals("Public transport"),
group(
{ label: "Questions" },
{
publicTransport: textField({
label: "What type of public transport do you use?",
required: true,
}),
},
),
],
],
});
export default function VariantSchema() {
const [schema, changeSchema] = React.useState<string | Schema>(
generateSchema(form),
);
form.onDataChange((data) => {
changeSchema(generateSchema(form, data));
});
return (
<div>
<StatefulFormView form={form} hideSubmit={true} />
<h4>Here's the schema:</h4>
<pre>{beautify.default(schema, null, 2, 80)}</pre>
</div>
);
}