From ad8568677cc6b2462afec4cc0c2a5eb4ae8c110f Mon Sep 17 00:00:00 2001 From: johndoknjas Date: Tue, 24 Feb 2026 00:11:53 -0800 Subject: [PATCH 1/2] Prevent just a pointerdown event on close button from closing modal dialog. --- ui/lib/src/view/dialog.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/ui/lib/src/view/dialog.ts b/ui/lib/src/view/dialog.ts index 508d6ece9c257..2fe2f16ddd1a6 100644 --- a/ui/lib/src/view/dialog.ts +++ b/ui/lib/src/view/dialog.ts @@ -85,9 +85,7 @@ export async function domDialog(o: DomDialogOpts): Promise { (o.parent ?? document.body).appendChild(dialog); const wrapper = new DialogWrapper(dialog, view, o, false); - if (o.show) return wrapper.show(); - - return wrapper; + return o.show ? wrapper.show() : wrapper; } export function snabDialog(o: SnabDialogOpts): VNode { @@ -167,7 +165,10 @@ class DialogWrapper implements Dialog { if (!this.dialog.isConnected) console.trace('likely zombie dialog. Always Be Close()ing'); if (Date.now() - justThen < 200) return; const r = dialog.getBoundingClientRect(); - if (e.clientX < r.left || e.clientX > r.right || e.clientY < r.top || e.clientY > r.bottom) + if ( + (e.clientX < r.left || e.clientX > r.right || e.clientY < r.top || e.clientY > r.bottom) && + !dialog.contains(e.target as Node | null) // close button could be positioned outside the dialog + ) this.close('cancel'); }; this.observer.observe(document.body, { childList: true, subtree: true }); @@ -176,7 +177,7 @@ class DialogWrapper implements Dialog { this.dialogEvents.addListener(dialog, 'cancel', e => { if (o.noClickAway && o.noCloseButton && o.class !== 'alert') return e.preventDefault(); - if (!this.returnValue) this.returnValue = 'cancel'; + this.returnValue ||= 'cancel'; }); this.dialogEvents.addListener(dialog, 'close', this.onRemove); if (!o.noCloseButton) From 70152e7dcaef8377098f82136839062783af5bc7 Mon Sep 17 00:00:00 2001 From: johndoknjas Date: Fri, 27 Feb 2026 00:02:26 -0800 Subject: [PATCH 2/2] Remove condition checking that the event is in the bounding client rect. --- ui/lib/src/view/dialog.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/ui/lib/src/view/dialog.ts b/ui/lib/src/view/dialog.ts index 2fe2f16ddd1a6..6af1a71985470 100644 --- a/ui/lib/src/view/dialog.ts +++ b/ui/lib/src/view/dialog.ts @@ -163,13 +163,7 @@ class DialogWrapper implements Dialog { const justThen = Date.now(); const cancelOnInterval = (e: PointerEvent) => { if (!this.dialog.isConnected) console.trace('likely zombie dialog. Always Be Close()ing'); - if (Date.now() - justThen < 200) return; - const r = dialog.getBoundingClientRect(); - if ( - (e.clientX < r.left || e.clientX > r.right || e.clientY < r.top || e.clientY > r.bottom) && - !dialog.contains(e.target as Node | null) // close button could be positioned outside the dialog - ) - this.close('cancel'); + if (Date.now() - justThen >= 200 && !dialog.contains(e.target as Node | null)) this.close('cancel'); }; this.observer.observe(document.body, { childList: true, subtree: true }); document.body.style.setProperty('---viewport-height', `${window.innerHeight}px`);