Checkbox and Radio Group

Conform provides a set of conform helper to configure each form control. For example, you can use the collection helper to setup a checkbox or radio group.

Radio Group

Setting up a radio group is no different from other inputs. You just need to pass the list of options to the helper and each option will be set as the value of the input. The helper will also derive the defaultChecked property and manage the id and aria attributes for you.

1import { conform, useForm } from '@conform-to/react';
2import { parse } from '@conform-to/zod';
3import { z } from 'zod';
4
5const schema = z.object({
6  color: z.string(),
7});
8
9function Example() {
10  const [form, { color }] = useForm({
11    onValidate({ formData }) {
12      return parse(formData, { schema });
13    },
14  });
15
16  return (
17    <form {...form.props}>
18      <fieldset>
19        <legend>Please select your favorite color</legend>
20        {conform
21          .collection(color, {
22            type: 'radio',
23            options: ['red', 'green', 'blue'],
24          })
25          .map((props, index) => (
26            <div key={index}>
27              <label>{props.value}</label>
28              <input {...props} />
29            </div>
30          ))}
31        <div>{color.error}</div>
32      </fieldset>
33      <button>Submit</button>
34    </form>
35  );
36}
37

Checkbox

Setting up a checkbox group would be similar to a radio group except the type is set to checkbox.

1import { conform, useForm } from '@conform-to/react';
2import { parse } from '@conform-to/zod';
3import { z } from 'zod';
4
5const schema = z.object({
6  answer: z
7    .string()
8    .array()
9    .nonEmpty('At least one answer is required'),
10});
11
12function Example() {
13  const [form, { answer }] = useForm({
14    onValidate({ formData }) {
15      return parse(formData, { schema });
16    },
17  });
18
19  return (
20    <form {...form.props}>
21      <fieldset>
22        <legend>Please select the correct answers</legend>
23        {conform
24          .collection(answer, {
25            type: 'checkbox',
26            options: ['a', 'b', 'c', 'd'],
27          })
28          .map((props, index) => (
29            <div key={index}>
30              <label>{props.value}</label>
31              <input {...props} />
32            </div>
33          ))}
34        <div>{answer.error}</div>
35      </fieldset>
36      <button>Submit</button>
37    </form>
38  );
39}
40

However, if you are using checkbox as a boolean, you can use the input helper instead.

1import { conform, useForm } from '@conform-to/react';
2import { parse } from '@conform-to/zod';
3import { z } from 'zod';
4
5const schema = z.object({
6  acceptTerms: z.boolean({
7    required_error: 'You must accept the terms and conditions',
8  }),
9  subscribeNewsletter: z.boolean().optional(),
10});
11
12function Example() {
13  const [form, { acceptTerms, subscribeNewsletter }] = useForm({
14    onValidate({ formData }) {
15      return parse(formData, { schema });
16    },
17  });
18
19  return (
20    <form {...form.props}>
21      <div>
22        <label>Terms and conditions</label>
23        <input {...conform.input(acceptTerms, { type: 'checkbox' })} />
24        <div>{acceptTerms.error}</div>
25      </div>
26      <div>
27        <label>Subscribe Newsletter</label>
28        <input {...conform.input(subscribeNewsletter, { type: 'checkbox' })} />
29        <div>{subscribeNewsletter.error}</div>
30      </div>
31      <button>Submit</button>
32    </form>
33  );
34}
35