chat: circular send button, ringed standalone mic / Voice Mode buttons - #328137
chat: circular send button, ringed standalone mic / Voice Mode buttons#328137eli-w-king wants to merge 6 commits into
Conversation
Make the chat composer's execute toolbar read as one uniform set of 22px circular controls. - Send button is a circle rather than a rounded square, in both its idle and enabled states and in its focus ring, so the shape never changes with state. - The standalone dictation / Voice Mode buttons lose the segmented pill's enclosure when they render on their own, so each now carries a circular outline of its own. The ring is drawn in `currentColor` so it matches the glyph it encircles in every state — resting icon foreground, and the blue / purple / green the glyph takes while Voice Mode is listening, speaking or offering to disconnect. A border token can't track that, and the obvious ones aren't even visible here: both `input.border` and `widget.border` are `null` outside high contrast and fall back to a 20%-alpha color that all but disappears on a 1px circle. High-contrast themes still take `contrastBorder`. - The dictation mic glow follows the button's radius so the light no longer spills past its own edge. - Configure Tools moves to the `settingsCompact` glyph. It was the only icon in the primary toolbar still at the base 16px, towering over the 11-12px text chips beside it. The dependent selector in the automation dialog is updated with it. - Icon-only chips in the primary toolbar are sized and centered by one rule. The base action-bar rule gives them a fixed 16px box with no inline centering, so a compact glyph would otherwise sit flush left. This also retires an off-ramp `14px` codicon size and a `:has()` selector on `.action-item` (microsoft#324985). The chat input fixture was still constructing its toolbar with `newLine` / `settingsGear`, so it wasn't exercising the shipping icons. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Standardizes chat composer controls as compact circular actions.
Changes:
- Makes send, dictation, and Voice Mode controls circular.
- Uses compact toolbar glyphs and consistent icon centering.
- Updates fixture and automation-dialog selectors.
Show a summary per file
| File | Description |
|---|---|
renderChatInput.ts |
Updates fixture icons. |
chat.css |
Adds circular controls and compact sizing. |
dictationMicGlow.css |
Makes standalone mic glow circular. |
aiCustomizationManagement.css |
Updates hidden configure-tools selector. |
chatToolActions.ts |
Uses the compact settings glyph. |
Review details
- Files reviewed: 5/5 changed files
- Comments generated: 2
- Review effort level: Medium
|
|
||
| .interactive-session .chat-input-toolbar .action-item:has(.codicon-add) .codicon-add { | ||
| font-size: 14px; | ||
| font-size: var(--vscode-codiconFontSize-compact); |
There was a problem hiding this comment.
Done — switched to Codicon.addCompact in AttachContextAction, the fixture, and the automation-dialog selector (.codicon-add-compact).
Also applied it to the Agents window's attach button (newChatInput.ts), which was on Codicon.add at an off-ramp 14px — that now uses the compact glyph and token too.
One doc follow-up: design-tokens.instructions.md listed "plus" among the icons with no compact variant, which is no longer true — updated so the next person doesn't skip the swap for the same reason.
The ring was drawn in `currentColor` so it would track the glyph through Voice Mode's state colors, but that made it far too heavy at rest — in light themes `currentColor` is a dark icon foreground, so the circle read as a hard dark outline next to the pill's soft one. These buttons are single-cell stand-ins for the segmented pill, so the enclosure should be indistinguishable when the UI swaps between them. Use the pill's exact border declaration instead. Measured against a real pill: dark rgb(60,60,60) vs rgb(58,58,58), light rgb(206,206,206) vs rgb(210,210,210) — the deltas are antialiasing on the curve. This also restores correct high-contrast behaviour through the same token, since `input.border` resolves to `contrastBorder` there. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
hawkticehurst
left a comment
There was a problem hiding this comment.
Can you please make sure to apply circular send button styling across both editor and agents window?
Also ensure that agents window new chat and active chat are verified since they are implemented as distinct widgets
…voice fixtures Apply the circular send styling across every chat composer, not just the editor one: - The sessions part re-declared the send button's radius as `cornerRadius-small`, overriding the base rule and leaving the Agents window's active chat a rounded square. Drop those overrides so it inherits from chat.css — duplicating the radius per surface is what let the two drift apart in the first place. - The Agents window's new-chat composer is a distinct widget with its own send button, so give `.sessions-chat-send-button` the circular radius too, and carry the ringed-circle treatment to its voice toolbar and dictation mic so the row stays consistent with the editor. Use the compact glyph for Add Context. `Codicon.addCompact` exists, and the convention is to swap to the optically tuned glyph rather than only scaling the base one. Updated in both composers plus the automation dialog's selector, and the Agents attach button drops an off-ramp 14px size in the process. The design-tokens doc listed "plus" as having no compact variant, which is no longer true. Add screenshot fixture variants for the standalone dictation and Voice Mode controls across all eight states they style differently: dictation idle / recording / preparing, and Voice Mode idle / connecting / listening / speaking / disconnect. The glow's audio-reactive level is pinned so the screenshots stay deterministic. Those fixtures immediately caught a live bug: the green disconnect rule was specificity (0,3,0) while the blanket `icon-foreground !important` rule that colors every toolbar codicon is (0,5,0). With equal `!important` the higher specificity wins, so the disconnect button had been rendering grey rather than green. Scoped the rule to the full toolbar path so it wins, rather than baselining the bug. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
@hawkticehurst thanks — you were right, it only covered the editor composer. Fixed across all three, and the root cause was worth calling out: Agents window active chat — Agents window new chat — Editor — unchanged from before. Verified each: the Agents new-chat send button measures a 22px disc (I had to force the enabled fill to see it — the fixture's default empty-input state renders it transparent). The active chat now inherits from Left the agent-feedback widget alone — its send control is a bare 16px glyph with no button surface, so it's a different tier rather than the same control styled differently. Happy to pull it in if you'd rather it match. Also addressed both Copilot comments: Add Context moves to |
📬 CODENOTIFYThe following users are being notified based on files changed in this PR: @benibenjMatched files:
|
There was a problem hiding this comment.
Review details
Comments suppressed due to low confidence (3)
src/vs/workbench/contrib/chat/browser/widget/media/chat.css:2109
justify-content: centerhas no effect unless the element is a flex/grid container. The prior rule explicitly setdisplay: flex(andalign-items: center) but the replacement rule doesn’t, so icon-only chips may no longer be centered. Adddisplay: flexplus vertical centering (e.g.align-items: center) to this selector, or use a centering approach that matches the element’s actual display type.
.monaco-workbench .interactive-session .chat-input-toolbar .monaco-action-bar .action-item > .action-label.codicon[class*='codicon-'] {
justify-content: center;
font-size: var(--vscode-codiconFontSize-compact);
}
src/vs/workbench/contrib/chat/browser/speechToText/media/dictationMicGlow.css:64
- This rule sets
--dictation-mic-glow-radiustovar(--vscode-cornerRadius-circle), which is already set by the existing.dictation-mic-active { --dictation-mic-glow-radius: ... }rule earlier in the file. If there isn’t an intervening override you’re trying to out-specify, consider removing this block to avoid duplicated declarations (or adjust it to only cover the cases that actually differ).
/* Standalone dictation buttons are discs, so the glow has to be one too —
otherwise the light spills past the button's own edge. Covers the editor
chat toolbar and the Agents window composer's mic button. */
.chat-execute-toolbar .monaco-action-bar .action-item.dictation-mic-active,
.sessions-chat-stt-button.dictation-mic-active {
--dictation-mic-glow-radius: var(--vscode-cornerRadius-circle);
}
src/vs/workbench/test/browser/componentFixtures/chat/renderChatInput.ts:11
ThemeIconis only used as a type in this file. Consider switching this to a type-only import (import type { ThemeIcon } ...) to avoid emitting a runtime import under TS configurations that preserve value imports.
import { ThemeIcon } from '../../../../../base/common/themables.js';
- Files reviewed: 11/11 changed files
- Comments generated: 0 new
- Review effort level: Low
meganrogge
left a comment
There was a problem hiding this comment.
Some checks are failing
Switching Add Context to `Codicon.addCompact` changes the `+` in the inline chat zone widget, which is a blocks-ci fixture. Verified the change is intentional and confined before accepting the new hashes: rendering the fixture on this branch and on its merge-base and diffing them locally shows a single 12×12px region differing — the `+` glyph going from 11×11 to 10×10 of ink. That is the optically tuned compact glyph replacing the scaled-down base one, at a call site already rendering at `codiconFontSize-compact`, which is the pairing the design tokens guidance asks for. Nothing else in the widget moved. Hashes are exactly the ones the failing run computed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Makes the chat composer's execute toolbar read as one uniform set of 22px circular controls.
Send button
Now a circle in its idle and enabled states and in its focus ring, so the shape never changes with state.
Standalone dictation / Voice Mode buttons
When the segmented voice pill isn't active these render on their own and lose its enclosure, so each now carries a circular outline of its own.
The ring is drawn in
currentColorso it always matches the glyph it encircles — the resting icon foreground, and the same blue / purple / green the glyph takes while Voice Mode is listening, speaking, or offering to disconnect.A border token can't track that, and the obvious ones can't even be seen here:
input.borderandwidget.borderare bothnulloutside high contrast, so they resolve to a 20%-alpha fallback. On a 1px circle that measured contrast 9 against the background (luminance 58 vs 49) — the rings were effectively invisible, which left these buttons looking weightless next to the filled send disc. WithcurrentColorthe ring matches the glyph exactly (rgb(188,188,188)on both). High-contrast themes still takecontrastBorder, so the ring stays fully opaque there.The dictation mic glow now follows the button's radius, so the light no longer spills past its own edge.
Configure Tools icon
This was the only icon in the primary toolbar still at the base 16px, towering over the 11–12px text chips beside it. It moves to the
settingsCompactglyph, per the guidance to swap to the*Compactvariant when sizing down. The dependent selector in the automation dialog — which hides the chip by glyph class — is updated with it.Icon-only chips in that toolbar are now sized and centered by a single rule. The base action-bar rule gives them a fixed 16px box with
align-items: centerbut nojustify-content, so a compact glyph sits flush left inside it; folding centering in with the size keeps the two from drifting apart. That also retires an off-ramp14pxcodicon size and a:has()selector on.action-item(#324985).Verification
Measured from rendered component fixtures rather than by eye. With 1px debug outlines on each label and glyph, every icon is centered to the pixel:
+All five share one vertical center, and the three execute-toolbar buttons are all 22px with ~10px glyphs. Checked in dark and light, including the recording-glow, download-ring, and Voice Mode listening states.
hygieneandstylelintpass.The chat input fixture was still building its toolbar with
newLine/settingsGear, so it wasn't exercising the shipping icons; it now usesarrowUpCompact/settingsCompact.