Skip to content

Toggle

A switch control for binary on/off states. Renders with the switch ARIA role for correct screen reader semantics.

Preview

Sizes

SizeTrack widthTrack heightThumb size
sm36 px20 px16 px
md44 px24 px20 px

Features

  • Label -- optional label rendered next to the toggle. Position can be left or right.
  • Disabled -- reduces opacity to 50% and prevents interaction.
  • Spring easing -- the thumb uses the spring easing curve for a tactile feel.

Props

PropTypeDefaultDescription
checkedbooleanfalseWhether the toggle is on
onChange(checked: boolean) => void--Called when the state changes
size'sm' | 'md''md'Toggle dimensions
labelstring--Visible label text
labelPosition'left' | 'right''right'Which side the label appears on
disabledbooleanfalseDisables the toggle
classNamestring--Additional CSS classes

Code example

React

tsx
import { useState } from 'react';
import { Toggle } from '@thepace/lexicon/components';

function NotificationSettings() {
  const [email, setEmail] = useState(true);
  const [sms, setSms] = useState(false);

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-4)' }}>
      <Toggle
        checked={email}
        onChange={setEmail}
        label="Email notifications"
      />
      <Toggle
        checked={sms}
        onChange={setSms}
        label="SMS notifications"
        size="sm"
      />
      <Toggle
        checked={false}
        label="Push notifications"
        disabled
      />
    </div>
  );
}

Vanilla HTML

html
<label class="lex-toggle">
  <button
    class="lex-toggle__track lex-toggle__track--on"
    role="switch"
    aria-checked="true"
    aria-label="Email notifications"
  >
    <span class="lex-toggle__thumb"></span>
  </button>
  <span class="lex-toggle__label">Email notifications</span>
</label>

<label class="lex-toggle lex-toggle--sm">
  <button
    class="lex-toggle__track"
    role="switch"
    aria-checked="false"
    aria-label="SMS notifications"
  >
    <span class="lex-toggle__thumb"></span>
  </button>
  <span class="lex-toggle__label">SMS notifications</span>
</label>

CSS class reference

ClassPurpose
.lex-toggleWrapper (flex container with label)
.lex-toggle--smSmall size
.lex-toggle--mdMedium size (default)
.lex-toggle--disabledDisabled state
.lex-toggle__trackThe track (pill-shaped background)
.lex-toggle__track--onActive/on state
.lex-toggle__thumbThe sliding circle
.lex-toggle__labelLabel text

Accessibility

  • Uses role="switch" with aria-checked reflecting the current state.
  • When a label prop is provided, it is linked via aria-labelledby. Without a label, provide aria-label directly.
  • The toggle is focusable and activates on Space or Enter.
  • When disabled, aria-disabled="true" is set and interaction is suppressed.
  • The focus ring uses --border-focus for clear keyboard navigation visibility.

Released under the MIT License. A product by the pace.