Radio

A radio input allows users to select only one option from a number of choices. Radio is generally displayed in a radio group.

Neutral selected states

When the platform-dst-tokens-finesse feature flag is enabled, this component uses the new neutral treatment for selected states.

Default

The default way to present a single option from a list.

In most situations where you want to present a list of mutually exclusive options, you will want to use a radio group.

import React from 'react'; import noop from '@atlaskit/ds-lib/noop'; import { Box } from '@atlaskit/primitives/compiled/box'; import Radio from '@atlaskit/radio/radio'; export default function RadioDefaultExample(): React.JSX.Element { return ( <Box> <Radio value="default radio" label="Default radio" name="radio-default" testId="radio-default" isChecked={true} onChange={noop} /> <Radio value="disabled radio" label="Disabled radio" name="radio-disabled" testId="radio-disabled" isChecked={false} isDisabled={true} onChange={noop} /> </Box> ); }

Complex radio usage

There may be some situations where you are unable to directly stack the radio inputs vertically (for example, within a table). In those situations, you can use individual Radio components rather than a RadioGroup.

BranchLast commitUpdated
masterdcc0f1514 minutes ago
feature/dark-modecbc0fa356 minutes ago
feature/right-to-left69568ea16 hours ago
bug/type-incorrect-for-checked-prop1159c76yesterday
currently selected value: 1
import { type SyntheticEvent, useCallback, useState } from 'react'; import { cssMap, jsx } from '@atlaskit/css'; import { Box } from '@atlaskit/primitives/compiled/box'; import Radio from '@atlaskit/radio/radio'; import { token } from '@atlaskit/tokens'; const styles = cssMap({ selectedValue: { marginBlock: token('space.200'), paddingBlockStart: token('space.100'), paddingInlineEnd: token('space.100'), paddingBlockEnd: token('space.100'), paddingInlineStart: token('space.100'), borderColor: token('color.border'), borderStyle: 'dashed', borderWidth: token('border.width'), color: token('color.text'), }, }); interface RadioOptions { id: number; value: string; name: string; description: string; commit: string; updated: string; } const items: Array<RadioOptions> = [ { id: 1, value: '1', name: 'branch', description: 'master', commit: 'dcc0f15', updated: '14 minutes ago', }, { id: 2, value: '2', name: 'branch', description: 'feature/dark-mode', commit: 'cbc0fa3', updated: '56 minutes ago', }, { id: 3, value: '3', name: 'branch', description: 'feature/right-to-left', commit: '69568ea', updated: '16 hours ago', }, { id: 4, value: '4', name: 'branch', description: 'bug/type-incorrect-for-checked-prop', commit: '1159c76', updated: 'yesterday', }, ]; export default function RadioInputExample(): JSX.Element { const [value, setValue] = useState<string>('1'); const onChange = useCallback( ({ currentTarget: { value } }: SyntheticEvent<any>) => { setValue(value); }, [setValue], ); return ( <Box> <table> <thead> <tr> {/* eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766 */} <td style={{ width: 0 }} /> <th id="head-description">Branch</th> <th id="head-commit">Last commit</th> <th id="head-updated">Updated</th> </tr> </thead> <tbody> {items.map((item) => ( <tr onClick={() => setValue(item.value)} key={`${item.value}${item.name}${item.id}`} style={{ backgroundColor: item.value === value ? token('color.background.selected') : 'transparent', transition: 'background-color 200ms ease-in-out', }} > {/* eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766 */} <th scope="row" style={{ width: 24, paddingRight: 0 }}> <Radio isChecked={item.value === value} onChange={onChange} name={item.name} value={item.value} labelId={`head-description row-${item.id}-description head-commit row-${item.id}-commit head-updated row-${item.id}-updated`} /> </th> <td id={`row-${item.id}-description`}>{item.description}</td> <td id={`row-${item.id}-commit`}>{item.commit}</td> <td id={`row-${item.id}-updated`}>{item.updated}</td> </tr> ))} </tbody> </table> <Box xcss={styles.selectedValue}>currently selected value: {value}</Box> </Box> ); }

Invalid radio

Use isInvalid for situations where the selected field is invalid or incorrect. Remember to provide useful validation messages to help people understand how to proceed.

import React from 'react'; import Button from '@atlaskit/button/default/button'; import Field from '@atlaskit/form/field'; import Form from '@atlaskit/form/form'; import { FormFooter } from '@atlaskit/form/form-footer'; import RadioGroup from '@atlaskit/radio/radio-group'; import { type OptionsPropType } from '@atlaskit/radio/types'; interface FormData { [key: string]: string; 'radio-group-invalid': string; } const validateOnSubmit = (data: FormData) => { let errors; errors = requiredValidator(data, 'radio-group-invalid'); return errors; }; const requiredValidator = (data: FormData, key: string) => { if (data[key] === 'invalid') { return { [key]: `This field is invalid.`, }; } }; const options: OptionsPropType = [ { name: 'radio-group-invalid', value: 'valid', label: 'Valid' }, { name: 'radio-group-invalid', value: 'invalid', label: 'Invalid' }, ]; export default function RadioInvalid(): React.JSX.Element { return ( <Form<FormData> onSubmit={(data) => { console.log('form data', data); return Promise.resolve(validateOnSubmit(data)); }} > <Field label="Radio group with validation" name="radio-group-invalid" defaultValue="valid" component={({ fieldProps }) => <RadioGroup {...fieldProps} options={options} />} /> <FormFooter> <Button type="submit">Submit</Button> </FormFooter> </Form> ); }

Required radio

Use isRequired to require users to fill out the input field before submitting the form.

import React from 'react'; import Button from '@atlaskit/button/default/button'; import Field from '@atlaskit/form/field'; import Form from '@atlaskit/form/form'; import { FormFooter } from '@atlaskit/form/form-footer'; import RadioGroup from '@atlaskit/radio/radio-group'; import { type OptionsPropType } from '@atlaskit/radio/types'; const colorItems: OptionsPropType = [ { name: 'color', value: 'red', label: 'Red' }, { name: 'color', value: 'blue', label: 'Blue' }, { name: 'color', value: 'yellow', label: 'Yellow' }, { name: 'color', value: 'green', label: 'Green' }, ]; export default function RadioRequired(): React.JSX.Element { return ( <Form<FormData> onSubmit={(formData) => console.log('form data', formData)}> <Field label="Required radio group" name="color" defaultValue="" isRequired> {({ fieldProps }) => <RadioGroup {...fieldProps} options={colorItems} />} </Field> <FormFooter> <Button type="submit">Submit</Button> </FormFooter> </Form> ); }
Was this page helpful?
We use this feedback to improve our documentation.
© 2026 AtlassianTrademark, (opens new window)Privacy, (opens new window)License