Radio Group
Radio Groups contain a set of checkable buttons where only one of the buttons can be checked at a time.
Introduction
'use client';
import * as React from 'react';
import * as RadioGroup from '@base_ui/react/RadioGroup';
import * as Radio from '@base_ui/react/Radio';
import { styled } from '@mui/system';
export default function UnstyledRadioGroupIntroduction() {
  return (
    <RadioGroup.Root name="root" style={{ display: 'flex', gap: 8 }}>
      <RadioItem value="light">
        <Indicator />
        Light
      </RadioItem>
      <RadioItem value="medium">
        <Indicator />
        Medium
      </RadioItem>
      <RadioItem value="heavy">
        <Indicator />
        Heavy
      </RadioItem>
    </RadioGroup.Root>
  );
}
const grey = {
  100: '#E5EAF2',
  200: '#D8E0E9',
  300: '#CBD4E2',
};
const blue = {
  400: '#3399FF',
  600: '#0072E6',
  800: '#004C99',
};
const RadioItem = styled(Radio.Root)`
  display: flex;
  align-items: center;
  padding: 8px 16px;
  border-radius: 4px;
  border: none;
  background-color: ${grey[100]};
  color: black;
  outline: none;
  font-size: 16px;
  cursor: default;
  &:hover {
    background-color: ${grey[100]};
  }
  &:focus-visible {
    outline: 2px solid ${blue[400]};
    outline-offset: 2px;
  }
  &[data-radio='checked'] {
    background-color: ${blue[600]};
    color: white;
  }
`;
const Indicator = styled(Radio.Indicator)`
  border-radius: 50%;
  width: 8px;
  height: 8px;
  margin-right: 8px;
  outline: 1px solid black;
  &[data-radio='checked'] {
    background-color: white;
    border: none;
    outline: none;
  }
`;
Installation
Base UI components are all available as a single package.
npm install @base_ui/react
Once you have the package installed, import the component.
import * as RadioGroup from '@base_ui/react/RadioGroup'; import * as Radio from '@base_ui/react/Radio';
Anatomy
Radio Group is composed of a Root and Radio components:
- <RadioGroup.Root />is a top-level element that wraps the other components.
- <Radio.Root />renders an individual- <button>radio item.
- <Radio.Indicator />renders a- <span>for providing a visual indicator. You can style this itself and/or place an icon inside.
<RadioGroup.Root>
  <Radio.Root>
    <Radio.Indicator />
  </Radio.Root>
</RadioGroup.Root>Identifying items
The value prop is required on Radio.Root to identify it in the Radio Group:
<RadioGroup.Root>
  <Radio.Root value="a">
    <Radio.Indicator />
  </Radio.Root>
  <Radio.Root value="b">
    <Radio.Indicator />
  </Radio.Root>
</RadioGroup.Root>Default value
The defaultValue prop determines the initial value of the component when uncontrolled, linked to the value prop on an individual Radio item:
<RadioGroup.Root defaultValue="a">
  <Radio.Root value="a" />
  <Radio.Root value="b" />
</RadioGroup.Root>Controlled
The value and onValueChange props contain the value string of the currently selected Radio item in the Radio Group:
const [value, setValue] = React.useState('a');
 
return (
  <RadioGroup.Root value={value} onValueChange={setValue}>
    <Radio.Root value="a" />
    <Radio.Root value="b" />
  </RadioGroup.Root>
);Styling
The Radio components have a [data-radio] attribute with values "checked" or "unchecked" to style based on the checked state:
<Radio.Root className="Radio">
  <Radio.Indicator className="RadioIndicator" />
</Radio.Root>.Radio {
  border: 1px solid black;
}
 
.RadioIndicator {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  border: 1px solid black;
}
 
.Radio[data-radio='checked'] {
  background: black;
  color: white;
}
 
.RadioIndicator[data-radio='checked'] {
  background: white;
}API Reference
RadioGroupRoot
| Prop | Type | Default | Description | 
|---|---|---|---|
| className | union | Class names applied to the element or a function that returns them based on the component's state. | |
| defaultValue | any | The default value of the selected radio button. Use when uncontrolled. | |
| disabled | bool | false | Determines if the radio group is disabled. | 
| name | string | The name of the radio group submitted with the form data. | |
| onValueChange | func | Callback fired when the value changes. | |
| readOnly | bool | false | Determines if the radio group is readonly. | 
| render | union | A function to customize rendering of the component. | |
| required | bool | false | Determines if the radio group is required. | 
| value | any | The value of the selected radio button. Use when controlled. | 
RadioRoot
| Prop | Type | Default | Description | 
|---|---|---|---|
| value | any | The unique identifying value of the radio in a group. | |
| className | union | Class names applied to the element or a function that returns them based on the component's state. | |
| disabled | bool | false | Determines if the radio is disabled. | 
| readOnly | bool | false | Determines if the radio is readonly. | 
| render | union | A function to customize rendering of the component. | |
| required | bool | false | Determines if the radio is required. | 
RadioIndicator
| Prop | Type | Default | Description | 
|---|---|---|---|
| className | union | Class names applied to the element or a function that returns them based on the component's state. | |
| keepMounted | bool | true | Whether the component should be kept mounted when not checked. | 
| render | union | A function to customize rendering of the component. |