fix(task-viewer): esc capture phase to prevent App.vue handler conflict
Register the Esc keydown listener in capture phase (useCapture=true) and call stopPropagation() so App.vue's document-level handler never fires. Without this, both handlers ran: App.vue pushed "/" and the component pushed "/projects/:id", with non-deterministic winner. Also fixes the blur-then-navigate issue where App.vue blurring an input caused the component's handler to see body as the active element and navigate immediately instead of stopping at the blur step. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -96,8 +96,12 @@ async function loadTask(id: number) {
|
||||
|
||||
function handleKeydown(e: KeyboardEvent) {
|
||||
if (e.key !== "Escape") return;
|
||||
e.stopPropagation(); // prevent App.vue's global handler from also firing
|
||||
const active = document.activeElement as HTMLElement | null;
|
||||
if (active && active !== document.body) { active.blur(); return; }
|
||||
if (active && active !== document.body) {
|
||||
(active as HTMLElement).blur();
|
||||
return;
|
||||
}
|
||||
if (store.currentTask?.project_id) {
|
||||
router.push(`/projects/${store.currentTask.project_id}`);
|
||||
} else {
|
||||
@@ -107,9 +111,10 @@ function handleKeydown(e: KeyboardEvent) {
|
||||
|
||||
onMounted(() => {
|
||||
loadTask(taskId.value);
|
||||
window.addEventListener("keydown", handleKeydown);
|
||||
// Capture phase so this fires before App.vue's document-level handler
|
||||
window.addEventListener("keydown", handleKeydown, true);
|
||||
});
|
||||
onUnmounted(() => window.removeEventListener("keydown", handleKeydown));
|
||||
onUnmounted(() => window.removeEventListener("keydown", handleKeydown, true));
|
||||
|
||||
watch(() => route.params.id, (newId) => {
|
||||
if (newId) loadTask(Number(newId));
|
||||
|
||||
Reference in New Issue
Block a user