Skip to content

Commit

Permalink
fix(material/checkbox): clear static aria attributes from host nodes (#…
Browse files Browse the repository at this point in the history
…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)
  • Loading branch information
crisbeto authored and andrewseguin committed Feb 22, 2022
1 parent fc204e4 commit cbd4b0c
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 40 deletions.
44 changes: 24 additions & 20 deletions src/material-experimental/mdc-checkbox/checkbox.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -641,16 +641,12 @@ describe('MDC-based MatCheckbox', () => {
}));
});

describe('aria-label', () => {
let checkboxDebugElement: DebugElement;
let checkboxNativeElement: HTMLElement;
let inputElement: HTMLInputElement;

describe('aria handling', () => {
it('should use the provided aria-label', fakeAsync(() => {
fixture = createComponent(CheckboxWithAriaLabel);
checkboxDebugElement = fixture.debugElement.query(By.directive(MatCheckbox))!;
checkboxNativeElement = checkboxDebugElement.nativeElement;
inputElement = <HTMLInputElement>checkboxNativeElement.querySelector('input');
const checkboxDebugElement = fixture.debugElement.query(By.directive(MatCheckbox))!;
const checkboxNativeElement = checkboxDebugElement.nativeElement;
const inputElement = <HTMLInputElement>checkboxNativeElement.querySelector('input');

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

expect(fixture.nativeElement.querySelector('input').hasAttribute('aria-label')).toBe(false);
}));
});

describe('with provided aria-labelledby ', () => {
let checkboxDebugElement: DebugElement;
let checkboxNativeElement: HTMLElement;
let inputElement: HTMLInputElement;

it('should use the provided aria-labelledby', fakeAsync(() => {
fixture = createComponent(CheckboxWithAriaLabelledby);
checkboxDebugElement = fixture.debugElement.query(By.directive(MatCheckbox))!;
checkboxNativeElement = checkboxDebugElement.nativeElement;
inputElement = <HTMLInputElement>checkboxNativeElement.querySelector('input');
const checkboxDebugElement = fixture.debugElement.query(By.directive(MatCheckbox))!;
const checkboxNativeElement = checkboxDebugElement.nativeElement;
const inputElement = <HTMLInputElement>checkboxNativeElement.querySelector('input');

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

it('should not assign aria-labelledby if none is provided', fakeAsync(() => {
fixture = createComponent(SingleCheckbox);
checkboxDebugElement = fixture.debugElement.query(By.directive(MatCheckbox))!;
checkboxNativeElement = checkboxDebugElement.nativeElement;
inputElement = <HTMLInputElement>checkboxNativeElement.querySelector('input');
const checkboxDebugElement = fixture.debugElement.query(By.directive(MatCheckbox))!;
const checkboxNativeElement = checkboxDebugElement.nativeElement;
const inputElement = <HTMLInputElement>checkboxNativeElement.querySelector('input');

fixture.detectChanges();
expect(inputElement.getAttribute('aria-labelledby')).toBe(null);
}));

it('should clear the static aria attributes from the host node', () => {
fixture = createComponent(CheckboxWithStaticAriaAttributes);
const checkbox = fixture.debugElement.query(By.directive(MatCheckbox))!.nativeElement;
fixture.detectChanges();

expect(checkbox.hasAttribute('aria')).toBe(false);
expect(checkbox.hasAttribute('aria-labelledby')).toBe(false);
});
});

describe('with provided aria-describedby ', () => {
Expand Down Expand Up @@ -1147,3 +1146,8 @@ class CheckboxWithoutLabel {
/** Test component with the native tabindex attribute. */
@Component({template: `<mat-checkbox tabindex="5"></mat-checkbox>`})
class CheckboxWithTabindexAttr {}

@Component({
template: `<mat-checkbox aria-label="Checkbox" aria-labelledby="something"></mat-checkbox>`,
})
class CheckboxWithStaticAriaAttributes {}
2 changes: 2 additions & 0 deletions src/material-experimental/mdc-checkbox/checkbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ const _MatCheckboxBase = mixinColor(
host: {
'class': 'mat-mdc-checkbox',
'[attr.tabindex]': 'null',
'[attr.aria-label]': 'null',
'[attr.aria-labelledby]': 'null',
'[class._mat-animation-noopable]': `_animationMode === 'NoopAnimations'`,
'[class.mdc-checkbox--disabled]': 'disabled',
'[id]': 'id',
Expand Down
44 changes: 24 additions & 20 deletions src/material/checkbox/checkbox.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -724,16 +724,12 @@ describe('MatCheckbox', () => {
}));
});

describe('aria-label', () => {
let checkboxDebugElement: DebugElement;
let checkboxNativeElement: HTMLElement;
let inputElement: HTMLInputElement;

describe('aria handling', () => {
it('should use the provided aria-label', () => {
fixture = createComponent(CheckboxWithAriaLabel);
checkboxDebugElement = fixture.debugElement.query(By.directive(MatCheckbox))!;
checkboxNativeElement = checkboxDebugElement.nativeElement;
inputElement = <HTMLInputElement>checkboxNativeElement.querySelector('input');
const checkboxDebugElement = fixture.debugElement.query(By.directive(MatCheckbox))!;
const checkboxNativeElement = checkboxDebugElement.nativeElement;
const inputElement = <HTMLInputElement>checkboxNativeElement.querySelector('input');

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

expect(fixture.nativeElement.querySelector('input').hasAttribute('aria-label')).toBe(false);
});
});

describe('with provided aria-labelledby ', () => {
let checkboxDebugElement: DebugElement;
let checkboxNativeElement: HTMLElement;
let inputElement: HTMLInputElement;

it('should use the provided aria-labelledby', () => {
fixture = createComponent(CheckboxWithAriaLabelledby);
checkboxDebugElement = fixture.debugElement.query(By.directive(MatCheckbox))!;
checkboxNativeElement = checkboxDebugElement.nativeElement;
inputElement = <HTMLInputElement>checkboxNativeElement.querySelector('input');
const checkboxDebugElement = fixture.debugElement.query(By.directive(MatCheckbox))!;
const checkboxNativeElement = checkboxDebugElement.nativeElement;
const inputElement = <HTMLInputElement>checkboxNativeElement.querySelector('input');

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

it('should not assign aria-labelledby if none is provided', () => {
fixture = createComponent(SingleCheckbox);
checkboxDebugElement = fixture.debugElement.query(By.directive(MatCheckbox))!;
checkboxNativeElement = checkboxDebugElement.nativeElement;
inputElement = <HTMLInputElement>checkboxNativeElement.querySelector('input');
const checkboxDebugElement = fixture.debugElement.query(By.directive(MatCheckbox))!;
const checkboxNativeElement = checkboxDebugElement.nativeElement;
const inputElement = <HTMLInputElement>checkboxNativeElement.querySelector('input');

fixture.detectChanges();
expect(inputElement.getAttribute('aria-labelledby')).toBe(null);
});

it('should clear the static aria attributes from the host node', () => {
fixture = createComponent(CheckboxWithStaticAriaAttributes);
const checkbox = fixture.debugElement.query(By.directive(MatCheckbox))!.nativeElement;
fixture.detectChanges();

expect(checkbox.hasAttribute('aria')).toBe(false);
expect(checkbox.hasAttribute('aria-labelledby')).toBe(false);
});
});

describe('with provided aria-describedby ', () => {
Expand Down Expand Up @@ -1443,3 +1442,8 @@ class TextBindingComponent {
/** Test component with a simple checkbox with no inputs. */
@Component({template: `<mat-checkbox></mat-checkbox>`})
class SimpleCheckbox {}

@Component({
template: `<mat-checkbox aria-label="Checkbox" aria-labelledby="something"></mat-checkbox>`,
})
class CheckboxWithStaticAriaAttributes {}
2 changes: 2 additions & 0 deletions src/material/checkbox/checkbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ const _MatCheckboxBase = mixinTabIndex(
'class': 'mat-checkbox',
'[id]': 'id',
'[attr.tabindex]': 'null',
'[attr.aria-label]': 'null',
'[attr.aria-labelledby]': 'null',
'[class.mat-checkbox-indeterminate]': 'indeterminate',
'[class.mat-checkbox-checked]': 'checked',
'[class.mat-checkbox-disabled]': 'disabled',
Expand Down

0 comments on commit cbd4b0c

Please sign in to comment.