Give WorkbenchButtonBar ownership of icon-label spacing - #335350
Give WorkbenchButtonBar ownership of icon-label spacing#335350Cherry Wang (chryw) wants to merge 11 commits into
Conversation
36dca59 to
0e1b0bb
Compare
0e1b0bb to
bfb94e8
Compare
bfb94e8 to
64812ca
Compare
There was a problem hiding this comment.
🟡 Changes recommended
Container-wide gaps mis-space multipart labels, and production selector coverage remains absent.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Moves leading icon-label spacing ownership into WorkbenchButtonBar while preserving the Changes view’s intended geometry.
Changes:
- Adds configurable compact/default icon-label spacing.
- Migrates Changes view spacing to the shared control.
- Extends button-bar tests and fixtures.
File summaries
| File | Description |
|---|---|
buttonBar.fixture.ts |
Exercises default spacing visually. |
changesView.css |
Removes consumer spacing and preserves diff-stat gaps. |
changesView.ts |
Selects default spacing for primary actions. |
buttonbar.test.ts |
Verifies spacing classes and leading slots. |
buttonbar.ts |
Adds spacing configuration and state classes. |
buttonbar.css |
Defines icon sizing and spacing variants. |
Review details
- Files reviewed: 6/6 changed files
- Comments generated: 2
- Review effort level: Balanced
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
64812ca to
78128ea
Compare
There was a problem hiding this comment.
🟡 Changes recommended
The compact CSS variant remains implicit, and the new fixture does not accurately reproduce two claimed production compositions.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (1)
src/vs/sessions/contrib/changes/test/browser/changesButtonBar.fixture.ts:60
- This fixture is the only code in the repository that emits
working-set-diff-stats; neither production button configuration adds that class, and production diff stats render throughChangesDiffStatsActionItemwithchanges-diff-stats-action. As a result, the fixture validates a synthetic control rather than the claimed production diff-stat composition. Render the production action item, or wire the marker into production if this button is intended to exist there.
case lineCounts.id:
return {
showLabel: true,
customLabel: '$(add) 2 $(remove) 1',
customClass: 'working-set-diff-stats',
isSecondary: true,
- Files reviewed: 7/7 changed files
- Comments generated: 2
- Review effort level: Balanced
1497942 to
7b1d2d4
Compare
|
Addressed the review summary's synthetic diff-stat fixture finding in 78bd91f. The fixture now contains only the production button-bar composition: a primary labelled action and icon-only secondary action. Diff statistics use a separate |
There was a problem hiding this comment.
🟡 Changes recommended
The optional spacing API does not document that omission selects compact rather than its explicitly named default variant.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
- Files reviewed: 7/7 changed files
- Comments generated: 1
- Review effort level: Balanced
78bd91f to
7ba053d
Compare
bbb615c to
06cbfb9
Compare
There was a problem hiding this comment.
🟡 Changes recommended
The central pair-specific spacing behavior lacks an automated regression assertion or blocking visual fixture.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (1)
src/vs/sessions/contrib/changes/test/browser/changesButtonBar.fixture.ts:41
- This four-line comment restates the option and the current implementation detail in
WorkbenchButtonBar.update, so it can become stale when the cap changes. Keep only the fixture invariant in a single line.
// Both production call sites of this outside-card composition pass
// `renderSecondaryActions: false`, which caps the bar at a single button
// (see `WorkbenchButtonBar.update`). Match that here so the fixture cannot
// claim geometry the real Changes view never renders.
- Files reviewed: 7/7 changed files
- Comments generated: 1
- Review effort level: Balanced
- buttonbar.test.ts now imports buttonbar.css and mounts the button bar in the live document with the spacing custom properties it depends on, so the pair-specific spacing test asserts the actual computed margin-inline-end instead of only DOM class/text shape. Also adds a compact-spacing counterpart test. - changesButtonBar.fixture.ts: trims the explanatory comment to one line, keeping the durable fixture invariant without restating WorkbenchButtonBar.update's internal cap logic. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Pushed
Verified: 8/8 targeted |
There was a problem hiding this comment.
🟡 Changes recommended
Shared widget configuration unintentionally widens icon-label spacing in the single-pane Changes header.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (2)
src/vs/sessions/contrib/changes/browser/changesView.ts:337
- The Agent Host variant is reused by
ChangesActionsBarin the single-pane editor header (changesView.ts:581-583) as well as by the outside-card view (changesView.ts:1645-1647). Only the latter previously received the consumer's extra 2px, so selectingdefaultinside this shared provider unintentionally widens the compact header too. Make spacing a host-supplied option and usedefaultonly for the outside-card composition.
? { showIcon: true, showLabel: true, customLabel: primaryCustomLabel ?? stripIcons(action.label), showSpinner: primaryIsBusy, iconLabelSpacing: 'default' }
src/vs/platform/actions/test/browser/buttonbar.test.ts:192
- This long method-body comment obscures the assertion it explains; reduce it to the pair-specific regression invariant.
// The pair-specific spacing rule in buttonbar.css only targets the
// leading icon; the inline icon inside the label keeps its ordinary,
// symmetric codicon margin. A regression that widens column-gap, or
// that makes the pair-specific rule apply too broadly, shows up here
// even though the class list above wouldn't catch it.
- Files reviewed: 7/7 changed files
- Comments generated: 3
- Review effort level: Balanced
- changesView.ts: ChangesWorkbenchButtonBarWidget and ChangesMenuWorkbenchButtonBarWidget hardcoded iconLabelSpacing to 'default'. Both widgets are shared between the outside-card composition (ChangesViewPane.createActionsButtonBar) and the single-pane editor header (ChangesActionsBar), so the header was unintentionally widened from its existing compact 4px relationship to 6px. iconLabelSpacing is now a constructor parameter: 'default' for the outside-card view, 'compact' for the single-pane header. - buttonbar.test.ts: condensed the new computed-style assertion's explanatory comment to one line, and the createButtonBar helper's setup comment likewise. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Pushed
Verified: 8/8 targeted |
There was a problem hiding this comment.
🟡 Changes recommended
The tests do not yet guard container-gap regressions or exercise the actual host-specific production wiring.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (1)
Previously missed (1) — in code that hasn't changed since the last review.
src/vs/platform/actions/test/browser/buttonbar.test.ts:192
- This still does not guard against the regression named by the test. A flex
column-gapcontributes to rendered separation without changing either child's computed margins, so reintroducing a broad gap can leave all three assertions passing. Assert the button's computedcolumnGapis zero/normal, or compare the rendered child-to-child distances against the corresponding margins, so spacing added by the container is detected.
- Files reviewed: 7/7 changed files
- Comments generated: 1
- Review effort level: Balanced
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Addressed the review summary's container-gap test gap in 0849550. The inline-icon regression now asserts the button's computed |
The prior commit derived spacing from the container's CSS class list
(container.classList.contains('outside-card')), which makes a layout
policy decision by sniffing a class name meant for styling, not by an
explicit contract between each call site and the widget. Restore an
explicit iconLabelSpacing constructor parameter on both
ChangesWorkbenchButtonBarWidget and ChangesMenuWorkbenchButtonBarWidget,
matching the review's ask for "a host-supplied option": the single-pane
header (ChangesActionsBar) passes 'compact', the outside-card view
(ChangesViewPane.createActionsButtonBar) passes 'default', and the
shared button-bar fixture does the same instead of re-deriving it from
DOM state.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Pushed
Validation: 8 focused WorkbenchButtonBar tests pass; both Changes fixtures render without errors and remain stable across three dark/light captures. |
|
Since the last review, pushed:
Verified: 8/8 targeted |
There was a problem hiding this comment.
🔵 Needs a closer look
The production host-specific spacing selection remains uncovered because the fixture constructs the shared button bar directly.
Review details
Suppressed comments (1)
Previously missed (1) — in code that hasn't changed since the last review.
src/vs/sessions/contrib/changes/test/browser/changesButtonBar.fixture.ts:51
- This fixture still constructs
WorkbenchButtonBardirectly and selects the outside-card constant independently of the production wiring atchangesView.ts:1648-1650. If that call site is accidentally switched to the compact header constant, this fixture continues rendering the default spacing and stays green. Render through the owning Changes widget/host, or expose a host-to-spacing helper that both production and the fixture invoke so the host-specific selection is actually covered.
- Files reviewed: 8/8 changed files
- Comments generated: 0 new
- Review effort level: Balanced
|
Re: the "closer look" note that the fixture doesn't exercise the actual per-host constructor call — noted and left as accepted scope for this pilot.
The pieces that are covered:
Wiring an automated guard that fails if a call site is switched to the wrong constant would need either full DI-driven fixture rendering or a source-level lint rule; both feel like broader test-infrastructure investment better suited to #335370 than this pilot. |
Both production call sites and the fixture now call getChangesButtonBarIconLabelSpacing(host) with an explicit 'header' | 'outside-card' host identifier, instead of importing raw spacing constants independently. This keeps the mapping in a single function both consumers invoke, per review feedback that the fixture's independent constant selection didn't structurally guard against a production call site drifting to the wrong host. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Pushed
This directly implements the suggested "host-to-spacing helper that both production and the fixture invoke." To be transparent about its limits: it does not add a structural guard against a production call site passing the wrong host string (that would still require rendering through the real Verified: 8/8 targeted |
There was a problem hiding this comment.
🟡 Changes recommended
The Changes fixture still bypasses the production host-selection wiring it is intended to protect.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
- Files reviewed: 8/8 changed files
- Comments generated: 1
- Review effort level: Balanced
| showIcon: true, | ||
| showLabel: true, | ||
| iconLabelSpacing: getChangesButtonBarIconLabelSpacing('outside-card'), |
Predictable UI composition - 3 of 3: shared-control pilot
This is the third PR in a three-part draft stack:
WorkbenchButtonBarand the Changes view.This PR is an experiment supporting review of the broader proposal. It validates a concrete composition, not every token or every ownership boundary in #335354.
Problem
Before this draft, the effective icon-label separation in the Changes view had two contributors:
WorkbenchButtonBarsupplied 4px through its internal leading icon/spinner margin.The resulting 6px distance was not described by either rule alone. A future change to either layer could silently alter or double the relationship.
The old margin was already part of the shared control implementation; a child-targeted margin is not inherently child-owned. The problem is the additional consumer contribution, not the use of margin itself.
Pilot implementation
The draft consolidates the relationship in
WorkbenchButtonBar:--vscode-iconSize-small(16px).iconLabelSpacingresolves to the explicit compact 4px variant for current consumers.iconLabelSpacing: 'default'selects a 6px relationship for the Changes view.Review findings addressed
The review identified and the latest commits address these gaps:
column-gapwas replaced with a targeted leading-slot margin. A unit test and shared button fixture cover a label containing an inline icon..changes-view-body .chat-editing-session-actions.outside-cardhierarchy with its production single-button geometry. It consumes the same named outside-card spacing constant as the production host, so the mapping cannot drift independently.working-set-diff-statsbutton-bar consumer. Production diff statistics use a separateActionViewItemand are outside this pilot.iconLabelSpacingwas hardcoded to'default'inside the widget classes shared by both the outside-card composition and the single-pane editor header, so the header picked up the wider 6px relationship it never had before. The widgets retain an explicit host-supplied constructor parameter; production and fixtures consume shared named constants for compact header and default outside-card spacing.The explicit
'compact'value and omission intentionally resolve to the same compatibility variant; both apply an explicit compact selector rather than relying on an implicit base rule.Shared-control visual validation
The updated
platform/buttonBar/ButtonBarsfixture exercises primary/trailing actions, split buttons, busy spinner replacement, and secondary overflow.Component Explorer validation:
platform/buttonBar/fixtures and both production-derived Changes fixtures render and dispose without errors.ButtonsandButtonBarsfixtures are stable across three captures.Automated validation
./scripts/test.sh --run src/vs/platform/actions/test/browser/buttonbar.test.ts- 8 focused button tests passnpm run stylelint -- src/vs/platform/actions/browser/buttonbar.css src/vs/sessions/contrib/changes/browser/media/changesView.css- cleangit diff --check- cleanCurrent unit coverage includes normal and dropdown buttons, icon/spinner replacement, menu and non-menu actions, icon-only variants, an inline-icon label, compact/default margins, and an assertion that the button container contributes no broad column gap. Component Explorer covers the computed production geometry.
Review questions
Context