Skip to content

Commit 0b747c5

Browse files
committed
fix(checkbox): clear static aria attributes from host nodes
Follow-up from #16938. Clears the aria-* attributes from the host node so that they're not duplicated with the underlying input.
1 parent 0f6cd05 commit 0b747c5

File tree

4 files changed

+71
-57
lines changed

4 files changed

+71
-57
lines changed

src/material-experimental/mdc-checkbox/checkbox.spec.ts

+42-37
Original file line numberDiff line numberDiff line change
@@ -607,54 +607,54 @@ describe('MatCheckbox', () => {
607607
}));
608608
});
609609

610-
describe('aria-label', () => {
611-
let checkboxDebugElement: DebugElement;
612-
let checkboxNativeElement: HTMLElement;
613-
let inputElement: HTMLInputElement;
614-
610+
describe('aria handling', () => {
615611
it('should use the provided aria-label', fakeAsync(() => {
616-
fixture = createComponent(CheckboxWithAriaLabel);
617-
checkboxDebugElement = fixture.debugElement.query(By.directive(MatCheckbox))!;
618-
checkboxNativeElement = checkboxDebugElement.nativeElement;
619-
inputElement = <HTMLInputElement>checkboxNativeElement.querySelector('input');
612+
fixture = createComponent(CheckboxWithAriaLabel);
613+
const checkboxDebugElement = fixture.debugElement.query(By.directive(MatCheckbox))!;
614+
const checkboxNativeElement = checkboxDebugElement.nativeElement;
615+
const inputElement = <HTMLInputElement>checkboxNativeElement.querySelector('input');
620616

621-
fixture.detectChanges();
622-
expect(inputElement.getAttribute('aria-label')).toBe('Super effective');
623-
}));
617+
fixture.detectChanges();
618+
expect(inputElement.getAttribute('aria-label')).toBe('Super effective');
619+
}));
624620

625621
it('should not set the aria-label attribute if no value is provided', fakeAsync(() => {
626-
fixture = createComponent(SingleCheckbox);
627-
fixture.detectChanges();
628-
629-
expect(fixture.nativeElement.querySelector('input').hasAttribute('aria-label'))
630-
.toBe(false);
631-
}));
632-
});
622+
fixture = createComponent(SingleCheckbox);
623+
fixture.detectChanges();
633624

634-
describe('with provided aria-labelledby ', () => {
635-
let checkboxDebugElement: DebugElement;
636-
let checkboxNativeElement: HTMLElement;
637-
let inputElement: HTMLInputElement;
625+
expect(fixture.nativeElement.querySelector('input').hasAttribute('aria-label'))
626+
.toBe(false);
627+
}));
638628

639629
it('should use the provided aria-labelledby', fakeAsync(() => {
640-
fixture = createComponent(CheckboxWithAriaLabelledby);
641-
checkboxDebugElement = fixture.debugElement.query(By.directive(MatCheckbox))!;
642-
checkboxNativeElement = checkboxDebugElement.nativeElement;
643-
inputElement = <HTMLInputElement>checkboxNativeElement.querySelector('input');
630+
fixture = createComponent(CheckboxWithAriaLabelledby);
631+
const checkboxDebugElement = fixture.debugElement.query(By.directive(MatCheckbox))!;
632+
const checkboxNativeElement = checkboxDebugElement.nativeElement;
633+
const inputElement = <HTMLInputElement>checkboxNativeElement.querySelector('input');
644634

645-
fixture.detectChanges();
646-
expect(inputElement.getAttribute('aria-labelledby')).toBe('some-id');
647-
}));
635+
fixture.detectChanges();
636+
expect(inputElement.getAttribute('aria-labelledby')).toBe('some-id');
637+
}));
648638

649639
it('should not assign aria-labelledby if none is provided', fakeAsync(() => {
650-
fixture = createComponent(SingleCheckbox);
651-
checkboxDebugElement = fixture.debugElement.query(By.directive(MatCheckbox))!;
652-
checkboxNativeElement = checkboxDebugElement.nativeElement;
653-
inputElement = <HTMLInputElement>checkboxNativeElement.querySelector('input');
640+
fixture = createComponent(SingleCheckbox);
641+
const checkboxDebugElement = fixture.debugElement.query(By.directive(MatCheckbox))!;
642+
const checkboxNativeElement = checkboxDebugElement.nativeElement;
643+
const inputElement = <HTMLInputElement>checkboxNativeElement.querySelector('input');
644+
645+
fixture.detectChanges();
646+
expect(inputElement.getAttribute('aria-labelledby')).toBe(null);
647+
}));
648+
649+
it('should clear the static aria attributes from the host node', () => {
650+
fixture = createComponent(CheckboxWithStaticAriaAttributes);
651+
const checkbox = fixture.debugElement.query(By.directive(MatCheckbox))!.nativeElement;
652+
fixture.detectChanges();
653+
654+
expect(checkbox.hasAttribute('aria')).toBe(false);
655+
expect(checkbox.hasAttribute('aria-labelledby')).toBe(false);
656+
});
654657

655-
fixture.detectChanges();
656-
expect(inputElement.getAttribute('aria-labelledby')).toBe(null);
657-
}));
658658
});
659659

660660
describe('with provided tabIndex', () => {
@@ -1049,3 +1049,8 @@ class CheckboxWithoutLabel {
10491049
@Component({template: `<mat-checkbox tabindex="5"></mat-checkbox>`})
10501050
class CheckboxWithTabindexAttr {
10511051
}
1052+
1053+
@Component({
1054+
template: `<mat-checkbox aria-label="Checkbox" aria-labelledby="something"></mat-checkbox>`
1055+
})
1056+
class CheckboxWithStaticAriaAttributes {}

src/material-experimental/mdc-checkbox/checkbox.ts

+2
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ export class MatCheckboxChange {
5656
host: {
5757
'class': 'mat-mdc-checkbox',
5858
'[attr.tabindex]': 'null',
59+
'[attr.aria-label]': 'null',
60+
'[attr.aria-labelledby]': 'null',
5961
'[class.mat-primary]': 'color == "primary"',
6062
'[class.mat-accent]': 'color == "accent"',
6163
'[class.mat-warn]': 'color == "warn"',

src/material/checkbox/checkbox.spec.ts

+25-20
Original file line numberDiff line numberDiff line change
@@ -728,16 +728,12 @@ describe('MatCheckbox', () => {
728728
}));
729729
});
730730

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

742738
fixture.detectChanges();
743739
expect(inputElement.getAttribute('aria-label')).toBe('Super effective');
@@ -749,32 +745,36 @@ describe('MatCheckbox', () => {
749745

750746
expect(fixture.nativeElement.querySelector('input').hasAttribute('aria-label')).toBe(false);
751747
});
752-
});
753-
754-
describe('with provided aria-labelledby ', () => {
755-
let checkboxDebugElement: DebugElement;
756-
let checkboxNativeElement: HTMLElement;
757-
let inputElement: HTMLInputElement;
758748

759749
it('should use the provided aria-labelledby', () => {
760750
fixture = createComponent(CheckboxWithAriaLabelledby);
761-
checkboxDebugElement = fixture.debugElement.query(By.directive(MatCheckbox))!;
762-
checkboxNativeElement = checkboxDebugElement.nativeElement;
763-
inputElement = <HTMLInputElement>checkboxNativeElement.querySelector('input');
751+
const checkboxDebugElement = fixture.debugElement.query(By.directive(MatCheckbox))!;
752+
const checkboxNativeElement = checkboxDebugElement.nativeElement;
753+
const inputElement = <HTMLInputElement>checkboxNativeElement.querySelector('input');
764754

765755
fixture.detectChanges();
766756
expect(inputElement.getAttribute('aria-labelledby')).toBe('some-id');
767757
});
768758

769759
it('should not assign aria-labelledby if none is provided', () => {
770760
fixture = createComponent(SingleCheckbox);
771-
checkboxDebugElement = fixture.debugElement.query(By.directive(MatCheckbox))!;
772-
checkboxNativeElement = checkboxDebugElement.nativeElement;
773-
inputElement = <HTMLInputElement>checkboxNativeElement.querySelector('input');
761+
const checkboxDebugElement = fixture.debugElement.query(By.directive(MatCheckbox))!;
762+
const checkboxNativeElement = checkboxDebugElement.nativeElement;
763+
const inputElement = <HTMLInputElement>checkboxNativeElement.querySelector('input');
774764

775765
fixture.detectChanges();
776766
expect(inputElement.getAttribute('aria-labelledby')).toBe(null);
777767
});
768+
769+
it('should clear the static aria attributes from the host node', () => {
770+
fixture = createComponent(CheckboxWithStaticAriaAttributes);
771+
const checkbox = fixture.debugElement.query(By.directive(MatCheckbox))!.nativeElement;
772+
fixture.detectChanges();
773+
774+
expect(checkbox.hasAttribute('aria')).toBe(false);
775+
expect(checkbox.hasAttribute('aria-labelledby')).toBe(false);
776+
});
777+
778778
});
779779

780780
describe('with provided tabIndex', () => {
@@ -1394,3 +1394,8 @@ class TextBindingComponent {
13941394
@Component({template: `<mat-checkbox></mat-checkbox>`})
13951395
class SimpleCheckbox {
13961396
}
1397+
1398+
@Component({
1399+
template: `<mat-checkbox aria-label="Checkbox" aria-labelledby="something"></mat-checkbox>`
1400+
})
1401+
class CheckboxWithStaticAriaAttributes {}

src/material/checkbox/checkbox.ts

+2
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ const _MatCheckboxMixinBase:
120120
'class': 'mat-checkbox',
121121
'[id]': 'id',
122122
'[attr.tabindex]': 'null',
123+
'[attr.aria-label]': 'null',
124+
'[attr.aria-labelledby]': 'null',
123125
'[class.mat-checkbox-indeterminate]': 'indeterminate',
124126
'[class.mat-checkbox-checked]': 'checked',
125127
'[class.mat-checkbox-disabled]': 'disabled',

0 commit comments

Comments
 (0)