Skip to content
UI

Switch

Turns a single setting on or off, with the change taking effect immediately.

@zenoxai/ui/components/switchBase UI Markdown
<div className="flex items-center gap-2">
  <Switch id="critical-alerts" defaultChecked />
  <Label htmlFor="critical-alerts">Notify on critical alerts</Label>
</div>

Usage

import { Label } from "@zenoxai/ui/components/label"
import { Switch } from "@zenoxai/ui/components/switch"

export function CriticalAlertsSetting() {
  return (
    <div className="flex items-center gap-2">
      <Switch id="critical-alerts" defaultChecked />
      <Label htmlFor="critical-alerts">Notify on critical alerts</Label>
    </div>
  )
}

Use a switch for a setting that applies as soon as it flips: enabling monitoring, turning on notifications. When the choice is saved later with a submit button, or when it reads as agreement (“I accept the terms”), use a Checkbox instead. For a pressed state on a toolbar button, use a Toggle.

Write the label as the setting when it is on (“Notify on critical alerts”), not as a question.

Examples

With a description

Put the label and a short explanation in a horizontal Field, with the switch at the end of the row. This is the layout for settings pages.

Close an alert 24 hours after its source reports it resolved.

<Field orientation="horizontal" className="max-w-sm">
  <FieldContent>
    <FieldLabel htmlFor="auto-close">Auto-close resolved alerts</FieldLabel>
    <FieldDescription id="auto-close-description">
      Close an alert 24 hours after its source reports it resolved.
    </FieldDescription>
  </FieldContent>
  <Switch id="auto-close" aria-describedby="auto-close-description" />
</Field>

Sizes

default (18px tall) for forms and settings. sm (14px) fits table rows and dense panels.

<div className="flex flex-col gap-3">
  <div className="flex items-center gap-2">
    <Switch id="switch-size-sm" size="sm" defaultChecked />
    <Label htmlFor="switch-size-sm">Small</Label>
  </div>
  <div className="flex items-center gap-2">
    <Switch id="switch-size-default" defaultChecked />
    <Label htmlFor="switch-size-default">Default</Label>
  </div>
</div>

Disabled

Disable a switch the user cannot change, for example a setting enforced by the tenant administrator. Say why next to it or in a tooltip on the label.

<div className="flex flex-col gap-3">
  <div className="flex items-center gap-2">
    <Switch id="sso-enforced" defaultChecked disabled />
    <Label htmlFor="sso-enforced">Enforce single sign-on</Label>
  </div>
  <div className="flex items-center gap-2">
    <Switch id="public-reports" disabled />
    <Label htmlFor="public-reports">Share reports by public link</Label>
  </div>
</div>

Controlled

Pass checked and onCheckedChange when the rest of the view reacts to the value. The callback receives the new state as a boolean.

Scanning every 6 hours.

function SwitchControlled() {
  const [monitoring, setMonitoring] = React.useState(true)

  return (
    <div className="flex flex-col gap-2">
      <div className="flex items-center gap-2">
        <Switch
          id="domain-monitoring"
          checked={monitoring}
          onCheckedChange={setMonitoring}
        />
        <Label htmlFor="domain-monitoring">Monitor acme-corp.com</Label>
      </div>
      <p className="text-sm text-text-secondary">
        {monitoring
          ? "Scanning every 6 hours."
          : "Monitoring paused. No new alerts will be raised."}
      </p>
    </div>
  )
}

Accessibility

  • The switch renders role="switch" with aria-checked, and toggles with Space or Enter. A hidden checkbox input next to it carries name and value into native form submission.
  • It needs an accessible name. Give the switch an id and point a Label at it with htmlFor, wrap both in a <label>, or set aria-label when there is no visible label.
  • Link a description with aria-describedby; Field does not wire it for you.

API reference

Generated from the TypeScript source. className, style and children are accepted everywhere and omitted below.

Switch

Switch turns a setting on or off with immediate effect, such as email notifications. For a choice that applies only when a form is submitted, use Checkbox.

PropTypeDefault
checkedboolean

Whether the switch is currently active.

-
defaultCheckedboolean

Whether the switch is initially active.

false
disabledboolean

Whether the component should ignore user interaction.

false
formstring

Identifies the form that owns the hidden input. Useful when the switch is rendered outside the form.

-
idstring

The id of the hidden input element.

-
inputRefRef<HTMLInputElement>

A ref to access the hidden `<input>` element.

-
namestring

Identifies the field when a form is submitted.

-
nativeButtonboolean

Whether the component renders a native `<button>` element when replacing it via the `render` prop. Set to `false` if the rendered element is not a button (for example, `<div>`).

true
onCheckedChange((checked: boolean, eventDetails: { reason: "none"; event: Event; cancel: () => void; allowPropagation: () => void; isCanceled: boolean; isPropagationAllowed: boolean; trigger: Element; }) => void)

Event handler called when the switch is activated or deactivated.

-
readOnlyboolean

Whether the user should be unable to activate or deactivate the switch.

false
renderReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, SwitchRootState>

Allows you to replace the component's HTML element with a different tag, or compose it with another component.

-
requiredboolean

Whether the user must activate the switch before submitting a form.

false
size"default" | "sm"

`default` is 32 by 18px; `sm` is 24 by 14px.

default
uncheckedValuestring

The value submitted with the form when the switch is off. By default, unchecked switches do not submit any value, matching native checkbox behavior.

-
valuestring

The value submitted with the form when the switch is on. By default, switch submits the "on" value, matching native checkbox behavior.

-