Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix modal close animation #702

Merged
merged 13 commits into from
Jan 23, 2024
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
Loading