Skip to content

Commit

Permalink
fix(dialog): fixed escape key bug when persistent and improved destro…
Browse files Browse the repository at this point in the history
…y logic (#823)
  • Loading branch information
DRiFTy17 authored Feb 14, 2025
1 parent 2ae0d96 commit e4bd264
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 43 deletions.
34 changes: 15 additions & 19 deletions src/lib/dialog/dialog-adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,11 @@ export interface IDialogAdapter extends IBaseAdapter<IDialogComponent> {
readonly moveHandleElement: HTMLElement;
readonly surfaceElement: HTMLElement;
triggerElement: HTMLElement | null;
destroy(): void;
show(): void;
hide(): Promise<void>;
addDialogFormSubmitListener(listener: EventListener): void;
removeDialogFormSubmitListener(listener: EventListener): void;
addDialogCancelListener(listener: EventListener): void;
removeDialogCancelListener(listener: EventListener): void;
addBackdropDismissListener(listener: EventListener): void;
removeBackdropDismissListener(listener: EventListener): void;
tryAutofocus(): void;
Expand Down Expand Up @@ -62,6 +61,10 @@ export class DialogAdapter extends BaseAdapter<IDialogComponent> implements IDia
}
}

public destroy(): void {
this._forceClose();
}

public show(): void {
/* c8 ignore next 3 */
if (this._dialogElement.open) {
Expand Down Expand Up @@ -112,20 +115,14 @@ export class DialogAdapter extends BaseAdapter<IDialogComponent> implements IDia
}

public async hide(): Promise<void> {
const close = (): void => {
this._surfaceElement.classList.remove(BACKDROP_CONSTANTS.classes.EXITING);
this._dialogElement.close();
DialogComponent[dialogStack].delete(this._component);
this._showBackdropMostRecent();
};

if (this._component.animationType === 'none') {
return Promise.resolve(close());
this._forceClose();
return Promise.resolve();
}

this._backdropElement.fadeOut();
await playKeyframeAnimation(this._surfaceElement, BACKDROP_CONSTANTS.classes.EXITING);
close();
this._forceClose();
}

public addDialogFormSubmitListener(listener: EventListener): void {
Expand All @@ -136,14 +133,6 @@ export class DialogAdapter extends BaseAdapter<IDialogComponent> implements IDia
this._dialogElement.removeEventListener('submit', listener);
}

public addDialogCancelListener(listener: EventListener): void {
this._dialogElement.addEventListener('cancel', listener);
}

public removeDialogCancelListener(listener: EventListener): void {
this._dialogElement.removeEventListener('cancel', listener);
}

public addBackdropDismissListener(listener: EventListener): void {
this._backdropElement.addEventListener('click', listener);
}
Expand Down Expand Up @@ -260,4 +249,11 @@ export class DialogAdapter extends BaseAdapter<IDialogComponent> implements IDia
element.textContent = content;
return element;
}

private _forceClose(): void {
this._surfaceElement.classList.remove(BACKDROP_CONSTANTS.classes.EXITING);
this._dialogElement.close();
DialogComponent[dialogStack].delete(this._component);
this._showBackdropMostRecent();
}
}
49 changes: 25 additions & 24 deletions src/lib/dialog/dialog-core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,9 @@ export class DialogCore implements IDialogCore {
this._destroyMoveController();
}

if (this._open) {
this._hide();
}
this._release();
this._tryResetFullscreenValue();
this._adapter.destroy();
}

public dispatchBeforeCloseEvent(): boolean {
Expand All @@ -115,9 +115,7 @@ export class DialogCore implements IDialogCore {
this._adapter.addDialogFormSubmitListener(this._dialogFormSubmitListener);
DismissibleStack.instance.add(this._adapter.hostElement);

if (this._mode === 'modal') {
this._adapter.addDialogCancelListener(this._escapeDismissListener);
} else if (this._mode === 'inline-modal') {
if (this._mode === 'modal' || this._mode === 'inline-modal') {
this._adapter.addDocumentListener('keydown', this._escapeDismissListener);
}

Expand All @@ -138,19 +136,11 @@ export class DialogCore implements IDialogCore {
}

private async _hide(): Promise<void> {
this._adapter.removeDialogFormSubmitListener(this._dialogFormSubmitListener);
this._adapter.removeDialogCancelListener(this._escapeDismissListener);
this._adapter.removeDocumentListener('keydown', this._escapeDismissListener);
this._adapter.removeBackdropDismissListener(this._backdropDismissListener);
DismissibleStack.instance.remove(this._adapter.hostElement);

this._release();
await this._adapter.hide();

// Reset the fullscreen value to the original value if it was changed internally by our media query listener
if (typeof this._originalFullscreenValue === 'boolean') {
this.fullscreen = this._originalFullscreenValue;
}
this._originalFullscreenValue = undefined;
this._tryResetFullscreenValue();

if (this._moveController) {
this._destroyMoveController();
Expand All @@ -159,6 +149,20 @@ export class DialogCore implements IDialogCore {
this._adapter.dispatchHostEvent(new CustomEvent(DIALOG_CONSTANTS.events.CLOSE, { bubbles: true, composed: true }));
}

private _release(): void {
this._adapter.removeDialogFormSubmitListener(this._dialogFormSubmitListener);
this._adapter.removeDocumentListener('keydown', this._escapeDismissListener);
this._adapter.removeBackdropDismissListener(this._backdropDismissListener);
DismissibleStack.instance.remove(this._adapter.hostElement);
}

private _tryResetFullscreenValue(): void {
if (typeof this._originalFullscreenValue === 'boolean') {
this.fullscreen = this._originalFullscreenValue;
}
this._originalFullscreenValue = undefined;
}

private async _applyOpen(): Promise<void> {
if (this._open) {
this._show();
Expand All @@ -171,16 +175,13 @@ export class DialogCore implements IDialogCore {
this._adapter.toggleHostAttribute(DIALOG_CONSTANTS.attributes.OPEN, this._open);
}

private _onEscapeDismiss(evt: Event): void {
if (evt.type === 'keydown') {
const key = (evt as KeyboardEvent).key;
if (key !== 'Escape' || !DismissibleStack.instance.isMostRecent(this._adapter.hostElement)) {
return;
}
} else if (evt.type === 'cancel') {
evt.preventDefault();
private _onEscapeDismiss(evt: KeyboardEvent): void {
if (evt.key !== 'Escape' || !DismissibleStack.instance.isMostRecent(this._adapter.hostElement)) {
return;
}

evt.preventDefault();

if (!this._persistent) {
this._tryClose();
}
Expand Down

0 comments on commit e4bd264

Please sign in to comment.