fix(frontend): defer cursor offset update in onCategoryEnter

When @category is selected, ms.setCursorOffset and ms.setValue were called
in the same event loop tick — the cursor sync effect later read the DOM
before the new mention value flushed, restoring the old caret position.

Defer ms.setCursorOffset via setTimeout so it fires after the DOM
reconciliation. Same fix applied to insertCategory imperative handle.
This commit is contained in:
ZhenYi 2026-04-18 11:24:01 +08:00
parent 5103d99a00
commit fb09553b79

View File

@ -131,8 +131,10 @@ const ChatInputArea = memo(function ChatInputArea({
const newCursorPos = startPos + 1 + category.length + 1;
onDraftChangeRef.current(newValue);
ms.setValue(newValue);
ms.setCursorOffset(newCursorPos);
ms.setShowMentionPopover(!!newValue.substring(0, newCursorPos).match(/@([^:@\s]*)(:([^\s]*))?$/));
setTimeout(() => {
ms.setCursorOffset(newCursorPos);
ms.setShowMentionPopover(!!newValue.substring(0, newCursorPos).match(/@([^:@\s]*)(:([^\s]*))?$/));
}, 0);
},
}));
@ -247,7 +249,8 @@ const ChatInputArea = memo(function ChatInputArea({
const newCursorPos = startPos + 1 + category.length + 1;
onDraftChangeRef.current(newValue);
ms.setValue(newValue);
ms.setCursorOffset(newCursorPos);
// Defer cursor update until after DOM has flushed the new mention value
setTimeout(() => ms.setCursorOffset(newCursorPos), 0);
}}
suggestions={ms.suggestions}
selectedIndex={ms.selectedIndex}