Skip to content

Commit 307889e

Browse files
crisbetojelbourn
authored andcommitted
fix(dialog): remove default aria-label from mat-dialog-close (#15654)
Currently we add an `aria-label` by default to close buttons that don't have text. This is unreliable, because text can come in at any time and it takes a lot of code to keep track of it. Furthermore, the default text is in English which means that sites in different languages will have to override it anyway. These changes remove the default `aria-label` and add some guidance to the docs on how to deal with labelling the close button. Fixes #15542.
1 parent c02b09c commit 307889e

File tree

4 files changed

+7
-45
lines changed

4 files changed

+7
-45
lines changed

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

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -29,25 +29,19 @@ let dialogElementUid = 0;
2929
exportAs: 'matDialogClose',
3030
host: {
3131
'(click)': 'dialogRef.close(dialogResult)',
32-
'[attr.aria-label]': '_hasAriaLabel ? ariaLabel : null',
32+
'[attr.aria-label]': 'ariaLabel || null',
3333
'type': 'button', // Prevents accidental form submits.
3434
}
3535
})
3636
export class MatDialogClose implements OnInit, OnChanges {
3737
/** Screenreader label for the button. */
38-
@Input('aria-label') ariaLabel: string = 'Close dialog';
38+
@Input('aria-label') ariaLabel: string;
3939

4040
/** Dialog close input. */
4141
@Input('mat-dialog-close') dialogResult: any;
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-
5145
constructor(
5246
@Optional() public dialogRef: MatDialogRef<any>,
5347
private _elementRef: ElementRef<HTMLElement>,
@@ -62,30 +56,14 @@ export class MatDialogClose implements OnInit, OnChanges {
6256
// be resolved at constructor time.
6357
this.dialogRef = getClosestDialog(this._elementRef, this._dialog.openDialogs)!;
6458
}
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-
}
7659
}
7760

7861
ngOnChanges(changes: SimpleChanges) {
79-
const proxiedChange =
80-
changes['_matDialogClose'] || changes['_matDialogCloseResult'];
62+
const proxiedChange = changes['_matDialogClose'] || changes['_matDialogCloseResult'];
8163

8264
if (proxiedChange) {
8365
this.dialogResult = proxiedChange.currentValue;
8466
}
85-
86-
if (changes.ariaLabel) {
87-
this._hasAriaLabel = !!changes.ariaLabel.currentValue;
88-
}
8967
}
9068
}
9169

src/lib/dialog/dialog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,10 @@ a [focus trap](https://material.angular.io/cdk/a11y/overview#focustrap) to conta
154154
within itself. Once a dialog is closed, it will return focus to the element that was focused
155155
before the dialog was opened.
156156

157+
If you're adding a close button that doesn't have text (e.g. a purely icon-based button), make sure
158+
that it has a meaningful `aria-label` so that users with assistive technology know what it is used
159+
for.
160+
157161
#### Focus management
158162
By default, the first tabbable element within the dialog will receive focus upon open. This can
159163
be configured by setting the `cdkFocusInitial` attribute on another focusable element.

src/lib/dialog/dialog.spec.ts

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,26 +1143,11 @@ 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-
11561146
it('should allow for a user-specified aria-label on the close button', fakeAsync(() => {
11571147
let button = overlayContainerElement.querySelector('.close-with-aria-label')!;
11581148
expect(button.getAttribute('aria-label')).toBe('Best close button ever');
11591149
}));
11601150

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-
11661151
it('should override the "type" attribute of the close button', () => {
11671152
let button = overlayContainerElement.querySelector('button[mat-dialog-close]')!;
11681153

@@ -1463,8 +1448,6 @@ class PizzaMsg {
14631448
<mat-dialog-content>Lorem ipsum dolor sit amet.</mat-dialog-content>
14641449
<mat-dialog-actions>
14651450
<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>
14681451
<button class="close-with-true" [mat-dialog-close]="true">Close and return true</button>
14691452
<button
14701453
class="close-with-aria-label"
@@ -1483,8 +1466,6 @@ class ContentElementDialog {}
14831466
<mat-dialog-content>Lorem ipsum dolor sit amet.</mat-dialog-content>
14841467
<mat-dialog-actions>
14851468
<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>
14881469
<button class="close-with-true" [mat-dialog-close]="true">Close and return true</button>
14891470
<button
14901471
class="close-with-aria-label"

tools/public_api_guard/lib/dialog.d.ts

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

4747
export declare class MatDialogClose implements OnInit, OnChanges {
48-
_hasAriaLabel?: boolean;
4948
_matDialogClose: any;
5049
ariaLabel: string;
5150
dialogRef: MatDialogRef<any>;

0 commit comments

Comments
 (0)