diff --git a/packages/popover/src/vaadin-popover.d.ts b/packages/popover/src/vaadin-popover.d.ts index ecc4fece9c..00ca8de338 100644 --- a/packages/popover/src/vaadin-popover.d.ts +++ b/packages/popover/src/vaadin-popover.d.ts @@ -22,6 +22,8 @@ export type PopoverOpenedChangedEvent = CustomEvent<{ value: boolean }>; export interface PopoverCustomEventMap { 'opened-changed': PopoverOpenedChangedEvent; + + closed: Event; } export type PopoverEventMap = HTMLElementEventMap & PopoverCustomEventMap; @@ -64,6 +66,7 @@ export type PopoverEventMap = HTMLElementEventMap & PopoverCustomEventMap; * See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation. * * @fires {CustomEvent} opened-changed - Fired when the `opened` property changes. + * @fires {CustomEvent} closed - Fired when the popover is closed. */ declare class Popover extends PopoverPositionMixin( PopoverTargetMixin(OverlayClassMixin(ThemePropertyMixin(ElementMixin(HTMLElement)))), diff --git a/packages/popover/src/vaadin-popover.js b/packages/popover/src/vaadin-popover.js index ddab95dc37..6171ce18e9 100644 --- a/packages/popover/src/vaadin-popover.js +++ b/packages/popover/src/vaadin-popover.js @@ -162,6 +162,7 @@ class PopoverOpenedStateController { * See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation. * * @fires {CustomEvent} opened-changed - Fired when the `opened` property changes. + * @fires {CustomEvent} closed - Fired when the popover is closed. * * @customElement * @extends HTMLElement @@ -715,6 +716,8 @@ class Popover extends PopoverPositionMixin( if (this.modal && this.target.style.pointerEvents) { this.target.style.pointerEvents = ''; } + + this.dispatchEvent(new CustomEvent('closed')); } /** @@ -771,6 +774,12 @@ class Popover extends PopoverPositionMixin( this.__updateDimension(overlay, 'width', width); } } + + /** + * Fired when the popover is closed. + * + * @event closed + */ } defineCustomElement(Popover); diff --git a/packages/popover/test/basic.test.js b/packages/popover/test/basic.test.js index 7740101a29..a818b8c98e 100644 --- a/packages/popover/test/basic.test.js +++ b/packages/popover/test/basic.test.js @@ -399,4 +399,32 @@ describe('popover', () => { expect(overlay.getAttribute('style')).to.be.not.ok; }); }); + + describe('closed event', () => { + beforeEach(async () => { + popover.opened = true; + await nextRender(); + }); + + it('should dispatch closed event when closed', async () => { + const closedSpy = sinon.spy(); + popover.addEventListener('closed', closedSpy); + popover.opened = false; + await nextRender(); + expect(closedSpy).to.be.calledOnce; + }); + + it('should dispatch closed event after overlay is closed', async () => { + const closedPromise = new Promise((resolve) => { + const closedListener = () => { + expect(overlay.parentElement).to.be.not.ok; + resolve(); + }; + popover.addEventListener('closed', closedListener, { once: true }); + }); + popover.opened = false; + await nextRender(); + await closedPromise; + }); + }); }); diff --git a/packages/popover/test/typings/popover.types.ts b/packages/popover/test/typings/popover.types.ts index e8c3130b07..7cd3f500b3 100644 --- a/packages/popover/test/typings/popover.types.ts +++ b/packages/popover/test/typings/popover.types.ts @@ -48,3 +48,7 @@ popover.addEventListener('opened-changed', (event) => { assertType(event); assertType(event.detail.value); }); + +popover.addEventListener('closed', (event) => { + assertType(event); +});