Skip to content

Commit

Permalink
Fix: listen for modal close animation (#702)
Browse files Browse the repository at this point in the history
* 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]>
  • Loading branch information
JesmoDev and nielslyngsoe authored Jan 23, 2024
1 parent 7d8affd commit 4552287
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 7 deletions.
38 changes: 34 additions & 4 deletions packages/uui-modal/lib/uui-modal-container.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { LitElement, PropertyValueMap, css, html } from 'lit';
import { property, query, state } from 'lit/decorators.js';
import { UUIModalSidebarElement } from './uui-modal-sidebar.element';
import { UUIModalElement } from './uui-modal.element';
import { UUIModalCloseEvent, UUIModalElement } from './uui-modal.element';
import { defineElement } from '@umbraco-ui/uui-base/lib/registration';

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

constructor() {
super();
this.addEventListener('close', this.#onClose);
this.addEventListener(UUIModalCloseEvent, this.#onCloseModalClose);
}

protected firstUpdated(
Expand All @@ -38,13 +38,29 @@ export class UUIModalContainerElement extends LitElement {
}

#onSlotChange = () => {
const existingModals = this._modals ?? [];

this._modals =
(this.modalSlot
?.assignedElements({ flatten: true })
.filter(
el => el instanceof UUIModalElement
) as Array<UUIModalElement>) ?? [];

const oldModals = existingModals.filter(
modal => this._modals!.indexOf(modal) === -1
);
oldModals.forEach(modal =>
modal.removeEventListener(UUIModalCloseEvent, this.#onCloseModalClose)
);

const newModals = this._modals.filter(
modal => existingModals.indexOf(modal) === -1
);
newModals.forEach(modal =>
modal.addEventListener(UUIModalCloseEvent, this.#onCloseModalClose)
);

this._sidebars = this._modals.filter(
el => el instanceof UUIModalSidebarElement
) as Array<UUIModalSidebarElement>;
Expand All @@ -58,7 +74,13 @@ export class UUIModalContainerElement extends LitElement {
this.#updateSidebars();
};

#onClose = () => {
#onCloseModalClose = (event: Event) => {
event.stopImmediatePropagation();

event.target?.removeEventListener(
UUIModalCloseEvent,
this.#onCloseModalClose
);
if (!this._modals || this._modals.length <= 1) {
this.removeAttribute('backdrop');
return;
Expand Down Expand Up @@ -99,7 +121,15 @@ export class UUIModalContainerElement extends LitElement {
for (let i = 0; i < reversed.length; i++) {
const sidebar = reversed[i];
const nextSidebar = reversed[i + 1];
sidebar.style.setProperty('--uui-modal-offset', sidebarOffset + 'px');
const tempSidebarOffset = sidebarOffset; // Cache to prevent it from being overwritten before the updateComplete.
// The sidebar checks it's own width at sets it's --uui-modal-offset to negative that width.
// This enables it to slide in from the right. So we need to set the new --uui-modal-offset after the updateComplete.
sidebar.updateComplete.then(() => {
sidebar.style.setProperty(
'--uui-modal-offset',
tempSidebarOffset + 'px'
);
});

// Stop the calculations if the next sidebar is hidden
if (nextSidebar?.hasAttribute('hide')) break;
Expand Down
4 changes: 2 additions & 2 deletions packages/uui-modal/lib/uui-modal-sidebar.element.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { css, html, PropertyValueMap } from 'lit';
import { property } from 'lit/decorators.js';
import { UUIModalElement } from './uui-modal.element';
import { UUIModalCloseEvent, UUIModalElement } from './uui-modal.element';
import { defineElement } from '@umbraco-ui/uui-base/lib/registration';

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

constructor() {
super();
this.addEventListener('close', this.#onClose.bind(this));
this.addEventListener(UUIModalCloseEvent, this.#onClose.bind(this));
}

protected firstUpdated(
Expand Down
4 changes: 3 additions & 1 deletion packages/uui-modal/lib/uui-modal.element.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { LitElement, css } from 'lit';
import { property, query } from 'lit/decorators.js';

export const UUIModalCloseEvent = 'uui:modal-close';
export class UUIModalElement extends LitElement {
@query('dialog')
protected _dialogElement?: HTMLDialogElement;
Expand Down Expand Up @@ -58,7 +60,7 @@ export class UUIModalElement extends LitElement {
event?.preventDefault();
event?.stopImmediatePropagation();

const closeEvent = new CustomEvent('close', {
const closeEvent = new CustomEvent(UUIModalCloseEvent, {
cancelable: true,
});
this.dispatchEvent(closeEvent);
Expand Down

0 comments on commit 4552287

Please sign in to comment.