Dynamic form
Fields are added (mounted) and removed (unmounted) as the checkboxes above
the form are toggled. Internally it uses the Form's conditionalFields —
one predicate per field receives the current values and decides whether the
field renders.
When the predicate turns false, the Form unmounts the field. When it
turns true, it mounts again (react-hook-form keeps the previous value
unless you called resetField).
Demo
Check/uncheck the checkboxes to see fields appear/disappear.
Code
import { useState } from 'react';
import { Form } from '@apollion-dsi/core/form/form';
import { Input } from '@apollion-dsi/core/form/input';
import { InputMask } from '@apollion-dsi/core/form/input-mask';
import { TextArea } from '@apollion-dsi/core/form/text-area';
import { Checkbox } from '@apollion-dsi/core/form/checkbox';
import { Flex } from '@apollion-dsi/core/containers/flex';
import { z } from 'zod';
const FormDynamic = () => {
const [enabledFields, setEnabledFields] = useState({ phone: false, address: false, bio: false });
const toggleField = (key) => setEnabledFields((p) => ({ ...p, [key]: !p[key] }));
const fields = {
name: {
label: 'Name',
component: Input,
validation: z.string().min(1, 'Required'),
inputProps: { clearable: true },
},
email: {
label: 'E-mail',
component: Input,
validation: z.email('Not a valid email'),
inputProps: { type: 'email', clearable: true },
},
phone: {
label: 'Phone',
component: InputMask,
validation: z.string().min(1, 'Required'),
inputProps: { mask: '(00) 0 0000-0000', clearable: true },
},
address: {
label: 'Address',
component: Input,
validation: z.string().min(1, 'Required'),
inputProps: { clearable: true },
},
bio: { label: 'Bio', component: TextArea, validation: z.string().max(280), inputProps: { maxLength: 280 } },
};
return (
<Flex gap="medium">
<Flex flexDirection="row" gap="medium">
<Checkbox checked={enabledFields.phone} onChange={() => toggleField('phone')} text="Phone" />
<Checkbox checked={enabledFields.address} onChange={() => toggleField('address')} text="Address" />
<Checkbox checked={enabledFields.bio} onChange={() => toggleField('bio')} text="Bio" />
</Flex>
<Form
fields={fields}
conditionalFields={{
phone: () => enabledFields.phone,
address: () => enabledFields.address,
bio: () => enabledFields.bio,
}}
handleSubmit={(values) => console.log(values)}
/>
</Flex>
);
};See also
- Form — full form with every field type.
- Basic form — minimal version (name + e-mail only).