Toggle Field

Switch Group

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

View as Markdown
stable
switchgroupmultipletoggle

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

Prop Type Default Description
type 'switch-group' - Field type (required)
label string - Group label
helperText string - Help text below field
options Option[] - Array of switch options
value string[] [] Default selected values
optionsClassName string - CSS classes for options container
columns Partial<Record<Breakpoint, number>> - Grid columns by breakpoint
disabled boolean | function | ConditionGroup false Disable all switches
hidden boolean | function | ConditionGroup | Responsive false Hide 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 Group Use Checkbox Group
Settings pages Form selections
Prominent toggles Compact lists
On/off states Yes/no choices
Immediate feedback Submit 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