Skip to main content

RadioGroup

Provides a set of checkable buttons, known as radio buttons, where no more than one of the buttons can be checked at a time.

Submit feedback
github

Migration Information

For teams migrating from the V1 to V2 component, please refer to the migration guide for changes to the component.
Component Guide
import { RadioGroup } from '@uhg-abyss/web/ui/RadioGroup';
() => {
const [radioValue, setRadioValue] = useState('one');
console.log('radioValue', radioValue);
return (
<RadioGroup
label="Radio Sandbox"
subText="This is subtext"
onChange={(e) => setRadioValue(e.target.value)}
value={radioValue}
>
<RadioGroup.Column>
<RadioGroup.Radio label="One" value="one" />
<RadioGroup.Radio label="Two" value="two" />
<RadioGroup.Radio label="Three" value="three" />
<RadioGroup.Radio label="Four" value="four" />
</RadioGroup.Column>
<RadioGroup.Column>
<RadioGroup.Radio label="Five" value="five" />
<RadioGroup.Radio label="Six" value="six" />
<RadioGroup.Radio label="Seven" value="seven" />
<RadioGroup.Radio label="Eight" value="eight" />
</RadioGroup.Column>
</RadioGroup>
);
};

Using useForm and FormProvider simplifies form management by providing out-of-the-box validation, form state handling, and performance optimizations, leveraging the power of react-hook-form.

useState

Using the useState hook gets values from the component state.

RadioGroup.Column

The radio group is organized into RadioGroup.Column subcomponents. Each RadioGroup.Radio in required to be wrapped in a RadioGroup.Column when using RadioGroup.

Label

Every RadioGroup must have a label to be accessible. Use the label prop to change the displayed label for the group. Set hideLabel to true to visibly hide the label but retain accessibility.

Helper

Use the helper prop to display a help icon next to the label. Simply passing a string value will render the default helper, a Tooltip containing that string. The helper can be customized by passing in a node. It is recommended to use either a Tooltip or a Popover. See When should I use a Tooltip vs. a Popover? for more information on best practices regarding the two.

Subtext

Use the subText prop to display helpful information related to the input field. The prop accepts either a string or an object of the form:

{
text: string;
position: 'above' | 'below';
}

The position property determines where the subtext will be displayed in relation to the input field. The default value is 'below'.

Validation

Form Compatibility
useState
useForm

Use the validators prop to provide validation rules, such as required.

Note: The default error message when required is true is minimally acceptable for accessibility. It is highly recommended to customize it to be more specific to the use of the field and form.

Error message

Form Compatibility
useState
useForm

Use the errorMessage prop to display a custom error message below the radio group.

Note: The errorMessage prop does not work with useForm and is only applicable within our form input components when useState is being utilized. See the useForm Docs for example use cases with useForm.

Success message

Form Compatibility
useState
useForm

Use the successMessage prop to display a custom success message below the input field. To provide a single success message across all form input components using useForm/FormProvider, you can provide successMessage to FormProvider as shown here.

Disabled

Set the isDisabled prop to true to disable all radios in the group. Individual radios can be disabled by setting isDisabled to true in their respective Radio instead of the outer component.

Multi-line wrapping

The label for each radio button has a maximum width of 743px. After that, the text will wrap.

RadioGroup Props

NameTypeDefaultRequiredDescription
children
React.ReactNode
-
The contents of the radio group component
className
string
--
CSS class name to apply to each element within the component
css
Abyss.CSSProperties | Partial<Record<`abyss-${T}`, Abyss.CSSProperties>>
--
Object containing CSS styling to apply; uses the classes listed in the "Integration" tab of the component's documentation

See CSS Prop Styling for more information
data-testid
string
--
Suffix used to create a unique ID used for automated testing

See Component Testing for more information
disableDefaultProviderProps
boolean
false
-
If set to true, the component will not use the DefaultPropsProvider values.

If you aren’t using the DefaultPropsProvider, this prop can be ignored.
errorMessage
string | never
--
Error message to display for the input. Only used when not in a FormProvider.
errorMessage should not exist in useForm mode.
helper
React.ReactNode
--
Helper element next to label
hideLabel
boolean
false
-
If true, the label will be visually hidden
highlighted
boolean
false
-
If true, the input field will be highlighted
isDisabled
boolean
false
-
If true, the input will be disabled
isRequired
boolean | never
--
Whether the input is required. Only used when not in a FormProvider.
isRequired should not exist in useForm mode.
label
string
-
The label for the input
model
never | string
--
model should not exist in useState mode.
Model name for form validation. Only used when in a FormProvider.
onBlur
React.FocusEventHandler<HTMLInputElement>
--
Callback function executed when the input is blurred
onChange
React.ChangeEventHandler<HTMLInputElement>
--
Callback function executed when the input value changes
onFocus
React.FocusEventHandler<HTMLInputElement>
--
Callback function executed when the input is focused
subText
string | { text: string; position: SubTextPosition; }
--
Additional descriptive text for the input
successMessage
string
--
Success message to display for the input
validators
never | RegisterOptions
--
validators should not exist in useState mode.
Validators for the input. Only used when in a FormProvider.
value
ValueType | never
--
The value of the input. Only used when not in a FormProvider.
value should not exist in useForm mode.

Below are the link(s) to the relevant GitHub type files:

Abyss.d.ts

Radio Props

NameTypeDefaultRequiredDescription
checked
boolean
false
-
Flag to see if radio is checked
className
string
--
CSS class name to apply to each element within the component
css
Abyss.CSSProperties | Partial<Record<`abyss-${T}`, Abyss.CSSProperties>>
--
Object containing CSS styling to apply; uses the classes listed in the "Integration" tab of the component's documentation

See CSS Prop Styling for more information
data-testid
string
--
Suffix used to create a unique ID used for automated testing

See Component Testing for more information
disableDefaultProviderProps
boolean
false
-
If set to true, the component will not use the DefaultPropsProvider values.

If you aren’t using the DefaultPropsProvider, this prop can be ignored.
hideLabel
boolean
false
-
Flag to hide label
isDisabled
boolean
false
-
Flag to see if radio is disabled
label
string
-
Set the label of radio
onKeyDown
React.KeyboardEventHandler<HTMLInputElement>
--
Called when a key is pressed down on the radio
value
string
-
Value of the radio

Below are the link(s) to the relevant GitHub type files:

Abyss.d.ts

RadioGroupColumn Props

NameTypeDefaultRequiredDescription
children
React.ReactNode
-
The elements the radio group column wraps
className
string
--
CSS class name to apply to each element within the component
css
Abyss.CSSProperties | Partial<Record<`abyss-${T}`, Abyss.CSSProperties>>
--
Object containing CSS styling to apply; uses the classes listed in the "Integration" tab of the component's documentation

See CSS Prop Styling for more information
data-testid
string
--
Suffix used to create a unique ID used for automated testing

See Component Testing for more information
disableDefaultProviderProps
boolean
false
-
If set to true, the component will not use the DefaultPropsProvider values.

If you aren’t using the DefaultPropsProvider, this prop can be ignored.

Below are the link(s) to the relevant GitHub type files:

Abyss.d.ts

RadioGroup Classes

Class NameDescription
.abyss-radio-group-rootRadio group root element
.abyss-radio-group-label-containerLabel element container
.abyss-radio-group-labelLabel element
.abyss-radio-group-containerRadio group container
.abyss-radio-group-descriptorsDescriptor element
.abyss-radio-group-sub-textSubtext element

Radio Classes

Class NameDescription
.abyss-radio-rootRadio root element
.abyss-radioRadio element
.abyss-radio-labelLabel element

RadioGroupColumn Classes

Class NameDescription
.abyss-radio-group-columnThe elements the radio group column wraps

A radio group is a set of checkable buttons, known as radio buttons, where no more than one of the buttons can be checked at a time. Some implementations may initialize the set with all buttons in the unchecked state in order to force the user to check one of the buttons before moving past a certain point in the workflow.

The component adheres to standard HTML practices by correctly implementing <fieldset>, <legend>, and <input type="radio"> elements. By wrapping the radio buttons within a <fieldset> element, the component groups them together, providing semantic structure and an accessible boundary recognized by screen readers. A <legend> element is used within the <fieldset> to offer a descriptive label, aiding users, especially those utilizing screen readers, in understanding the context of the radio buttons. Each radio button is implemented as an <input type="radio"> element, ensuring proper behavior and interaction as expected in a web form.

The component's input wrapper has a role="radiogroup" attribute, which is essential for screen readers to identify the group of radio buttons and further allow the usage of aria-required and aria-invalid inside the component. For more details, please visit the following:

Differences from common group implementations

Required and error reporting are associated with the group <fieldset>, not the radio buttons. This is to more clearly associate errors and requirements with the group. Otherwise, unlike <select> (which is very similar), one or all of the individual radio buttons might be mistakenly considered "required" or "invalid."

Another difference is that though <legend> is used to label the grouping, aria-labelledby is also used in <fieldset>. This is necessary since, according to HTML standards, <legend> must be the first child of <fieldset>. Since presentation requires wrapping <legend> with <div>s, aria-labelledby is used to "patch" the broken relationship and ensure the grouping has an accessible name.

For more details on these HTML elements and their usage, please visit the following W3Schools links:

Adheres to the Radio Group WAI-ARIA design pattern.

Keyboard Interactions

KeyDescription
TabMoves focus to either the checked radio item or the first radio item in the group.
SpaceWhen focus is on an unchecked radio item, checks it.
EnterWhen focus is on an unchecked radio item, checks it.
Arrow DownMoves focus to the next radio item in the group.
Arrow RightMoves focus to the next radio item in the group.
Arrow UpMoves focus to the previous radio item in the group.
Arrow LeftMoves focus to the previous radio item in the group.

Component Tokens

Note: Click on the token row to copy the token to your clipboard.

RadioGroup Tokens

Token NameValue
radio-group.color.surface.control.enabled.rest
#FFFFFF
radio-group.color.surface.control.enabled.hover
#FFFFFF
radio-group.color.surface.control.disabled.default
#CBCCCD
radio-group.color.surface.control.disabled.selected
#7D7F81
radio-group.color.surface.control.selected.rest
#196ECF
radio-group.color.surface.control.selected.hover
#004BA0
radio-group.color.border.control.enabled.rest
#7D7F81
radio-group.color.border.control.enabled.hover
#4B4D4F
radio-group.color.border.control.disabled.default
#7D7F81
radio-group.color.border.control.disabled.selected
#7D7F81
radio-group.color.border.control.selected.rest
#196ECF
radio-group.color.border.control.selected.hover
#004BA0
radio-group.color.border.container.error
#990000
radio-group.color.border.container.success
#007000
radio-group.border-radius.all.control.default
500px
radio-group.border-radius.all.container
4px
radio-group.border-width.all.control.default
2px
radio-group.border-width.all.container
1px
radio-group.spacing.gap.horizontal.label
8px
radio-group.spacing.gap.horizontal.container
8px
radio-group.spacing.gap.vertical.column
8px
radio-group.spacing.padding.all.container
8px
radio-group.spacing.padding.top.validation
8px

Header Tokens

Token NameValue
input-header.color.text.label
#4B4D4F
input-header.color.text.hint
#4B4D4F
input-header.color.icon.info.rest
#196ECF
input-header.color.icon.info.hover
#004BA0
input-header.color.icon.info.active
#002677
input-header.sizing.all.icon
24px
input-header.spacing.gap.horizontal.container
4px
input-header.spacing.gap.horizontal.label
4px
input-header.spacing.gap.vertical.content
4px
input-header.spacing.padding.top.content
2px

Validation Tokens

Token NameValue
input-validation.color.surface.container
#FFFFFF
input-validation.color.text.error
#990000
input-validation.color.text.success
#007000
input-validation.color.icon.error
#990000
input-validation.color.icon.success
#007000
input-validation.sizing.all.icon
20px
input-validation.spacing.gap.horizontal.container
4px
Table of Contents