Docs
Dynamic Form

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).