diff --git a/src/bundled/channels/ChannelSettingsPanel.test.tsx b/src/bundled/channels/ChannelSettingsPanel.test.tsx index a8c7dd9d87..a413c8cae5 100644 --- a/src/bundled/channels/ChannelSettingsPanel.test.tsx +++ b/src/bundled/channels/ChannelSettingsPanel.test.tsx @@ -10,7 +10,7 @@ import { } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { createPortal } from "react-dom"; -import { afterEach, assert, expect, it, vi } from "vitest"; +import { afterEach, assert, expect, it, onTestFinished, vi } from "vitest"; import { ChannelSettingsPanel } from "./ChannelSettingsPanel"; import type { ChannelSummary } from "../../features/relay/contracts"; import { @@ -64,6 +64,9 @@ it("shows known channel details with diagnostics collapsed until requested", asy it("closes with Escape or its close button without swallowing other keys", async () => { const user = userEvent.setup(); const close = vi.fn(); + const windowKeyDown = vi.fn(); + window.addEventListener("keydown", windowKeyDown); + onTestFinished(() => window.removeEventListener("keydown", windowKeyDown)); render( }{Escape}{/Shift}"); + expect(close).not.toHaveBeenCalled(); + expect(windowKeyDown).toHaveBeenCalledWith( + expect.objectContaining({ key: "Escape", shiftKey: true }), + ); + windowKeyDown.mockClear(); await user.keyboard("{Escape}"); expect(close).toHaveBeenCalledTimes(1); + expect(windowKeyDown).not.toHaveBeenCalledWith( + expect.objectContaining({ key: "Escape" }), + ); await user.click( screen.getByRole("button", { name: "Close Channel settings tab" }), ); diff --git a/src/bundled/channels/ChannelSettingsPanel.tsx b/src/bundled/channels/ChannelSettingsPanel.tsx index a0af3f5f9e..709200f12a 100644 --- a/src/bundled/channels/ChannelSettingsPanel.tsx +++ b/src/bundled/channels/ChannelSettingsPanel.tsx @@ -96,9 +96,11 @@ export function ChannelSettingsPanel({ aria-label="Channel settings" aria-busy={loading} onKeyDown={(event) => { + // Shift+Escape is Mark all as read, not a dismissal. // Portalled menus and cards bubble here through React but own their Escape. if ( event.key === "Escape" && + !event.shiftKey && !event.defaultPrevented && event.currentTarget.contains(event.target as Node) ) {