OPERATOR

Toggle

States

Sizes

Inside a Field

Invalid

An invalid switch is announced as invalid and draws its track in the error color, whether it is on or off. A Field with an error sets this for you; a standalone switch takes aria-invalid. Keep the error text: color is not the only cue.

Required

A required switch is announced as required and, like a required Checkbox, blocks native form submission until it is on. The browser's own check runs, so a form that submits without it needs no extra validation once the page is interactive. The native required attribute is added when the page hydrates: the server markup carries aria-required and aria-invalid, because React Aria's switch cannot render the native attribute on the server. A form submitted before that is not blocked by the browser, so validate on the server as well.

Props

PROPTYPEDEFAULTREQUIRED
motion

Tactile pointer/touch feedback. None disables motion; keyboard and system reduced motion are always immediate.

enum
auto | none
"auto"no
checkedboolean—no
defaultCheckedbooleanfalseno
onCheckedChange

Receives the new checked value.

function—no
disabledbooleanfalseno
required

Announced as required. Like a required Checkbox, it blocks native form submission until the switch is on. The native attribute is added when the page hydrates (the server markup has aria-required), so a form submitted earlier is not blocked: validate on the server too.

booleanfalseno
sizeenum
sm | md | lg
"md"no
namestring—no
valuestring—no
id

Id of the switch input. Inside a Field it defaults to the Field's id.

string—no
className

Classes applied to the switch's label root.

string—no
aria-label

Accessible name when there is no visible label. Inside a Field the Field's label names the switch.

string—no
aria-labelledby

Id of the element that names the switch.

string—no
aria-describedby

Id of the element that describes the switch. A Field supplies its help or error.

string—no
aria-invalid

Marks the switch invalid: announced as invalid, with its track in the error color. A Field with an error sets it.

boolean | string—no

Accessibility

  • switch role; Space toggles.
  • Inherits id, aria-describedby, and aria-invalid from Field.
  • Every size has a target at least 24px high.
  • required sets aria-required, which is in the server-rendered markup with aria-invalid, and the native required attribute once the page has hydrated.
  • In forced-colors (high contrast) mode the thumb, the on state and keyboard focus are drawn from system colors: a Highlight track with a HighlightText thumb when on, and a 2px outline on focus.

Manifest entry

<Field label="ENABLE TELEMETRY">
  <Toggle defaultChecked />
</Field>
View agent manifest
{
  "description": "Binary on/off switch. Square thumb sliding inside a square track. Accent fill when on; an invalid switch draws its track in the error color. In forced-colors mode the on state, the thumb and keyboard focus use system colors.",
  "props": {
    "motion": {
      "type": "enum",
      "values": [
        "auto",
        "none"
      ],
      "default": "auto",
      "description": "Tactile pointer/touch feedback. None disables motion; keyboard and system reduced motion are always immediate."
    },
    "checked": {
      "type": "boolean"
    },
    "defaultChecked": {
      "type": "boolean",
      "default": false
    },
    "onCheckedChange": {
      "type": "function",
      "description": "Receives the new checked value."
    },
    "disabled": {
      "type": "boolean",
      "default": false
    },
    "required": {
      "type": "boolean",
      "default": false,
      "description": "Announced as required. Like a required Checkbox, it blocks native form submission until the switch is on. The native attribute is added when the page hydrates (the server markup has aria-required), so a form submitted earlier is not blocked: validate on the server too."
    },
    "size": {
      "type": "enum",
      "values": [
        "sm",
        "md",
        "lg"
      ],
      "default": "md"
    },
    "name": {
      "type": "string"
    },
    "value": {
      "type": "string"
    },
    "id": {
      "type": "string",
      "description": "Id of the switch input. Inside a Field it defaults to the Field's id."
    },
    "className": {
      "type": "string",
      "description": "Classes applied to the switch's label root."
    },
    "aria-label": {
      "type": "string",
      "description": "Accessible name when there is no visible label. Inside a Field the Field's label names the switch."
    },
    "aria-labelledby": {
      "type": "string",
      "description": "Id of the element that names the switch."
    },
    "aria-describedby": {
      "type": "string",
      "description": "Id of the element that describes the switch. A Field supplies its help or error."
    },
    "aria-invalid": {
      "type": "union",
      "types": [
        "boolean",
        "string"
      ],
      "description": "Marks the switch invalid: announced as invalid, with its track in the error color. A Field with an error sets it."
    }
  },
  "composable_with": [
    "Field",
    "Toolbar"
  ],
  "never_inside": [
    "Button",
    "Badge"
  ],
  "example": "<Field label=\"ENABLE TELEMETRY\">\n  <Toggle defaultChecked />\n</Field>"
}

Motion

The thumb travels to the selected position in 150ms. Selection callbacks and form values update immediately; repeated changes retarget the current transition.

Use motion="none" for frequently operated controls. The default motion="auto" respects system reduced motion, skips keyboard and assistive activation, and starts from the supplied resting state. See Motion for the interactive playground.

On this page