Skip to content

Commit 3163cc6

Browse files
crisbetojelbourn
authored andcommitted
fix(dialog): don't assign aria-label to close button if button has text (#11093)
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 7cd002d commit 3163cc6

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

@@ -1493,11 +1508,13 @@ class PizzaMsg {
14931508
<mat-dialog-content>Lorem ipsum dolor sit amet.</mat-dialog-content>
14941509
<mat-dialog-actions>
14951510
<button mat-dialog-close>Close</button>
1511+
<button class="close-without-text" mat-dialog-close></button>
1512+
<button class="close-icon-button" mat-icon-button mat-dialog-close>exit</button>
14961513
<button class="close-with-true" [mat-dialog-close]="true">Close and return true</button>
14971514
<button
14981515
class="close-with-aria-label"
14991516
aria-label="Best close button ever"
1500-
[mat-dialog-close]="true">Close</button>
1517+
[mat-dialog-close]="true"></button>
15011518
<div mat-dialog-close>Should not close</div>
15021519
</mat-dialog-actions>
15031520
`
@@ -1511,11 +1528,13 @@ class ContentElementDialog {}
15111528
<mat-dialog-content>Lorem ipsum dolor sit amet.</mat-dialog-content>
15121529
<mat-dialog-actions>
15131530
<button mat-dialog-close>Close</button>
1531+
<button class="close-without-text" mat-dialog-close></button>
1532+
<button class="close-icon-button" mat-icon-button mat-dialog-close>exit</button>
15141533
<button class="close-with-true" [mat-dialog-close]="true">Close and return true</button>
15151534
<button
15161535
class="close-with-aria-label"
15171536
aria-label="Best close button ever"
1518-
[mat-dialog-close]="true">Close</button>
1537+
[mat-dialog-close]="true"></button>
15191538
<div mat-dialog-close>Should not close</div>
15201539
</mat-dialog-actions>
15211540
</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)