Toggle

A switch. Underneath, a native checkbox with role="switch".

Usage

Use it like a checkbox, for settings that apply right away.

tsx
const [checked, setChecked] = useState(true);

<Toggle id="notifications" checked={checked} onChange={(event) => setChecked(event.target.checked)} />
<Label as="label" htmlFor="notifications">notifications</Label>

A list of settings

tsx
const [enabled, setEnabled] = useState<readonly string[]>(["notifications"]);

const toggle = (setting: string) =>
  setEnabled((current) =>
    current.includes(setting) ? current.filter((item) => item !== setting) : [...current, setting],
  );

<List
  array={settings}
  itemExtractor={({ row }) => (
    <div key={row} className="flex items-center justify-between gap-4">
      <Label as="label" htmlFor={row}>{row}</Label>
      <Toggle id={row} checked={enabled.includes(row)} onChange={() => toggle(row)} />
    </div>
  )}
/>

States

tsx
<Toggle defaultChecked={false} />
<Toggle defaultChecked />
<Toggle defaultChecked disabled />
<Toggle disabled />

Size

tsx
<Toggle className="h-6 w-11 [--margo-toggle-travel:1.25rem]" />

Reference

proptypedefault
checked?boolean—controlled, with onChange
defaultChecked?boolean—uncontrolled
disabled?booleanfalsenative
…restprops of input—name, onChange and the rest; type and role are fixed
--margo-toggle-travel?CSS length1remhow far the thumb moves; change it when you resize