Skip to main content

Toggle

A toggle switch component for on/off states with support for labels, validation, and keyboard interaction

Toggle

The Toggle component provides an accessible switch control for binary on/off states. It’s ideal for settings, preferences, and feature flags. The component includes full keyboard support, ARIA attributes, and flexible label positioning using typography tokens for consistent text rendering.

Basic Toggle

Click or tap to toggle on/off state

Switch between light and dark themes

Current State:

Feature: OFF
Theme: Light

API Reference

Props

PropTypeDefaultDescription
idstringrequiredUnique identifier for the toggle
namestringidForm field name
labelstringrequiredToggle label text
checkedbooleanfalseToggle state (bindable)
requiredbooleanfalseWhether field is required
disabledbooleanfalseDisables the toggle
errorstring \| nullnullError message to display
helperstring-Helper text below toggle
labelPosition'left' \| 'right''right'Position of label relative to toggle

Usage Examples

Basic Toggle

<script>
  import Toggle from '$lib/shared/components/forms/Toggle.svelte';
  
  let darkMode = $state(false);
</script>

<Toggle
  id="theme"
  label="Dark mode"
  bind:checked={darkMode}
/>

With Helper Text

<script>
  import Toggle from '$lib/shared/components/forms/Toggle.svelte';
  
  let notifications = $state(true);
</script>

<Toggle
  id="notifications"
  label="Enable notifications"
  bind:checked={notifications}
  helper="Receive alerts for important updates"
/>

Left-aligned Label

<script>
  import Toggle from '$lib/shared/components/forms/Toggle.svelte';
  
  let autoSave = $state(true);
</script>

<Toggle
  id="autosave"
  label="Auto-save documents"
  labelPosition="left"
  bind:checked={autoSave}
  helper="Automatically save changes every 30 seconds"
/>

Settings Group

<script>
  import Toggle from '$lib/shared/components/forms/Toggle.svelte';
  
  let settings = $state({
    darkMode: false,
    notifications: true,
    analytics: false
  });
</script>

<fieldset>
  <legend>Preferences</legend>
  
  <Toggle
    id="pref-dark"
    label="Dark mode"
    bind:checked={settings.darkMode}
  />
  
  <Toggle
    id="pref-notif"
    label="Notifications"
    bind:checked={settings.notifications}
  />
  
  <Toggle
    id="pref-analytics"
    label="Analytics"
    bind:checked={settings.analytics}
    helper="Help us improve with anonymous usage data"
  />
</fieldset>

Typography System

The Toggle component uses design system typography tokens:

Applied Tokens

/* Label Text */
--typography-body-size
--typography-body-color
--typography-body-weight

/* Helper Text */
--typography-caption-size
--typography-muted-color
--typography-caption-weight

/* Error Text */
--typography-caption-size
--error (semantic color)
--typography-caption-weight

Visual Design

Toggle Switch

The toggle switch uses a pill-shaped design with smooth transitions:

  • Track: 2.75rem × 1.5rem with rounded ends
  • Thumb: Circular indicator that slides
  • Colors: Theme-aware with primary accent when ON
  • Transition: Smooth 200ms animation

States

  • OFF: Neutral background, thumb on left
  • ON: Primary color background, thumb on right
  • Disabled: Reduced opacity, no interaction
  • Focus: Focus ring for keyboard navigation
  • Error: Red border with error message

Accessibility

The Toggle component is fully accessible:

ARIA Support

  • role="switch" - Identifies as a toggle switch
  • aria-checked - Communicates ON/OFF state
  • aria-label - Provides accessible name
  • aria-required - Indicates required fields
  • aria-invalid - Communicates error states
  • aria-describedby - Links helper and error text

Keyboard Interaction

  • Space - Toggle ON/OFF state
  • Enter - Toggle ON/OFF state
  • Tab - Navigate to toggle
  • Shift+Tab - Navigate backwards

Screen Reader Support

  • State changes announced immediately
  • Labels properly associated
  • Helper text linked via ARIA
  • Error messages announced via live regions

Implementation Details

Hidden Checkbox

The component uses a hidden native checkbox for form compatibility:

<!-- Hidden checkbox for form submission -->
<input
  type="checkbox"
  class="sr-only"
  bind:checked
/>

<!-- Visual toggle button -->
<button
  role="switch"
  aria-checked={checked}
/>

This ensures:

  • Form submission works correctly
  • Progressive enhancement
  • Fallback for assistive technologies

Styling

CSS Classes

  • .field-toggle - Toggle switch container
  • .field-choice-label - Label wrapper
  • .checked - Applied when ON
  • .field-error - Error state modifier
  • .field-error-message - Error message styling
  • .field-hint - Helper text styling

Customization

The toggle appearance can be customized via CSS variables:

/* Toggle dimensions */
--toggle-width: 2.75rem;
--toggle-height: 1.5rem;
--toggle-thumb-size: 1.25rem;

/* Colors */
--toggle-off-bg: var(--surface-tertiary);
--toggle-on-bg: var(--primary);
--toggle-thumb: var(--surface);

Best Practices

  1. Clear labels - Use action-oriented labels that describe the result
  2. Immediate effect - Changes should apply immediately, not on form submit
  3. Visual feedback - Smooth transitions and clear state indication
  4. Group related toggles - Use fieldsets for logical grouping
  5. Avoid negatives - Prefer “Enable notifications” over “Disable notifications”
  6. Provide context - Use helper text for complex settings

Common Use Cases

Settings & Preferences

  • Theme switching (dark/light mode)
  • Notification preferences
  • Privacy settings
  • Feature flags

Forms & Configuration

  • Accept terms and conditions
  • Newsletter subscription
  • Two-factor authentication
  • Auto-save options

Feature Control

  • Enable/disable features
  • Show/hide content
  • Activate premium features
  • Debug mode toggles

Toggle vs Checkbox

Use Toggle when:

  • The change takes effect immediately
  • It’s an on/off or enabled/disabled state
  • The setting is a preference or configuration

Use Checkbox when:

  • Multiple selections are possible
  • Changes apply on form submission
  • It’s a yes/no question or agreement