fix: enhance UI layout and improve accessibility for tool controls

This commit is contained in:
Daniel Riccio 2025-06-16 12:03:03 -05:00
parent 6c965dcff3
commit 3445b1314d

View file

@ -37,34 +37,44 @@ const McpToolRow = ({ tool, serverName, serverSource, alwaysAllowMcp }: McpToolR
}
return (
<div
key={tool.name}
style={{
padding: "3px 0",
}}>
<div key={tool.name} className="py-2 border-b border-vscode-panel-border last:border-b-0">
<div
data-testid="tool-row-container"
className="flex items-center justify-between gap-4"
className="flex items-center gap-4"
onClick={(e) => e.stopPropagation()}>
{/* Tool name section */}
<div className="flex items-center min-w-0 flex-1">
<span className="codicon codicon-symbol-method mr-1.5 flex-shrink-0"></span>
<span className="font-medium truncate" title={tool.name}>
<span className="codicon codicon-symbol-method mr-2 flex-shrink-0 text-vscode-symbolIcon-methodForeground"></span>
<span className="font-medium truncate text-vscode-foreground" title={tool.name}>
{tool.name}
</span>
</div>
<div className="flex items-center space-x-4 flex-shrink-0">
{" "}
{/* Wrapper for checkboxes */}
{serverName && (
{/* Controls section */}
{serverName && (
<div className="flex items-center gap-4 flex-shrink-0">
{/* Always Allow checkbox */}
{alwaysAllowMcp && (
<VSCodeCheckbox
checked={tool.alwaysAllow}
onChange={handleAlwaysAllowChange}
data-tool={tool.name}
className="text-xs">
<span className="text-vscode-descriptionForeground whitespace-nowrap">
{t("mcp:tool.alwaysAllow")}
</span>
</VSCodeCheckbox>
)}
{/* Enabled switch */}
<div
role="switch"
aria-checked={tool.enabledForPrompt}
aria-label={t("mcp:tool.togglePromptInclusion")}
tabIndex={0}
className={`relative h-4 w-8 cursor-pointer rounded-full transition-colors ${
tool.enabledForPrompt
? "bg-vscode-button-background"
: "bg-vscode-titleBar-inactiveForeground"
} ${tool.enabledForPrompt ? "opacity-100" : "opacity-60"}`}
className={`relative h-5 w-9 cursor-pointer rounded-full transition-colors ${
tool.enabledForPrompt ? "bg-vscode-button-background" : "bg-vscode-input-background"
}`}
onClick={handleEnabledForPromptChange}
onKeyDown={(e) => {
if (e.key === "Enter" || e.key === " ") {
@ -75,46 +85,22 @@ const McpToolRow = ({ tool, serverName, serverSource, alwaysAllowMcp }: McpToolR
data-tool-prompt-toggle={tool.name}
title={t("mcp:tool.togglePromptInclusion")}>
<div
className={`absolute top-0.5 h-3 w-3 rounded-full bg-vscode-titleBar-activeForeground transition-all ${
tool.enabledForPrompt ? "left-[18px]" : "left-0.5"
className={`absolute top-0.5 h-4 w-4 rounded-full bg-vscode-button-foreground shadow-sm transition-transform ${
tool.enabledForPrompt ? "translate-x-4" : "translate-x-0.5"
}`}
/>
</div>
)}
{serverName && alwaysAllowMcp && (
<VSCodeCheckbox
checked={tool.alwaysAllow}
onChange={handleAlwaysAllowChange}
data-tool={tool.name}>
{t("mcp:tool.alwaysAllow")}
</VSCodeCheckbox>
)}
</div>
</div>
)}
</div>
{tool.description && (
<div
style={{
marginLeft: "0px",
marginTop: "4px",
opacity: 0.8,
fontSize: "12px",
}}>
{tool.description}
</div>
<div className="mt-1 text-xs text-vscode-descriptionForeground opacity-80">{tool.description}</div>
)}
{tool.inputSchema &&
"properties" in tool.inputSchema &&
Object.keys(tool.inputSchema.properties as Record<string, any>).length > 0 && (
<div
style={{
marginTop: "8px",
fontSize: "12px",
border: "1px solid color-mix(in srgb, var(--vscode-descriptionForeground) 30%, transparent)",
borderRadius: "3px",
padding: "8px",
}}>
<div
style={{ marginBottom: "4px", opacity: 0.8, fontSize: "11px", textTransform: "uppercase" }}>
<div className="mt-2 text-xs border border-vscode-panel-border rounded p-2">
<div className="mb-1 text-[11px] uppercase opacity-80 text-vscode-descriptionForeground">
{t("mcp:tool.parameters")}
</div>
{Object.entries(tool.inputSchema.properties as Record<string, any>).map(
@ -126,29 +112,12 @@ const McpToolRow = ({ tool, serverName, serverSource, alwaysAllowMcp }: McpToolR
tool.inputSchema.required.includes(paramName)
return (
<div
key={paramName}
style={{
display: "flex",
alignItems: "baseline",
marginTop: "4px",
}}>
<code
style={{
color: "var(--vscode-textPreformat-foreground)",
marginRight: "8px",
}}>
<div key={paramName} className="flex items-baseline mt-1">
<code className="text-vscode-textPreformat-foreground mr-2">
{paramName}
{isRequired && (
<span style={{ color: "var(--vscode-errorForeground)" }}>*</span>
)}
{isRequired && <span className="text-vscode-errorForeground">*</span>}
</code>
<span
style={{
opacity: 0.8,
overflowWrap: "break-word",
wordBreak: "break-word",
}}>
<span className="opacity-80 break-words text-vscode-descriptionForeground">
{schema.description || t("mcp:tool.noDescription")}
</span>
</div>