Skip to content

Radio Group

Radio groups are a collection of radio options. Use this when only one entry is allowed in the form field.

Basic usage

Would you like to receive our newsletter?
Selected: —
template
<RadioGroup
  v-model="receiveNewsletter"
  label="Would you like to receive our newsletter?"
  name="newsletter"
>
  <RadioNew
    id="yes"
    label="Yes"
    value="yes"
  />
  <RadioNew
    id="no"
    label="No"
    value="no"
  />
</RadioGroup>

Variants

The RadioGroup component comes with four variants. You can set them via the variant property. The default value is radio.

Radio

Shirt size
template
<RadioGroup variant="radio" label="Shirt size">
  <RadioNew
    id="small"
    label="Small"
    value="sm"
  />
  <RadioNew
    id="medium"
    label="Medium"
    value="md"
  />
  <RadioNew
    id="large"
    label="Large"
    value="lg"
  />
</RadioGroup>

You can also customize the RadioNew component by leveraging the default slot of the RadioGroup component. This allows you to compose the RadioNew component with other components.

Priority
template
<RadioGroup variant="radio" label="Priority">
  <Card>
    <template #top-left>
      <RadioNew id="low" label="Low. This option designates tasks or items with a lower level of urgency or criticality, providing a more relaxed timeline for completion." value="low" />
    </template>
  </Card>
  <Card>
    <template #top-left>
      <RadioNew id="high" label="High. This choice signifies a commitment to addressing tasks or items with heightened urgency or critical importance promptly." value="high" />
    </template>
  </Card>
</RadioGroup>

Button

WARNING

To avoid layout bugs when the button group is wider than the parent container, the button variant will always switch to use the vertical orientation. The only exception is if the fullWidth prop is also used. See the example below on how you can set this up yourself.

Resize this window to see how the below example reacts.

Preferred operating system
template
<RadioGroup variant="button" label="Preferred operating system">
  <RadioNew
    id="linux"
    label="Linux"
    value="linux"
  />
  <RadioNew
    id="macos"
    label="MacOS"
    value="macos"
  />
  <RadioNew
    id="windows"
    label="Windows"
    value="windows"
  />
</RadioGroup>

Chip

Availability
template
<RadioGroup variant="chip" label="Availability">
  <RadioNew
    id="monday"
    label="Monday"
    value="monday"
  />
  <RadioNew
    id="tuesday"
    label="Tuesday"
    value="tuesday"
  />
  <RadioNew
    id="wednesday"
    label="Wednesday"
    value="wednesday"
  />
  <RadioNew
    id="thursday"
    label="Thursday"
    value="thursday"
  />
  <RadioNew
    id="friday"
    label="Friday"
    value="friday"
  />
</RadioGroup>

Tile

Delivery method
template
<RadioGroup variant="tile" label="Delivery method">
  <RadioNew
    id="standard"
    label="Standard"
    value="standard"
  >
    <p>5 - 10 business days</p>
    <p>$10.00</p>
  </RadioNew>
  <RadioNew
    id="express"
    label="Express"
    value="express"
  >
    <p>3 - 5 business days</p>
    <p>$25.00</p>
  </RadioNew>
</RadioGroup>

Hint text and error states

You can provide hint text for a RadioGroup by using its hint-text prop.

Should I buy Ice Cream?
You know you want to.
template
<RadioGroup
  v-model="hintText"
  label="Should I buy Ice Cream?"
  name="icecream-hint"
  hint-text="You know you want to."
>
  <RadioNew id="yes" label="Yes" value="yes" />
  <RadioNew id="no" label="No" value="no" />
</RadioGroup>

If you provide error-text, the RadioGroup will display an error state, which overrides the hint text.

Vanilla or Chocolate?
You have to select one.
template
<RadioGroup
  v-model="errorText"
  label="Vanilla or Chocolate?"
  name="icecream-error"
  :error-text="!errorText ? 'You have to select one.' : undefined"
  hint-text="You know you want to."
>
  <RadioNew id="Vanilla" label="Vanilla" value="Vanilla" />
  <RadioNew id="Chocolate" label="Chocolate" value="Chocolate" />
</RadioGroup>
<div>
  <Button @click="errorText = undefined">Reset</Button>
</div>

You can also leverage the <Field> component to add individual hint-text and/or error states to each radio element.

Vanilla or Chocolate?
Delicious classic flavor
Rich and indulgent
vue
<script setup>
  import Field from '../../../src/components/Field/Field.vue';
  import RadioGroup from '../../../src/components/RadioGroup/RadioGroup.vue';
  import RadioNew from '../../../src/components/RadioNew/RadioNew.vue';
</script>

<template>
  <RadioGroup label="Vanilla or Chocolate?" name="icecream-individual-hint">
    <Field>
      <template #hint>
        <span class="tw-ml-8">Delicious classic flavor</span>
      </template>

      <RadioNew id="Vanilla" label="Vanilla" value="Vanilla" />
    </Field>
    <Field>
      <template #hint>
        <span class="tw-ml-8">Rich and indulgent</span>
      </template>

      <RadioNew id="Chocolate" label="Chocolate" value="Chocolate" />
    </Field>
  </RadioGroup>
</template>

Orientation

The radio group can be displayed either horizontally or vertically using the orientation prop. The button variant will default to vertical if the group is wider than it's parent container to avoid layout issues, ignoring any explicitly passed values.

Radios

Ice cream flavor

Tiles

Ice cream flavor

Buttons

Ice cream flavor

Chips

Ice cream flavor
vue
<script setup>
  import RadioGroup from '../../../src/components/RadioGroup/RadioGroup.vue';
  import RadioNew from '../../../src/components/RadioNew/RadioNew.vue';
</script>

<template>
  <h3>Radios</h3>
  <RadioGroup orientation="vertical" label="Ice cream flavor" name="orientation-vertical">
    <RadioNew id="Vanilla" label="Vanilla" value="Vanilla" />
    <RadioNew id="Chocolate" label="Chocolate" value="Chocolate" />
    <RadioNew id="Strawberry" label="Strawberry" value="Strawberry" />
    <RadioNew id="Mint Chip" label="Mint Chip" value="Mint Chip" />
  </RadioGroup>

  <h3 class="tw-mt-6">Tiles</h3>
  <RadioGroup orientation="vertical" variant="tile" label="Ice cream flavor" name="orientation-vertical-tile">
    <RadioNew id="Vanilla" label="Vanilla" value="Vanilla" />
    <RadioNew id="Chocolate" label="Chocolate" value="Chocolate" />
    <RadioNew id="Strawberry" label="Strawberry" value="Strawberry" />
    <RadioNew id="Mint Chip" label="Mint Chip" value="Mint Chip" />
  </RadioGroup>

  <h3 class="tw-mt-6">Buttons</h3>
  <RadioGroup orientation="vertical" variant="button" label="Ice cream flavor" name="orientation-vertical-button">
    <RadioNew id="Vanilla" label="Vanilla" value="Vanilla" />
    <RadioNew id="Chocolate" label="Chocolate" value="Chocolate" />
    <RadioNew id="Strawberry" label="Strawberry" value="Strawberry" />
    <RadioNew id="Mint Chip" label="Mint Chip" value="Mint Chip" />
  </RadioGroup>

  <h3 class="tw-mt-6">Chips</h3>
  <RadioGroup orientation="vertical" variant="chip" label="Ice cream flavor" name="orientation-vertical-chip">
    <RadioNew id="Vanilla" label="Vanilla" value="Vanilla" />
    <RadioNew id="Chocolate" label="Chocolate" value="Chocolate" />
    <RadioNew id="Strawberry" label="Strawberry" value="Strawberry" />
    <RadioNew id="Mint Chip" label="Mint Chip" value="Mint Chip" />
  </RadioGroup>
</template>

Responsive full width button groups

At this time we are not able to provide responsive full width button groups due to their dynamic nature. It is up to the developer to control the orientation based on the window width, and how their button group interacts with the surrounding layout.

Resize the example below to see it in action.

Ice cream flavor
vue
<script setup lang="ts">
  import { onMounted, onUnmounted, ref } from 'vue';

  import RadioGroup, { RadioGroupProps } from '../../../src/components/RadioGroup/RadioGroup.vue';
  import RadioNew from '../../../src/components/RadioNew/RadioNew.vue';

  const resizeObserver = ref<ResizeObserver>();
  const buttonGroupOrientation = ref<RadioGroupProps['orientation']>('horizontal');

  onMounted(() => {
    resizeObserver.value = new ResizeObserver(() => {
      // Add in your own window widths here depending on your use case.
      // Some designs might need to check multiple breakpoints.
      buttonGroupOrientation.value = window.innerWidth < 650 ? 'vertical' : 'horizontal';
    });

    resizeObserver.value.observe(window.document.body);
  });

  onUnmounted(() => {
    // always make sure to disconnect the observer!
    if (resizeObserver.value) {
      resizeObserver.value.disconnect();
    }
  });
</script>

<template>
  <RadioGroup
    full-width
    variant="button"
    label="Ice cream flavor"
    name="responsive-full-width"
    :orientation="buttonGroupOrientation"
  >
    <RadioNew id="Vanilla" label="Vanilla" value="Vanilla" />
    <RadioNew id="Chocolate" label="Chocolate" value="Chocolate" />
    <RadioNew id="Strawberry" label="Strawberry" value="Strawberry" />
    <RadioNew id="Mint Chip" label="Mint Chip" value="Mint Chip" />
  </RadioGroup>
</template>

Disabled

You can indicate that a specific Radio option is disabled by setting its disabled prop.

template
<RadioGroup
  variant="radio"
  v-model="disabledRadios"
  name="radio-variant"
  class="tw-mb-3"
>
  <RadioNew
    v-for="option in ['one', 'two',]"
    :id="option"
    :label="option"
    :value="option"
    disabled
  />
</RadioGroup>

API

See the documentation below for a complete reference to all the props and classes available to the components mentioned here.