Skip to content

editor: restore connected tab border and divider customizations - #338796

Open
Cherry Wang (chryw) wants to merge 23 commits into
mainfrom
dev/cherwan/agents/connected-tabs-border-bug-fix-audit
Open

Cherry Wang (chryw) wants to merge 23 commits into
mainfrom
dev/cherwan/agents/connected-tabs-border-bug-fix-audit

Conversation

@chryw

@chryw Cherry Wang (chryw) commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Connected editor tabs still suppressed tab.activeBorder and gave tab.border conflicting paint ownership after the broader color-customization restoration in #337986. This restores the remaining legacy border customizations and separates rounded tab boundaries from inter-tab dividers.

  • Restore active top, bottom, hover, selected, modified, focused, and unfocused border customizations in Connected tabs.
  • Preserve explicit legacy, shared Modern, and editor-specific Modern fill, label, hover, selected-action, and action-surface customizations.
  • Add tab.divider, which inherits tab.border by default but can be customized independently.
  • Keep paint ownership style-specific:
    • Legacy continues using tab.border as its separator and renders no dedicated divider.
    • Pill uses rounded tab.border outlines plus dividers at every adjacent boundary.
    • Connected uses tab.border for the active document cap and dividers only between inactive neighbors.
    • High Contrast keeps complete theme-owned tab boundaries and renders no redundant divider.
  • Keep rounded top and bottom accents inside Pill and wrapped Connected corners, and avoid duplicate first-tab/editor-frame edges.

Fixes #325250.

Visuals

The issue contains the failing before state. These captures show the fixed implementation.

Connected customization in native Code OSS

Dark Modern with distinct active/inactive surfaces, active top and bottom accents, a structural active-tab boundary, and dividers only between inactive neighbors:

Native Code OSS with customized Connected tab boundaries, surfaces, accents, and inactive dividers

Same tokens across tab styles

Top to bottom: Legacy keeps its existing separators without dedicated dividers; Pill uses rounded boundaries and dividers at every adjacency; Connected gives the active cap boundary ownership and limits dividers to inactive neighbors.

Matched Legacy, Pill, and Connected production fixtures using the same custom colors

Wrapped Connected tabs

An upper-row active tab remains a standalone pill. Its customized top and bottom accents stop before the rounded corners.

Wrapped Connected tabs with inset top and bottom accents on the upper-row pill

High Contrast defaults

Top to bottom: Dark HC and Light HC with no color overrides. Complete theme-owned tab boundaries remain visible and no dedicated divider is added.

Dark and Light High Contrast Connected tabs using complete stock boundaries without dedicated dividers

Testing

  1. Enable Modern UI and set workbench.experimental.modernUIEditorTabStyle to connected.
  2. Customize tab.border, tab.divider, tab.activeBorder, and tab.activeBorderTop with distinct colors. Verify the active cap uses the tab boundary and top/bottom accents, while dividers appear only between adjacent inactive tabs.
  3. Switch to pill. Verify each rounded tab uses tab.border, top and bottom accents stop before the corners, and dividers appear between every adjacent pair, including beside the active tab.
  4. Disable Modern UI or use Legacy tabs. Verify the existing tab.border separator remains the only shared-edge paint and no dedicated divider is duplicated.
  5. Wrap tabs onto multiple rows. Verify upper-row active tabs retain Pill geometry with inset accents and bottom-row active tabs remain connected to the editor.
  6. Switch between Dark High Contrast and Light High Contrast without color overrides. Verify complete stock tab boundaries and active focus ownership remain visible, with no dedicated divider.
  7. Exercise hover, modified, multi-selection, pinned, split-group, clipped, compact-height, and action-left states.

Validation

  • npm install
  • npm run compile
  • npm run transpile-client
  • Modern UI and multi-editor tab unit suites
  • Editor-tab production component fixture Playwright suite
  • Stylelint for the changed tab styles
  • Freshly built native Code OSS token audit across focused, hover, multi-selected, pinned, drag-and-drop, modified, and unfocused states
  • Exhaustive registry guard and computed-style coverage for all 46 relevant tab.*, modernTab.*, modernEditorTab.*, and editor-group-header colors

Cherry Wang (chryw) and others added 14 commits September 29, 2026 08:11
Keep pill tabs on fill-owned borders while allowing connected tabs to use the standard full-width theme border indicators. Add component fixtures and computed-style coverage for active, unfocused, and selected border colors.

Fixes #325250.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Give explicit tab.border customizations precedence over the connected tab header border default, and cover the connected side stroke in unit, fixture, and Playwright assertions.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Paint active top border customizations on the rounded connected cap instead of layering a straight indicator over it. Preserve the transparent default top-row border and keep selected and modified indicator ownership unchanged.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add matched legacy, pill, and connected fixtures plus first/middle continuity fixtures. Reuse the production legacy-to-modern color collector in the fixture harness and preserve connected structural borders and unfocused colors during active multi-selection.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add a customizable tab.divider element between tabs while reserving tab.border for tab boundaries. Modern pill and connected styles show short dividers only between inactive tabs; legacy keeps dividers at every shared boundary.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Default tab.divider to tab.border while preserving an explicit divider customization as an independent override.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Show dedicated dividers at every pill boundary while keeping connected dividers inactive-only. Keep tab.border as the rounded pill outline and inset active top/bottom accents so mixed colors do not protrude through the corners.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Make the divider transparent in continuity fixtures so the shared tab and editor boundary is tested without an inherited divider repainting it.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use a longer inactive tab run so divider ownership remains visually obvious across legacy, pill, and connected styles.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep inactive connected tabs unoutlined so their dedicated dividers own shared boundaries. Preserve the active left edge and inset selected top accents before their corners.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Expose first-in-row state directly instead of deriving it from sibling selectors, and add Dark and Light High Contrast fixtures and assertions for connected tab boundaries.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Let the outer editor frame own the left edge when the first connected tab is active, while retaining the tab boundary when no outer frame is present.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep legacy tab separators single-owned, make modern divider policies explicit, align the connected active bottom accent, and inherit high-contrast divider accents from the active group frame.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep dedicated dividers out of High Contrast, retain complete theme-owned tab outlines, and render customized wrapped-tab accents inside rounded pill corners. Align the tab geometry tests with production row and grid ownership.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings September 29, 2026 22:35

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Configured hover borders can render as two adjacent strokes on inactive Connected tabs.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)
What changed in this PR

Restores legacy tab border customizations in Modern UI and introduces independently configurable tab dividers.

Changes:

  • Adds tab.divider and separates divider/boundary paint ownership.
  • Restores Connected and Pill border accents across themes and wrapped tabs.
  • Expands unit and component-fixture coverage.
File Description
test/​componentFixtures/​playwright/​tests/​editorTabBar.spec.ts Tests border ownership and continuity.
src/​vs/​workbench/​test/​browser/​parts/​editor/​multiEditorTabsControl.test.ts Tests row-boundary classes.
src/​vs/​workbench/​test/​browser/​componentFixtures/​editor/​editorTabBar.fixture.ts Adds themed border fixtures.
src/​vs/​workbench/​services/​themes/​browser/​modernTabColorCustomizations.ts Emits legacy border customization variables.
src/​vs/​workbench/​contrib/​modernUI/​test/​browser/​modernUI.contribution.test.ts Tests theming and border behavior.
src/​vs/​workbench/​contrib/​modernUI/​browser/​media/​tabs.css Implements Pill boundaries, accents, and dividers.
src/​vs/​workbench/​contrib/​modernUI/​browser/​media/​connectedEditorTabs.css Implements Connected border ownership.
src/​vs/​workbench/​common/​theme.ts Registers tab.divider.
src/​vs/​workbench/​browser/​parts/​editor/​multiEditorTabsControl.ts Adds divider elements and row markers.
src/​vs/​workbench/​browser/​parts/​editor/​media/​multieditortabscontrol.css Defines divider and indicator styling.
build/​lib/​stylelint/​vscode-known-variables.json Registers new CSS variables.

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/vs/workbench/contrib/modernUI/browser/media/connectedEditorTabs.css Outdated
Keep editor-only Pill accent pseudo-elements off shared Sessions tabs, model production row-start ownership in the Sessions fixture, and restore the missing component-fixture theme type import.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions

github-actions Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Screenshot Changes

Base: 4fbe620f Current: f26b0c8f

Changed (34)

sessions/grid/sessionsGrid/MultipleChats/Light
Before After
before after
sessions/editorHeader/editorHeader/ConnectedChangesCard/Light
Before After
before after
sessions/editorHeader/editorHeader/ConnectedSecondTabCard/Light
Before After
before after
sessions/editorHeader/editorHeader/FullHeader/Light
Before After
before after
sessions/editorHeader/editorHeader/CompactFullHeader/Light
Before After
before after
sessions/editorHeader/editorHeader/BreadcrumbsAndAction/Light
Before After
before after
sessions/editorHeader/editorHeader/BreadcrumbsAndSecondaryAction/Light
Before After
before after
sessions/editorHeader/editorHeader/BreadcrumbsOnly/Light
Before After
before after
sessions/editorHeader/editorHeader/PrimaryActionOnly/Light
Before After
before after
sessions/editorHeader/editorHeader/SecondaryActionOnly/Light
Before After
before after
sessions/editorHeader/editorHeader/LayoutActionsOnly/Light
Before After
before after
chat/aiCustomizations/aiCustomizationManagementEditor/DiscoverInfiniteScroll/Light
Before After
before after
chat/aiCustomizations/aiCustomizationManagementEditor/DiscoverPluginsLoadingMore/Light
Before After
before after
editor/tabs/Density/PinnedSeparateRow/Default/Light
Before After
before after
editor/tabs/Density/PinnedSeparateRow/Compact/Light
Before After
before after
editor/tabs/Density/SingleRow/Default/Light
Before After
before after
editor/tabs/Density/SingleRow/Compact/Light
Before After
before after
editor/tabs/Density/Wrapped/Default/Light
Before After
before after
editor/tabs/Density/Wrapped/Compact/Light
Before After
before after
editor/tabs/FileIcons/Disabled/Light
Before After
before after
editor/tabs/FileIcons/Minimal/Light
Before After
before after
editor/tabs/Layout/ActionsLeading/Light
Before After
before after
editor/tabs/Layout/CloseActionsHidden/Light
Before After
before after
editor/tabs/Layout/LongNamesFit/Light
Before After
before after
editor/tabs/Layout/LongNamesFixed/Light
Before After
before after
editor/tabs/Layout/LongNamesShrink/Light
Before After
before after
editor/tabs/Layout/ModifiedAndMultiSelected/Light
Before After
before after
editor/tabs/Layout/PinnedIconOnly/Light
Before After
before after
editor/tabs/Layout/SingleEditor/Light
Before After
before after
editor/tabs/Scrolling/Breadcrumbs/Light
Before After
before after
editor/tabs/Scrolling/ClippedActiveTab/Light
Before After
before after
editor/tabs/Scrolling/StickyPinnedTabs/Light
Before After
before after
editor/tabs/TabStyles/Connected/Light
Before After
before after
editor/tabs/TabStyles/Pill/Light
Before After
before after

2 insignificant change(s) omitted (≤20 px, Δ≤2). See CI logs for details.

Added (2)

editor/tabs/Colors/ConnectedLegacyBorders/ActiveGroup/Light

current

editor/tabs/Colors/ConnectedLegacyBorders/InactiveGroup/Light

current

Use the boundary-aligned standard indicator for bottom-row Connected hover accents while upper wrapped pills keep their inset fill-owned border.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@chryw
Cherry Wang (chryw) marked this pull request as ready for review September 29, 2026 23:34
@vs-code-engineering

Copy link
Copy Markdown
Contributor

📬 CODENOTIFY

The following users are being notified based on files changed in this PR:

Benjamin Christopher Simmonds (@benibenj)

Matched files:

  • src/vs/workbench/browser/parts/editor/media/multieditortabscontrol.css
  • src/vs/workbench/browser/parts/editor/multiEditorTabsControl.ts

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Wrapped hover borders remain missing or mispainted, and connected dividers conflict with pinned-tab separators.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)
Resolved since last review (1)
Previously missed (2)

In code that hasn't changed since last review

Medium severity Suppress generic divider at pinned-to-normal boundary

src/​vs/​workbench/​contrib/​modernUI/​browser/​media/​connectedEditorTabs.css:75

At an inactive pinned-to-normal boundary this divider paints above the existing tab.lastPinnedBorder inset shadow (tabs.css:115-116) because .tab-divider has z-index 9. With distinct custom colors, the last-pinned separator is covered through its center and survives only as short fragments. Suppress the generic divider at that transition so the semantic pinned separator retains paint ownership.

Medium severity Add inset hover accent for active upper-row tabs

src/​vs/​workbench/​contrib/​modernUI/​browser/​media/​connectedEditorTabs.css:674

The inset replacement is gated on .tab-border-bottom, so active upper-row hover rendering is inconsistent: without tab.activeBorder, tab.hoverBorder remains a full-width straight indicator across the rounded corners; with tab.activeBorder, this rule hides the hover indicator and the pseudo-element keeps the active-border color instead. Handle hovered active upper-row tabs explicitly with an inset hover accent.

Cherry Wang (chryw) and others added 2 commits September 30, 2026 11:02
Render focused and unfocused hover-border customizations as a single inset accent on upper wrapped tabs, preserving their rounded pill geometry.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Honor explicit Modern editor action colors in Connected tabs while preserving seamless defaults. Guard the complete 46-token editor-tab audit across legacy, shared Modern, editor-specific Modern, and editor-group-header color families.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Cherry Wang (chryw) and others added 5 commits October 1, 2026 12:28
…nnected-tabs-border-bug-fix-audit

# Conflicts:
#	src/vs/workbench/contrib/modernUI/browser/media/connectedEditorTabs.css
#	src/vs/workbench/test/browser/componentFixtures/editor/editorTabBar.fixture.ts
Preserve the shared HC frame edge and load the production editor-frame styles in the migrated tab fixture harness.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Drop editor-group-header color imports that became unused when the color fixtures moved into the curated tabs harness.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove the redundant first-in-row marker introduced by this branch and use the row-boundary selectors owned by the merged tab structure overhaul.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Scope the editor frame to continuity fixtures, suppress uncustomized Connected active-top accents, and require exact cap/frame/body alignment without changing the tab layout geometry.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Modern UI: tab.activeBorder color customization not respected

5 participants