diff --git a/docs/components/dialog/src/external-dialog.js b/docs/components/dialog/src/external-dialog.js new file mode 100644 index 0000000000..cd7c9aeb56 --- /dev/null +++ b/docs/components/dialog/src/external-dialog.js @@ -0,0 +1,32 @@ +import { LitElement, html } from 'lit'; + +class DialogTriggerDemo extends LitElement { + static get properties() { + return { + _isOpen: { state: true }, + }; + } + + toggleDialog(open) { + // eslint-disable-next-line no-return-assign + return () => (this._isOpen = open); + } + + handleDialog(e) { + this._isOpen = e.detail.opened; + } + + render() { + return html` + + +
+ Hello! You can close this notification here: + +
+
+ `; + } +} + +customElements.define('dialog-trigger-demo', DialogTriggerDemo); diff --git a/docs/components/dialog/use-cases.md b/docs/components/dialog/use-cases.md index 23441f4ef4..0ea5f21419 100644 --- a/docs/components/dialog/use-cases.md +++ b/docs/components/dialog/use-cases.md @@ -10,6 +10,7 @@ import '@lion/ui/define/lion-dialog.js'; import { demoStyle } from './src/demoStyle.js'; import './src/styled-dialog-content.js'; import './src/slots-dialog-content.js'; +import './src/external-dialog.js'; ``` ```html @@ -22,6 +23,51 @@ import './src/slots-dialog-content.js'; ``` +## External trigger + +```js preview-story +export const externalTrigger = () => { + const externalTriggerDialog = () => { + class DialogTriggerDemo extends LitElement { + static get properties() { + return { + _isOpen: { state: true }, + }; + } + + toggleDialog(open) { + return () => (this._isOpen = open); + } + + handleDialog(e) { + this._isOpen = e.detail.opened; + } + + render() { + return html` + + +
+ Hello! You can close this notification here: + +
+
+ `; + } + } + }; + + return html` + +
+ +
+ `; +}; +``` + ## Placement overrides ```js preview-story diff --git a/packages/ui/components/dialog/test/lion-dialog.test.js b/packages/ui/components/dialog/test/lion-dialog.test.js index 97b81a22df..0f8545ba9e 100644 --- a/packages/ui/components/dialog/test/lion-dialog.test.js +++ b/packages/ui/components/dialog/test/lion-dialog.test.js @@ -127,5 +127,42 @@ describe('lion-dialog', () => { invokerNode.click(); expect(document.activeElement).to.equal(invokerNode); }); + + it('opened-changed event should send detail object with opened state', async () => { + const el = /** @type {LionDialog} */ await fixture(html` + + +
+ + +
+
+ `); + + el.setAttribute('opened', ''); + expect(el.opened).to.be.true; + + el.addEventListener('opened-changed', e => { + expect(e.detail.opened).to.be.false; + }); + el.removeAttribute('opened'); + }); + + it("opened-changed event's target should point to lion-dialog", async () => { + const el = /** @type {LionDialog} */ await fixture(html` + + +
+ + +
+
+ `); + + el.addEventListener('opened-changed', e => { + expect(e.target).to.equal(el); + }); + el.setAttribute('opened', ''); + }); }); }); diff --git a/packages/ui/components/overlays/src/OverlayMixin.js b/packages/ui/components/overlays/src/OverlayMixin.js index af65f0ff5a..2676c757b6 100644 --- a/packages/ui/components/overlays/src/OverlayMixin.js +++ b/packages/ui/components/overlays/src/OverlayMixin.js @@ -72,7 +72,11 @@ export const OverlayMixinImplementation = superclass => requestUpdate(name, oldValue, options) { super.requestUpdate(name, oldValue, options); if (name === 'opened' && this.opened !== oldValue) { - this.dispatchEvent(new Event('opened-changed')); + this.dispatchEvent( + new CustomEvent('opened-changed', { + detail: { opened: this.opened }, + }), + ); } }