Skip to content

Commit 2b7c266

Browse files
mrubensdaniel-lxs
andauthored
Update icons in chattextarea (#5520)
* Update icons in chattextarea * fix: update icons in ChatTextArea and IndexingStatusBadge components * fix: update Camera icon to Image and fix alignment - Changed Camera icon to Image icon from lucide-react - Fixed alignment issue by adjusting gap and removing extra margin - Updated tests to work with new Lucide icon structure * fix: revert alignment changes for Image icon - Keep original alignment with gap-0.5 and mr-1 to match send and enhance buttons --------- Co-authored-by: Daniel Riccio <[email protected]>
1 parent fed603a commit 2b7c266

File tree

4 files changed

+81
-36
lines changed

4 files changed

+81
-36
lines changed

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

Lines changed: 58 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,8 @@ import Thumbnails from "../common/Thumbnails"
2525
import ModeSelector from "./ModeSelector"
2626
import { MAX_IMAGES_PER_MESSAGE } from "./ChatView"
2727
import ContextMenu from "./ContextMenu"
28-
import { VolumeX, Pin, Check } from "lucide-react"
29-
import { IconButton } from "./IconButton"
30-
import { IndexingStatusDot } from "./IndexingStatusBadge"
28+
import { VolumeX, Pin, Check, Image, WandSparkles, SendHorizontal } from "lucide-react"
29+
import { IndexingStatusBadge } from "./IndexingStatusBadge"
3130
import { cn } from "@/lib/utils"
3231
import { usePromptHistory } from "./hooks/usePromptHistory"
3332

@@ -962,24 +961,49 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
962961
)}
963962

964963
<div className="absolute top-1 right-1 z-30">
965-
<IconButton
966-
iconClass={isEnhancingPrompt ? "codicon-loading" : "codicon-sparkle"}
964+
<button
965+
aria-label={t("chat:enhancePrompt")}
967966
title={t("chat:enhancePrompt")}
968967
disabled={sendingDisabled}
969-
isLoading={isEnhancingPrompt}
970-
onClick={handleEnhancePrompt}
971-
className="opacity-60 hover:opacity-100 text-vscode-descriptionForeground hover:text-vscode-foreground"
972-
/>
968+
onClick={!sendingDisabled ? handleEnhancePrompt : undefined}
969+
className={cn(
970+
"relative inline-flex items-center justify-center",
971+
"bg-transparent border-none p-1.5",
972+
"rounded-md min-w-[28px] min-h-[28px]",
973+
"opacity-60 hover:opacity-100 text-vscode-descriptionForeground hover:text-vscode-foreground",
974+
"transition-all duration-150",
975+
"hover:bg-[rgba(255,255,255,0.03)] hover:border-[rgba(255,255,255,0.15)]",
976+
"focus:outline-none focus-visible:ring-1 focus-visible:ring-vscode-focusBorder",
977+
"active:bg-[rgba(255,255,255,0.1)]",
978+
!sendingDisabled && "cursor-pointer",
979+
sendingDisabled &&
980+
"opacity-40 cursor-not-allowed grayscale-[30%] hover:bg-transparent hover:border-[rgba(255,255,255,0.08)] active:bg-transparent",
981+
)}>
982+
<WandSparkles className={cn("w-4 h-4", isEnhancingPrompt && "animate-spin")} />
983+
</button>
973984
</div>
974985

975986
<div className="absolute bottom-1 right-1 z-30">
976-
<IconButton
977-
iconClass="codicon-send"
987+
<button
988+
aria-label={t("chat:sendMessage")}
978989
title={t("chat:sendMessage")}
979990
disabled={sendingDisabled}
980-
onClick={onSend}
981-
className="opacity-60 hover:opacity-100 text-vscode-descriptionForeground hover:text-vscode-foreground"
982-
/>
991+
onClick={!sendingDisabled ? onSend : undefined}
992+
className={cn(
993+
"relative inline-flex items-center justify-center",
994+
"bg-transparent border-none p-1.5",
995+
"rounded-md min-w-[28px] min-h-[28px]",
996+
"opacity-60 hover:opacity-100 text-vscode-descriptionForeground hover:text-vscode-foreground",
997+
"transition-all duration-150",
998+
"hover:bg-[rgba(255,255,255,0.03)] hover:border-[rgba(255,255,255,0.15)]",
999+
"focus:outline-none focus-visible:ring-1 focus-visible:ring-vscode-focusBorder",
1000+
"active:bg-[rgba(255,255,255,0.1)]",
1001+
!sendingDisabled && "cursor-pointer",
1002+
sendingDisabled &&
1003+
"opacity-40 cursor-not-allowed grayscale-[30%] hover:bg-transparent hover:border-[rgba(255,255,255,0.08)] active:bg-transparent",
1004+
)}>
1005+
<SendHorizontal className="w-4 h-4" />
1006+
</button>
9831007
</div>
9841008

9851009
{!inputValue && (
@@ -1145,14 +1169,28 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
11451169
</div>
11461170

11471171
<div className={cn("flex", "items-center", "gap-0.5", "shrink-0")}>
1148-
<IndexingStatusDot />
1149-
<IconButton
1150-
iconClass="codicon-device-camera"
1172+
<IndexingStatusBadge />
1173+
<button
1174+
aria-label={t("chat:addImages")}
11511175
title={t("chat:addImages")}
11521176
disabled={shouldDisableImages}
1153-
onClick={onSelectImages}
1154-
className="mr-1"
1155-
/>
1177+
onClick={!shouldDisableImages ? onSelectImages : undefined}
1178+
className={cn(
1179+
"relative inline-flex items-center justify-center",
1180+
"bg-transparent border-none p-1.5",
1181+
"rounded-md min-w-[28px] min-h-[28px]",
1182+
"text-vscode-foreground opacity-85",
1183+
"transition-all duration-150",
1184+
"hover:opacity-100 hover:bg-[rgba(255,255,255,0.03)] hover:border-[rgba(255,255,255,0.15)]",
1185+
"focus:outline-none focus-visible:ring-1 focus-visible:ring-vscode-focusBorder",
1186+
"active:bg-[rgba(255,255,255,0.1)]",
1187+
!shouldDisableImages && "cursor-pointer",
1188+
shouldDisableImages &&
1189+
"opacity-40 cursor-not-allowed grayscale-[30%] hover:bg-transparent hover:border-[rgba(255,255,255,0.08)] active:bg-transparent",
1190+
"mr-1",
1191+
)}>
1192+
<Image className="w-4 h-4" />
1193+
</button>
11561194
</div>
11571195
</div>
11581196
</div>

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

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
import React, { useState, useEffect, useMemo } from "react"
2+
import { Database } from "lucide-react"
23
import { cn } from "@src/lib/utils"
34
import { vscode } from "@src/utils/vscode"
45
import { useAppTranslation } from "@/i18n/TranslationContext"
56
import { useTooltip } from "@/hooks/useTooltip"
67
import { CodeIndexPopover } from "./CodeIndexPopover"
78
import type { IndexingStatus, IndexingStatusUpdateMessage } from "@roo/ExtensionMessage"
89

9-
interface IndexingStatusDotProps {
10+
interface IndexingStatusBadgeProps {
1011
className?: string
1112
}
1213

13-
export const IndexingStatusDot: React.FC<IndexingStatusDotProps> = ({ className }) => {
14+
export const IndexingStatusBadge: React.FC<IndexingStatusBadgeProps> = ({ className }) => {
1415
const { t } = useAppTranslation()
1516
const { showTooltip, handleMouseEnter, handleMouseLeave, cleanup } = useTooltip({ delay: 300 })
1617
const [isHovered, setIsHovered] = useState(false)
@@ -77,23 +78,23 @@ export const IndexingStatusDot: React.FC<IndexingStatusDotProps> = ({ className
7778
handleMouseLeave()
7879
}
7980

80-
// Get status color classes based on status and hover state
81+
// Get status color classes for the badge dot
8182
const getStatusColorClass = () => {
8283
const statusColors = {
8384
Standby: {
84-
default: "bg-vscode-descriptionForeground/40",
85-
hover: "bg-vscode-descriptionForeground/60",
85+
default: "bg-vscode-descriptionForeground/60",
86+
hover: "bg-vscode-descriptionForeground/80",
8687
},
8788
Indexing: {
88-
default: "bg-yellow-500/40 animate-pulse",
89+
default: "bg-yellow-500 animate-pulse",
8990
hover: "bg-yellow-500 animate-pulse",
9091
},
9192
Indexed: {
92-
default: "bg-green-500/40",
93+
default: "bg-green-500",
9394
hover: "bg-green-500",
9495
},
9596
Error: {
96-
default: "bg-red-500/40",
97+
default: "bg-red-500",
9798
hover: "bg-red-500",
9899
},
99100
}
@@ -117,12 +118,17 @@ export const IndexingStatusDot: React.FC<IndexingStatusDotProps> = ({ className
117118
"hover:opacity-100 hover:bg-[rgba(255,255,255,0.03)] hover:border-[rgba(255,255,255,0.15)]",
118119
"focus:outline-none focus-visible:ring-1 focus-visible:ring-vscode-focusBorder",
119120
"active:bg-[rgba(255,255,255,0.1)]",
121+
"cursor-pointer",
120122
className,
121123
)}
122124
aria-label={getTooltipText()}>
125+
{/* File search icon */}
126+
<Database className="w-4 h-4 text-vscode-foreground" />
127+
128+
{/* Status dot badge */}
123129
<span
124130
className={cn(
125-
"inline-block w-2 h-2 rounded-full relative z-10 transition-colors duration-200",
131+
"absolute top-0.5 right-0.5 w-1.5 h-1.5 rounded-full transition-colors duration-200",
126132
getStatusColorClass(),
127133
)}
128134
/>

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ vi.mock("@src/context/ExtensionStateContext")
3838
const getEnhancePromptButton = () => {
3939
return screen.getByRole("button", {
4040
name: (_, element) => {
41-
// Find the button with the sparkle icon
42-
return element.querySelector(".codicon-sparkle") !== null
41+
// Find the button with the wand sparkles icon (Lucide React)
42+
return element.querySelector(".lucide-wand-sparkles") !== null
4343
},
4444
})
4545
}
@@ -154,8 +154,9 @@ describe("ChatTextArea", () => {
154154
const enhanceButton = getEnhancePromptButton()
155155
fireEvent.click(enhanceButton)
156156

157-
const loadingSpinner = screen.getByText("", { selector: ".codicon-loading" })
158-
expect(loadingSpinner).toBeInTheDocument()
157+
// Check if the WandSparkles icon has the animate-spin class
158+
const animatingIcon = enhanceButton.querySelector(".animate-spin")
159+
expect(animatingIcon).toBeInTheDocument()
159160
})
160161
})
161162

webview-ui/src/components/chat/__tests__/IndexingStatusBadge.spec.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { render, screen, fireEvent, waitFor, act } from "@/utils/test-utils"
33

44
import { vscode } from "@src/utils/vscode"
55

6-
import { IndexingStatusDot } from "../IndexingStatusBadge"
6+
import { IndexingStatusBadge } from "../IndexingStatusBadge"
77

88
vi.mock("@/i18n/setup", () => ({
99
__esModule: true,
@@ -104,9 +104,9 @@ vi.mock("@/i18n/TranslationContext", () => ({
104104
}),
105105
}))
106106

107-
describe("IndexingStatusDot", () => {
107+
describe("IndexingStatusBadge", () => {
108108
const renderComponent = (props = {}) => {
109-
return render(<IndexingStatusDot {...props} />)
109+
return render(<IndexingStatusBadge {...props} />)
110110
}
111111

112112
beforeEach(() => {

0 commit comments

Comments
 (0)