S
Toggle Field

Switch

A toggle switch for boolean values with a more prominent visual than checkbox.

stable
switch toggle boolean on-off

Interactive demo of switch field

Receive push notifications about updates

Use dark theme throughout the app

Help us improve by sending anonymous usage data

Required to use this service

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

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

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

const config = FormBuilder.create('switch-demo')
  .layout('manual')
  .columns(12)
  .addField('notifications', (f) =>
    f
      .type('switch')
      .label('Enable notifications')
      .helperText('Receive push notifications about updates')
      .optional()
      .columns({ default: 12 }),
  )
  .addField('darkMode', (f) =>
    f
      .type('switch')
      .label('Dark mode')
      .helperText('Use dark theme throughout the app')
      .value(true)
      .optional()
      .columns({ default: 12 }),
  )
  .addField('analytics', (f) =>
    f
      .type('switch')
      .label('Analytics')
      .helperText('Help us improve by sending anonymous usage data')
      .optional()
      .columns({ default: 12 }),
  )
  .addField('consent', (f) =>
    f
      .type('switch')
      .label('I consent to data processing')
      .helperText('Required to use this service')
      .required()
      .mustBeTrue('You must consent to continue')
      .columns({ default: 12 }),
  )
  .addStep('main', ['notifications', 'darkMode', 'analytics', 'consent'])
  .build();

export default function SwitchDemo() {
  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 field is a toggle control for boolean values. It’s more visually prominent than a checkbox and is commonly used for settings, preferences, and on/off states.

Usage

Basic Switch

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

const config = FormBuilder.create('settings')
  .addField('notifications', (f) =>
    f
      .type('switch')
      .label('Enable notifications')
      .helperText('Receive push notifications')
      .optional(),
  )
  .addStep('main', ['notifications'])
  .build();

Default On

.addField('darkMode', (f) =>
  f.type('switch')
    .label('Dark Mode')
    .value(true)
    .optional()
)

With Description

.addField('analytics', (f) =>
  f.type('switch')
    .label('Analytics')
    .helperText('Help us improve by sending anonymous usage data. We never collect personal information.')
    .optional()
)

JSON Configuration

{
  "type": "switch",
  "label": "Enable notifications",
  "helperText": "Receive push notifications",
  "value": false,
  "schema": { "required": false }
}

Props

PropTypeDefaultDescription
type'switch'-Field type (required)
labelstring-Label shown next to switch
helperTextstring-Description text
valuebooleanfalseInitial value
size'sm' | 'md' | 'lg''md'Switch size variant
columnsPartial<Record<Breakpoint, number>>-Grid columns by breakpoint
disabledboolean | function | ConditionGroupfalseDisable the switch
hiddenboolean | function | ConditionGroup | ResponsivefalseHide the field

Validation

Optional (default)

.addField('marketing', (f) =>
  f.type('switch')
    .label('Marketing emails')
    .optional()
)

Required to be On

.addField('consent', (f) =>
  f.type('switch')
    .label('I consent to data processing')
    .required()
    .mustBeTrue('You must consent to continue')
)

Conditional Logic

Show switch based on another field

.addField('advancedSettings', (f) =>
  f.type('switch')
    .label('Show advanced options')
    .hidden((values) => !values.isPowerUser)
)

Disable based on condition

.addField('autoSave', (f) =>
  f.type('switch')
    .label('Auto-save')
    .disabled((values) => values.offlineMode === true)
)

Styling

Custom Classes

.addField('notifications', (f) =>
  f.type('switch')
    .label('Enable notifications')
    .optional()
    .classNames({
      wrapper: 'flex items-center justify-between p-4 border rounded-lg',
      input: 'data-[state=checked]:bg-primary',
      label: 'font-medium',
      helper: 'text-muted-foreground text-sm',
    })
)

Responsive Layout

.addField('darkMode', (f) =>
  f.type('switch')
    .label('Dark Mode')
    .optional()
    .columns({ default: 12, md: 6 })
)

JSON Styling

{
  "type": "switch",
  "label": "Enable notifications",
  "wrapper_className": "flex items-center justify-between p-4 border rounded-lg",
  "label_className": "font-medium",
  "columns": { "default": 12, "md": 6 }
}

Switch vs Checkbox

Use SwitchUse Checkbox
Settings/preferencesForms and agreements
Immediate effectSubmit with form
On/off statesYes/no questions
More prominentLess prominent

Accessibility

  • Uses Radix UI Switch for accessibility
  • Supports keyboard activation (Space)
  • Proper labeling via label prop
  • Focus visible states
  • Screen reader announcements for state changes