Skip to content

Commit cbd4b0c

Browse files
crisbetoandrewseguin
authored andcommitted
fix(material/checkbox): clear static aria attributes from host nodes (#17092)
Follow-up from #16938. Clears the aria-* attributes from the host node so that they're not duplicated with the underlying input. (cherry picked from commit ab39847)
1 parent fc204e4 commit cbd4b0c

File tree

4 files changed

+52
-40
lines changed

4 files changed

+52
-40
lines changed

Diff for: src/material-experimental/mdc-checkbox/checkbox.spec.ts

+24-20
Original file line numberDiff line numberDiff line change
@@ -641,16 +641,12 @@ describe('MDC-based MatCheckbox', () => {
641641
}));
642642
});
643643

644-
describe('aria-label', () => {
645-
let checkboxDebugElement: DebugElement;
646-
let checkboxNativeElement: HTMLElement;
647-
let inputElement: HTMLInputElement;
648-
644+
describe('aria handling', () => {
649645
it('should use the provided aria-label', fakeAsync(() => {
650646
fixture = createComponent(CheckboxWithAriaLabel);
651-
checkboxDebugElement = fixture.debugElement.query(By.directive(MatCheckbox))!;
652-
checkboxNativeElement = checkboxDebugElement.nativeElement;
653-
inputElement = <HTMLInputElement>checkboxNativeElement.querySelector('input');
647+
const checkboxDebugElement = fixture.debugElement.query(By.directive(MatCheckbox))!;
648+
const checkboxNativeElement = checkboxDebugElement.nativeElement;
649+
const inputElement = <HTMLInputElement>checkboxNativeElement.querySelector('input');
654650

655651
fixture.detectChanges();
656652
expect(inputElement.getAttribute('aria-label')).toBe('Super effective');
@@ -662,32 +658,35 @@ describe('MDC-based MatCheckbox', () => {
662658

663659
expect(fixture.nativeElement.querySelector('input').hasAttribute('aria-label')).toBe(false);
664660
}));
665-
});
666-
667-
describe('with provided aria-labelledby ', () => {
668-
let checkboxDebugElement: DebugElement;
669-
let checkboxNativeElement: HTMLElement;
670-
let inputElement: HTMLInputElement;
671661

672662
it('should use the provided aria-labelledby', fakeAsync(() => {
673663
fixture = createComponent(CheckboxWithAriaLabelledby);
674-
checkboxDebugElement = fixture.debugElement.query(By.directive(MatCheckbox))!;
675-
checkboxNativeElement = checkboxDebugElement.nativeElement;
676-
inputElement = <HTMLInputElement>checkboxNativeElement.querySelector('input');
664+
const checkboxDebugElement = fixture.debugElement.query(By.directive(MatCheckbox))!;
665+
const checkboxNativeElement = checkboxDebugElement.nativeElement;
666+
const inputElement = <HTMLInputElement>checkboxNativeElement.querySelector('input');
677667

678668
fixture.detectChanges();
679669
expect(inputElement.getAttribute('aria-labelledby')).toBe('some-id');
680670
}));
681671

682672
it('should not assign aria-labelledby if none is provided', fakeAsync(() => {
683673
fixture = createComponent(SingleCheckbox);
684-
checkboxDebugElement = fixture.debugElement.query(By.directive(MatCheckbox))!;
685-
checkboxNativeElement = checkboxDebugElement.nativeElement;
686-
inputElement = <HTMLInputElement>checkboxNativeElement.querySelector('input');
674+
const checkboxDebugElement = fixture.debugElement.query(By.directive(MatCheckbox))!;
675+
const checkboxNativeElement = checkboxDebugElement.nativeElement;
676+
const inputElement = <HTMLInputElement>checkboxNativeElement.querySelector('input');
687677

688678
fixture.detectChanges();
689679
expect(inputElement.getAttribute('aria-labelledby')).toBe(null);
690680
}));
681+
682+
it('should clear the static aria attributes from the host node', () => {
683+
fixture = createComponent(CheckboxWithStaticAriaAttributes);
684+
const checkbox = fixture.debugElement.query(By.directive(MatCheckbox))!.nativeElement;
685+
fixture.detectChanges();
686+
687+
expect(checkbox.hasAttribute('aria')).toBe(false);
688+
expect(checkbox.hasAttribute('aria-labelledby')).toBe(false);
689+
});
691690
});
692691

693692
describe('with provided aria-describedby ', () => {
@@ -1147,3 +1146,8 @@ class CheckboxWithoutLabel {
11471146
/** Test component with the native tabindex attribute. */
11481147
@Component({template: `<mat-checkbox tabindex="5"></mat-checkbox>`})
11491148
class CheckboxWithTabindexAttr {}
1149+
1150+
@Component({
1151+
template: `<mat-checkbox aria-label="Checkbox" aria-labelledby="something"></mat-checkbox>`,
1152+
})
1153+
class CheckboxWithStaticAriaAttributes {}

Diff for: src/material-experimental/mdc-checkbox/checkbox.ts

+2
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ const _MatCheckboxBase = mixinColor(
7777
host: {
7878
'class': 'mat-mdc-checkbox',
7979
'[attr.tabindex]': 'null',
80+
'[attr.aria-label]': 'null',
81+
'[attr.aria-labelledby]': 'null',
8082
'[class._mat-animation-noopable]': `_animationMode === 'NoopAnimations'`,
8183
'[class.mdc-checkbox--disabled]': 'disabled',
8284
'[id]': 'id',

Diff for: src/material/checkbox/checkbox.spec.ts

+24-20
Original file line numberDiff line numberDiff line change
@@ -724,16 +724,12 @@ describe('MatCheckbox', () => {
724724
}));
725725
});
726726

727-
describe('aria-label', () => {
728-
let checkboxDebugElement: DebugElement;
729-
let checkboxNativeElement: HTMLElement;
730-
let inputElement: HTMLInputElement;
731-
727+
describe('aria handling', () => {
732728
it('should use the provided aria-label', () => {
733729
fixture = createComponent(CheckboxWithAriaLabel);
734-
checkboxDebugElement = fixture.debugElement.query(By.directive(MatCheckbox))!;
735-
checkboxNativeElement = checkboxDebugElement.nativeElement;
736-
inputElement = <HTMLInputElement>checkboxNativeElement.querySelector('input');
730+
const checkboxDebugElement = fixture.debugElement.query(By.directive(MatCheckbox))!;
731+
const checkboxNativeElement = checkboxDebugElement.nativeElement;
732+
const inputElement = <HTMLInputElement>checkboxNativeElement.querySelector('input');
737733

738734
fixture.detectChanges();
739735
expect(inputElement.getAttribute('aria-label')).toBe('Super effective');
@@ -745,32 +741,35 @@ describe('MatCheckbox', () => {
745741

746742
expect(fixture.nativeElement.querySelector('input').hasAttribute('aria-label')).toBe(false);
747743
});
748-
});
749-
750-
describe('with provided aria-labelledby ', () => {
751-
let checkboxDebugElement: DebugElement;
752-
let checkboxNativeElement: HTMLElement;
753-
let inputElement: HTMLInputElement;
754744

755745
it('should use the provided aria-labelledby', () => {
756746
fixture = createComponent(CheckboxWithAriaLabelledby);
757-
checkboxDebugElement = fixture.debugElement.query(By.directive(MatCheckbox))!;
758-
checkboxNativeElement = checkboxDebugElement.nativeElement;
759-
inputElement = <HTMLInputElement>checkboxNativeElement.querySelector('input');
747+
const checkboxDebugElement = fixture.debugElement.query(By.directive(MatCheckbox))!;
748+
const checkboxNativeElement = checkboxDebugElement.nativeElement;
749+
const inputElement = <HTMLInputElement>checkboxNativeElement.querySelector('input');
760750

761751
fixture.detectChanges();
762752
expect(inputElement.getAttribute('aria-labelledby')).toBe('some-id');
763753
});
764754

765755
it('should not assign aria-labelledby if none is provided', () => {
766756
fixture = createComponent(SingleCheckbox);
767-
checkboxDebugElement = fixture.debugElement.query(By.directive(MatCheckbox))!;
768-
checkboxNativeElement = checkboxDebugElement.nativeElement;
769-
inputElement = <HTMLInputElement>checkboxNativeElement.querySelector('input');
757+
const checkboxDebugElement = fixture.debugElement.query(By.directive(MatCheckbox))!;
758+
const checkboxNativeElement = checkboxDebugElement.nativeElement;
759+
const inputElement = <HTMLInputElement>checkboxNativeElement.querySelector('input');
770760

771761
fixture.detectChanges();
772762
expect(inputElement.getAttribute('aria-labelledby')).toBe(null);
773763
});
764+
765+
it('should clear the static aria attributes from the host node', () => {
766+
fixture = createComponent(CheckboxWithStaticAriaAttributes);
767+
const checkbox = fixture.debugElement.query(By.directive(MatCheckbox))!.nativeElement;
768+
fixture.detectChanges();
769+
770+
expect(checkbox.hasAttribute('aria')).toBe(false);
771+
expect(checkbox.hasAttribute('aria-labelledby')).toBe(false);
772+
});
774773
});
775774

776775
describe('with provided aria-describedby ', () => {
@@ -1443,3 +1442,8 @@ class TextBindingComponent {
14431442
/** Test component with a simple checkbox with no inputs. */
14441443
@Component({template: `<mat-checkbox></mat-checkbox>`})
14451444
class SimpleCheckbox {}
1445+
1446+
@Component({
1447+
template: `<mat-checkbox aria-label="Checkbox" aria-labelledby="something"></mat-checkbox>`,
1448+
})
1449+
class CheckboxWithStaticAriaAttributes {}

Diff for: src/material/checkbox/checkbox.ts

+2
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@ const _MatCheckboxBase = mixinTabIndex(
117117
'class': 'mat-checkbox',
118118
'[id]': 'id',
119119
'[attr.tabindex]': 'null',
120+
'[attr.aria-label]': 'null',
121+
'[attr.aria-labelledby]': 'null',
120122
'[class.mat-checkbox-indeterminate]': 'indeterminate',
121123
'[class.mat-checkbox-checked]': 'checked',
122124
'[class.mat-checkbox-disabled]': 'disabled',

0 commit comments

Comments
 (0)