Skip to content

Commit 57c68d4

Browse files
committed
fix(material/radio): required attribute being set on buttons
fixes when `MatRadioGroup` is set to be required it was setting all of its `MatRadioButton' to be required as-well which is confusing for assistive technologies, this commit ensures we only set aria-required on group rather than all buttons unless button is being used standalone of `MatRadioGroup` fixes angular#30399
1 parent 1b3c42e commit 57c68d4

File tree

3 files changed

+33
-1
lines changed

3 files changed

+33
-1
lines changed

src/material/radio/radio.html

+5-1
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,17 @@
22
<div class="mdc-radio" [class.mdc-radio--disabled]="disabled">
33
<!-- Render this element first so the input is on top. -->
44
<div class="mat-mdc-radio-touch-target" (click)="_onTouchTargetClick($event)"></div>
5+
<!-- We don't want to add required attribute when button is used with MatRadioGroup as
6+
we want to set directly it on MatRadioGroup as setting it on all MatRadioButton would be
7+
confusing for assistive technology users unless MatRadioButton is being used
8+
standalone -->
59
<input #input class="mdc-radio__native-control" type="radio"
610
[id]="inputId"
711
[checked]="checked"
812
[disabled]="disabled && !disabledInteractive"
913
[attr.name]="name"
1014
[attr.value]="value"
11-
[required]="required"
15+
[required]="radioGroup ? null : required"
1216
[attr.aria-label]="ariaLabel"
1317
[attr.aria-labelledby]="ariaLabelledby"
1418
[attr.aria-describedby]="ariaDescribedby"

src/material/radio/radio.spec.ts

+27
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,33 @@ describe('MatRadio', () => {
524524
expect(groupInstance.selected).toBe(null);
525525
expect(groupInstance.value).toBe('fire');
526526
});
527+
528+
it('should set aria-required on radio group when required', () => {
529+
fixture.changeDetectorRef.markForCheck();
530+
fixture.detectChanges();
531+
532+
let group = fixture.debugElement.query(By.directive(MatRadioGroup)).nativeElement;
533+
534+
// by default it shouldn't be there
535+
expect(group.hasAttribute('aria-required')).toBeFalse();
536+
537+
testComponent.isGroupRequired = true;
538+
fixture.changeDetectorRef.markForCheck();
539+
fixture.detectChanges();
540+
541+
group = fixture.debugElement.query(By.directive(MatRadioGroup)).nativeElement;
542+
expect(group.hasAttribute('aria-required')).toBe(true);
543+
});
544+
545+
it('should set not set required attribute on matRadioButton when matRadioGroup is required', () => {
546+
testComponent.isGroupRequired = true;
547+
fixture.changeDetectorRef.markForCheck();
548+
fixture.detectChanges();
549+
550+
for (const radio of radioDebugElements) {
551+
expect(radio.nativeElement.hasAttribute('aria-required')).toBeFalse();
552+
}
553+
});
527554
});
528555

529556
describe('group with ngModel', () => {

src/material/radio/radio.ts

+1
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ export function MAT_RADIO_DEFAULT_OPTIONS_FACTORY(): MatRadioDefaultOptions {
118118
host: {
119119
'role': 'radiogroup',
120120
'class': 'mat-mdc-radio-group',
121+
'[attr.aria-required]': 'required ? required : null',
121122
},
122123
})
123124
export class MatRadioGroup implements AfterContentInit, OnDestroy, ControlValueAccessor {

0 commit comments

Comments
 (0)