Skip to content
This repository was archived by the owner on May 15, 2026. It is now read-only.

Commit 8303710

Browse files
authored
ux: improve stop button visibility and streamline error handling (#10696)
* Restores the send button in the message edit mode * Makes the stop button more prominent
1 parent 749026a commit 8303710

1 file changed

Lines changed: 69 additions & 61 deletions

File tree

webview-ui/src/components/chat/ChatTextArea.tsx

Lines changed: 69 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React, { forwardRef, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react"
22
import { useEvent } from "react-use"
33
import DynamicTextArea from "react-textarea-autosize"
4-
import { VolumeX, Image, WandSparkles, SendHorizontal, MessageSquareX, ListEnd, Square } from "lucide-react"
4+
import { VolumeX, Image, WandSparkles, SendHorizontal, X, ListEnd, Square } from "lucide-react"
55

66
import type { ExtensionMessage } from "@roo-code/types"
77

@@ -1148,30 +1148,7 @@ export const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
11481148
<Image className="w-4 h-4" />
11491149
</button>
11501150
</StandardTooltip>
1151-
<StandardTooltip content={t("chat:enhancePrompt")}>
1152-
<button
1153-
aria-label={t("chat:enhancePrompt")}
1154-
disabled={false}
1155-
onClick={handleEnhancePrompt}
1156-
className={cn(
1157-
"relative inline-flex items-center justify-center",
1158-
"bg-transparent border-none p-1.5",
1159-
"rounded-md min-w-[28px] min-h-[28px]",
1160-
"text-vscode-descriptionForeground hover:text-vscode-foreground",
1161-
"transition-all duration-1000",
1162-
"cursor-pointer",
1163-
hasInputContent
1164-
? "opacity-50 hover:opacity-100 delay-750 pointer-events-auto"
1165-
: "opacity-0 pointer-events-none duration-200 delay-0",
1166-
hasInputContent &&
1167-
"hover:bg-[rgba(255,255,255,0.03)] hover:border-[rgba(255,255,255,0.15)]",
1168-
"focus:outline-none focus-visible:ring-1 focus-visible:ring-vscode-focusBorder",
1169-
hasInputContent && "active:bg-[rgba(255,255,255,0.1)]",
1170-
)}>
1171-
<WandSparkles className={cn("w-4 h-4", isEnhancingPrompt && "animate-spin")} />
1172-
</button>
1173-
</StandardTooltip>
1174-
{isEditMode && (
1151+
{isEditMode ? (
11751152
<StandardTooltip content={t("chat:cancel.title")}>
11761153
<button
11771154
aria-label={t("chat:cancel.title")}
@@ -1188,7 +1165,33 @@ export const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
11881165
"active:bg-[rgba(255,255,255,0.1)]",
11891166
"cursor-pointer",
11901167
)}>
1191-
<MessageSquareX className="w-4 h-4" />
1168+
<X className="w-4 h-4" />
1169+
</button>
1170+
</StandardTooltip>
1171+
) : (
1172+
<StandardTooltip content={t("chat:enhancePrompt")}>
1173+
<button
1174+
aria-label={t("chat:enhancePrompt")}
1175+
disabled={false}
1176+
onClick={handleEnhancePrompt}
1177+
className={cn(
1178+
"relative inline-flex items-center justify-center",
1179+
"bg-transparent border-none p-1.5",
1180+
"rounded-md min-w-[28px] min-h-[28px]",
1181+
"text-vscode-descriptionForeground hover:text-vscode-foreground",
1182+
"transition-all duration-1000",
1183+
"cursor-pointer",
1184+
hasInputContent
1185+
? "opacity-50 hover:opacity-100 delay-750 pointer-events-auto"
1186+
: "opacity-0 pointer-events-none duration-200 delay-0",
1187+
hasInputContent &&
1188+
"hover:bg-[rgba(255,255,255,0.03)] hover:border-[rgba(255,255,255,0.15)]",
1189+
"focus:outline-none focus-visible:ring-1 focus-visible:ring-vscode-focusBorder",
1190+
hasInputContent && "active:bg-[rgba(255,255,255,0.1)]",
1191+
)}>
1192+
<WandSparkles
1193+
className={cn("w-4 h-4", isEnhancingPrompt && "animate-spin")}
1194+
/>
11921195
</button>
11931196
</StandardTooltip>
11941197
)}
@@ -1215,45 +1218,50 @@ export const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
12151218
</button>
12161219
</StandardTooltip>
12171220
)}
1218-
{/* Send/Stop button - morphs based on streaming state */}
1219-
{!isEditMode && (
1220-
<StandardTooltip
1221-
content={
1222-
isStreaming
1221+
{/* Send/Stop button - morphs based on streaming state, always visible in edit mode */}
1222+
<StandardTooltip
1223+
content={
1224+
isEditMode
1225+
? t("chat:pressToSend", { keyCombination: sendKeyCombination })
1226+
: isStreaming
12231227
? t("chat:stop.title")
12241228
: t("chat:pressToSend", { keyCombination: sendKeyCombination })
1225-
}>
1226-
<button
1227-
aria-label={
1228-
isStreaming
1229+
}>
1230+
<button
1231+
aria-label={
1232+
isEditMode
1233+
? t("chat:pressToSend", { keyCombination: sendKeyCombination })
1234+
: isStreaming
12291235
? t("chat:stop.title")
12301236
: t("chat:pressToSend", { keyCombination: sendKeyCombination })
1231-
}
1232-
disabled={false}
1233-
onClick={isStreaming ? onStop : onSend}
1234-
className={cn(
1235-
"relative inline-flex items-center justify-center",
1236-
"bg-transparent border-none p-1.5",
1237-
"rounded-md min-w-[28px] min-h-[28px]",
1238-
"text-vscode-descriptionForeground hover:text-vscode-foreground",
1239-
"transition-all duration-200",
1240-
isStreaming || hasInputContent
1241-
? "opacity-100 hover:opacity-100 pointer-events-auto"
1242-
: "opacity-0 pointer-events-none",
1243-
(isStreaming || hasInputContent) &&
1244-
"hover:bg-[rgba(255,255,255,0.03)] hover:border-[rgba(255,255,255,0.15)]",
1245-
"focus:outline-none focus-visible:ring-1 focus-visible:ring-vscode-focusBorder",
1246-
(isStreaming || hasInputContent) && "active:bg-[rgba(255,255,255,0.1)]",
1247-
(isStreaming || hasInputContent) && "cursor-pointer",
1248-
)}>
1249-
{isStreaming ? (
1250-
<Square className="size-4 fill-vscode-descriptionForeground" />
1251-
) : (
1252-
<SendHorizontal className="size-4" />
1253-
)}
1254-
</button>
1255-
</StandardTooltip>
1256-
)}
1237+
}
1238+
disabled={false}
1239+
onClick={isStreaming ? onStop : onSend}
1240+
className={cn(
1241+
"relative inline-flex items-center justify-center",
1242+
"bg-transparent border-none p-1.5",
1243+
"rounded-full min-w-[28px] min-h-[28px]",
1244+
"text-vscode-descriptionForeground hover:text-vscode-foreground",
1245+
"transition-all duration-200",
1246+
isEditMode || isStreaming || hasInputContent
1247+
? "opacity-100 hover:opacity-100 pointer-events-auto"
1248+
: "opacity-0 pointer-events-none",
1249+
(isEditMode || isStreaming || hasInputContent) &&
1250+
"hover:bg-[rgba(255,255,255,0.03)] hover:border-[rgba(255,255,255,0.15)]",
1251+
"focus:outline-none focus-visible:ring-1 focus-visible:ring-vscode-focusBorder",
1252+
(isEditMode || isStreaming || hasInputContent) &&
1253+
"active:bg-[rgba(255,255,255,0.1)]",
1254+
(isEditMode || isStreaming || hasInputContent) && "cursor-pointer",
1255+
isStreaming &&
1256+
"bg-vscode-button-background hover:bg-vscode-button-background",
1257+
)}>
1258+
{isStreaming ? (
1259+
<Square className="size-4 stroke-none fill-vscode-button-foreground" />
1260+
) : (
1261+
<SendHorizontal className="size-4" />
1262+
)}
1263+
</button>
1264+
</StandardTooltip>
12571265
</div>
12581266

12591267
{!inputValue && (

0 commit comments

Comments
 (0)