Skip to content

Commit 4552287

Browse files
Fix: listen for modal close animation (#702)
* add bubble and change event name * correct event name * use eventlisterners instead of bubbling * change event name * export event name * wait for update to complete before starting animation * comments * only add eventlisterns for who is needed to get it. --------- Co-authored-by: Niels Lyngsø <[email protected]>
1 parent 7d8affd commit 4552287

File tree

3 files changed

+39
-7
lines changed

3 files changed

+39
-7
lines changed

packages/uui-modal/lib/uui-modal-container.ts

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { LitElement, PropertyValueMap, css, html } from 'lit';
22
import { property, query, state } from 'lit/decorators.js';
33
import { UUIModalSidebarElement } from './uui-modal-sidebar.element';
4-
import { UUIModalElement } from './uui-modal.element';
4+
import { UUIModalCloseEvent, UUIModalElement } from './uui-modal.element';
55
import { defineElement } from '@umbraco-ui/uui-base/lib/registration';
66

77
@defineElement('uui-modal-container')
@@ -23,7 +23,7 @@ export class UUIModalContainerElement extends LitElement {
2323

2424
constructor() {
2525
super();
26-
this.addEventListener('close', this.#onClose);
26+
this.addEventListener(UUIModalCloseEvent, this.#onCloseModalClose);
2727
}
2828

2929
protected firstUpdated(
@@ -38,13 +38,29 @@ export class UUIModalContainerElement extends LitElement {
3838
}
3939

4040
#onSlotChange = () => {
41+
const existingModals = this._modals ?? [];
42+
4143
this._modals =
4244
(this.modalSlot
4345
?.assignedElements({ flatten: true })
4446
.filter(
4547
el => el instanceof UUIModalElement
4648
) as Array<UUIModalElement>) ?? [];
4749

50+
const oldModals = existingModals.filter(
51+
modal => this._modals!.indexOf(modal) === -1
52+
);
53+
oldModals.forEach(modal =>
54+
modal.removeEventListener(UUIModalCloseEvent, this.#onCloseModalClose)
55+
);
56+
57+
const newModals = this._modals.filter(
58+
modal => existingModals.indexOf(modal) === -1
59+
);
60+
newModals.forEach(modal =>
61+
modal.addEventListener(UUIModalCloseEvent, this.#onCloseModalClose)
62+
);
63+
4864
this._sidebars = this._modals.filter(
4965
el => el instanceof UUIModalSidebarElement
5066
) as Array<UUIModalSidebarElement>;
@@ -58,7 +74,13 @@ export class UUIModalContainerElement extends LitElement {
5874
this.#updateSidebars();
5975
};
6076

61-
#onClose = () => {
77+
#onCloseModalClose = (event: Event) => {
78+
event.stopImmediatePropagation();
79+
80+
event.target?.removeEventListener(
81+
UUIModalCloseEvent,
82+
this.#onCloseModalClose
83+
);
6284
if (!this._modals || this._modals.length <= 1) {
6385
this.removeAttribute('backdrop');
6486
return;
@@ -99,7 +121,15 @@ export class UUIModalContainerElement extends LitElement {
99121
for (let i = 0; i < reversed.length; i++) {
100122
const sidebar = reversed[i];
101123
const nextSidebar = reversed[i + 1];
102-
sidebar.style.setProperty('--uui-modal-offset', sidebarOffset + 'px');
124+
const tempSidebarOffset = sidebarOffset; // Cache to prevent it from being overwritten before the updateComplete.
125+
// The sidebar checks it's own width at sets it's --uui-modal-offset to negative that width.
126+
// This enables it to slide in from the right. So we need to set the new --uui-modal-offset after the updateComplete.
127+
sidebar.updateComplete.then(() => {
128+
sidebar.style.setProperty(
129+
'--uui-modal-offset',
130+
tempSidebarOffset + 'px'
131+
);
132+
});
103133

104134
// Stop the calculations if the next sidebar is hidden
105135
if (nextSidebar?.hasAttribute('hide')) break;

packages/uui-modal/lib/uui-modal-sidebar.element.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { css, html, PropertyValueMap } from 'lit';
22
import { property } from 'lit/decorators.js';
3-
import { UUIModalElement } from './uui-modal.element';
3+
import { UUIModalCloseEvent, UUIModalElement } from './uui-modal.element';
44
import { defineElement } from '@umbraco-ui/uui-base/lib/registration';
55

66
export type UUIModalSidebarSize = 'small' | 'medium' | 'large' | 'full';
@@ -15,7 +15,7 @@ export class UUIModalSidebarElement extends UUIModalElement {
1515

1616
constructor() {
1717
super();
18-
this.addEventListener('close', this.#onClose.bind(this));
18+
this.addEventListener(UUIModalCloseEvent, this.#onClose.bind(this));
1919
}
2020

2121
protected firstUpdated(

packages/uui-modal/lib/uui-modal.element.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { LitElement, css } from 'lit';
22
import { property, query } from 'lit/decorators.js';
3+
4+
export const UUIModalCloseEvent = 'uui:modal-close';
35
export class UUIModalElement extends LitElement {
46
@query('dialog')
57
protected _dialogElement?: HTMLDialogElement;
@@ -58,7 +60,7 @@ export class UUIModalElement extends LitElement {
5860
event?.preventDefault();
5961
event?.stopImmediatePropagation();
6062

61-
const closeEvent = new CustomEvent('close', {
63+
const closeEvent = new CustomEvent(UUIModalCloseEvent, {
6264
cancelable: true,
6365
});
6466
this.dispatchEvent(closeEvent);

0 commit comments

Comments
 (0)