Skip to content

feat(core): header-aware content sizing seam#1384

Merged
mathuo merged 3 commits into
v8-branchfrom
feat/header-content-sizing-seam
Jun 30, 2026
Merged

feat(core): header-aware content sizing seam#1384
mathuo merged 3 commits into
v8-branchfrom
feat/header-content-sizing-seam

Conversation

@mathuo

@mathuo mathuo commented Jun 30, 2026

Copy link
Copy Markdown
Owner

What

Free-core correctness fix: DockviewGroupPanelModel now lays panels out with the content-area dimensions (group box minus the header along its axis) instead of the header-inclusive group box.

Today DockviewGroupPanelModel.layout(w, h) forwarded the full group box straight to panel.layout(w, h) — the header was never subtracted (there was a literal TODO to this effect in dockviewPanel.ts). ContentContainer.layout is a no-op and always-overlays position off getBoundingClientRect, so the visual box was already correct; only the reported numbers (panel.layout args / onDidDimensionsChange) were wrong — harmless for CSS-fill renderers, but over-reporting height for canvas / virtualised / embed consumers.

Changes

  • contentDimensions() helper subtracts the header along its axis (offsetHeight for top/bottom, offsetWidth for left/right; a hidden header measures 0 → no subtraction, floored at 0). All three panel-sizing sites route through it.
  • Generic no-arg relayout() on the model + DockviewGroupPanel wrapper — re-applies the stored dimensions so a header-size change can propagate without the group box changing.
  • Removed the resolved dockviewPanel.ts TODO.

Why now

This is the free seam that unblocks the planned multi-row / advanced-overflow modules (a variable-height header makes the over-report grow per row). It's a standalone correctness fix that benefits everyone and lands in free core; the wrap mode that needs it stays pro.

Back-compat

⚠️ BREAKING (v8): panels and onDidDimensionsChange now receive the content-area height (group box minus header) instead of the header-inclusive group box. Within core nothing consumes the reported height, so the only observable change is more-correct numbers to apps that read panel dimensions. CSS-fill renderers are unaffected. Applied always (not gated) — gating would leave the latent bug in the default path.

Tests

  • Unit (groupContentSizing.spec.ts): stubs header offsets (jsdom has no layout) — content height/width subtraction for top/bottom + left/right headers, full box when unmeasured, floor at 0, relayout() re-application. jsdom reports offsetHeight === 0 so the seam is inert by default → all existing layout tests stay green unchanged.
  • e2e (content-sizing.spec.ts): real Chromium geometry — panel laid out with the content box (group height − real header height), not the full group box. Fixture instrumented to record panel layout dims via __dv.panelDimensions.
  • core: 1103 passed · e2e: 26 passed · lint/format clean.

🤖 Generated with Claude Code

mathuo and others added 3 commits June 30, 2026 21:16
DockviewGroupPanelModel.layout forwarded the full group box straight to
panel.layout(), header included — over-reporting content height by the
header size. Harmless for CSS-fill renderers, wrong for canvas /
virtualised / embed consumers that read the reported dimensions
(onDidDimensionsChange).

Add a contentDimensions() helper that subtracts the header along its axis
(offsetHeight for top/bottom, offsetWidth for left/right; a hidden header
measures 0, so nothing is subtracted), and route all three panel-sizing
sites through it. Also add a generic no-arg relayout() on the model and
the DockviewGroupPanel wrapper so a header-size change can be re-applied
without the group box changing (the entry point the planned multi-row /
overflow modules build on).

Applied always (not gated): within core nothing consumes the reported
height (content.layout is a no-op, always-overlays measure the DOM), so
the only observable change is more-correct numbers to numeric-height
consumers.

BREAKING (v8): panels and onDidDimensionsChange now receive the content
area height (group box minus header) instead of the header-inclusive
group box. CSS-fill renderers are unaffected.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Stub the header element's offset size (jsdom has no layout) and assert the
panel receives the content area: height = group height - header height for
top/bottom headers, width = group width - header width for left/right,
the full box when the header is unmeasured/hidden, floored at 0, and that
relayout() re-applies with the latest header size.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
jsdom can't lay out a header, so verify in Chromium that a panel is laid
out with the content box (group height minus the real header height), not
the header-inclusive group box. Instrument the fixture panel to record the
dimensions it is laid out with and expose them via __dv.panelDimensions.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

@mathuo mathuo merged commit da68458 into v8-branch Jun 30, 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