

<Tabs items="[&#x22;Preview&#x22;, &#x22;Code&#x22;]">
  <Tab value="Preview">
    <Preview name="SingleLogicShowcaseExample" />
  </Tab>

  <Tab value="Code">
    ```tsx
    "use client";

    import { z } from "zod";
    import { FormBuilder } from "@tilt-legal/cubitt-components/composites";

    const schema = z.object({
      mode: z.enum(["basic", "advanced"]),
      name: z.string().min(1, "Required"),
      email: z.string().email().optional(),
      notes: z.string().optional(),
      accept: z.boolean().default(false),
    });

    type FormValues = z.infer<typeof schema>;

    const formDefs = [
      {
        kind: "group",
        title: "Settings",
        children: [
          {
            kind: "field",
            name: "mode",
            label: "Mode",
            component: "radio",
            size: "full",
            options: [
              { id: "basic", value: "basic", label: "Basic" },
              { id: "advanced", value: "advanced", label: "Advanced" },
            ],
          },
        ],
      },
      {
        kind: "group",
        title: "Details",
        children: [
          {
            kind: "field",
            name: "name",
            label: "Name",
            component: "text",
            size: "half",
            requiredIf: () => true,
          },
          {
            kind: "field",
            name: "email",
            label: "Email",
            component: "email",
            size: "half",
            showIf: (v: FormValues) => v.mode === "advanced",
            requiredIf: (v: FormValues) => v.mode === "advanced",
          },
          {
            kind: "field",
            name: "notes",
            label: "Notes",
            component: "textarea",
            size: "full",
            readOnlyIf: (v: FormValues) => v.mode === "basic",
            disabledIf: (v: FormValues) => v.mode === "basic",
          },
        ],
      },
      {
        kind: "group",
        title: "Confirm",
        children: [
          {
            kind: "field",
            name: "accept",
            label: "I confirm the above is accurate",
            component: "checkbox",
            size: "full",
          },
        ],
      },
    ] as const satisfies FormDefs<FormValues>;

    export default function LogicForm() {
      return (
        <FormBuilder.Single
          schema={schema}
          formDefs={formDefs}
          defaultValues={{
            mode: "basic",
            name: "",
            email: "",
            notes: "",
            accept: false,
          }}
          submitLabel="Continue"
          onSubmit={async (values) => console.log(values)}
        />
      );
    }
    ```
  </Tab>
</Tabs>

## How It Works [#how-it-works]

All predicate functions receive the current form values and return a boolean:

```tsx
showIf: (values) => values.mode === "advanced";
```

In this example:

* **`showIf`** – Email field only appears in Advanced mode
* **`disabledIf` + `readOnlyIf`** – Notes field is locked in Basic mode
* **`requiredIf`** – Email becomes required only in Advanced mode

Toggle the Mode radio to see the conditional behaviour in action.

<Callout type="info">
  See [Conditional
  Predicates](/composites/form-builder/form-defs#conditional-predicates) for all
  available predicates.
</Callout>
