Skip to content

Commit d506fe6

Browse files
(Radio, RadioGroup): improve a11y
1 parent f8b18fa commit d506fe6

File tree

2 files changed

+26
-5
lines changed

2 files changed

+26
-5
lines changed

src/scripts/Radio.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export type RadioProps = {
1717
*
1818
*/
1919
export const Radio: FC<RadioProps> = ({
20+
id,
2021
className,
2122
label,
2223
name,
@@ -26,7 +27,12 @@ export const Radio: FC<RadioProps> = ({
2627
children,
2728
...props
2829
}) => {
29-
const { name: grpName, onValueChange } = useContext(RadioGroupContext);
30+
const {
31+
name: grpName,
32+
error,
33+
errorId,
34+
onValueChange,
35+
} = useContext(RadioGroupContext);
3036
const onChange = useEventCallback(
3137
(e: React.ChangeEvent<HTMLInputElement>) => {
3238
onChange_?.(e);
@@ -45,6 +51,8 @@ export const Radio: FC<RadioProps> = ({
4551
value={value}
4652
onChange={onChange}
4753
{...props}
54+
id={id}
55+
aria-describedby={error ? errorId : undefined}
4856
/>
4957
<label className='slds-radio__label' htmlFor={id}>
5058
<span className='slds-radio_faux' />

src/scripts/RadioGroup.tsx

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React, {
2+
useId,
23
HTMLAttributes,
34
Ref,
45
createContext,
@@ -9,6 +10,7 @@ import React, {
910
import classnames from 'classnames';
1011
import { FieldSetColumnContext } from './FieldSet';
1112
import { TooltipContent } from './TooltipContent';
13+
import { FormElementProps } from './FormElement';
1214
import { createFC } from './common';
1315
import { Bivariant } from './typeUtils';
1416

@@ -22,6 +24,8 @@ export type RadioValueType = string | number;
2224
*/
2325
export const RadioGroupContext = createContext<{
2426
name?: string;
27+
error?: FormElementProps['error'];
28+
errorId?: string;
2529
onValueChange?: Bivariant<(value: RadioValueType) => void>;
2630
}>({});
2731

@@ -83,21 +87,25 @@ export const RadioGroup = createFC<RadioGroupProps, { isFormElement: boolean }>(
8387
? error.message
8488
: undefined
8589
: undefined;
90+
91+
const errorId = useId();
8692
const grpCtx = useMemo(
87-
() => ({ name, onValueChange }),
88-
[name, onValueChange]
93+
() => ({ name, error, errorId, onValueChange }),
94+
[name, error, errorId, onValueChange]
8995
);
9096

9197
return (
9298
<fieldset
9399
ref={elementRef}
94100
className={grpClassNames}
95101
style={grpStyles}
102+
role='radiogroup'
103+
aria-required={required}
96104
{...rprops}
97105
>
98106
<legend className='slds-form-element__label'>
99107
{required ? (
100-
<abbr className='slds-required' title='required'>
108+
<abbr className='slds-required' title='required' aria-hidden='true'>
101109
*
102110
</abbr>
103111
) : undefined}
@@ -112,7 +120,12 @@ export const RadioGroup = createFC<RadioGroupProps, { isFormElement: boolean }>(
112120
<RadioGroupContext.Provider value={grpCtx}>
113121
{children}
114122
{errorMessage ? (
115-
<div className='slds-form-element__help'>{errorMessage}</div>
123+
<div
124+
className='slds-form-element__help'
125+
id={error ? errorId : undefined}
126+
>
127+
{errorMessage}
128+
</div>
116129
) : undefined}
117130
</RadioGroupContext.Provider>
118131
</div>

0 commit comments

Comments
 (0)