Skip to content

Commit 13adbd0

Browse files
committed
fix: enhance UI layout and improve accessibility for tool controls
1 parent 7bca8fe commit 13adbd0

File tree

1 file changed

+38
-69
lines changed

1 file changed

+38
-69
lines changed

webview-ui/src/components/mcp/McpToolRow.tsx

Lines changed: 38 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -37,34 +37,44 @@ const McpToolRow = ({ tool, serverName, serverSource, alwaysAllowMcp }: McpToolR
3737
}
3838

3939
return (
40-
<div
41-
key={tool.name}
42-
style={{
43-
padding: "3px 0",
44-
}}>
40+
<div key={tool.name} className="py-2 border-b border-vscode-panel-border last:border-b-0">
4541
<div
4642
data-testid="tool-row-container"
47-
className="flex items-center justify-between gap-4"
43+
className="flex items-center gap-4"
4844
onClick={(e) => e.stopPropagation()}>
45+
{/* Tool name section */}
4946
<div className="flex items-center min-w-0 flex-1">
50-
<span className="codicon codicon-symbol-method mr-1.5 flex-shrink-0"></span>
51-
<span className="font-medium truncate" title={tool.name}>
47+
<span className="codicon codicon-symbol-method mr-2 flex-shrink-0 text-vscode-symbolIcon-methodForeground"></span>
48+
<span className="font-medium truncate text-vscode-foreground" title={tool.name}>
5249
{tool.name}
5350
</span>
5451
</div>
55-
<div className="flex items-center space-x-4 flex-shrink-0">
56-
{" "}
57-
{/* Wrapper for checkboxes */}
58-
{serverName && (
52+
53+
{/* Controls section */}
54+
{serverName && (
55+
<div className="flex items-center gap-4 flex-shrink-0">
56+
{/* Always Allow checkbox */}
57+
{alwaysAllowMcp && (
58+
<VSCodeCheckbox
59+
checked={tool.alwaysAllow}
60+
onChange={handleAlwaysAllowChange}
61+
data-tool={tool.name}
62+
className="text-xs">
63+
<span className="text-vscode-descriptionForeground whitespace-nowrap">
64+
{t("mcp:tool.alwaysAllow")}
65+
</span>
66+
</VSCodeCheckbox>
67+
)}
68+
69+
{/* Enabled switch */}
5970
<div
6071
role="switch"
6172
aria-checked={tool.enabledForPrompt}
73+
aria-label={t("mcp:tool.togglePromptInclusion")}
6274
tabIndex={0}
63-
className={`relative h-4 w-8 cursor-pointer rounded-full transition-colors ${
64-
tool.enabledForPrompt
65-
? "bg-vscode-button-background"
66-
: "bg-vscode-titleBar-inactiveForeground"
67-
} ${tool.enabledForPrompt ? "opacity-100" : "opacity-60"}`}
75+
className={`relative h-5 w-9 cursor-pointer rounded-full transition-colors ${
76+
tool.enabledForPrompt ? "bg-vscode-button-background" : "bg-vscode-input-background"
77+
}`}
6878
onClick={handleEnabledForPromptChange}
6979
onKeyDown={(e) => {
7080
if (e.key === "Enter" || e.key === " ") {
@@ -75,46 +85,22 @@ const McpToolRow = ({ tool, serverName, serverSource, alwaysAllowMcp }: McpToolR
7585
data-tool-prompt-toggle={tool.name}
7686
title={t("mcp:tool.togglePromptInclusion")}>
7787
<div
78-
className={`absolute top-0.5 h-3 w-3 rounded-full bg-vscode-titleBar-activeForeground transition-all ${
79-
tool.enabledForPrompt ? "left-[18px]" : "left-0.5"
88+
className={`absolute top-0.5 h-4 w-4 rounded-full bg-vscode-button-foreground shadow-sm transition-transform ${
89+
tool.enabledForPrompt ? "translate-x-4" : "translate-x-0.5"
8090
}`}
8191
/>
8292
</div>
83-
)}
84-
{serverName && alwaysAllowMcp && (
85-
<VSCodeCheckbox
86-
checked={tool.alwaysAllow}
87-
onChange={handleAlwaysAllowChange}
88-
data-tool={tool.name}>
89-
{t("mcp:tool.alwaysAllow")}
90-
</VSCodeCheckbox>
91-
)}
92-
</div>
93+
</div>
94+
)}
9395
</div>
9496
{tool.description && (
95-
<div
96-
style={{
97-
marginLeft: "0px",
98-
marginTop: "4px",
99-
opacity: 0.8,
100-
fontSize: "12px",
101-
}}>
102-
{tool.description}
103-
</div>
97+
<div className="mt-1 text-xs text-vscode-descriptionForeground opacity-80">{tool.description}</div>
10498
)}
10599
{tool.inputSchema &&
106100
"properties" in tool.inputSchema &&
107101
Object.keys(tool.inputSchema.properties as Record<string, any>).length > 0 && (
108-
<div
109-
style={{
110-
marginTop: "8px",
111-
fontSize: "12px",
112-
border: "1px solid color-mix(in srgb, var(--vscode-descriptionForeground) 30%, transparent)",
113-
borderRadius: "3px",
114-
padding: "8px",
115-
}}>
116-
<div
117-
style={{ marginBottom: "4px", opacity: 0.8, fontSize: "11px", textTransform: "uppercase" }}>
102+
<div className="mt-2 text-xs border border-vscode-panel-border rounded p-2">
103+
<div className="mb-1 text-[11px] uppercase opacity-80 text-vscode-descriptionForeground">
118104
{t("mcp:tool.parameters")}
119105
</div>
120106
{Object.entries(tool.inputSchema.properties as Record<string, any>).map(
@@ -126,29 +112,12 @@ const McpToolRow = ({ tool, serverName, serverSource, alwaysAllowMcp }: McpToolR
126112
tool.inputSchema.required.includes(paramName)
127113

128114
return (
129-
<div
130-
key={paramName}
131-
style={{
132-
display: "flex",
133-
alignItems: "baseline",
134-
marginTop: "4px",
135-
}}>
136-
<code
137-
style={{
138-
color: "var(--vscode-textPreformat-foreground)",
139-
marginRight: "8px",
140-
}}>
115+
<div key={paramName} className="flex items-baseline mt-1">
116+
<code className="text-vscode-textPreformat-foreground mr-2">
141117
{paramName}
142-
{isRequired && (
143-
<span style={{ color: "var(--vscode-errorForeground)" }}>*</span>
144-
)}
118+
{isRequired && <span className="text-vscode-errorForeground">*</span>}
145119
</code>
146-
<span
147-
style={{
148-
opacity: 0.8,
149-
overflowWrap: "break-word",
150-
wordBreak: "break-word",
151-
}}>
120+
<span className="opacity-80 break-words text-vscode-descriptionForeground">
152121
{schema.description || t("mcp:tool.noDescription")}
153122
</span>
154123
</div>

0 commit comments

Comments
 (0)