Skip to content

shadcn.io is an independent project built on shadcn/ui

Free

Form with Checkbox for React

Marketing, security, and terms checkboxes with descriptions. Terms must be checked, and security starts on.

Marketing emails starts off, security alerts starts on, and the terms box starts off. Terms must be checked, or the form shows You must accept the terms and conditions.

Use it for opt-ins that need a sentence of explanation. A single on or off setting is a Switch. In React, Base UI does not require the terms box. The schema does.

Preview

Preview width

Installation

Sign in to get your install command
Free with an account. It carries your token, so the CLI installs everything in one go.

Usage

<form className="w-full max-w-md" onSubmit={form.handleSubmit(onSubmit)}>
  <FieldGroup>
    {options.map((option) => (
      <Controller
        control={form.control}
        key={option.name}
        name={option.name}
        render={({ field, fieldState }) => (
          <Field invalid={fieldState.invalid} orientation="horizontal">
            <Checkbox
              checked={field.value}
              id={`form-with-checkbox-${option.name}`}
              name={field.name}
              onCheckedChange={field.onChange}
            />
            <FieldContent>
              <FieldLabel htmlFor={`form-with-checkbox-${option.name}`}>
                {option.label}
              </FieldLabel>
              <FieldDescription>{option.description}</FieldDescription>
              <FieldError>{fieldState.error?.message}</FieldError>
            </FieldContent>
          </Field>
        )}
      />
    ))}
    <Field orientation="horizontal">
      <Button type="submit">Submit</Button>
    </Field>
  </FieldGroup>
</form>

FAQ

How is the terms checkbox required?

terms is z.boolean().refine((value) => value, …) with the message "You must accept the terms and conditions." While the box is unchecked, submit fails, the row's Field gets invalid and its FieldError shows the message under the description.

Do the other two boxes have to be checked?

No. marketing and security are plain z.boolean(), so either value submits. Their FieldError stays empty.

Which boxes start checked?

defaultValues sets marketing to false, security to true and terms to false. Each Checkbox is controlled by its field's value: checked={field.value} and onCheckedChange={field.onChange}.

How is each row laid out?

The three rows come from one options array mapped to a Controller each. A row is Field orientation="horizontal" with the Checkbox, then FieldContent with the FieldLabel, the FieldDescription and the FieldError. The label's htmlFor matches the checkbox's id, such as form-with-checkbox-terms.

What do the three descriptions say?

Marketing emails: "Receive emails about new products and features." Security alerts: "Receive emails about account security." Terms: "You agree to our Terms of Service and Privacy Policy."

What does Submit do?

Submit is a type="submit" button. form.handleSubmit(onSubmit) runs the Zod schema and, once terms is checked, logs { marketing, security, terms } to the console. Replace onSubmit with your own request.

API Reference

Field

Sets invalid={fieldState.invalid}, orientation="horizontal", htmlFor, form-with-checkbox-, option and name. The rest is on the Field page.

Checkbox

Sets checked={field.value}, id, form-with-checkbox-, option, name and name={field.name}. The rest is on the Checkbox page.

Button

Sets type="submit". The rest is on the Button page.