Skip to content

fix(dialog): remove default aria-label from mat-dialog-close #15654

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 3 additions & 25 deletions src/lib/dialog/dialog-content-directives.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,25 +29,19 @@ let dialogElementUid = 0;
exportAs: 'matDialogClose',
host: {
'(click)': 'dialogRef.close(dialogResult)',
'[attr.aria-label]': '_hasAriaLabel ? ariaLabel : null',
'[attr.aria-label]': 'ariaLabel || null',
'type': 'button', // Prevents accidental form submits.
}
})
export class MatDialogClose implements OnInit, OnChanges {
/** Screenreader label for the button. */
@Input('aria-label') ariaLabel: string = 'Close dialog';
@Input('aria-label') ariaLabel: string;

/** Dialog close input. */
@Input('mat-dialog-close') dialogResult: any;

@Input('matDialogClose') _matDialogClose: any;

/**
* Whether the button should have an `aria-label`. Used for clearing the
* attribute to prevent it from being read instead of the button's text.
*/
_hasAriaLabel?: boolean;

constructor(
@Optional() public dialogRef: MatDialogRef<any>,
private _elementRef: ElementRef<HTMLElement>,
Expand All @@ -62,30 +56,14 @@ export class MatDialogClose implements OnInit, OnChanges {
// be resolved at constructor time.
this.dialogRef = getClosestDialog(this._elementRef, this._dialog.openDialogs)!;
}

if (typeof this._hasAriaLabel === 'undefined') {
const element = this._elementRef.nativeElement;

if (element.hasAttribute('mat-icon-button')) {
this._hasAriaLabel = true;
} else {
const buttonTextContent = element.textContent;
this._hasAriaLabel = !buttonTextContent || buttonTextContent.trim().length === 0;
}
}
}

ngOnChanges(changes: SimpleChanges) {
const proxiedChange =
changes['_matDialogClose'] || changes['_matDialogCloseResult'];
const proxiedChange = changes['_matDialogClose'] || changes['_matDialogCloseResult'];

if (proxiedChange) {
this.dialogResult = proxiedChange.currentValue;
}

if (changes['ariaLabel']) {
this._hasAriaLabel = !!changes['ariaLabel'].currentValue;
}
}
}

Expand Down
4 changes: 4 additions & 0 deletions src/lib/dialog/dialog.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,10 @@ a [focus trap](https://material.angular.io/cdk/a11y/overview#focustrap) to conta
within itself. Once a dialog is closed, it will return focus to the element that was focused
before the dialog was opened.

If you're adding a close button that doesn't have text (e.g. a purely icon-based button), make sure
that it has a meaningful `aria-label` so that users with assistive technology know what it is used
for.

#### Focus management
By default, the first tabbable element within the dialog will receive focus upon open. This can
be configured by setting the `cdkFocusInitial` attribute on another focusable element.
Expand Down
19 changes: 0 additions & 19 deletions src/lib/dialog/dialog.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1143,26 +1143,11 @@ describe('MatDialog', () => {
expect(overlayContainerElement.querySelectorAll('.mat-dialog-container').length).toBe(1);
});

it('should set an aria-label on a button without text', fakeAsync(() => {
let button = overlayContainerElement.querySelector('.close-without-text')!;
expect(button.getAttribute('aria-label')).toBeTruthy();
}));

it('should not have an aria-label if a button has text', fakeAsync(() => {
let button = overlayContainerElement.querySelector('[mat-dialog-close]')!;
expect(button.getAttribute('aria-label')).toBeFalsy();
}));

it('should allow for a user-specified aria-label on the close button', fakeAsync(() => {
let button = overlayContainerElement.querySelector('.close-with-aria-label')!;
expect(button.getAttribute('aria-label')).toBe('Best close button ever');
}));

it('should always have an aria-label on a mat-icon-button', fakeAsync(() => {
let button = overlayContainerElement.querySelector('.close-icon-button')!;
expect(button.getAttribute('aria-label')).toBeTruthy();
}));

it('should override the "type" attribute of the close button', () => {
let button = overlayContainerElement.querySelector('button[mat-dialog-close]')!;

Expand Down Expand Up @@ -1508,8 +1493,6 @@ class PizzaMsg {
<mat-dialog-content>Lorem ipsum dolor sit amet.</mat-dialog-content>
<mat-dialog-actions>
<button mat-dialog-close>Close</button>
<button class="close-without-text" mat-dialog-close></button>
<button class="close-icon-button" mat-icon-button mat-dialog-close>exit</button>
<button class="close-with-true" [mat-dialog-close]="true">Close and return true</button>
<button
class="close-with-aria-label"
Expand All @@ -1528,8 +1511,6 @@ class ContentElementDialog {}
<mat-dialog-content>Lorem ipsum dolor sit amet.</mat-dialog-content>
<mat-dialog-actions>
<button mat-dialog-close>Close</button>
<button class="close-without-text" mat-dialog-close></button>
<button class="close-icon-button" mat-icon-button mat-dialog-close>exit</button>
<button class="close-with-true" [mat-dialog-close]="true">Close and return true</button>
<button
class="close-with-aria-label"
Expand Down
1 change: 0 additions & 1 deletion tools/public_api_guard/lib/dialog.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ export declare const matDialogAnimations: {
};

export declare class MatDialogClose implements OnInit, OnChanges {
_hasAriaLabel?: boolean;
_matDialogClose: any;
ariaLabel: string;
dialogRef: MatDialogRef<any>;
Expand Down