---
title: "Radio Group"
description: "A set of checkable buttons—known as radio buttons—where no more than one of the buttons can be checked at a time."
canonical_url: "https://vinicunca.dev/akar/components/radio-group"
---
# Radio Group

> A set of checkable buttons—known as radio buttons—where no more than one of the buttons can be checked at a time.

## RadioGroup

```vue [index.vue]
<script setup lang="ts">
import { RadioGroupIndicator, RadioGroupItem, RadioGroupRoot } from 'akar'
import { ref } from 'vue'
import './styles.css'

const radioStateSingle = ref('default')
</script>

<template>
  <div class="akar-demo akar-demo-RadioGroup">
    <RadioGroupRoot
        v-model="radioStateSingle"
        class="RadioGroupRoot"
        default-value="default"
        aria-label="View density"
      >
        <div :style="{ display: 'flex', alignItems: 'center' }">
          <RadioGroupItem
            id="r1"
            class="RadioGroupItem"
            value="default"
          >
            <RadioGroupIndicator
              class="RadioGroupIndicator"
            />
          </RadioGroupItem>
          <label
            class="Label"
            for="r1"
          >
            Default
          </label>
        </div>
        <div :style="{ display: 'flex', alignItems: 'center' }">
          <RadioGroupItem
            id="r2"
            class="RadioGroupItem"
            value="comfortable"
          >
            <RadioGroupIndicator
              class="RadioGroupIndicator"
            />
          </RadioGroupItem>
          <label
            class="Label"
            for="r2"
          >
            Comfortable
          </label>
        </div>
        <div :style="{ display: 'flex', alignItems: 'center' }">
          <RadioGroupItem
            id="r3"
            class="RadioGroupItem"
            value="compact"
          >
            <RadioGroupIndicator
              class="RadioGroupIndicator"
            />
          </RadioGroupItem>
          <label
            class="Label"
            for="r3"
          >
            Compact
          </label>
        </div>
      </RadioGroupRoot>
  </div>
</template>
```

```css [styles.css]
@import '../_colors/black-alpha.css';
@import '../_colors/grass.css';

@scope (.akar-demo-RadioGroup) {
/* reset */
button {
  all: unset;
}

.RadioGroupRoot {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.RadioGroupItem {
  background-color: white;
  width: 25px;
  height: 25px;
  border-radius: 100%;
  box-shadow: 0 2px 10px var(--black-a7);
}
.RadioGroupItem:hover {
  background-color: var(--grass-3);
}
.RadioGroupItem:focus {
  box-shadow: 0 0 0 2px black;
}

.RadioGroupIndicator {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  position: relative;
}
.RadioGroupIndicator::after {
  content: '';
  display: block;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background-color: var(--grass-11);
}

.Label {
  color: white;
  font-size: 15px;
  line-height: 1;
  padding-left: 15px;
}
}
```

## Features

- Full keyboard navigation.
- Supports horizontal/vertical orientation.
- Can be controlled or uncontrolled.

## Installation

Install the component from your command line.

```bash [pnpm]
pnpm add akar
```

```bash [yarn]
yarn add akar
```

```bash [npm]
npm install akar
```

```bash [bun]
bun add akar
```

## Anatomy

Import all parts and piece them together.

```vue
<script setup>
import { RadioGroupIndicator, RadioGroupItem, RadioGroupRoot } from 'akar';
</script>

<template>
  <RadioGroupRoot>
    <RadioGroupItem>
      <RadioGroupIndicator />
    </RadioGroupItem>
  </RadioGroupRoot>
</template>
```

## API Reference

### Root

Contains all the parts of a radio group.

**Props**

| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| `as` | `"div"` | `AsTag \| Component` | The element or component this component should render as. Can be overwritten by `asChild`. |
| `asChild` |  | `boolean` | Change the default rendered element for the one passed as a child, merging their props and behavior.<br><br>Read our [Composition](https://vinicunca.dev/akar/guides/composition) guide for more details. |
| `defaultValue` |  | `AcceptableValue` | The value of the radio item that should be checked when initially rendered.<br><br>Use when you do not need to control the state of the radio items. |
| `dir` |  | `"ltr" \| "rtl"` | The reading direction of the combobox when applicable.<br><br>If omitted, inherits globally from `ConfigProvider` or assumes LTR (left-to-right) reading mode. |
| `disabled` | `false` | `boolean` | When `true`, prevents the user from interacting with radio items. |
| `loop` | `true` | `boolean` | When `true`, keyboard navigation will loop from last item to first, and vice versa. |
| `modelValue` |  | `AcceptableValue` | The controlled value of the radio item to check. Can be binded as `v-model`. |
| `name` |  | `string` | The name of the field. Submitted with its owning form as part of a name/value pair. |
| `orientation` |  | `"vertical" \| "horizontal"` | The orientation of the component. |
| `required` | `false` | `boolean` | When `true`, indicates that the user must set the value before the owning form can be submitted. |

**Events**

| Event | Payload | Description |
| --- | --- | --- |
| `update:modelValue` | `payload: AcceptableValue` | Event handler called when the radio group value changes |

**Slots**

| Slot | Payload | Description |
| --- | --- | --- |
| `modelValue` | `null \| string \| number \| bigint \| Record<string, any>` | Current input values |

[RadioGroupRoot.vue source](https://github.com/vinicunca/akar/blob/v2.0.20/packages/core/src/RadioGroup/RadioGroupRoot.vue)

| Data attribute | Value |
| --- | --- |
| `[data-disabled]` | Present when disabled |

### Item

An item in the group that can be checked. An `input` will also render when used within a `form` to ensure events propagate correctly.

**Props**

| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| `as` | `"button"` | `AsTag \| Component` | The element or component this component should render as. Can be overwritten by `asChild`. |
| `asChild` |  | `boolean` | Change the default rendered element for the one passed as a child, merging their props and behavior.<br><br>Read our [Composition](https://vinicunca.dev/akar/guides/composition) guide for more details. |
| `disabled` | `false` | `boolean` | When `true`, prevents the user from interacting with the radio item. |
| `id` |  | `string` |  |
| `name` |  | `string` | The name of the field. Submitted with its owning form as part of a name/value pair. |
| `required` |  | `boolean` | When `true`, indicates that the user must set the value before the owning form can be submitted. |
| `value` |  | `AcceptableValue` | The value given as data when submitted with a `name`. |

**Events**

| Event | Payload | Description |
| --- | --- | --- |
| `select` | `event: SelectEvent` |  |

**Slots**

| Slot | Payload | Description |
| --- | --- | --- |
| `checked` | `boolean` | Current checked state |
| `required` | `boolean` | Required state |
| `disabled` | `boolean` | Disabled state |

[RadioGroupItem.vue source](https://github.com/vinicunca/akar/blob/v2.0.20/packages/core/src/RadioGroup/RadioGroupItem.vue)

| Data attribute | Value |
| --- | --- |
| `[data-state]` | "checked" \\| "unchecked" |
| `[data-disabled]` | Present when disabled |

### Indicator

Renders when the radio item is in a checked state. You can style this element directly, or you can use it as a wrapper to put an icon into, or both.

> [!NOTE]
> 
> Defer mounting with `forceMount` / [`Presence`](https://vinicunca.dev/akar/utilities/presence). See the [animation guide](https://vinicunca.dev/akar/guides/animation).

**Props**

| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| `as` | `"span"` | `AsTag \| Component` | The element or component this component should render as. Can be overwritten by `asChild`. |
| `asChild` |  | `boolean` | Change the default rendered element for the one passed as a child, merging their props and behavior.<br><br>Read our [Composition](https://vinicunca.dev/akar/guides/composition) guide for more details. |
| `forceMount` |  | `boolean` | Used to force mounting when more control is needed. Useful when<br>controlling animation with Vue animation libraries. |

[RadioGroupIndicator.vue source](https://github.com/vinicunca/akar/blob/v2.0.20/packages/core/src/RadioGroup/RadioGroupIndicator.vue)

| Data attribute | Value |
| --- | --- |
| `[data-state]` | "checked" \\| "unchecked" |
| `[data-disabled]` | Present when disabled |

## Accessibility

Adheres to the [Radio Group WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/radiobutton) and uses [roving tabindex](https://www.w3.org/TR/wai-aria-practices-1.2/examples/radio/radio.html) to manage focus movement among radio items.

### Keyboard Interactions

| Key | Description |
| --- | --- |
| <kbd>Tab</kbd> | Moves focus to either the checked radio item or the first radio item in the group. |
| <kbd>Space</kbd> | When focus is on an unchecked radio item, checks it. |
| <kbd>ArrowDown</kbd> | Moves focus and checks the next radio item in the group. |
| <kbd>ArrowRight</kbd> | Moves focus and checks the next radio item in the group. |
| <kbd>ArrowUp</kbd> | Moves focus to the previous radio item in the group. |
| <kbd>ArrowLeft</kbd> | Moves focus to the previous radio item in the group. |

---

- [ARIA](https://www.w3.org/WAI/ARIA/apg/patterns/radiobutton)
- [GitHub](https://github.com/vinicunca/akar/blob/v2.0.20/packages/core/src/RadioGroup)
- [npm](https://www.npmjs.com/package/akar)


## Sitemap

See the full [sitemap](https://vinicunca.dev/sitemap.md) for all pages.
