From 9f230420c4fd55ee60c900e713e7f8032ab4bc5a Mon Sep 17 00:00:00 2001 From: Victor Vogel Date: Sat, 31 Oct 2026 22:03:28 +0000 Subject: [PATCH 1/2] fix(web): pending-question digit shortcuts ignore dialogs, menus and selects While a question was pending, pressing 1-9 with focus in a dialog, a menu (including the web fallback context menu), a select/combobox popup or a native select picked an answer (single-select could auto-advance and submit) and swallowed the key from the focused control. The document keydown handler now also skips targets inside select, [role="dialog"], [aria-modal="true"], [role="menu"] and [data-slot$="popup"], matching the usage and settings shortcut guards. Co-Authored-By: Claude Opus 5.5 --- ...oserPendingUserInputPanel.browser.test.tsx | 93 +++++++++++++++++++ .../chat/ComposerPendingUserInputPanel.tsx | 4 +- 2 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 apps/web/src/components/chat/ComposerPendingUserInputPanel.browser.test.tsx diff --git a/apps/web/src/components/chat/ComposerPendingUserInputPanel.browser.test.tsx b/apps/web/src/components/chat/ComposerPendingUserInputPanel.browser.test.tsx new file mode 100644 index 0000000000000..963502d753c70 --- /dev/null +++ b/apps/web/src/components/chat/ComposerPendingUserInputPanel.browser.test.tsx @@ -0,0 +1,93 @@ +import { EnvironmentId, RuntimeRequestId, ThreadId } from "@t3tools/contracts"; +import type { ReactNode } from "react"; +import { expect, it, vi } from "vite-plus/test"; +import { userEvent } from "vite-plus/test/browser"; + +import { render } from "../../../test/render"; +import type { PendingUserInput } from "../../session-logic"; +import { ComposerPendingUserInputPanel } from "./ComposerPendingUserInputPanel"; + +const threadRef = { environmentId: EnvironmentId.make("env"), threadId: ThreadId.make("thread") }; + +const prompt: PendingUserInput = { + requestId: RuntimeRequestId.make("question-shortcuts"), + createdAt: "2026-10-31T00:00:00.000Z", + dismissible: false, + responseCapability: "live", + questions: [ + { + id: "question", + header: "Rollout", + question: "How should this ship?", + options: [{ label: "Incremental", description: "One module at a time" }], + multiSelect: true, + }, + ], +}; + +it.each<{ focus: string; control: ReactNode; toggles: boolean }>([ + { focus: "a page button", control: