Skip to main content
You are viewing Pre-Alpha documentation.
Vuetify0 Logo
Mode
Accessibility
Vuetify

Radio

A headless radio button component for single-selection groups with keyboard navigation and roving tabindex.

IntermediateJan 13, 2026

Usage

Radio buttons must be used within a Radio.Group. Use v-model on the group to bind the selected value:

Selected: none

Anatomy

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

<template>
  <Radio.Group>
    <Radio.Root>
      <Radio.Indicator />
    </Radio.Root>

    <Radio.Root>
      <Radio.Indicator />
    </Radio.Root>
  </Radio.Group>

  <!-- With form submission -->
  <Radio.Group>
    <Radio.Root>
      <Radio.Indicator />

      <Radio.HiddenInput />
    </Radio.Root>

    <Radio.Root>
      <Radio.Indicator />

      <Radio.HiddenInput />
    </Radio.Root>
  </Radio.Group>
</template>

Auto-Select First Option

Radio groups are inherently mandatory—once a selection is made, it can only be changed, not cleared. Use mandatory="force" to automatically select the first non-disabled option on mount:

Selected plan:

Accessibility

The Radio components handle all ARIA attributes automatically:

  • role="radiogroup" on the Group
  • role="radio" on each Root
  • aria-checked reflects checked state
  • aria-disabled when radio is disabled
  • aria-required for form validation (set on Group)
  • aria-label from the label prop
  • Roving tabindex - only the selected radio (or first if none) is tabbable
  • Space key selects the focused radio
  • Arrow keys navigate between radios

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

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

Keyboard Navigation

Arrow keys provide circular navigation within a radio group:

KeyAction
SpaceSelect focused radio
ArrowUp / ArrowLeftMove to previous radio
ArrowDown / ArrowRightMove to next radio

Navigation automatically skips disabled items and wraps around.

Form Integration

Set the name prop on Radio.Group to enable form submission for all radios in the group:

vue
<template>
  <Radio.Group v-model="selected" name="size">
    <Radio.Root value="small">
      <Radio.Indicator />
      Small
    </Radio.Root>

    <Radio.Root value="large">
      <Radio.Indicator />
      Large
    </Radio.Root>
  </Radio.Group>
</template>

Each Radio.Root automatically renders a hidden native radio input with the shared name and its own value.

For custom form integration, use Radio.HiddenInput explicitly:

vue
<template>
  <Radio.Group>
    <Radio.Root value="a">
      <Radio.Indicator />

      <Radio.HiddenInput name="custom" value="override" />
    </Radio.Root>
  </Radio.Group>
</template>

API Reference

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

Radio.Root

Props

id

ID

Unique identifier (auto-generated if not provided)

Default: genId()

label

string

Optional display label (passed through to slot)

value

V

Value associated with this radio for group selection and form submission

name

string

Form field name - triggers auto hidden input when provided

form

string

Associate with a form by ID (for radios outside the form element)

disabled

MaybeRef<boolean>

Disables this radio (prevents selection and keyboard focus)

Default: false

namespace

string

Namespace for context provision to children (Indicator, HiddenInput)

Default: "v0:radio:root"

groupNamespace

string

Namespace for connecting to parent Radio.Group

Default: "v0:radio:group"

ariaLabelledby

string

ID of element that labels this radio

ariaDescribedby

string

ID of element that describes this radio

ariaInvalid

boolean

Marks the radio as invalid for form validation

Slots

default

RadioRootSlotProps<V>

Default slot with radio state, actions, and ARIA attributes

Radio.Group

Props

namespace

string

Namespace for dependency injection

Default: "v0:radio:group"

disabled

boolean

Disables the entire radio group

Default: false

mandatory

boolean | "force"

Auto-selects the first non-disabled item on mount. Radio groups are inherently mandatory (selection can only be changed, not cleared), so `mandatory="force"` is the only meaningful option.

Default: false

label

string

Accessible name for the group

ariaLabelledby

string

ID of element that labels this group

ariaDescribedby

string

ID of element that describes this group

ariaRequired

boolean

Whether a selection is required before form submission

name

string

Form field name - enables native form submission for all radios in group

Events

Slots

default

RadioGroupSlotProps

Default slot with group state and ARIA attributes

Radio.HiddenInput

Props

value

string

Submitted value when checked (defaults to context value or 'on'). Use to override the Radio.Root value for form submission.

name

string

Form field name (defaults to context value from Radio.Group)

namespace

string

Namespace for context injection from parent Radio.Root

Default: "v0:radio:root"

form

string

Associate with form by ID (for inputs outside the form element)

Radio.Indicator

Props

namespace

string

Namespace for context injection from parent Radio.Root

Default: "v0:radio:root"

Slots

default

RadioIndicatorSlotProps

Default slot for custom indicator content


© 2016-1970 Vuetify, LLC
Ctrl+/