Radio Group
Allows single selection from multiple options.
Anatomy
To set up the radio group correctly, you'll need to understand its anatomy and how we name its parts.
Each part includes a
data-part
attribute to help identify them in the DOM.
Design impact on the asChild property
The RadioGroup.Item
element of the radio group is a label
element. This is because the radio
group is a form control and should be associated with a label to provide context and meaning to the
user. Otherwise, the HTML and accessibility structure will be invalid.
If you need to use the
asChild
property, make sure that thelabel
element is the direct child of theRadioGroup.Item
component.
Examples
Learn how to use the RadioGroup
component in your project. Let's take a look at the most basic
example:
import { RadioGroup } from '@ark-ui/react'
export const Basic = () => {
const frameworks = ['React', 'Solid', 'Vue']
return (
<RadioGroup.Root>
<RadioGroup.Label>Framework</RadioGroup.Label>
<RadioGroup.Indicator />
{frameworks.map((framework) => (
<RadioGroup.Item key={framework} value={framework}>
<RadioGroup.ItemText>{framework}</RadioGroup.ItemText>
<RadioGroup.ItemControl />
<RadioGroup.ItemHiddenInput />
</RadioGroup.Item>
))}
</RadioGroup.Root>
)
}
import { Index } from 'solid-js'
import { RadioGroup } from '@ark-ui/solid'
export const Basic = () => {
const frameworks = ['React', 'Solid', 'Vue']
return (
<RadioGroup.Root>
<RadioGroup.Label>Framework</RadioGroup.Label>
<RadioGroup.Indicator />
<Index each={frameworks}>
{(framework) => (
<RadioGroup.Item value={framework()}>
<RadioGroup.ItemText>{framework()}</RadioGroup.ItemText>
<RadioGroup.ItemControl />
<RadioGroup.ItemHiddenInput />
</RadioGroup.Item>
)}
</Index>
</RadioGroup.Root>
)
}
<script setup lang="ts">
import { ref } from 'vue'
import { RadioGroup } from '@ark-ui/vue'
const frameworks = ref(['React', 'Solid', 'Vue'])
</script>
<template>
<RadioGroup.Root>
<RadioGroup.Label>Framework</RadioGroup.Label>
<RadioGroup.Indicator />
<RadioGroup.Item v-for="framework in frameworks" :key="framework" :value="framework">
<RadioGroup.ItemText>{{ framework }}</RadioGroup.ItemText>
<RadioGroup.ItemControl />
<RadioGroup.ItemHiddenInput />
</RadioGroup.Item>
</RadioGroup.Root>
</template>
Disabling the radio group
To make a radio group disabled, set the disabled
prop to true
.
import { RadioGroup } from '@ark-ui/react'
export const Disabled = () => {
const frameworks = ['React', 'Solid', 'Vue']
return (
<RadioGroup.Root disabled>
<RadioGroup.Label>Framework</RadioGroup.Label>
{frameworks.map((framework) => (
<RadioGroup.Item key={framework} value={framework}>
<RadioGroup.ItemText>{framework}</RadioGroup.ItemText>
<RadioGroup.ItemControl />
<RadioGroup.ItemHiddenInput />
</RadioGroup.Item>
))}
</RadioGroup.Root>
)
}
import { Index } from 'solid-js'
import { RadioGroup } from '@ark-ui/solid'
export const Disabled = () => {
const frameworks = ['React', 'Solid', 'Vue']
return (
<RadioGroup.Root disabled>
<RadioGroup.Label>Framework</RadioGroup.Label>
<Index each={frameworks}>
{(framework) => (
<RadioGroup.Item value={framework()}>
<RadioGroup.ItemText>{framework()}</RadioGroup.ItemText>
<RadioGroup.ItemControl />
<RadioGroup.ItemHiddenInput />
</RadioGroup.Item>
)}
</Index>
</RadioGroup.Root>
)
}
<script setup lang="ts">
import { ref } from 'vue'
import { RadioGroup } from '@ark-ui/vue'
const frameworks = ref(['React', 'Solid', 'Vue'])
</script>
<template>
<RadioGroup.Root disabled>
<RadioGroup.Label>Framework</RadioGroup.Label>
<RadioGroup.Indicator />
<RadioGroup.Item v-for="framework in frameworks" :key="framework" :value="framework">
<RadioGroup.ItemText>{{ framework }}</RadioGroup.ItemText>
<RadioGroup.ItemControl />
<RadioGroup.ItemHiddenInput />
</RadioGroup.Item>
</RadioGroup.Root>
</template>
Setting the initial value
To set the radio group's initial value, set the defaultValue
prop to the value of the radio item
to be selected by default.
import { RadioGroup } from '@ark-ui/react'
export const InitialValue = () => {
const frameworks = ['React', 'Solid', 'Vue']
return (
<RadioGroup.Root defaultValue="Solid">
<RadioGroup.Label>Framework</RadioGroup.Label>
{frameworks.map((framework) => (
<RadioGroup.Item key={framework} value={framework}>
<RadioGroup.ItemText>{framework}</RadioGroup.ItemText>
<RadioGroup.ItemControl />
<RadioGroup.ItemHiddenInput />
</RadioGroup.Item>
))}
</RadioGroup.Root>
)
}
import { Index } from 'solid-js'
import { RadioGroup } from '@ark-ui/solid'
export const InitialValue = () => {
const frameworks = ['React', 'Solid', 'Vue']
return (
<RadioGroup.Root value="Solid">
<RadioGroup.Label>Framework</RadioGroup.Label>
<Index each={frameworks}>
{(framework) => (
<RadioGroup.Item value={framework()}>
<RadioGroup.ItemText>{framework()}</RadioGroup.ItemText>
<RadioGroup.ItemControl />
<RadioGroup.ItemHiddenInput />
</RadioGroup.Item>
)}
</Index>
</RadioGroup.Root>
)
}
<script setup lang="ts">
import { ref } from 'vue'
import { RadioGroup } from '@ark-ui/vue'
const frameworks = ref(['React', 'Solid', 'Vue'])
</script>
<template>
<RadioGroup.Root model-value="Solid">
<RadioGroup.Label>Framework</RadioGroup.Label>
<RadioGroup.Indicator />
<RadioGroup.Item v-for="framework in frameworks" :key="framework" :value="framework">
<RadioGroup.ItemText>{{ framework }}</RadioGroup.ItemText>
<RadioGroup.ItemControl />
<RadioGroup.ItemHiddenInput />
</RadioGroup.Item>
</RadioGroup.Root>
</template>
Listening for changes
When the radio group value changes, the onValueChange
callback is invoked.
import { RadioGroup } from '@ark-ui/react'
export const OnEvent = () => {
const frameworks = ['React', 'Solid', 'Vue']
return (
<RadioGroup.Root onValueChange={(details) => console.log(details.value)}>
<RadioGroup.Label>Framework</RadioGroup.Label>
{frameworks.map((framework) => (
<RadioGroup.Item key={framework} value={framework}>
<RadioGroup.ItemText>{framework}</RadioGroup.ItemText>
<RadioGroup.ItemControl />
<RadioGroup.ItemHiddenInput />
</RadioGroup.Item>
))}
</RadioGroup.Root>
)
}
import { Index } from 'solid-js'
import { RadioGroup } from '@ark-ui/solid'
export const OnEvent = () => {
const frameworks = ['React', 'Solid', 'Vue']
return (
<RadioGroup.Root onValueChange={(details) => console.log(details.value)}>
<RadioGroup.Label>Framework</RadioGroup.Label>
<Index each={frameworks}>
{(framework) => (
<RadioGroup.Item value={framework()}>
<RadioGroup.ItemText>{framework()}</RadioGroup.ItemText>
<RadioGroup.ItemControl />
<RadioGroup.ItemHiddenInput />
</RadioGroup.Item>
)}
</Index>
</RadioGroup.Root>
)
}
<script setup lang="ts">
import { ref } from 'vue'
import { RadioGroup } from '@ark-ui/vue'
const frameworks = ref(['React', 'Solid', 'Vue'])
</script>
<template>
<RadioGroup.Root @value-change="(details) => console.log(details.value)">
<RadioGroup.Label>Framework</RadioGroup.Label>
<RadioGroup.Indicator />
<RadioGroup.Item v-for="framework in frameworks" :key="framework" :value="framework">
<RadioGroup.ItemText>{{ framework }}</RadioGroup.ItemText>
<RadioGroup.ItemControl />
<RadioGroup.ItemHiddenInput />
</RadioGroup.Item>
</RadioGroup.Root>
</template>
API Reference
Root
Prop | Default | Type |
---|---|---|
asChild | boolean Render as a different element type. | |
defaultValue | string The initial value of the radio group when it is first rendered. Use when you do not need to control the state of the radio group. | |
disabled | boolean If `true`, the radio group will be disabled | |
form | string The associate form of the underlying input. | |
id | string The unique identifier of the machine. | |
ids | Partial<{
root: string
label: string
indicator: string
item(value: string): string
itemLabel(value: string): string
itemControl(value: string): string
itemHiddenInput(value: string): string
}> The ids of the elements in the radio. Useful for composition. | |
name | string The name of the input fields in the radio (Useful for form submission). | |
onValueChange | (details: ValueChangeDetails) => void Function called once a radio is checked | |
orientation | 'horizontal' | 'vertical' Orientation of the radio group | |
readOnly | boolean Whether the checkbox is read-only | |
value | string The value of the checked radio |
Data Attribute | Value |
---|---|
[data-scope] | radio-group |
[data-part] | root |
[data-orientation] | The orientation of the radio-group |
[data-disabled] | Present when disabled |
Indicator
Prop | Default | Type |
---|---|---|
asChild | boolean Render as a different element type. |
Data Attribute | Value |
---|---|
[data-scope] | radio-group |
[data-part] | indicator |
[data-disabled] | Present when disabled |
[data-orientation] | The orientation of the indicator |
ItemControl
Prop | Default | Type |
---|---|---|
asChild | boolean Render as a different element type. |
Data Attribute | Value |
---|---|
[data-scope] | radio-group |
[data-part] | item-control |
[data-active] | Present when active or pressed |
ItemHiddenInput
Prop | Default | Type |
---|---|---|
asChild | boolean Render as a different element type. |
Item
Prop | Default | Type |
---|---|---|
value | string | |
asChild | boolean Render as a different element type. | |
disabled | boolean | |
invalid | boolean |
ItemText
Prop | Default | Type |
---|---|---|
asChild | boolean Render as a different element type. |
Label
Prop | Default | Type |
---|---|---|
asChild | boolean Render as a different element type. |
Data Attribute | Value |
---|---|
[data-scope] | radio-group |
[data-part] | label |
[data-orientation] | The orientation of the label |
[data-disabled] | Present when disabled |
RootProvider
Prop | Default | Type |
---|---|---|
value | UseRadioGroupReturn | |
asChild | boolean Render as a different element type. |
Accessibility
Complies with the Radio WAI-ARIA design pattern.
Keyboard Support
Key | Description |
---|---|
Tab | Moves focus to either the checked radio item or the first radio item in the group. |
Space | When focus is on an unchecked radio item, checks it. |
ArrowDown | Moves focus and checks the next radio item in the group. |
ArrowRight | Moves focus and checks the next radio item in the group. |
ArrowUp | Moves focus to the previous radio item in the group. |
ArrowLeft | Moves focus to the previous radio item in the group. |