Introduce a global dialog stack to correctly manage dismissal through the esc key.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@tp/tp-dialog",
|
||||
"version": "1.4.0",
|
||||
"version": "1.5.0",
|
||||
"description": "",
|
||||
"main": "tp-dialog.js",
|
||||
"scripts": {
|
||||
|
71
tp-dialog.js
71
tp-dialog.js
@@ -9,6 +9,21 @@ import { LitElement, html, css, svg } from 'lit';
|
||||
import { EventHelpers } from '@tp/helpers/event-helpers.js';
|
||||
import { closest } from '@tp/helpers/closest.js';
|
||||
|
||||
// Global stack to track opened dialogs with closeOnEsc
|
||||
const dialogStack = [];
|
||||
let escKeyListener = null;
|
||||
|
||||
// Global escape key handler
|
||||
function handleGlobalEscKey(event) {
|
||||
if (event.key === 'Escape' && dialogStack.length > 0) {
|
||||
// Get the most recently opened dialog
|
||||
const lastDialog = dialogStack[dialogStack.length - 1];
|
||||
if (lastDialog && lastDialog.closeOnEsc) {
|
||||
lastDialog.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TpDialog extends EventHelpers(LitElement) {
|
||||
static get styles() {
|
||||
return [
|
||||
@@ -83,7 +98,6 @@ class TpDialog extends EventHelpers(LitElement) {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this._handleEscKey = this._handleEscKey.bind(this);
|
||||
this._currentPromise = null;
|
||||
this._resolvePromise = null;
|
||||
}
|
||||
@@ -103,9 +117,8 @@ class TpDialog extends EventHelpers(LitElement) {
|
||||
this.unlisten(this, 'confirmed', '_handleConfirmed');
|
||||
this.unlisten(this, 'dismissed', '_handleDismissed');
|
||||
|
||||
if (this.closeOnEsc) {
|
||||
document.removeEventListener('keydown', this._handleEscKey);
|
||||
}
|
||||
// Remove this dialog from the stack
|
||||
this._removeFromDialogStack();
|
||||
|
||||
// Clean up promise if dialog is removed while open
|
||||
if (this._currentPromise && this._resolvePromise) {
|
||||
@@ -119,9 +132,8 @@ class TpDialog extends EventHelpers(LitElement) {
|
||||
this.dialog.show();
|
||||
this.open = true;
|
||||
|
||||
if (this.closeOnEsc) {
|
||||
document.addEventListener('keydown', this._handleEscKey, { once: true });
|
||||
}
|
||||
// Add to dialog stack if closeOnEsc is enabled
|
||||
this._addToDialogStack();
|
||||
|
||||
// Create and return a new promise
|
||||
this._currentPromise = new Promise((resolve) => {
|
||||
@@ -135,9 +147,8 @@ class TpDialog extends EventHelpers(LitElement) {
|
||||
this.dialog.showModal();
|
||||
this.open = true;
|
||||
|
||||
if (this.closeOnEsc) {
|
||||
document.addEventListener('keydown', this._handleEscKey, { once: true });
|
||||
}
|
||||
// Add to dialog stack if closeOnEsc is enabled
|
||||
this._addToDialogStack();
|
||||
|
||||
if (this.closeOnOutsideClick) {
|
||||
this.addEventListener('click', this._handleOutsideClick, { once: true });
|
||||
@@ -161,6 +172,9 @@ class TpDialog extends EventHelpers(LitElement) {
|
||||
this.dispatchEvent(new CustomEvent('closed', { detail: null, bubbles: true, composed: true }));
|
||||
this.open = false;
|
||||
|
||||
// Remove from dialog stack
|
||||
this._removeFromDialogStack();
|
||||
|
||||
// If closed without explicit confirm/dismiss (like ESC key), treat as dismissed
|
||||
if (this._currentPromise && this._resolvePromise) {
|
||||
this._resolvePromise('dismissed');
|
||||
@@ -185,6 +199,35 @@ class TpDialog extends EventHelpers(LitElement) {
|
||||
}
|
||||
}
|
||||
|
||||
_addToDialogStack() {
|
||||
if (this.closeOnEsc) {
|
||||
// Remove if already in stack (shouldn't happen, but just in case)
|
||||
this._removeFromDialogStack();
|
||||
|
||||
// Add to the end of the stack
|
||||
dialogStack.push(this);
|
||||
|
||||
// Set up global listener if this is the first dialog
|
||||
if (dialogStack.length === 1 && !escKeyListener) {
|
||||
escKeyListener = handleGlobalEscKey;
|
||||
document.addEventListener('keydown', escKeyListener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_removeFromDialogStack() {
|
||||
const index = dialogStack.indexOf(this);
|
||||
if (index > -1) {
|
||||
dialogStack.splice(index, 1);
|
||||
|
||||
// Remove global listener if no more dialogs with closeOnEsc
|
||||
if (dialogStack.length === 0 && escKeyListener) {
|
||||
document.removeEventListener('keydown', escKeyListener);
|
||||
escKeyListener = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_onDialogClick(event) {
|
||||
if (this.closeOnOutsideClick) {
|
||||
const path = event.composedPath();
|
||||
@@ -217,10 +260,10 @@ class TpDialog extends EventHelpers(LitElement) {
|
||||
}
|
||||
}
|
||||
|
||||
_handleEscKey(event) {
|
||||
if (event.key === 'Escape' && this.closeOnEsc) {
|
||||
this.close();
|
||||
}
|
||||
_handleOutsideClick(event) {
|
||||
// This method should be implemented if closeOnOutsideClick functionality is needed
|
||||
// For now, just close the dialog when clicking outside
|
||||
this.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user