From 1676fdd84dee0daa5ac5519185450678442cd362 Mon Sep 17 00:00:00 2001 From: Charles Vien Date: Sat, 28 Mar 2026 17:12:34 +0000 Subject: [PATCH 1/2] Fix Enter key blocked after dismissing empty suggestion popup --- .../features/message-editor/tiptap/CommandMention.ts | 5 +++++ .../renderer/features/message-editor/tiptap/FileMention.ts | 5 +++++ .../features/message-editor/tiptap/SuggestionList.tsx | 7 +++++-- .../features/message-editor/tiptap/useTiptapEditor.ts | 7 ++++--- 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/apps/code/src/renderer/features/message-editor/tiptap/CommandMention.ts b/apps/code/src/renderer/features/message-editor/tiptap/CommandMention.ts index 1c68e308c..dccdbc3d6 100644 --- a/apps/code/src/renderer/features/message-editor/tiptap/CommandMention.ts +++ b/apps/code/src/renderer/features/message-editor/tiptap/CommandMention.ts @@ -23,9 +23,11 @@ function createSuggestion( render: () => { let component: ReactRenderer | null = null; let popup: TippyInstance | null = null; + let dismissed = false; return { onStart: (props) => { + dismissed = false; component = new ReactRenderer(SuggestionList, { props: { items: props.items, @@ -67,9 +69,12 @@ function createSuggestion( if (props.event.key === "Escape") { props.event.stopPropagation(); popup?.hide(); + dismissed = true; return true; } + if (dismissed) return false; + return component?.ref?.onKeyDown(props) ?? false; }, diff --git a/apps/code/src/renderer/features/message-editor/tiptap/FileMention.ts b/apps/code/src/renderer/features/message-editor/tiptap/FileMention.ts index 3ba26bed4..2eaece93d 100644 --- a/apps/code/src/renderer/features/message-editor/tiptap/FileMention.ts +++ b/apps/code/src/renderer/features/message-editor/tiptap/FileMention.ts @@ -27,9 +27,11 @@ function createSuggestion( render: () => { let component: ReactRenderer | null = null; let popup: TippyInstance | null = null; + let dismissed = false; return { onStart: (props) => { + dismissed = false; const items = props.items.length > 0 ? props.items : lastItems; component = new ReactRenderer(SuggestionList, { props: { @@ -73,9 +75,12 @@ function createSuggestion( if (props.event.key === "Escape") { props.event.stopPropagation(); popup?.hide(); + dismissed = true; return true; } + if (dismissed) return false; + return component?.ref?.onKeyDown(props) ?? false; }, diff --git a/apps/code/src/renderer/features/message-editor/tiptap/SuggestionList.tsx b/apps/code/src/renderer/features/message-editor/tiptap/SuggestionList.tsx index aed1a863e..3d4622f84 100644 --- a/apps/code/src/renderer/features/message-editor/tiptap/SuggestionList.tsx +++ b/apps/code/src/renderer/features/message-editor/tiptap/SuggestionList.tsx @@ -57,8 +57,11 @@ export const SuggestionList = forwardRef< return true; } if (event.key === "Enter" || event.key === "Tab") { - if (items[selectedIndex]) command(items[selectedIndex]); - return true; + if (items[selectedIndex]) { + command(items[selectedIndex]); + return true; + } + return false; } return false; }, diff --git a/apps/code/src/renderer/features/message-editor/tiptap/useTiptapEditor.ts b/apps/code/src/renderer/features/message-editor/tiptap/useTiptapEditor.ts index 3fc67d1c2..408c2738c 100644 --- a/apps/code/src/renderer/features/message-editor/tiptap/useTiptapEditor.ts +++ b/apps/code/src/renderer/features/message-editor/tiptap/useTiptapEditor.ts @@ -187,9 +187,10 @@ export function useTiptapEditor(options: UseTiptapEditorOptions) { if (isSubmitKey) { if (!view.editable || submitDisabledRef.current) return false; - const suggestionPopup = - document.querySelector("[data-tippy-root]"); - if (suggestionPopup) return false; + const visibleSuggestion = document.querySelector( + "[data-tippy-root] .tippy-box:not([data-state='hidden'])", + ); + if (visibleSuggestion) return false; event.preventDefault(); historyActions.reset(); submitRef.current(); From 4f832ddb531e6a1dc21e6f81a10a609751d7ec8e Mon Sep 17 00:00:00 2001 From: Charles Vien Date: Thu, 2 Apr 2026 14:58:29 -0700 Subject: [PATCH 2/2] Reset dismissed flag on suggestion update --- .../renderer/features/message-editor/tiptap/CommandMention.ts | 1 + .../src/renderer/features/message-editor/tiptap/FileMention.ts | 1 + .../renderer/features/message-editor/tiptap/useTiptapEditor.ts | 1 + 3 files changed, 3 insertions(+) diff --git a/apps/code/src/renderer/features/message-editor/tiptap/CommandMention.ts b/apps/code/src/renderer/features/message-editor/tiptap/CommandMention.ts index dccdbc3d6..4856668be 100644 --- a/apps/code/src/renderer/features/message-editor/tiptap/CommandMention.ts +++ b/apps/code/src/renderer/features/message-editor/tiptap/CommandMention.ts @@ -53,6 +53,7 @@ function createSuggestion( }, onUpdate: (props) => { + if (props.items.length > 0) dismissed = false; component?.updateProps({ items: props.items, command: props.command, diff --git a/apps/code/src/renderer/features/message-editor/tiptap/FileMention.ts b/apps/code/src/renderer/features/message-editor/tiptap/FileMention.ts index 2eaece93d..440fd2d28 100644 --- a/apps/code/src/renderer/features/message-editor/tiptap/FileMention.ts +++ b/apps/code/src/renderer/features/message-editor/tiptap/FileMention.ts @@ -58,6 +58,7 @@ function createSuggestion( }, onUpdate: (props) => { + if (props.items.length > 0) dismissed = false; const items = props.items.length > 0 ? props.items : lastItems; component?.updateProps({ items, diff --git a/apps/code/src/renderer/features/message-editor/tiptap/useTiptapEditor.ts b/apps/code/src/renderer/features/message-editor/tiptap/useTiptapEditor.ts index 408c2738c..85165613e 100644 --- a/apps/code/src/renderer/features/message-editor/tiptap/useTiptapEditor.ts +++ b/apps/code/src/renderer/features/message-editor/tiptap/useTiptapEditor.ts @@ -187,6 +187,7 @@ export function useTiptapEditor(options: UseTiptapEditorOptions) { if (isSubmitKey) { if (!view.editable || submitDisabledRef.current) return false; + // tippy.js sets data-state="hidden" when hiding via .hide() const visibleSuggestion = document.querySelector( "[data-tippy-root] .tippy-box:not([data-state='hidden'])", );