Skip to main content

Overview

The Switch component allows users to toggle between two states, typically on/off or enabled/disabled. It provides immediate visual feedback and is commonly used for settings and preferences.

Import

import { Switch } from '@naturacosmeticos/natds-react'

Basic Usage

import React, { useState } from 'react'
import { Switch } from '@naturacosmeticos/natds-react'

function App() {
  const [enabled, setEnabled] = useState(false)

  return (
    <Switch
      id="notifications"
      value="notifications"
      checked={enabled}
      onChange={(e) => setEnabled(e.target.checked)}
    />
  )
}

With Label

For better UX, pair switches with descriptive labels:
import React, { useState } from 'react'
import { Switch } from '@naturacosmeticos/natds-react'

function Settings() {
  const [notifications, setNotifications] = useState(true)

  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
      <Switch
        id="push-notifications"
        value="notifications"
        checked={notifications}
        onChange={(e) => setNotifications(e.target.checked)}
      />
      <label htmlFor="push-notifications">Enable push notifications</label>
    </div>
  )
}

States

On and Off

// Off state
<Switch
  id="switch-off"
  value="off"
  checked={false}
  onChange={handleChange}
/>

// On state
<Switch
  id="switch-on"
  value="on"
  checked={true}
  onChange={handleChange}
/>

Disabled

// Disabled Off
<Switch
  id="disabled-off"
  value="disabled-off"
  checked={false}
  disabled
  onChange={() => {}}
/>

// Disabled On
<Switch
  id="disabled-on"
  value="disabled-on"
  checked={true}
  disabled
  onChange={() => {}}
/>

Settings Panel Example

import React, { useState } from 'react'
import { Switch } from '@naturacosmeticos/natds-react'

function SettingsPanel() {
  const [settings, setSettings] = useState({
    notifications: true,
    darkMode: false,
    autoSave: true,
    soundEffects: false
  })

  const handleToggle = (key: keyof typeof settings) => {
    setSettings(prev => ({
      ...prev,
      [key]: !prev[key]
    }))
  }

  return (
    <div>
      <h2>Settings</h2>
      
      <div style={{ display: 'flex', justifyContent: 'space-between', padding: '12px 0' }}>
        <label htmlFor="notifications">Push Notifications</label>
        <Switch
          id="notifications"
          value="notifications"
          checked={settings.notifications}
          onChange={() => handleToggle('notifications')}
        />
      </div>

      <div style={{ display: 'flex', justifyContent: 'space-between', padding: '12px 0' }}>
        <label htmlFor="darkMode">Dark Mode</label>
        <Switch
          id="darkMode"
          value="darkMode"
          checked={settings.darkMode}
          onChange={() => handleToggle('darkMode')}
        />
      </div>

      <div style={{ display: 'flex', justifyContent: 'space-between', padding: '12px 0' }}>
        <label htmlFor="autoSave">Auto Save</label>
        <Switch
          id="autoSave"
          value="autoSave"
          checked={settings.autoSave}
          onChange={() => handleToggle('autoSave')}
        />
      </div>

      <div style={{ display: 'flex', justifyContent: 'space-between', padding: '12px 0' }}>
        <label htmlFor="soundEffects">Sound Effects</label>
        <Switch
          id="soundEffects"
          value="soundEffects"
          checked={settings.soundEffects}
          onChange={() => handleToggle('soundEffects')}
        />
      </div>
    </div>
  )
}

Props

id
string
default:"toggleSwitch"
Unique identifier for the switch element
value
string
required
The value attribute of the switch when submitting a form
onChange
React.ChangeEventHandler<HTMLInputElement>
required
Callback fired when the switch state changes
checked
boolean
default:"false"
If true, the switch is in the on position
disabled
boolean
default:"false"
If true, the switch is disabled and cannot be toggled
brand
BrandTypes
Brand theme to apply (avon, natura, theBodyShop, etc.)
className
string
Optional CSS class name for custom styling
testID
string
Optional ID for testing purposes
accessibilityLabel
AriaAttributes
ARIA attributes for the switch label element

Accessibility

Built-in Features

The Switch component provides:
  • Keyboard support (Space and Enter to toggle)
  • Focus indicators
  • ARIA role and state attributes
  • Mouse leave blur handling
  • Clear visual state indication

Best Practices

// Good: Descriptive label explaining what the switch controls
<div>
  <label htmlFor="wifi">Wi-Fi</label>
  <Switch
    id="wifi"
    value="wifi"
    checked={wifiEnabled}
    onChange={(e) => setWifiEnabled(e.target.checked)}
    accessibilityLabel={{
      'aria-label': 'Toggle Wi-Fi connection'
    }}
  />
</div>

// Good: Provide context for the switch state
<div>
  <label htmlFor="airplane">
    Airplane Mode {airplaneMode ? '(On)' : '(Off)'}
  </label>
  <Switch
    id="airplane"
    value="airplane"
    checked={airplaneMode}
    onChange={(e) => setAirplaneMode(e.target.checked)}
  />
</div>

Guidelines

  • Always pair switches with clear labels
  • Position labels consistently (typically left of switch)
  • Use switches for immediate changes (no submit button needed)
  • Provide visual feedback when state changes
  • Show the current state clearly
  • Disable switches when action is unavailable
  • Make touch targets at least 44x44px
  • Consider showing toast/notification for important state changes

Switch vs Checkbox

Use Switch when:
  • The change takes immediate effect
  • Toggling a system setting or preference
  • Controlling a single independent option
  • The action is clearly on/off
Use Checkbox when:
  • Part of a form requiring submission
  • Multiple selections from a list
  • Agreement/consent scenarios
  • Data needs validation before applying

Form Integration

import React, { useState } from 'react'
import { Switch } from '@naturacosmeticos/natds-react'

function PreferencesForm() {
  const [preferences, setPreferences] = useState({
    emailNotifications: true,
    smsNotifications: false,
    newsletter: true,
    productUpdates: false
  })

  const handleToggle = (key: keyof typeof preferences) => {
    const newPreferences = {
      ...preferences,
      [key]: !preferences[key]
    }
    setPreferences(newPreferences)
    
    // Auto-save to backend
    savePreferences(newPreferences)
  }

  const savePreferences = async (prefs: typeof preferences) => {
    // API call to save preferences
    console.log('Saving:', prefs)
  }

  return (
    <div>
      <h2>Notification Preferences</h2>
      
      <div className="preference-item">
        <div>
          <strong>Email Notifications</strong>
          <p>Receive important updates via email</p>
        </div>
        <Switch
          id="email"
          value="emailNotifications"
          checked={preferences.emailNotifications}
          onChange={() => handleToggle('emailNotifications')}
        />
      </div>

      <div className="preference-item">
        <div>
          <strong>SMS Notifications</strong>
          <p>Get alerts via text message</p>
        </div>
        <Switch
          id="sms"
          value="smsNotifications"
          checked={preferences.smsNotifications}
          onChange={() => handleToggle('smsNotifications')}
        />
      </div>

      <div className="preference-item">
        <div>
          <strong>Newsletter</strong>
          <p>Monthly newsletter with tips and news</p>
        </div>
        <Switch
          id="newsletter"
          value="newsletter"
          checked={preferences.newsletter}
          onChange={() => handleToggle('newsletter')}
        />
      </div>

      <div className="preference-item">
        <div>
          <strong>Product Updates</strong>
          <p>News about new features and products</p>
        </div>
        <Switch
          id="updates"
          value="productUpdates"
          checked={preferences.productUpdates}
          onChange={() => handleToggle('productUpdates')}
        />
      </div>
    </div>
  )
}

TypeScript

import { SwitchProps } from '@naturacosmeticos/natds-react'

interface SettingItem {
  id: string
  label: string
  description?: string
  value: string
  checked: boolean
}

interface SettingsSwitchProps {
  setting: SettingItem
  onChange: (value: string, checked: boolean) => void
  disabled?: boolean
}

const SettingsSwitch: React.FC<SettingsSwitchProps> = ({
  setting,
  onChange,
  disabled = false
}) => {
  return (
    <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
      <div>
        <label htmlFor={setting.id}>{setting.label}</label>
        {setting.description && <p>{setting.description}</p>}
      </div>
      <Switch
        id={setting.id}
        value={setting.value}
        checked={setting.checked}
        disabled={disabled}
        onChange={(e) => onChange(setting.value, e.target.checked)}
      />
    </div>
  )
}
  • Checkbox - For multiple selections or form submissions
  • Radio - For selecting one option from multiple choices

Build docs developers (and LLMs) love