diff --git a/frontend/src/components/modal/ImageViewer.vue b/frontend/src/components/modal/ImageViewer.vue index 53e17be..d052bbd 100644 --- a/frontend/src/components/modal/ImageViewer.vue +++ b/frontend/src/components/modal/ImageViewer.vue @@ -97,20 +97,20 @@ let prevBodyOverflow = null // own keystrokes. function onKeyDown(ev) { if (ev.key === 'Escape') { - // Escape closes the modal even from inside a text input — that's - // the universal "get me out of here" expectation, and the - // autofocused tag-entry field would otherwise trap focus with no - // visible escape (operator-flagged 2026-06-01). EXCEPTION: when a - // nested Vuetify overlay is open (v-menu autocomplete dropdown, - // FandomPicker v-dialog, per-suggestion 3-dot menu), let that - // overlay's own Esc handling fire instead of closing the whole - // modal mid-interaction. Vuetify marks open overlays with - // `.v-overlay--active`. - // EXCLUDE tooltips (`.v-tooltip`): they're also `.v-overlay--active` while - // shown, so one lingering after a hover/click (e.g. just after accepting a - // suggested tag) wrongly suppressed the close (#700). Only real interactive - // overlays (menus/dialogs) should keep ESC from closing the modal. - if (document.querySelector('.v-overlay--active:not(.v-tooltip)')) return + // Escape closes the modal even from inside a text input — the universal + // "get me out of here" expectation; the autofocused tag field would + // otherwise trap focus (operator-flagged 2026-06-01). EXCEPTION: when the + // keystroke originates INSIDE an open Vuetify overlay's content (a rename/ + // fandom/alias dialog, or a kebab menu), let that overlay handle its own + // Esc and don't close the whole modal. + // + // #700 re-fix (2026-06-07): the prior guard queried for ANY active overlay + // anywhere in the DOM and suppressed the close — so a lingering overlay + // after accepting a suggestion (focus drops to
, not into any + // overlay) wrongly blocked Esc. Keying off the event's origin instead means + // a stray overlay no longer traps the modal: only an Esc pressed from + // within overlay content defers to that overlay. + if (ev.target?.closest?.('.v-overlay__content')) return ev.preventDefault() emit('close') } else if (ev.key === 'ArrowLeft') { diff --git a/frontend/src/components/modal/TagAutocomplete.vue b/frontend/src/components/modal/TagAutocomplete.vue index ec6a258..4e671f3 100644 --- a/frontend/src/components/modal/TagAutocomplete.vue +++ b/frontend/src/components/modal/TagAutocomplete.vue @@ -12,6 +12,7 @@ />