RadioGroupUpdated
Radio group for selecting a single option from a list
Usage
import { RadioGroup, Radio } from '@heroui/react';Anatomy
import {RadioGroup, Radio, Label, Description, FieldError} from '@heroui/react';
export default () => (
<RadioGroup>
<Label />
<Description />
<Radio value="option1">
<Radio.Content> {/* The clickable area: control + label */}
<Radio.Control>
<Radio.Indicator>
<span>✓</span> {/* Custom indicator (optional) */}
</Radio.Indicator>
</Radio.Control>
Label {/* plain text — the clickable label */}
</Radio.Content>
<Description /> {/* Sibling — stays outside the button (announced via aria-describedby) */}
<FieldError /> {/* Optional — per-radio validation message */}
</Radio>
<FieldError /> {/* Optional — group-level validation */}
</RadioGroup>
)Examples
Horizontal Orientation
Variants
The RadioGroup component supports two visual variants:
primary(default) - Standard styling with default background, suitable for most use casessecondary- Lower emphasis variant, suitable for use in Surface components
In Surface
When used inside a Surface component, use variant="secondary" to apply the lower emphasis variant suitable for surface backgrounds.
Disabled
Controlled
Uncontrolled
Combine defaultValue with onChange when you only need to react to updates.
Validation
Delivery & Payment
Custom Indicator
Render Function
Customization
Tailwind CSS
Global CSS
To customize the RadioGroup component classes, you can use the @layer components directive.
Learn more.
@layer components {
.radio-group {
@apply gap-2;
}
.radio {
@apply gap-4 rounded-lg border border-border p-3 hover:bg-surface-hovered;
}
.radio__control {
@apply border-2 border-accent;
}
.radio__indicator {
@apply bg-primary;
}
.radio__content {
@apply gap-1;
}
}Styling Reference
HeroUI follows the BEM methodology to ensure component variants and states are reusable and easy to customize.
CSS Classes
The RadioGroup component uses these CSS classes (View source styles):
Base Classes
.radio-group- Base radio group container.radio- Individual radio item.radio__content- Radio button (RAC label wrapper for control + label text).radio__control- Radio control (circular button).radio__indicator- Radio indicator (inner dot)
Modifier Classes
.radio--disabled- Disabled radio state
Interactive States
The radio supports both CSS pseudo-classes and data attributes for flexibility:
- Selected:
[aria-checked="true"]or[data-selected="true"](indicator appears) - Hover:
:hoveror[data-hovered="true"](border color changes) - Focus:
:focus-visibleor[data-focus-visible="true"](shows focus ring) - Pressed:
:activeor[data-pressed="true"](scale transform) - Disabled:
:disabledor[aria-disabled="true"](reduced opacity, no pointer events) - Invalid:
[data-invalid="true"]or[aria-invalid="true"](error border color)
API Reference
RadioGroup
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | - | The current value (controlled) |
defaultValue | string | - | The default value (uncontrolled) |
onChange | (value: string) => void | - | Handler called when the value changes |
isDisabled | boolean | false | Whether the radio group is disabled |
isRequired | boolean | false | Whether the radio group is required |
isReadOnly | boolean | false | Whether the radio group is read only |
isInvalid | boolean | false | Whether the radio group is in an invalid state |
variant | "primary" | "secondary" | "primary" | Visual variant of the component. primary is the default style with shadow. secondary is a lower emphasis variant without shadow, suitable for use in surfaces. |
name | string | - | The name of the radio group, used when submitting an HTML form |
orientation | 'horizontal' | 'vertical' | 'vertical' | The orientation of the radio group |
children | React.ReactNode | (values: RadioGroupRenderProps) => React.ReactNode | - | Radio group content or render prop |
render | DOMRenderFunction<keyof React.JSX.IntrinsicElements, RadioGroupRenderProps> | - | Overrides the default DOM element with a custom render function. |
Radio
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | - | The value of the radio button |
isDisabled | boolean | false | Whether the radio button is disabled |
name | string | - | The name of the radio button, used when submitting an HTML form |
children | React.ReactNode | (values: RadioFieldRenderProps) => React.ReactNode | - | Radio content or field render prop |
render | DOMRenderFunction<keyof React.JSX.IntrinsicElements, RadioFieldRenderProps> | - | Overrides the default DOM element with a custom render function. |
Radio.Control
Extends React.HTMLAttributes<HTMLSpanElement>.
| Prop | Type | Default | Description |
|---|---|---|---|
children | React.ReactNode | - | The content to render inside the control wrapper (typically Radio.Indicator) |
Radio.Indicator
Extends React.HTMLAttributes<HTMLSpanElement>.
| Prop | Type | Default | Description |
|---|---|---|---|
children | React.ReactNode | (values: RadioButtonRenderProps) => React.ReactNode | - | Optional content or render prop that receives the current radio button state. |
Radio.Content
The clickable area of the radio (the <label> wrapping the hidden input). Place Radio.Control and the Label inside it. className accepts a render function that receives RadioButtonRenderProps.
| Prop | Type | Default | Description |
|---|---|---|---|
children | React.ReactNode | (values: RadioButtonRenderProps) => React.ReactNode | - | The clickable content (typically Radio.Control and Label) |
RadioFieldRenderProps
When using a render prop on the root Radio, these field-level values are provided:
| Prop | Type | Description |
|---|---|---|
isSelected | boolean | Whether the radio is currently selected |
isDisabled | boolean | Whether the radio is disabled |
isReadOnly | boolean | Whether the radio is read only |
isInvalid | boolean | Whether the radio is in an invalid state |
isRequired | boolean | Whether the radio is required |
RadioButtonRenderProps
Radio.Control and Radio.Indicator use button-level render props (isHovered, isPressed, isFocusVisible, etc.). Pass a function as Radio.Control children or to Radio.Indicator to access them.





