fix(#552): compact text-only sidebar tab headers at narrow widths - #557
Merged
Conversation
Both sidebar tab rows (the upper Databases/Dashboards role switcher and the lower Library/History switcher) share `.side-tab`/`.side-count`, so a single CSS container query covers both: `.sidebar` gets `container-type: inline-size; container-name: sidebar`, and `@container sidebar (max-width: 220px)` hides `.side-tab svg` (icons) and `.side-tab .side-count` (the "· N" counts, dot and number together) once the dragged sidebar width crosses the bottom quarter of its 180-420px range. No markup change, so the full presentation returns automatically on widening. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GiubaoqEuBzAyo5C4P8Vqr
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
Closes #552. At narrow sidebar widths both tab rows kept their icons, separator dots and item counts, so the elements competed for space and the panel looked broken. This makes them compact text-only labels below a threshold.
Mechanism — a container query, not a media query. The sidebar's width is a dragged pixel value written to
sidebar.style.width(src/ui/app-shell.ts), which@mediacannot see..sidebarnow declarescontainer-type: inline-size; container-name: sidebar, following the existing.dash-tile-headprecedent insrc/styles.css.Threshold — 220px (owner decision). The drag range is
clamp(ev.clientX, 180, 420)(src/ui/splitters.ts), so 220px makes compact the bottom quarter: it engages only when the sidebar has been deliberately squeezed, and ordinary working widths (240–320px) are untouched.One rule covers both tab rows because they already share a vocabulary — the upper role tabs are
class: 'side-tabs upper-role-tabs'with.side-tab/.side-countchildren (src/ui/sidebar-upper.ts), the same grammar as the lower Library/History switcher. So Databases, Dashboards, Library and History are all handled by:The separator dot needs no separate rule:
.side-count's text is'· ' + count, so the dot and the number are one text node and hiding the span removes both.No markup change, no new class, no new
font-size— so the compact state is pure CSS with no JS state to desynchronise, and widening the sidebar restores the full presentation on its own.Verification
happy-dom cannot see CSS layout, so the real signal is a browser.
tests/e2e/sidebar-tabs-narrow.spec.js(4 tests) reusesdashboard-tree.html's realmountAppShellfixture and drags the actual.col-resizehandle (mousedown → mousemove → mouseup) rather than asserting against a hand-written width. It covers the wide default, the 220px compact state, the clamped 180px floor and the restored-wide state, measuringscrollWidth <= clientWidth, unclipped labels and no tab-rect overlap.Observed live at 200px: both rows measure an even 50/50 split per tab, labels unclipped, History tab still clickable and receiving
active; dragged back to 300px, icons and counts reappear.Note
The issue body says "Dashboard" but the rendered upper tab reads "Dashboards" (plural). Left as-is — a pre-existing label, not something #552 asked to rename.
Checklist
npm testpasses (the per-file coverage gate is non-negotiable)npm run buildsucceeds (single-filedist/sql.html)src/core/, network insrc/net/(injected fetch), DOM insrc/ui/CHANGELOG.md([Unreleased]) updated if behavior or the deployed surface changed🤖 Generated with Claude Code
https://claude.ai/code/session_01GiubaoqEuBzAyo5C4P8Vqr