S
Toggle Field

Checkbox Group

Multiple selection from a list of options using checkboxes.

stable
checkbox group multiple selection

Interactive demo of checkbox group field

Choose all that apply

Select 1-3 features

/**
 * Checkbox Group Field Demo - Interactive examples of checkbox group fields
 */

import { Form, FormBuilder } from '@saastro/forms';

import { FormProvider } from '@/components/FormProvider';
import { TooltipProvider } from '@/components/ui/tooltip';

const config = FormBuilder.create('checkbox-group-demo')
  .layout('manual')
  .columns(12)
  .addField('interests', (f) =>
    f
      .type('checkbox-group')
      .label('Select your interests')
      .helperText('Choose all that apply')
      .options([
        { label: 'Technology', value: 'tech' },
        { label: 'Design', value: 'design' },
        { label: 'Business', value: 'business' },
        { label: 'Marketing', value: 'marketing' },
        { label: 'Science', value: 'science' },
      ])
      .required('Please select at least one interest')
      .columns({ default: 12, md: 6 }),
  )
  .addField('features', (f) =>
    f
      .type('checkbox-group')
      .label('Features to enable')
      .helperText('Select 1-3 features')
      .options([
        { label: 'Dark Mode', value: 'dark-mode' },
        { label: 'Notifications', value: 'notifications' },
        { label: 'Auto-save', value: 'auto-save' },
        { label: 'Analytics', value: 'analytics' },
      ])
      .value(['dark-mode'])
      .required()
      .itemCount(1, 3)
      .columns({ default: 12, md: 6 }),
  )
  .addField('days', (f) =>
    f
      .type('checkbox-group')
      .label('Available days')
      .options([
        { label: 'Monday', value: 'mon' },
        { label: 'Tuesday', value: 'tue' },
        { label: 'Wednesday', value: 'wed' },
        { label: 'Thursday', value: 'thu' },
        { label: 'Friday', value: 'fri' },
      ])
      .required('Select at least one day')
      .columns({ default: 12 }),
  )
  .addStep('main', ['interests', 'features', 'days'])
  .build();

export default function CheckboxGroupDemo() {
  const handleSubmit = (data: Record<string, unknown>) => {
    console.log('Form submitted:', data);
    alert('Form submitted! Check console for data.');
  };

  return (
    <TooltipProvider>
      <FormProvider>
        <Form config={config} onSubmit={handleSubmit} className="space-y-4" />
      </FormProvider>
    </TooltipProvider>
  );
}

Overview

The checkbox group field allows users to select multiple options from a list. Each option is rendered as a checkbox, and the field value is an array of selected values.

Usage

Basic Checkbox Group

import { FormBuilder } from '@saastro/forms';

const config = FormBuilder.create('preferences')
  .addField('interests', (f) =>
    f
      .type('checkbox-group')
      .label('Select your interests')
      .options([
        { label: 'Technology', value: 'tech' },
        { label: 'Design', value: 'design' },
        { label: 'Business', value: 'business' },
        { label: 'Marketing', value: 'marketing' },
      ])
      .required('Please select at least one interest'),
  )
  .addStep('main', ['interests'])
  .build();

With Default Values

.addField('features', (f) =>
  f.type('checkbox-group')
    .label('Select features')
    .options([
      { label: 'Dark Mode', value: 'dark-mode' },
      { label: 'Notifications', value: 'notifications' },
      { label: 'Auto-save', value: 'auto-save' },
      { label: 'Analytics', value: 'analytics' },
    ])
    .value(['dark-mode', 'auto-save'])
    .optional()
)

With Min/Max Selection

.addField('toppings', (f) =>
  f.type('checkbox-group')
    .label('Select toppings')
    .helperText('Choose 2 to 4 toppings')
    .options([
      { label: 'Pepperoni', value: 'pepperoni' },
      { label: 'Mushrooms', value: 'mushrooms' },
      { label: 'Onions', value: 'onions' },
      { label: 'Peppers', value: 'peppers' },
      { label: 'Olives', value: 'olives' },
    ])
    .required()
    .itemCount(2, 4)
)

JSON Configuration

{
  "type": "checkbox-group",
  "label": "Select your interests",
  "options": [
    { "label": "Technology", "value": "tech" },
    { "label": "Design", "value": "design" },
    { "label": "Business", "value": "business" }
  ],
  "value": ["tech"],
  "schema": {
    "required": true,
    "minItems": 1
  }
}

Props

PropTypeDefaultDescription
type'checkbox-group'-Field type (required)
labelstring-Group label
helperTextstring-Help text below field
optionsOption[]-Array of checkbox options
valuestring[][]Default selected values
optionsClassNamestring-CSS classes for options container grid
columnsPartial<Record<Breakpoint, number>>-Grid columns by breakpoint
disabledboolean | function | ConditionGroupfalseDisable all checkboxes
hiddenboolean | function | ConditionGroup | ResponsivefalseHide the field

Validation

At Least One Selection

.addField('categories', (f) =>
  f.type('checkbox-group')
    .label('Categories')
    .options([...])
    .required('Select at least one category')
)

Exact Number of Selections

.addField('top3', (f) =>
  f.type('checkbox-group')
    .label('Select your top 3')
    .options([...])
    .required()
    .itemCount(3, 3)
)

Range of Selections

.addField('skills', (f) =>
  f.type('checkbox-group')
    .label('Skills')
    .helperText('Select 2-5 skills')
    .options([...])
    .required()
    .itemCount(2, 5)
)

Conditional Logic

Show based on another field

.addField('addons', (f) =>
  f.type('checkbox-group')
    .label('Add-ons')
    .options([...])
    .hidden((values) => values.plan === 'free')
)

Styling

Custom Classes

.addField('interests', (f) =>
  f.type('checkbox-group')
    .label('Interests')
    .options([...])
    .required()
    .classNames({
      wrapper: 'bg-muted/30 p-4 rounded-lg',
      label: 'text-lg font-semibold mb-3',
      error: 'text-destructive text-sm mt-2',
    })
)

Options Layout with optionsClassName

Control how checkboxes are arranged:

// 2 columns on mobile, 3 on tablet, 4 on desktop
.addField('skills', (f) =>
  f.type('checkbox-group')
    .label('Skills')
    .options([...])
)
{
  "type": "checkbox-group",
  "label": "Skills",
  "optionsClassName": "grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-3",
  "options": [...]
}

Responsive Field Layout

.addField('features', (f) =>
  f.type('checkbox-group')
    .label('Features')
    .options([...])
    .columns({ default: 12, md: 6 })
)

JSON Styling

{
  "type": "checkbox-group",
  "label": "Interests",
  "wrapper_className": "bg-muted/30 p-4 rounded-lg",
  "label_className": "text-lg font-semibold",
  "optionsClassName": "grid grid-cols-2 gap-4",
  "columns": { "default": 12, "md": 6 }
}

Accessibility

  • Uses Radix UI Checkbox for each option
  • Proper group labeling with ARIA
  • Keyboard navigation between options
  • Focus visible states
  • Screen reader support