From 3e52bfda309eb268e0d251fb1584a9ff5cdf9afc Mon Sep 17 00:00:00 2001 From: tusharmagar Date: Wed, 21 Jan 2026 16:09:56 +0530 Subject: [PATCH] Enhance PromptInputTextarea: Add external onKeyDown handler, improve backspace mention deletion logic, and update styling for better layout --- .../components/ai-elements/prompt-input.tsx | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/apps/x/apps/renderer/src/components/ai-elements/prompt-input.tsx b/apps/x/apps/renderer/src/components/ai-elements/prompt-input.tsx index b329fcbb..37a4f4be 100644 --- a/apps/x/apps/renderer/src/components/ai-elements/prompt-input.tsx +++ b/apps/x/apps/renderer/src/components/ai-elements/prompt-input.tsx @@ -910,6 +910,7 @@ export const PromptInputTextarea = ({ onChange, className, placeholder = "What would you like to know?", + onKeyDown: externalOnKeyDown, ...props }: PromptInputTextareaProps) => { const controller = useOptionalPromptInputController(); @@ -1027,10 +1028,11 @@ export const PromptInputTextarea = ({ } // Handle backspace to delete entire mention at once - if (e.key === "Backspace" && controller) { + if (e.key === "Backspace") { const textarea = e.currentTarget; const cursorPos = textarea.selectionStart; const selectionEnd = textarea.selectionEnd; + const textValue = controller?.textInput.value ?? textarea.value; // Only handle if no text is selected (cursor is at a single position) if (cursorPos === selectionEnd) { @@ -1039,13 +1041,19 @@ export const PromptInputTextarea = ({ const mentionText = `@${label}`; const startPos = cursorPos - mentionText.length; if (startPos >= 0) { - const textBefore = currentValue.substring(startPos, cursorPos); + const textBefore = textValue.substring(startPos, cursorPos); if (textBefore === mentionText) { // Check if it's at word boundary (start of string or preceded by whitespace) - if (startPos === 0 || /\s/.test(currentValue[startPos - 1])) { + if (startPos === 0 || /\s/.test(textValue[startPos - 1])) { e.preventDefault(); - const newText = currentValue.substring(0, startPos) + currentValue.substring(cursorPos); - controller.textInput.setInput(newText); + const newText = textValue.substring(0, startPos) + textValue.substring(cursorPos); + if (controller) { + controller.textInput.setInput(newText); + } else { + // Fallback: directly set textarea value and trigger change + textarea.value = newText; + textarea.dispatchEvent(new Event('input', { bubbles: true })); + } // Remove the mention from state if (mentionsCtx) { const mentionToRemove = mentionsCtx.mentions.find(m => m.displayName === label); @@ -1084,6 +1092,9 @@ export const PromptInputTextarea = ({ // Let the popover handle this return; } + + // Call external handler if provided + externalOnKeyDown?.(e); }; const handlePaste: ClipboardEventHandler = (event) => { @@ -1123,12 +1134,12 @@ export const PromptInputTextarea = ({ }; return ( -
+
{mentionHighlights.hasHighlights && (