Skip to content

Commit 5f5c438

Browse files
authored
fix: Fix Enter key blocked after dismissing empty suggestion popup (#1471)
## Problem Pressing Escape on a suggestion popup with no results hides it visually but leaves the Tippy DOM node mounted, causing the Enter-to-submit handler to think a suggestion is still active. <!-- Who is this for and what problem does it solve? --> <!-- Closes #ISSUE_ID --> ## Changes 1. Track dismissed flag in CommandMention and FileMention suggestion renderers 2. Return false from onKeyDown when dismissed so Enter propagates normally 3. Return false from SuggestionList when no item is selected instead of swallowing the event 4. Check for visible Tippy box (data-state not hidden) instead of just DOM presence 5. Reset dismissed flag when new non-empty suggestions arrive <!-- What did you change and why? --> <!-- If there are frontend changes, include screenshots. --> ## How did you test this? Manually <!-- Describe what you tested -- manual steps, automated tests, or both. --> <!-- If you're an agent, only list tests you actually ran. -->
1 parent 1fd277a commit 5f5c438

4 files changed

Lines changed: 22 additions & 5 deletions

File tree

apps/code/src/renderer/features/message-editor/tiptap/CommandMention.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,11 @@ function createSuggestion(
2323
render: () => {
2424
let component: ReactRenderer<SuggestionListRef> | null = null;
2525
let popup: TippyInstance | null = null;
26+
let dismissed = false;
2627

2728
return {
2829
onStart: (props) => {
30+
dismissed = false;
2931
component = new ReactRenderer(SuggestionList, {
3032
props: {
3133
items: props.items,
@@ -51,6 +53,7 @@ function createSuggestion(
5153
},
5254

5355
onUpdate: (props) => {
56+
if (props.items.length > 0) dismissed = false;
5457
component?.updateProps({
5558
items: props.items,
5659
command: props.command,
@@ -67,9 +70,12 @@ function createSuggestion(
6770
if (props.event.key === "Escape") {
6871
props.event.stopPropagation();
6972
popup?.hide();
73+
dismissed = true;
7074
return true;
7175
}
7276

77+
if (dismissed) return false;
78+
7379
return component?.ref?.onKeyDown(props) ?? false;
7480
},
7581

apps/code/src/renderer/features/message-editor/tiptap/FileMention.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,11 @@ function createSuggestion(
2727
render: () => {
2828
let component: ReactRenderer<SuggestionListRef> | null = null;
2929
let popup: TippyInstance | null = null;
30+
let dismissed = false;
3031

3132
return {
3233
onStart: (props) => {
34+
dismissed = false;
3335
const items = props.items.length > 0 ? props.items : lastItems;
3436
component = new ReactRenderer(SuggestionList, {
3537
props: {
@@ -56,6 +58,7 @@ function createSuggestion(
5658
},
5759

5860
onUpdate: (props) => {
61+
if (props.items.length > 0) dismissed = false;
5962
const items = props.items.length > 0 ? props.items : lastItems;
6063
component?.updateProps({
6164
items,
@@ -73,9 +76,12 @@ function createSuggestion(
7376
if (props.event.key === "Escape") {
7477
props.event.stopPropagation();
7578
popup?.hide();
79+
dismissed = true;
7680
return true;
7781
}
7882

83+
if (dismissed) return false;
84+
7985
return component?.ref?.onKeyDown(props) ?? false;
8086
},
8187

apps/code/src/renderer/features/message-editor/tiptap/SuggestionList.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,11 @@ export const SuggestionList = forwardRef<
5757
return true;
5858
}
5959
if (event.key === "Enter" || event.key === "Tab") {
60-
if (items[selectedIndex]) command(items[selectedIndex]);
61-
return true;
60+
if (items[selectedIndex]) {
61+
command(items[selectedIndex]);
62+
return true;
63+
}
64+
return false;
6265
}
6366
return false;
6467
},

apps/code/src/renderer/features/message-editor/tiptap/useTiptapEditor.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -187,9 +187,11 @@ export function useTiptapEditor(options: UseTiptapEditorOptions) {
187187

188188
if (isSubmitKey) {
189189
if (!view.editable || submitDisabledRef.current) return false;
190-
const suggestionPopup =
191-
document.querySelector("[data-tippy-root]");
192-
if (suggestionPopup) return false;
190+
// tippy.js sets data-state="hidden" when hiding via .hide()
191+
const visibleSuggestion = document.querySelector(
192+
"[data-tippy-root] .tippy-box:not([data-state='hidden'])",
193+
);
194+
if (visibleSuggestion) return false;
193195
event.preventDefault();
194196
historyActions.reset();
195197
submitRef.current();

0 commit comments

Comments
 (0)