Skip to content

Commit 15fec92

Browse files
committed
fix(dialog): don't assign aria-label to close button if button has text
No longer adds the `aria-label` to the `mat-dialog-close` directive, if the element that it's being applied to has text. This prevents the label from being read instead of the button text. Fixes #11084.
1 parent e7b0e40 commit 15fec92

File tree

3 files changed

+44
-3
lines changed

3 files changed

+44
-3
lines changed

src/lib/dialog/dialog-content-directives.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ let dialogElementUid = 0;
2929
exportAs: 'matDialogClose',
3030
host: {
3131
'(click)': 'dialogRef.close(dialogResult)',
32-
'[attr.aria-label]': 'ariaLabel',
32+
'[attr.aria-label]': '_hasAriaLabel ? ariaLabel : null',
3333
'type': 'button', // Prevents accidental form submits.
3434
}
3535
})
@@ -42,6 +42,12 @@ export class MatDialogClose implements OnInit, OnChanges {
4242

4343
@Input('matDialogClose') _matDialogClose: any;
4444

45+
/**
46+
* Whether the button should have an `aria-label`. Used for clearing the
47+
* attribute to prevent it from being read instead of the button's text.
48+
*/
49+
_hasAriaLabel?: boolean;
50+
4551
constructor(
4652
@Optional() public dialogRef: MatDialogRef<any>,
4753
private _elementRef: ElementRef<HTMLElement>,
@@ -56,6 +62,17 @@ export class MatDialogClose implements OnInit, OnChanges {
5662
// be resolved at constructor time.
5763
this.dialogRef = getClosestDialog(this._elementRef, this._dialog.openDialogs)!;
5864
}
65+
66+
if (typeof this._hasAriaLabel !== 'undefined') {
67+
const element = this._elementRef.nativeElement;
68+
69+
if (element.hasAttribute('mat-icon-button')) {
70+
this._hasAriaLabel = true;
71+
} else {
72+
const buttonTextContent = element.textContent;
73+
this._hasAriaLabel = !buttonTextContent || buttonTextContent.trim().length === 0;
74+
}
75+
}
5976
}
6077

6178
ngOnChanges(changes: SimpleChanges) {
@@ -64,6 +81,10 @@ export class MatDialogClose implements OnInit, OnChanges {
6481
if (proxiedChange) {
6582
this.dialogResult = proxiedChange.currentValue;
6683
}
84+
85+
if (changes.ariaLabel) {
86+
this._hasAriaLabel = !!changes.ariaLabel.currentValue;
87+
}
6788
}
6889
}
6990

src/lib/dialog/dialog.spec.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,11 +1143,26 @@ describe('MatDialog', () => {
11431143
expect(overlayContainerElement.querySelectorAll('.mat-dialog-container').length).toBe(1);
11441144
});
11451145

1146+
it('should set an aria-label on a button without text', fakeAsync(() => {
1147+
let button = overlayContainerElement.querySelector('.close-without-text')!;
1148+
expect(button.getAttribute('aria-label')).toBeTruthy();
1149+
}));
1150+
1151+
it('should not have an aria-label if a button has text', fakeAsync(() => {
1152+
let button = overlayContainerElement.querySelector('[mat-dialog-close]')!;
1153+
expect(button.getAttribute('aria-label')).toBeFalsy();
1154+
}));
1155+
11461156
it('should allow for a user-specified aria-label on the close button', fakeAsync(() => {
11471157
let button = overlayContainerElement.querySelector('.close-with-aria-label')!;
11481158
expect(button.getAttribute('aria-label')).toBe('Best close button ever');
11491159
}));
11501160

1161+
it('should always have an aria-label on a mat-icon-button', fakeAsync(() => {
1162+
let button = overlayContainerElement.querySelector('.close-icon-button')!;
1163+
expect(button.getAttribute('aria-label')).toBeTruthy();
1164+
}));
1165+
11511166
it('should override the "type" attribute of the close button', () => {
11521167
let button = overlayContainerElement.querySelector('button[mat-dialog-close]')!;
11531168

@@ -1448,11 +1463,13 @@ class PizzaMsg {
14481463
<mat-dialog-content>Lorem ipsum dolor sit amet.</mat-dialog-content>
14491464
<mat-dialog-actions>
14501465
<button mat-dialog-close>Close</button>
1466+
<button class="close-without-text" mat-dialog-close></button>
1467+
<button class="close-icon-button" mat-icon-button mat-dialog-close>exit</button>
14511468
<button class="close-with-true" [mat-dialog-close]="true">Close and return true</button>
14521469
<button
14531470
class="close-with-aria-label"
14541471
aria-label="Best close button ever"
1455-
[mat-dialog-close]="true">Close</button>
1472+
[mat-dialog-close]="true"></button>
14561473
<div mat-dialog-close>Should not close</div>
14571474
</mat-dialog-actions>
14581475
`
@@ -1466,11 +1483,13 @@ class ContentElementDialog {}
14661483
<mat-dialog-content>Lorem ipsum dolor sit amet.</mat-dialog-content>
14671484
<mat-dialog-actions>
14681485
<button mat-dialog-close>Close</button>
1486+
<button class="close-without-text" mat-dialog-close></button>
1487+
<button class="close-icon-button" mat-icon-button mat-dialog-close>exit</button>
14691488
<button class="close-with-true" [mat-dialog-close]="true">Close and return true</button>
14701489
<button
14711490
class="close-with-aria-label"
14721491
aria-label="Best close button ever"
1473-
[mat-dialog-close]="true">Close</button>
1492+
[mat-dialog-close]="true"></button>
14741493
<div mat-dialog-close>Should not close</div>
14751494
</mat-dialog-actions>
14761495
</ng-template>

tools/public_api_guard/lib/dialog.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export declare const matDialogAnimations: {
4545
};
4646

4747
export declare class MatDialogClose implements OnInit, OnChanges {
48+
_hasAriaLabel?: boolean;
4849
_matDialogClose: any;
4950
ariaLabel: string;
5051
dialogRef: MatDialogRef<any>;

0 commit comments

Comments
 (0)