From ff37ca8acbb36d72229265395dc2fcfb04fecdc7 Mon Sep 17 00:00:00 2001 From: Roo Code Date: Tue, 16 Dec 2025 09:11:55 +0000 Subject: [PATCH] feat: move cancel button from bar into input text area - Add isStreaming and onCancelTask props to ChatTextArea component - Add cancel button (X icon) inside input area when streaming - Remove large cancel button bar from ChatView when streaming - Keep other buttons (primary/secondary) in the bar for non-streaming actions - Cleaner, more compact UI during task execution Closes #10086 --- .../src/components/chat/ChatTextArea.tsx | 76 +++++++++++++------ webview-ui/src/components/chat/ChatView.tsx | 36 ++++----- 2 files changed, 68 insertions(+), 44 deletions(-) diff --git a/webview-ui/src/components/chat/ChatTextArea.tsx b/webview-ui/src/components/chat/ChatTextArea.tsx index 7fbc658718..0705d8a6b2 100644 --- a/webview-ui/src/components/chat/ChatTextArea.tsx +++ b/webview-ui/src/components/chat/ChatTextArea.tsx @@ -1,7 +1,7 @@ import React, { forwardRef, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react" import { useEvent } from "react-use" import DynamicTextArea from "react-textarea-autosize" -import { VolumeX, Image, WandSparkles, SendHorizontal, MessageSquareX } from "lucide-react" +import { VolumeX, Image, WandSparkles, SendHorizontal, MessageSquareX, X } from "lucide-react" import { mentionRegex, mentionRegexGlobal, commandRegexGlobal, unescapeSpaces } from "@roo/context-mentions" import { WebviewMessage } from "@roo/WebviewMessage" @@ -54,6 +54,9 @@ interface ChatTextAreaProps { // Browser session status isBrowserSessionActive?: boolean showBrowserDockToggle?: boolean + // Streaming/cancel props + isStreaming?: boolean + onCancelTask?: () => void } export const ChatTextArea = forwardRef( @@ -76,6 +79,8 @@ export const ChatTextArea = forwardRef( onCancel, isBrowserSessionActive = false, showBrowserDockToggle = false, + isStreaming = false, + onCancelTask, }, ref, ) => { @@ -1184,30 +1189,53 @@ export const ChatTextArea = forwardRef( )} - - - + "focus:outline-none focus-visible:ring-1 focus-visible:ring-vscode-focusBorder", + "active:bg-[rgba(255,255,255,0.1)]", + "cursor-pointer", + )}> + + + + )} + {(!isStreaming || isEditMode) && ( + + + + )} {!inputValue && ( diff --git a/webview-ui/src/components/chat/ChatView.tsx b/webview-ui/src/components/chat/ChatView.tsx index a002abf8cf..ab4d5aa269 100644 --- a/webview-ui/src/components/chat/ChatView.tsx +++ b/webview-ui/src/components/chat/ChatView.tsx @@ -144,7 +144,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction(false) const [primaryButtonText, setPrimaryButtonText] = useState(undefined) const [secondaryButtonText, setSecondaryButtonText] = useState(undefined) - const [didClickCancel, setDidClickCancel] = useState(false) + const [_didClickCancel, setDidClickCancel] = useState(false) const virtuosoRef = useRef(null) const [expandedRows, setExpandedRows] = useState>({}) const prevExpandedRowsRef = useRef>() @@ -1386,7 +1386,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction {showScrollToBottom ? ( @@ -1545,25 +1541,23 @@ const ChatViewComponent: React.ForwardRefRenderFunction )} - {(secondaryButtonText || isStreaming) && ( + {secondaryButtonText && !isStreaming && ( )} @@ -1612,6 +1606,8 @@ const ChatViewComponent: React.ForwardRefRenderFunction handleSecondaryButtonClick(inputValue, selectedImages)} /> {isProfileDisabled && (