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 },
+ }),
+ );
}
}