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

Radio


Renders elementIntermediateApr 10, 2026

A radio button for single-selection groups with roving focus and shared v-model state.

Usage

Radio Group

Three size options with shared single-selection state showing the active value.

Selected: none

Anatomy

vue
<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>

Examples

Mandatory Selection

Plan options (free, pro, enterprise) with mandatory="force" that auto-selects the first non-disabled item on mount.

Selected plan:

Recipes

Form Integration

Pass the name prop on Radio.Group and every Radio.Root inside it renders a hidden native radio input automatically — the group’s name cascades to each Radio.Root unless the child sets its own. No Radio.HiddenInput placement is required:

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>

Radio.HiddenInput is exported as an internal building block for custom layouts, but auto-rendering via name is the only supported form integration path — placing Radio.HiddenInput as a child of a Radio.Root that already resolves a name (from itself or the parent Radio.Group) will produce two hidden inputs.

Styling with Data Attributes

Radio.Root exposes data attributes for CSS styling without conditional classes:

AttributeValuesNotes
data-statechecked, uncheckedReflects current visual state
data-disabledtruePresent only when disabled
vue
<template>
  <Radio.Root class="size-5 rounded-full border data-[state=checked]:border-primary data-[disabled]:opacity-50">
    <Radio.Indicator class="size-2.5 rounded-full bg-primary" />
  </Radio.Root>
</template>

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 non-disabled if none selected) 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>

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.

API Reference

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

Radio.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 radio for group selection and form submission

name

string | undefined

Form field name - triggers auto hidden input when provided

form

string | undefined

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

disabled

MaybeRefOrGetter<boolean> | undefined

Disables this radio (prevents selection and keyboard focus)

Default: false

namespace

string | undefined

Namespace for context provision to children (Indicator, HiddenInput)

Default: "v0:radio:root"

groupNamespace

string | undefined

Namespace for connecting to parent Radio.Group

Default: "v0:radio:group"

ariaLabelledby

string | undefined

ID of element that labels this radio

ariaDescribedby

string | undefined

ID of element that describes this radio

ariaInvalid

boolean | undefined

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 | undefined

Namespace for dependency injection

Default: "v0:radio:group"

disabled

boolean | undefined

Disables the entire radio group

Default: false

mandatory

boolean | "force" | undefined

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 | undefined

Accessible name for the group

ariaLabelledby

string | undefined

ID of element that labels this group

ariaDescribedby

string | undefined

ID of element that describes this group

ariaRequired

boolean | undefined

Whether a selection is required before form submission

name

string | undefined

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

activation

any

Activation mode controlling when selection occurs: - `automatic` (default): Selection follows focus (arrow keys select) - `manual`: Selection requires explicit Enter/Space key press Per WAI-ARIA APG, radio groups should have selection follow focus by default. Use `manual` for toolbar radio groups or when deliberate selection is preferred.

Default: "automatic"

modelValue

T | undefined

Events

Slots

default

RadioGroupSlotProps

Default slot with group state and ARIA attributes

Radio.HiddenInput

Props

namespace

string | undefined

Namespace for context injection from parent Radio.Root

Default: "v0:radio:root"

name

string | undefined

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

value

string | undefined

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

form

string | undefined

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

Radio.Indicator

Props

namespace

string | undefined

Namespace for context injection from parent Radio.Root

Default: "v0:radio:root"

Slots

default

RadioIndicatorSlotProps

Default slot for custom indicator content

Was this page helpful?

© 2016-1970 Vuetify, LLC
Ctrl+/