Skip to main content

ToggleRow

Live preview

Result
Loading...
Live Editor
<Card variant="elevated" padding="none">
  <ToggleRow primary="Enable sync" secondary="Sync bookmarks, history, and open tabs" defaultChecked />
  <Divider />
  <ToggleRow primary="Send anonymous usage stats" />
  <Divider />
  <ToggleRow primary="Auto-update extensions" defaultChecked disabled />
</Card>

A purpose-built row for settings that toggle a single value. Clicking anywhere in the row — primary text, secondary text, leading icon — flips the switch. The whole row paints a hover fill on pointer-over.

The row is structurally one <label>: native HTML association ties the click target on the text to the underlying <input>. There is no extra event handling, no synthetic click — the affordance comes for free from the browser. That is exactly what chrome://settings does.

Reach for ToggleRow whenever a row's only trailing control is an on/off switch. For rows that drill into a sub-page, use PanelRow. For rows with inline controls (Select, Input, Slider) or multiple trailing widgets, use ListItem.

Import

import { ToggleRow } from 'chromium-ui-react';

Props

PropTypeDefaultDescription
primaryReactNodeTop (main) label
secondaryReactNodeHelper line below primary
iconReactNodeLeading slot (small icon)
checkedbooleanControlled value
defaultCheckedbooleanUncontrolled initial value
onChange(e: ChangeEvent) => voidStandard change handler
disabledbooleanfalseDisables the row and the switch
rowClassNamestringClass for the outer row label

All other <input> attributes are forwarded; className is applied to the underlying <input>. Ref goes to the underlying <input>.

Controlled

const [syncEnabled, setSyncEnabled] = useState(true);

<ToggleRow
primary="Sync bookmarks"
secondary="Keep bookmarks in sync across devices"
checked={syncEnabled}
onChange={(e) => setSyncEnabled(e.currentTarget.checked)}
/>

With a leading icon

<ToggleRow
icon={<span className="material-symbols-outlined">sync</span>}
primary="Sync"
secondary="Sync bookmarks, history, and open tabs"
defaultChecked
/>

Accessibility

  • The whole row is the click target via standard HTML <label> association — no synthetic event handling.
  • Only one focusable element per row (the <input>). The keyboard tab-order does not double up.
  • Screen readers announce the switch with the row's primary text as the accessible name.
  • Pressing Space on the focused switch toggles it (native <input type="checkbox"> behaviour).

When not to use

  • Drill-in rows — use PanelRow with navigateTo (chevron, not switch).
  • Multiple trailing controls — use ListItem and accept that the row is no longer single-click.
  • Inline form controls inside a row (Select, Input, Slider) — use ListItem with the control in end.