Skip to content

fix(theme): correct spaced-theme tab sizing in wrap overflow mode#1474

Merged
mathuo merged 4 commits into
v8-branchfrom
claude/spaced-themes-tab-height-wrap-hy8t3j
Jul 16, 2026
Merged

fix(theme): correct spaced-theme tab sizing in wrap overflow mode#1474
mathuo merged 4 commits into
v8-branchfrom
claude/spaced-themes-tab-height-wrap-hy8t3j

Conversation

@mathuo

@mathuo mathuo commented Jul 16, 2026

Copy link
Copy Markdown
Owner

Description

Spaced themes rendered tabs at the wrong size when overflow.mode: 'wrap' was enabled, in both header orientations.

Root cause. Core's multi-row wrap rules pin each wrapped tab to the full --dv-tabs-and-actions-container-height — as the tab's height for a horizontal header, and as its width for a vertical (edge-group) header. That assumes a zero tab margin, which holds for the default theme but not the spaced themes: those add --dv-tab-margin, and flex-wrap counts that margin toward each row's/column's cross-size. So a full-size tab plus its margins:

  • Horizontal: made every wrapped row 44px + 16px = 60px tall instead of 44px, and the tab filled the whole 44px instead of keeping the 28px pill inset it has in single-row mode (where flex align-items: stretch sizes it to the header height minus its margins).
  • Vertical edge-group: made every wrapped tab 44px wide (filling/overflowing the 44px strip) instead of the 28px pill — throwing off the edge-group rendering.

Fix (_space-mixin.scss). Subtract the tab's cross-axis margin from the pinned size so each wrapped row/column is exactly one header unit and the pill proportions match single-row mode:

  • Split --dv-tab-margin into --dv-tab-margin-block / --dv-tab-margin-inline parts (CSS calc() can't read a component out of the shorthand), keeping the shorthand composed from them so nothing else changes.
  • Horizontal wrap: height: calc(var(--dv-tabs-and-actions-container-height) - 2 * var(--dv-tab-margin-block)).
  • Vertical wrap: the cross-axis mirror on width (height stays core's live-measured --dv-wrap-vertical-tab-height). --dv-tab-margin-block is the cross-axis margin in both orientations.

Scoped entirely under the spaced-theme class — the default theme is untouched.

Type of change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation
  • Refactor / cleanup
  • Build / CI / tooling

Affected packages

  • dockview-core
  • dockview (vanilla JS)
  • dockview-react
  • dockview-vue
  • dockview-angular
  • docs

How to test

Real-browser regression tests were added to e2e/tests/multi-row-tabs.spec.ts (the wrap suite). The invariant they assert is the row/column band — tab border-box + its cross-axis margins — which must equal exactly one header unit; the existing zero-margin default-theme assertion (tabH === rowH) can't catch this. A ?theme=<name> param was added to the e2e fixture so the spaced theme is drivable.

  • spaced theme: each wrapped row band equals one header height (pill inset kept)
  • spaced theme (vertical header): each wrapped column band equals one header width (pill inset kept)

Both fail on the pre-fix CSS (tab fills the full unit, band overshoots) and pass with the fix. Verified end-to-end in headless Chromium; measured before→after: horizontal row band 60px → 44px, vertical tab width 44px → 28px.

Manual repro: any *-spaced theme with overflow: { mode: 'wrap' }, add enough tabs to wrap a horizontal group, and flip a group's header to left/right for the edge-group case.

Note: 3 pre-existing vertical-header resize/drag tests in this suite fail in the headless sandbox regardless of this change — confirmed failing identically on the base commit (unrelated to these theme-scoped edits).

Checklist

  • yarn lint:fix passes
  • yarn format passes
  • npm run gen has been run and generated files are up to date
  • yarn test passes
  • I have added or updated tests where applicable
  • Breaking changes are documented

🤖 Generated with Claude Code


Generated by Claude Code

mathuo and others added 4 commits July 15, 2026 21:51
Spaced themes give tabs a vertical margin (--dv-tab-margin), but core's
multi-row wrap rule pins each wrapped tab to the full
--dv-tabs-and-actions-container-height. flex-wrap counts the margin
toward each row's height, so wrapped rows overshot the header height and
the tab filled the full height instead of keeping the pill inset it has
in single-row mode.

Subtract the vertical tab margin from the wrapped tab height so each row
equals exactly one header height and the pill proportions match the
single-row layout. Splits --dv-tab-margin into block/inline parts so the
calc stays in sync with the shorthand.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LKiKo1SEYyTuLpDDfi4HDL
The vertical (edge-group) header is the cross-axis mirror of the
horizontal wrap bug: core pins each wrapped vertical tab's width to the
full --dv-tabs-and-actions-container-height, ignoring the spaced theme's
cross-axis tab margin. The full-width tab plus its left/right margins
overflows the edge-group strip and loses the pill inset it has in
single-column mode.

Subtract the cross-axis margin from the wrapped vertical tab width so the
pill fits the strip exactly (height stays core's live-measured
--dv-wrap-vertical-tab-height). Also expresses the vertical tab margin
via the shared block/inline variables so --dv-tab-margin-block is the
cross-axis margin in both orientations.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LKiKo1SEYyTuLpDDfi4HDL
Lets the e2e fixture render any exported theme (e.g. abyssSpaced) by
name so the spaced-theme wrap layout can be driven in a real browser.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LKiKo1SEYyTuLpDDfi4HDL
Adds two real-browser regression tests for the spaced-theme wrap fixes:
horizontal (each wrapped row band == one header height) and vertical
edge-group (each wrapped column band == one header width). The invariant
is the row/column BAND (tab border-box + its cross-axis margins), which
the existing zero-margin default-theme assertion (tabH == rowH) can't
catch. Both fail on the pre-fix CSS (tab fills the full unit, band
overshoots) and pass with the compensating margin subtraction.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LKiKo1SEYyTuLpDDfi4HDL
@sonarqubecloud

Copy link
Copy Markdown

@mathuo
mathuo merged commit f71738b into v8-branch Jul 16, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant