Switch

A hand-drawn toggle switch for immediate, on/off settings.

Overview

A Switch toggles a setting on or off immediately — unlike a Checkbox, which typically belongs to a form submitted later, a Switch’s effect is expected to apply right away.

Anatomy

A sketchy track drawn behind a real <input type="checkbox" role="switch"> (React/Web Components) or a Pressable with accessibilityRole="switch" (React Native). A second, smaller filled thumb (an ellipse computed directly from @ghds/sketch-core) renders inside the track, positioned left when off and right when checked.

Variants & States

State Status Notes
Off Implemented
On Implemented Track fills solid; the thumb moves to the right.
Disabled Implemented
Loading Not implemented

Usage

Do

  • Use Switch for settings that take effect immediately (e.g. "Enable notifications").
  • Pair a Switch with a clear, static label describing the setting, not the current state ("Notifications", not "On").

Don't

  • Don't use Switch inside a form that requires an explicit Save/Submit action — use Checkbox there instead.
  • Don't animate the thumb position — v1 ships an immediate, non-animated position swap on toggle; no component in this system has a transition system yet.

Accessibility

Content

The label names the setting itself (“Enable notifications”), not the current state or an action.

Props API

React@ghds/react

PropTypeDefaultDescription
labelstringVisible label, associated via Radix Label.
checkedbooleanControlled checked state.
defaultCheckedbooleanfalseInitial checked state when uncontrolled.
disabledbooleanfalseDisables interaction.
...restInputHTMLAttributesAll other native input attributes pass through.

Web Components@ghds/web-components

PropTypeDefaultDescription
checkedbooleanfalseReflected attribute.
disabledbooleanfalseDisables interaction and form participation.
namestringSubmitted control name.
valuestring'on'Submitted value when checked.
labelstringOptional visible label, also the accessible name.

React Native@ghds/react-native

PropTypeDefaultDescription
labelstringVisible, accessible label — required.
checkedbooleanControlled checked state.
defaultCheckedbooleanInitial checked state when uncontrolled.
onCheckedChange(checked: boolean) => voidFires with the next checked state on toggle.
disabledbooleanfalseDisables interaction.
testIDstringTest handle for queries.

Code examples

// React — @ghds/react
import { Switch } from '@ghds/react/switch';

<Switch
  label="Enable notifications"
  checked={notifications}
  onChange={(event) => setNotifications(event.target.checked)}
/>;
<!-- Web Components — @ghds/web-components -->
<script type="module">
  import '@ghds/web-components/switch';
</script>
<gh-switch id="notify" label="Enable notifications"></gh-switch>
<script>
  document.getElementById('notify').addEventListener('change', (e) => {
    console.log(e.target.checked);
  });
</script>
// React Native — @ghds/react-native
import { Switch } from '@ghds/react-native/switch';

<Switch label="Enable notifications" checked={notifications} onCheckedChange={setNotifications} />;

Live Demo

React and Web Components render live below. React Native can’t run in a browser without additional react-native-web wiring (not set up in this site), so its usage is shown as a code sample instead.

React @ghds/react

Web Components @ghds/web-components