diff --git a/ui/src/hooks/useKeyboardShortcuts.test.tsx b/ui/src/hooks/useKeyboardShortcuts.test.tsx new file mode 100644 index 00000000..9d1c59dc --- /dev/null +++ b/ui/src/hooks/useKeyboardShortcuts.test.tsx @@ -0,0 +1,58 @@ +// @vitest-environment jsdom + +import { act } from "react"; +import { createRoot } from "react-dom/client"; +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { useKeyboardShortcuts } from "./useKeyboardShortcuts"; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +(globalThis as any).IS_REACT_ACT_ENVIRONMENT = true; + +function TestHarness({ + onNewIssue, +}: { + onNewIssue: () => void; +}) { + useKeyboardShortcuts({ + enabled: true, + onNewIssue, + }); + + return
keyboard shortcuts test
; +} + +describe("useKeyboardShortcuts", () => { + let container: HTMLDivElement; + + beforeEach(() => { + container = document.createElement("div"); + document.body.appendChild(container); + }); + + afterEach(() => { + container.remove(); + }); + + it("ignores events already claimed by another handler", () => { + const root = createRoot(container); + const onNewIssue = vi.fn(); + + act(() => { + root.render(); + }); + + const event = new KeyboardEvent("keydown", { + key: "c", + bubbles: true, + cancelable: true, + }); + event.preventDefault(); + document.dispatchEvent(event); + + expect(onNewIssue).not.toHaveBeenCalled(); + + act(() => { + root.unmount(); + }); + }); +}); diff --git a/ui/src/hooks/useKeyboardShortcuts.ts b/ui/src/hooks/useKeyboardShortcuts.ts index c917ebba..1502adde 100644 --- a/ui/src/hooks/useKeyboardShortcuts.ts +++ b/ui/src/hooks/useKeyboardShortcuts.ts @@ -20,6 +20,10 @@ export function useKeyboardShortcuts({ if (!enabled) return; function handleKeyDown(e: KeyboardEvent) { + if (e.defaultPrevented) { + return; + } + // Don't fire shortcuts when typing in inputs if (isKeyboardShortcutTextInputTarget(e.target)) { return; diff --git a/ui/src/pages/IssueDetail.tsx b/ui/src/pages/IssueDetail.tsx index f9939b9b..41d0b25f 100644 --- a/ui/src/pages/IssueDetail.tsx +++ b/ui/src/pages/IssueDetail.tsx @@ -1332,11 +1332,13 @@ export function IssueDetail() { disarm(); if (action === "navigate_inbox") { event.preventDefault(); + event.stopPropagation(); navigate(sourceBreadcrumb.href.startsWith("/inbox") ? sourceBreadcrumb.href : "/inbox"); return; } if (action === "focus_comment") { event.preventDefault(); + event.stopPropagation(); setDetailTab("chat"); setPendingCommentComposerFocusKey((current) => current + 1); }