Skip to main content

Radio

Please refer to MUI's official docs for more details on component's usage guide and API documentation.

RadioGroup

RadioGroup is a helpful wrapper used to group Radio components that provides an easier API, and proper keyboard accessibility to the group.


// MUI Imports
import Radio from '@mui/material/Radio'
import RadioGroup from '@mui/material/RadioGroup'
import FormControl from '@mui/material/FormControl'
import FormControlLabel from '@mui/material/FormControlLabel'

const RadioGroupComponent = () => {
return (
<FormControl className='flex-wrap flex-row'>
<RadioGroup row defaultValue='checked' name='basic-radio' aria-label='basic-radio'>
<FormControlLabel value='checked' control={<Radio />} label='Checked' />
<FormControlLabel value='unchecked' control={<Radio />} label='Unchecked' />
</RadioGroup>

<RadioGroup row value='disabled-checked' name='basic-disabled-radio' aria-label='basic-disabled-radio'>
<FormControlLabel disabled value='disabled-checked' label='Disabled Checked' control={<Radio />} />
<FormControlLabel disabled value='disabled-unchecked' label='Disabled Unchecked' control={<Radio />} />
</RadioGroup>
</FormControl>
)
}

export default RadioGroupComponent
Controlled and Uncontrolled

Manage value prop with RadioGroup component with the help of a state for controlled radio defaultValue prop with RadioGroup component for uncontrolled radio.

Controlled

Uncontrolled


// React Imports
import { useState } from 'react'
import type { ChangeEvent } from 'react'

// MUI Imports
import Grid from '@mui/material/Grid'
import Radio from '@mui/material/Radio'
import Typography from '@mui/material/Typography'
import RadioGroup from '@mui/material/RadioGroup'
import FormControlLabel from '@mui/material/FormControlLabel'

const RadioControlledUncontrolled = () => {
// States
const [value, setValue] = useState<string>('controlled-checked')

const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
setValue((event.target as HTMLInputElement).value)
}

return (
<Grid container spacing={6}>
<Grid item xs={12} sm={6}>
<Typography color='text.primary'>Controlled</Typography>
<RadioGroup row aria-label='controlled' name='controlled' value={value} onChange={handleChange}>
<FormControlLabel value='controlled-checked' control={<Radio />} label='Checked' />
<FormControlLabel value='controlled-unchecked' control={<Radio />} label='Unchecked' />
</RadioGroup>
</Grid>
<Grid item xs={12} sm={6}>
<Typography color='text.primary'>Uncontrolled</Typography>
<RadioGroup row aria-label='uncontrolled' name='uncontrolled' defaultValue='uncontrolled-checked'>
<FormControlLabel value='uncontrolled-checked' control={<Radio />} label='Checked' />
<FormControlLabel value='uncontrolled-unchecked' control={<Radio />} label='Unchecked' />
</RadioGroup>
</Grid>
</Grid>
)
}

export default RadioControlledUncontrolled
Standalone Radio Buttons

Radio can also be used standalone, without the RadioGroup wrapper.


// React Imports
import { useState } from 'react'
import type { ChangeEvent } from 'react'

// MUI Imports
import Radio from '@mui/material/Radio'

const RadioStandalone = () => {
// States
const [selectedValue, setSelectedValue] = useState<string>('a')

const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
setSelectedValue(event.target.value)
}

return (
<div>
<Radio
value='a'
onChange={handleChange}
name='radio-button-demo'
checked={selectedValue === 'a'}
inputProps={{ 'aria-label': 'A' }}
/>
<Radio
value='b'
onChange={handleChange}
name='radio-button-demo'
checked={selectedValue === 'b'}
inputProps={{ 'aria-label': 'B' }}
/>
</div>
)
}

export default RadioStandalone
Colors

Use color prop with Radio component for different colored radio button


// MUI Imports
import Radio from '@mui/material/Radio'
import FormControlLabel from '@mui/material/FormControlLabel'

const RadioColor = () => {
return (
<>
<FormControlLabel value='primary' control={<Radio defaultChecked />} label='Primary' />
<FormControlLabel value='secondary' control={<Radio defaultChecked color='secondary' />} label='Secondary' />
<FormControlLabel value='success' label='Success' control={<Radio defaultChecked color='success' />} />
<FormControlLabel value='error' label='Error' control={<Radio defaultChecked color='error' />} />
<FormControlLabel value='warning' label='Warning' control={<Radio defaultChecked color='warning' />} />
<FormControlLabel value='info' label='Info' control={<Radio defaultChecked color='info' />} />
</>
)
}

export default RadioColor
Sizes

Use size prop with Radio component for different size radio button


// MUI Imports
import Radio from '@mui/material/Radio'
import RadioGroup from '@mui/material/RadioGroup'
import FormControlLabel from '@mui/material/FormControlLabel'

const RadioSizes = () => {
return (
<RadioGroup row aria-label='sizes' name='sizes' defaultValue='small'>
<FormControlLabel value='small' control={<Radio size='small' />} label='Small' />
<FormControlLabel value='medium' control={<Radio />} label='Medium' />
</RadioGroup>
)
}

export default RadioSizes
Customized Radio

Use styled hook to customize your radio button.

Gender

// MUI Imports
import Radio from '@mui/material/Radio'
import { styled } from '@mui/material/styles'
import FormLabel from '@mui/material/FormLabel'
import RadioGroup from '@mui/material/RadioGroup'
import FormControl from '@mui/material/FormControl'
import FormControlLabel from '@mui/material/FormControlLabel'
import type { RadioProps } from '@mui/material/Radio'

const BpIcon = styled('span')(({ theme }) => ({
width: 16,
height: 16,
borderRadius: '50%',
backgroundColor: theme.palette.mode === 'dark' ? '#394b59' : '#f5f8fa',
'input:hover ~ &': {
backgroundColor: theme.palette.mode === 'dark' ? '#30404d' : '#ebf1f5'
},
'.Mui-focusVisible &': {
outlineOffset: 2,
outline: '2px auto rgba(19,124,189,.6)'
},
'input:disabled ~ &': {
boxShadow: 'none',
background: theme.palette.mode === 'dark' ? 'rgba(57,75,89,.5)' : 'rgba(206,217,224,.5)'
},
boxShadow:
theme.palette.mode === 'dark'
? '0 0 0 1px rgb(16 22 26 / 40%)'
: 'inset 0 0 0 1px rgba(16,22,26,.2), inset 0 -1px 0 rgba(16,22,26,.1)',
backgroundImage:
theme.palette.mode === 'dark'
? 'linear-gradient(180deg,hsla(0,0%,100%,.05),hsla(0,0%,100%,0))'
: 'linear-gradient(180deg,hsla(0,0%,100%,.8),hsla(0,0%,100%,0))'
}))

const BpCheckedIcon = styled(BpIcon)({
backgroundColor: '#137cbd',
backgroundImage: 'linear-gradient(180deg,hsla(0,0%,100%,.1),hsla(0,0%,100%,0))',
'input:hover ~ &': {
backgroundColor: '#106ba3'
}
})

// Inspired by blueprints
const BpRadio = (props: RadioProps) => {
return (
<Radio
{...props}
disableRipple
color='default'
icon={<BpIcon />}
checkedIcon={<BpCheckedIcon />}
className='hover:bg-transparent'
/>
)
}

const RadioCustomized = () => {
return (
<FormControl>
<FormLabel component='legend'>Gender</FormLabel>
<RadioGroup row defaultValue='female' aria-label='gender' name='customized-radios'>
<FormControlLabel value='female' control={<BpRadio />} label='Female' />
<FormControlLabel value='male' control={<BpRadio />} label='Male' />
<FormControlLabel value='other' control={<BpRadio />} label='Other' />
<FormControlLabel value='disabled' disabled control={<BpRadio />} label='Disabled' />
</RadioGroup>
</FormControl>
)
}

export default RadioCustomized
Label Placement

You can change the placement of the label with FormControlLabel component's labelPlacement prop.


// MUI Imports
import Radio from '@mui/material/Radio'
import RadioGroup from '@mui/material/RadioGroup'
import FormControl from '@mui/material/FormControl'
import FormControlLabel from '@mui/material/FormControlLabel'

const RadioLabelPlacement = () => {
return (
<FormControl>
<RadioGroup row aria-label='position' name='vertical' defaultValue='top'>
<FormControlLabel value='top' label='Top' labelPlacement='top' className='mie-9' control={<Radio />} />
<FormControlLabel value='bottom' control={<Radio />} label='Bottom' labelPlacement='bottom' />
</RadioGroup>
<RadioGroup row aria-label='position' name='horizontal' defaultValue='start' className='mbs-4'>
<FormControlLabel value='start' label='Start' labelPlacement='start' className='mie-4' control={<Radio />} />
<FormControlLabel value='end' control={<Radio />} label='End' />
</RadioGroup>
</FormControl>
)
}

export default RadioLabelPlacement
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.

Pop quiz: MUI is...

Choose wisely


// React Imports
import { useState } from 'react'
import type { ChangeEvent, FormEvent } from 'react'

// MUI Imports
import Box from '@mui/material/Box'
import Radio from '@mui/material/Radio'
import Button from '@mui/material/Button'
import FormLabel from '@mui/material/FormLabel'
import RadioGroup from '@mui/material/RadioGroup'
import FormControl from '@mui/material/FormControl'
import FormHelperText from '@mui/material/FormHelperText'
import FormControlLabel from '@mui/material/FormControlLabel'

const RadioShowError = () => {
// States
const [value, setValue] = useState<string>('')
const [error, setError] = useState<boolean>(false)
const [helperText, setHelperText] = useState<string>('Choose wisely')

const handleRadioChange = (event: ChangeEvent<HTMLInputElement>) => {
setError(false)
setHelperText(' ')
setValue((event.target as HTMLInputElement).value)
}

const handleSubmit = (event: FormEvent<HTMLFormElement>) => {
event.preventDefault()

if (value === 'best') {
setError(false)
setHelperText('You got it!')
} else if (value === 'worst') {
setError(true)
setHelperText('Sorry, wrong answer!')
} else {
setError(true)
setHelperText('Please select an option.')
}
}

return (
<Box component='form' onSubmit={handleSubmit}>
<FormControl error={error}>
<FormLabel component='legend'>Pop quiz: MUI is...</FormLabel>
<RadioGroup aria-label='quiz' name='quiz' value={value} onChange={handleRadioChange}>
<FormControlLabel value='best' control={<Radio />} label='The best!' />
<FormControlLabel value='worst' control={<Radio />} label='The worst.' />
</RadioGroup>
<FormHelperText>{helperText}</FormHelperText>
<Button type='submit' variant='outlined' className='mbs-3'>
Check Answer
</Button>
</FormControl>
</Box>
)
}

export default RadioShowError