diff --git a/packages/notification/src/vaadin-notification.d.ts b/packages/notification/src/vaadin-notification.d.ts index 6737f31fbc..88c6c29fbf 100644 --- a/packages/notification/src/vaadin-notification.d.ts +++ b/packages/notification/src/vaadin-notification.d.ts @@ -27,8 +27,14 @@ export type NotificationRenderer = (root: HTMLElement, notification: Notificatio */ export type NotificationOpenedChangedEvent = CustomEvent<{ value: boolean }>; +/** + * Fired when the notification is closed. + */ +export type NotificationClosedEvent = CustomEvent; + export interface NotificationCustomEventMap { 'opened-changed': NotificationOpenedChangedEvent; + closed: NotificationClosedEvent; } export interface NotificationEventMap extends HTMLElementEventMap, NotificationCustomEventMap {} @@ -99,6 +105,7 @@ declare class NotificationCard extends ThemableMixin(HTMLElement) {} * propagated to the internal ``. * * @fires {CustomEvent} opened-changed - Fired when the `opened` property changes. + * @fires {CustomEvent} closed - Fired when the notification is closed. */ declare class Notification extends OverlayClassMixin(ThemePropertyMixin(ElementMixin(HTMLElement))) { /** diff --git a/packages/notification/src/vaadin-notification.js b/packages/notification/src/vaadin-notification.js index a25d5d2568..3d906c1464 100644 --- a/packages/notification/src/vaadin-notification.js +++ b/packages/notification/src/vaadin-notification.js @@ -257,6 +257,7 @@ class NotificationCard extends ThemableMixin(PolymerElement) { * propagated to the internal ``. * * @fires {CustomEvent} opened-changed - Fired when the `opened` property changes. + * @fires {CustomEvent} closed - Fired when the notification is closed. * * @customElement * @extends HTMLElement @@ -532,6 +533,7 @@ class Notification extends OverlayClassMixin(ThemePropertyMixin(ElementMixin(Pol } this._card.removeAttribute('closing'); this._container.opened = Boolean(this._container.firstElementChild); + this.dispatchEvent(new CustomEvent('closed')); } /** @private */ diff --git a/packages/notification/test/notification.test.js b/packages/notification/test/notification.test.js index c377cf5959..7485e5525b 100644 --- a/packages/notification/test/notification.test.js +++ b/packages/notification/test/notification.test.js @@ -53,6 +53,27 @@ describe('vaadin-notification', () => { expect(notification.opened).to.be.true; }); + it('should dispatch closed event', async () => { + const spy = sinon.spy(); + notification.addEventListener('closed', spy); + notification.opened = false; + await aTimeout(0); + expect(spy.calledOnce).to.be.true; + }); + + it('closed event should be called after overlay is closed', async () => { + const closedPromise = new Promise((resolve) => { + const closedListener = () => { + expect(notification._container.parentElement).to.be.not.ok; + resolve(); + }; + listenOnce(notification, 'closed', closedListener); + }); + notification.opened = false; + await aTimeout(0); + await closedPromise; + }); + describe('vaadin-notification-container', () => { it('should be in the body when notification opens', () => { expect(document.body.querySelectorAll('vaadin-notification-container').length).to.be.equal(1); diff --git a/packages/notification/test/typings/notification.types.ts b/packages/notification/test/typings/notification.types.ts index b9518fe95f..c3875b45e7 100644 --- a/packages/notification/test/typings/notification.types.ts +++ b/packages/notification/test/typings/notification.types.ts @@ -3,6 +3,7 @@ import type { ElementMixinClass } from '@vaadin/component-base/src/element-mixin import type { OverlayClassMixinClass } from '@vaadin/component-base/src/overlay-class-mixin.js'; import type { ThemePropertyMixinClass } from '@vaadin/vaadin-themable-mixin/vaadin-theme-property-mixin.js'; import type { + NotificationClosedEvent, NotificationOpenedChangedEvent, NotificationPosition, NotificationRenderer, @@ -31,6 +32,10 @@ notification.addEventListener('opened-changed', (event) => { assertType(event.detail.value); }); +notification.addEventListener('closed', (event) => { + assertType(event); +}); + Notification.show('Hello world', { position: 'middle', duration: 7000, theme: 'error' }); const renderer: NotificationRenderer = (root, owner) => {