diff --git a/src/lib/snack-bar/snack-bar-config.ts b/src/lib/snack-bar/snack-bar-config.ts index 9a78bc57c7cd..02893d6aae33 100644 --- a/src/lib/snack-bar/snack-bar-config.ts +++ b/src/lib/snack-bar/snack-bar-config.ts @@ -26,7 +26,10 @@ export class MatSnackBarConfig { /** The politeness level for the MatAriaLiveAnnouncer announcement. */ politeness?: AriaLivePoliteness = 'assertive'; - /** Message to be announced by the MatAriaLiveAnnouncer */ + /** + * Message to be announced by the LiveAnnouncer. When opening a snackbar without a custom + * component or template, the announcement message will default to the specified message. + */ announcementMessage?: string = ''; /** The view container to place the overlay for the snack bar into. */ diff --git a/src/lib/snack-bar/snack-bar.spec.ts b/src/lib/snack-bar/snack-bar.spec.ts index 25e6f9b51d68..bd676794f07f 100644 --- a/src/lib/snack-bar/snack-bar.spec.ts +++ b/src/lib/snack-bar/snack-bar.spec.ts @@ -75,21 +75,21 @@ describe('MatSnackBar', () => { .toBe('alert', 'Expected snack bar container to have role="alert"'); }); - it('should open and close a snackbar without a ViewContainerRef', fakeAsync(() => { - let snackBarRef = snackBar.open('Snack time!', 'Chew'); - viewContainerFixture.detectChanges(); + it('should open and close a snackbar without a ViewContainerRef', fakeAsync(() => { + let snackBarRef = snackBar.open('Snack time!', 'Chew'); + viewContainerFixture.detectChanges(); - let messageElement = overlayContainerElement.querySelector('snack-bar-container')!; - expect(messageElement.textContent).toContain('Snack time!', - 'Expected snack bar to show a message without a ViewContainerRef'); + let messageElement = overlayContainerElement.querySelector('snack-bar-container')!; + expect(messageElement.textContent).toContain('Snack time!', + 'Expected snack bar to show a message without a ViewContainerRef'); - snackBarRef.dismiss(); - viewContainerFixture.detectChanges(); - flush(); + snackBarRef.dismiss(); + viewContainerFixture.detectChanges(); + flush(); - expect(overlayContainerElement.childNodes.length) - .toBe(0, 'Expected snack bar to be dismissed without a ViewContainerRef'); - })); + expect(overlayContainerElement.childNodes.length) + .toBe(0, 'Expected snack bar to be dismissed without a ViewContainerRef'); + })); it('should open a simple message with a button', () => { let config: MatSnackBarConfig = {viewContainerRef: testViewContainerRef}; @@ -153,6 +153,36 @@ describe('MatSnackBar', () => { .toBe(0, 'Expected the overlay container element to have no child elements'); })); + + it('should default to the passed message for the announcement message', fakeAsync(() => { + spyOn(liveAnnouncer, 'announce'); + + snackBar.open(simpleMessage); + viewContainerFixture.detectChanges(); + + expect(overlayContainerElement.childElementCount) + .toBe(1, 'Expected the overlay with the default announcement message to be added'); + + // Expect the live announcer to have been called with the display message and some + // string for the politeness. We do not want to test for the default politeness here. + expect(liveAnnouncer.announce).toHaveBeenCalledWith(simpleMessage, jasmine.any(String)); + })); + + it('should be able to specify a custom announcement message', fakeAsync(() => { + spyOn(liveAnnouncer, 'announce'); + + snackBar.open(simpleMessage, '', { + announcementMessage: 'Custom announcement', + politeness: 'assertive' + }); + viewContainerFixture.detectChanges(); + + expect(overlayContainerElement.childElementCount) + .toBe(1, 'Expected the overlay with a custom `announcementMessage` to be added'); + + expect(liveAnnouncer.announce).toHaveBeenCalledWith('Custom announcement', 'assertive'); + })); + it('should be able to get dismissed through the service', fakeAsync(() => { snackBar.open(simpleMessage); viewContainerFixture.detectChanges(); diff --git a/src/lib/snack-bar/snack-bar.ts b/src/lib/snack-bar/snack-bar.ts index 82434acfe0d5..425e46ef2e32 100644 --- a/src/lib/snack-bar/snack-bar.ts +++ b/src/lib/snack-bar/snack-bar.ts @@ -112,7 +112,10 @@ export class MatSnackBar { // Since the user doesn't have access to the component, we can // override the data to pass in our own message and action. _config.data = {message, action}; - _config.announcementMessage = message; + + if (!_config.announcementMessage) { + _config.announcementMessage = message; + } return this.openFromComponent(SimpleSnackBar, _config); }