Close the Datei menu on Escape or a click outside it

Listens in the capture phase while the menu is open, so canvas and grid
handlers that stop propagation can't keep it open.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
wkh
2026-09-28 02:12:05 +02:00
co-authored by Claude Opus 5.5
parent 5a79ddee79
commit ac09df1482
+25 -2
View File
@@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, ref } from 'vue'; import { computed, onBeforeUnmount, ref, watch } from 'vue';
import { useDocument } from '../store/document'; import { useDocument } from '../store/document';
import { useTheme } from '../composables/useTheme'; import { useTheme } from '../composables/useTheme';
import { useToasts } from '../composables/useToasts'; import { useToasts } from '../composables/useToasts';
@@ -30,6 +30,29 @@ const { mode: themeMode, cycle: cycleTheme } = useTheme();
const toasts = useToasts(); const toasts = useToasts();
const fileMenuOpen = ref(false); const fileMenuOpen = ref(false);
const fileMenuWrap = ref<HTMLElement | null>(null);
// Close the Datei menu on Escape or on a press anywhere outside it. Capture
// phase, so canvas/grid handlers that stop propagation can't swallow it.
function onOutsidePointer(e: PointerEvent) {
if (!fileMenuWrap.value?.contains(e.target as Node)) fileMenuOpen.value = false;
}
function onMenuKey(e: KeyboardEvent) {
if (e.key === 'Escape') fileMenuOpen.value = false;
}
function detachMenuListeners() {
document.removeEventListener('pointerdown', onOutsidePointer, true);
document.removeEventListener('keydown', onMenuKey, true);
}
watch(fileMenuOpen, (open) => {
if (open) {
document.addEventListener('pointerdown', onOutsidePointer, true);
document.addEventListener('keydown', onMenuKey, true);
} else {
detachMenuListeners();
}
});
onBeforeUnmount(detachMenuListeners);
const aboutOpen = ref(false); const aboutOpen = ref(false);
const functionsOpen = ref(false); const functionsOpen = ref(false);
const namedRangesOpen = ref(false); const namedRangesOpen = ref(false);
@@ -295,7 +318,7 @@ function onSample() {
<div class="spacer" /> <div class="spacer" />
<div class="menu-wrap"> <div ref="fileMenuWrap" class="menu-wrap">
<button class="btn" @click="fileMenuOpen = !fileMenuOpen">Datei ▾</button> <button class="btn" @click="fileMenuOpen = !fileMenuOpen">Datei ▾</button>
<ul v-if="fileMenuOpen" class="menu" @click="fileMenuOpen = false"> <ul v-if="fileMenuOpen" class="menu" @click="fileMenuOpen = false">
<li><button @click="onNew">Neu</button></li> <li><button @click="onNew">Neu</button></li>