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> );};useForm (recommended)
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
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
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
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
| Name | Type | Default | Required | Description |
|---|---|---|---|---|
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 |
data-testid | string | - | - | Suffix used to create a unique ID used for automated testing |
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.tsRadio Props
| Name | Type | Default | Required | Description |
|---|---|---|---|---|
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 |
data-testid | string | - | - | Suffix used to create a unique ID used for automated testing |
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 |
RadioGroupColumn Props
| Name | Type | Default | Required | Description |
|---|---|---|---|---|
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 |
data-testid | string | - | - | Suffix used to create a unique ID used for automated testing |
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. |
RadioGroup Classes
| Class Name | Description |
|---|---|
| .abyss-radio-group-root | Radio group root element |
| .abyss-radio-group-label-container | Label element container |
| .abyss-radio-group-label | Label element |
| .abyss-radio-group-container | Radio group container |
| .abyss-radio-group-descriptors | Descriptor element |
| .abyss-radio-group-sub-text | Subtext element |
Radio Classes
| Class Name | Description |
|---|---|
| .abyss-radio-root | Radio root element |
| .abyss-radio | Radio element |
| .abyss-radio-label | Label element |
RadioGroupColumn Classes
| Class Name | Description |
|---|---|
| .abyss-radio-group-column | The 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
| Key | Description |
|---|---|
| Tab | Moves focus to either the checked radio item or the first radio item in the group. |
| Space | When focus is on an unchecked radio item, checks it. |
| Enter | When focus is on an unchecked radio item, checks it. |
| Arrow Down | Moves focus to the next radio item in the group. |
| Arrow Right | Moves focus to the next radio item in the group. |
| Arrow Up | Moves focus to the previous radio item in the group. |
| Arrow Left | Moves 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 Name | Value | |
|---|---|---|
| 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 Name | Value | |
|---|---|---|
| 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 Name | Value | |
|---|---|---|
| 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 |