Skip to main content
Vuetify0 is now in alpha!
Vuetify0 Logo
Theme
Mode
Palettes
Accessibility
Vuetify One
Sign in to Vuetify One

Access premium tools across the Vuetify ecosystem — Bin, Play, Studio, and more.

Not a subscriber? See what's included

Switch


Renders elementIntermediateApr 10, 2026

A switch for on/off state or multi-selection groups with tri-state support.

Usage

Basic Switch

A standalone boolean switch with label and slide animation.

Anatomy

vue
<script setup lang="ts">
  import { Switch } from '@vuetify/v0'
</script>

<template>
  <!-- Standalone -->
  <Switch.Root>
    <Switch.Track>
      <Switch.Thumb />
    </Switch.Track>
  </Switch.Root>

  <!-- Group -->
  <Switch.Group>
    <Switch.Root>
      <Switch.Track>
        <Switch.Thumb />
      </Switch.Track>
    </Switch.Root>

    <Switch.Root>
      <Switch.Track>
        <Switch.Thumb />
      </Switch.Track>
    </Switch.Root>
  </Switch.Group>

  <!-- Group with Select All -->
  <Switch.Group>
    <Switch.SelectAll>
      <Switch.Track>
        <Switch.Thumb />
      </Switch.Track>
    </Switch.SelectAll>

    <Switch.Root>
      <Switch.Track>
        <Switch.Thumb />
      </Switch.Track>
    </Switch.Root>
  </Switch.Group>

  <!-- With form submission -->
  <Switch.Root>
    <Switch.Track>
      <Switch.Thumb />
    </Switch.Track>

    <Switch.HiddenInput />
  </Switch.Root>
</template>

Examples

Switch Group

Multi-select switch group managing an array of connectivity options (WiFi, Bluetooth, Location).

Selected: none

Select-All Switch

A “select all” switch with indeterminate state over nested permission toggles.

Selected: none

The SelectAll component:

  • Binds to the group’s isAllSelected and isMixed state

  • Calls toggleAll on click

  • Does NOT register as a group item

  • Sets aria-checked="mixed" and data-state="indeterminate" when partially selected

Recipes

Form Integration

Pass the name prop on Switch.Root and a hidden native <input type="checkbox"> is rendered automatically — no Switch.HiddenInput placement is required. The input is visually hidden, inert, and tabindex="-1", so it only participates in FormData submission:

vue
<template>
  <Switch.Root name="notifications" value="on">
    <Switch.Track>
      <Switch.Thumb />
    </Switch.Track>
  </Switch.Root>
</template>

Switch.HiddenInput is exported as an internal building block for custom layouts, but auto-rendering via name is the only supported form integration path — placing Switch.HiddenInput as a child of a Switch.Root that already has a name will produce two hidden inputs.

Styling with Data Attributes

Switch subcomponents expose data attributes for CSS styling without conditional classes. Switch.Root and Switch.SelectAll emit both data-state and data-disabled, while Switch.Track and Switch.Thumb emit only data-state (they inherit disabled styling from the Root ancestor):

AttributeValuesComponents
data-statechecked, unchecked, indeterminateRoot, SelectAll, Track, Thumb
data-disabledtrueRoot, SelectAll
vue
<template>
  <Switch.Root class="data-[disabled]:opacity-50">
    <Switch.Track class="bg-gray-300 transition-colors data-[state=checked]:bg-primary">
      <Switch.Thumb />
    </Switch.Track>
  </Switch.Root>
</template>

Switch.Thumb applies an inline visibility: hidden when unchecked, so the thumb is not visible until the switch is on. This means a sliding transform on Switch.Thumb cannot animate from the “off” position. Animate the Switch.Track background color instead, as shown above.

Accessibility

The Switch.Root component renders as a button and handles all ARIA attributes automatically:

  • role="switch" for proper semantics

  • aria-checked reflects state (true, false, or "mixed")

  • aria-disabled when switch is disabled

  • aria-label from the label prop

  • tabindex="0" for keyboard focus (removed when disabled)

  • Space key toggles the switch (Enter works when rendered as button)

For custom implementations, use renderless mode and bind the attrs slot prop to your element:

vue
<template>
  <Switch.Root v-slot="{ attrs }" renderless>
    <div v-bind="attrs">
      <!-- Custom switch visual -->
    </div>
  </Switch.Root>
</template>

API Reference

The following API details are for all variations of the Switch component.

Switch.Root

Props

id

any

Unique identifier (auto-generated if not provided)

Default: useId()

label

string | undefined

Optional display label (passed through to slot)

value

V | undefined

Value associated with this switch (used in group mode and form submission)

name

string | undefined

Form field name - triggers auto hidden input when provided

form

string | undefined

Associate with form by ID

disabled

MaybeRefOrGetter<boolean> | undefined

Disables this switch

Default: false

indeterminate

MaybeRefOrGetter<boolean> | undefined

Sets the indeterminate state

Default: false

namespace

string | undefined

Namespace for context provision to children (Track, Thumb, HiddenInput)

Default: "v0:switch:root"

groupNamespace

string | undefined

Namespace for connecting to parent Switch.Group

Default: "v0:switch:group"

ariaLabelledby

string | undefined

ID of element that labels this switch

ariaDescribedby

string | undefined

ID of element that describes this switch

ariaInvalid

boolean | undefined

Whether the switch has an invalid value

modelValue

boolean | undefined

Events

update:model-value

[value: boolean]

Slots

default

SwitchRootSlotProps<V>

Switch.Group

Props

namespace

string | undefined

Namespace for context provision to children

Default: "v0:switch:group"

disabled

boolean | undefined

Disables all switches in the group

Default: false

enroll

boolean | undefined

Auto-select items on registration

Default: false

mandatory

boolean | "force" | undefined

Require at least one switch to be on. `'force'` prevents deselecting the last item

Default: false

label

string | undefined

Accessible group label

ariaLabelledby

string | undefined

ID of element that labels this group

ariaDescribedby

string | undefined

ID of element that describes this group

modelValue

T | T[] | undefined

Events

update:model-value

[value: T | T[]]

Slots

default

SwitchGroupSlotProps

Switch.HiddenInput

Props

namespace

string | undefined

Namespace for connecting to parent Switch.Root

Default: "v0:switch:root"

name

string | undefined

Form field name (overrides Root's name)

value

string | undefined

Form field value (overrides Root's value, defaults to 'on')

form

string | undefined

Associate with form by ID (overrides Root's form)

Switch.SelectAll

Props

label

string | undefined

Accessible label for the select-all toggle

disabled

boolean | undefined

Disables this toggle

namespace

string | undefined

Namespace for context provision to children (Track, Thumb)

Default: "v0:switch:root"

groupNamespace

string | undefined

Namespace for connecting to parent Switch.Group

Default: "v0:switch:group"

ariaLabelledby

string | undefined

ID of element that labels this toggle

ariaDescribedby

string | undefined

ID of element that describes this toggle

Slots

default

SwitchSelectAllSlotProps

Switch.Thumb

Props

namespace

string | undefined

Namespace for connecting to parent Switch.Root

Default: "v0:switch:root"

Slots

default

SwitchThumbSlotProps

Switch.Track

Props

namespace

string | undefined

Namespace for connecting to parent Switch.Root

Default: "v0:switch:root"

Slots

default

SwitchTrackSlotProps
Was this page helpful?

© 2016-1970 Vuetify, LLC
Ctrl+/