S
Toggle Field

Switch Group

Multiple toggle switches for selecting multiple options with prominent visual feedback.

stable
switch group multiple toggle

Interactive demo of switch group field

Choose how you want to be notified

Enable experimental features

/**
 * Switch Group Field Demo - Interactive examples of switch group fields
 */

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

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

const config = FormBuilder.create('switch-group-demo')
  .layout('manual')
  .columns(12)
  .addField('notifications', (f) =>
    f
      .type('switch-group')
      .label('Notification Settings')
      .helperText('Choose how you want to be notified')
      .options([
        { label: 'Email notifications', value: 'email' },
        { label: 'Push notifications', value: 'push' },
        { label: 'SMS notifications', value: 'sms' },
      ])
      .value(['email'])
      .optional()
      .columns({ default: 12, md: 6 }),
  )
  .addField('privacy', (f) =>
    f
      .type('switch-group')
      .label('Privacy Settings')
      .options([
        { label: 'Public profile', value: 'public' },
        { label: 'Show online status', value: 'online' },
        { label: 'Allow messages from anyone', value: 'messages' },
      ])
      .value(['public'])
      .optional()
      .columns({ default: 12, md: 6 }),
  )
  .addField('features', (f) =>
    f
      .type('switch-group')
      .label('Feature Flags')
      .helperText('Enable experimental features')
      .options([
        { label: 'Beta features', value: 'beta' },
        { label: 'Developer mode', value: 'dev' },
        { label: 'Debug logging', value: 'debug' },
      ])
      .optional()
      .columns({ default: 12 }),
  )
  .addStep('main', ['notifications', 'privacy', 'features'])
  .build();

export default function SwitchGroupDemo() {
  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 switch group field displays multiple toggle switches, allowing users to select multiple options. It’s similar to checkbox group but with a more prominent, settings-like visual style.

Usage

Basic Switch Group

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

const config = FormBuilder.create('settings')
  .addField('notifications', (f) =>
    f
      .type('switch-group')
      .label('Notification Settings')
      .options([
        { label: 'Email notifications', value: 'email' },
        { label: 'Push notifications', value: 'push' },
        { label: 'SMS notifications', value: 'sms' },
      ])
      .optional(),
  )
  .addStep('main', ['notifications'])
  .build();

With Default Values

.addField('privacy', (f) =>
  f.type('switch-group')
    .label('Privacy Settings')
    .options([
      { label: 'Public profile', value: 'public' },
      { label: 'Show online status', value: 'online' },
      { label: 'Allow messages', value: 'messages' },
    ])
    .value(['public', 'messages'])
    .optional()
)

JSON Configuration

{
  "type": "switch-group",
  "label": "Notification Settings",
  "options": [
    { "label": "Email notifications", "value": "email" },
    { "label": "Push notifications", "value": "push" },
    { "label": "SMS notifications", "value": "sms" }
  ],
  "value": ["email"],
  "schema": { "required": false }
}

Props

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

Validation

At Least One Selection

.addField('channels', (f) =>
  f.type('switch-group')
    .label('Communication channels')
    .options([...])
    .required('Enable at least one channel')
)

Selection Range

.addField('features', (f) =>
  f.type('switch-group')
    .label('Features')
    .options([...])
    .required()
    .itemCount(1, 3)
)

Styling

Custom Classes

.addField('notifications', (f) =>
  f.type('switch-group')
    .label('Notifications')
    .options([...])
    .optional()
    .classNames({
      wrapper: 'bg-muted/30 p-4 rounded-lg',
      label: 'text-lg font-semibold mb-3',
      error: 'text-destructive text-sm',
    })
)

Options Layout with optionsClassName

{
  "type": "switch-group",
  "label": "Settings",
  "optionsClassName": "space-y-4",
  "options": [...]
}

Responsive Layout

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

JSON Styling

{
  "type": "switch-group",
  "label": "Notifications",
  "wrapper_className": "bg-muted/30 p-4 rounded-lg",
  "label_className": "text-lg font-semibold",
  "optionsClassName": "space-y-3",
  "columns": { "default": 12, "md": 6 }
}

Switch Group vs Checkbox Group

Use Switch GroupUse Checkbox Group
Settings pagesForm selections
Prominent togglesCompact lists
On/off statesYes/no choices
Immediate feedbackSubmit with form

Accessibility

  • Uses Radix UI Switch for each option
  • Proper group labeling with ARIA
  • Keyboard navigation (Tab between, Space to toggle)
  • Focus visible states