Radio Group
The Radio Group allows the user to select one option from a set.
Use radio buttons when the user needs to see all available options. If available options can be collapsed, consider using a Select component because it uses less space.
Radio buttons should have the most commonly used option selected by default.
Radio group
RadioGroup is a helpful wrapper used to group Radio components that provides an easier API, and proper keyboard accessibility to the group.
import * as React from 'react';
import Radio from '@mui/material/Radio';
import RadioGroup from '@mui/material/RadioGroup';
import FormControlLabel from '@mui/material/FormControlLabel';
import FormControl from '@mui/material/FormControl';
import FormLabel from '@mui/material/FormLabel';
export default function RadioButtonsGroup() {
const id = React.useId();
return (
<FormControl>
<FormLabel id={`${id}-label`}>Gender</FormLabel>
<RadioGroup
aria-labelledby={`${id}-label`}
defaultValue="female"
name="radio-buttons-group"
>
<FormControlLabel value="female" control={<Radio />} label="Female" />
<FormControlLabel value="male" control={<Radio />} label="Male" />
<FormControlLabel value="other" control={<Radio />} label="Other" />
</RadioGroup>
</FormControl>
);
}
Direction
To lay out the buttons horizontally, set the row prop:
import * as React from 'react';
import Radio from '@mui/material/Radio';
import RadioGroup from '@mui/material/RadioGroup';
import FormControlLabel from '@mui/material/FormControlLabel';
import FormControl from '@mui/material/FormControl';
import FormLabel from '@mui/material/FormLabel';
export default function RowRadioButtonsGroup() {
const id = React.useId();
return (
<FormControl>
<FormLabel id={`${id}-label`}>Gender</FormLabel>
<RadioGroup row aria-labelledby={`${id}-label`} name="row-radio-buttons-group">
<FormControlLabel value="female" control={<Radio />} label="Female" />
<FormControlLabel value="male" control={<Radio />} label="Male" />
<FormControlLabel value="other" control={<Radio />} label="Other" />
<FormControlLabel
value="disabled"
disabled
control={<Radio />}
label="other"
/>
</RadioGroup>
</FormControl>
);
}
Controlled
You can control the radio with the value and onChange props:
import * as React from 'react';
import Radio from '@mui/material/Radio';
import RadioGroup from '@mui/material/RadioGroup';
import FormControlLabel from '@mui/material/FormControlLabel';
import FormControl from '@mui/material/FormControl';
import FormLabel from '@mui/material/FormLabel';
export default function ControlledRadioButtonsGroup() {
const id = React.useId();
const [value, setValue] = React.useState('female');
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setValue((event.target as HTMLInputElement).value);
};
return (
<FormControl>
<FormLabel id={`${id}-label`}>Gender</FormLabel>
<RadioGroup
aria-labelledby={`${id}-label`}
name="controlled-radio-buttons-group"
value={value}
onChange={handleChange}
>
<FormControlLabel value="female" control={<Radio />} label="Female" />
<FormControlLabel value="male" control={<Radio />} label="Male" />
</RadioGroup>
</FormControl>
);
}
Standalone radio buttons
Radio can also be used standalone, without the RadioGroup wrapper.
import * as React from 'react';
import Radio from '@mui/material/Radio';
export default function RadioButtons() {
const [selectedValue, setSelectedValue] = React.useState('a');
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setSelectedValue(event.target.value);
};
return (
<div>
<Radio
checked={selectedValue === 'a'}
onChange={handleChange}
value="a"
name="radio-buttons"
slotProps={{ input: { 'aria-label': 'A' } }}
/>
<Radio
checked={selectedValue === 'b'}
onChange={handleChange}
value="b"
name="radio-buttons"
slotProps={{ input: { 'aria-label': 'B' } }}
/>
</div>
);
}
Size
Use the size prop or customize the font size of the svg icons to change the size of the radios.
import * as React from 'react';
import Radio from '@mui/material/Radio';
export default function SizeRadioButtons() {
const [selectedValue, setSelectedValue] = React.useState('a');
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setSelectedValue(event.target.value);
};
const controlProps = (item: string) => ({
checked: selectedValue === item,
onChange: handleChange,
value: item,
name: 'size-radio-button-demo',
slotProps: { input: { 'aria-label': item } },
});
return (
<div>
<Radio {...controlProps('a')} size="small" />
<Radio {...controlProps('b')} />
<Radio
{...controlProps('c')}
sx={{
'& .MuiSvgIcon-root': {
fontSize: 28,
},
}}
/>
</div>
);
}
import * as React from 'react';
import { pink } from '@mui/material/colors';
import Radio from '@mui/material/Radio';
export default function ColorRadioButtons() {
const [selectedValue, setSelectedValue] = React.useState('a');
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setSelectedValue(event.target.value);
};
const controlProps = (item: string) => ({
checked: selectedValue === item,
onChange: handleChange,
value: item,
name: 'color-radio-button-demo',
slotProps: { input: { 'aria-label': item } },
});
return (
<div>
<Radio {...controlProps('a')} />
<Radio {...controlProps('b')} color="secondary" />
<Radio {...controlProps('c')} color="success" />
<Radio {...controlProps('d')} color="default" />
<Radio
{...controlProps('e')}
sx={{
color: pink[800],
'&.Mui-checked': {
color: pink[600],
},
}}
/>
</div>
);
}
Label placement
You can change the placement of the label with the FormControlLabel component's labelPlacement prop:
Show error
In general, radio buttons should have a value selected by default. If this is not the case, you can display an error if no value is selected when the form is submitted:
Customization
Here is an example of customizing the component. You can learn more about this in the overrides documentation page.
useRadioGroup
For advanced customization use cases, a useRadioGroup() hook is exposed.
It returns the context value of the parent radio group.
The Radio component uses this hook internally.
API
import { useRadioGroup } from '@mui/material/RadioGroup';
Returns
value (object):
value.name(string [optional]): The name used to reference the value of the control.value.onChange(func [optional]): Callback fired when a radio button is selected.value.value(any [optional]): Value of the selected radio button.
Example
import { styled } from '@mui/material/styles';
import RadioGroup, { useRadioGroup } from '@mui/material/RadioGroup';
import FormControlLabel from '@mui/material/FormControlLabel';
import type { FormControlLabelProps } from '@mui/material/FormControlLabel';
import Radio from '@mui/material/Radio';
interface StyledFormControlLabelProps extends FormControlLabelProps {
checked: boolean;
}
const StyledFormControlLabel = styled((props: StyledFormControlLabelProps) => (
<FormControlLabel {...props} />
))(({ theme }) => ({
variants: [
{
props: { checked: true },
style: {
'.MuiFormControlLabel-label': {
color: theme.palette.primary.main,
},
},
},
],
}));
function MyFormControlLabel(props: FormControlLabelProps) {
const radioGroup = useRadioGroup();
let checked = false;
if (radioGroup) {
checked = radioGroup.value === props.value;
}
return <StyledFormControlLabel checked={checked} {...props} />;
}
export default function UseRadioGroup() {
return (
<RadioGroup name="use-radio-group" defaultValue="first">
<MyFormControlLabel value="first" label="First" control={<Radio />} />
<MyFormControlLabel value="second" label="Second" control={<Radio />} />
</RadioGroup>
);
}
When to use
Accessibility
(WAI-ARIA: https://www.w3.org/WAI/ARIA/apg/patterns/radio/)
All form controls should have labels, and this includes radio buttons, checkboxes, and switches. In most cases, this is done by using the
<label>element (FormControlLabel).When a label can't be used, it's necessary to add an attribute directly to the input component. In this case, you can apply the additional attribute (for example
aria-label,aria-labelledby,title) via theslotProps.inputproperty.
<Radio
value="radioA"
slotProps={{
input: { 'aria-label': 'Radio A' },
}}
/>
API
See the documentation below for a complete reference to all of the props and classes available to the components mentioned here.