Skip to content

fix(tabs): wrap the pill nav instead of spilling off-screen past 8 Sparks - #82

Open
de1tydev wants to merge 1 commit into
MiaAI-Lab:mainfrom
de1tydev:tode/pill-nav-wrap
Open

fix(tabs): wrap the pill nav instead of spilling off-screen past 8 Sparks#82
de1tydev wants to merge 1 commit into
MiaAI-Lab:mainfrom
de1tydev:tode/pill-nav-wrap

Conversation

@de1tydev

@de1tydev de1tydev commented Sep 7, 2026

Copy link
Copy Markdown

Problem

The tab bar spills outside its rounded container — and then off the right edge of the page — once a deployment has more than ~7 Sparks registered.

.pill-nav is a flex container that keeps its default nowrap, every child (OverviewTab / TabChrome / the add button) is shrink-0 with white-space: nowrap, and the container sets no overflow behaviour. So when the tabs no longer fit there is nothing to give: they are simply painted outside the nav and outside the viewport. .dashboard-shell caps the page at max-width: 1440px, so a wider monitor does not help.

flex: 1 1 auto makes it worse: the nav's hypothetical main size is its full content width, so the header's own flex-wrap pushes the nav onto a second line and the settings/theme controls onto a third — and the nav still overflows after taking a whole row.

Measured on main (e03b9d6) at 1440x900 with 10 units:

nav.pill-nav      right = 1384      last tab/+ button right = 1739   -> 355px outside the nav
document          clientWidth 1440  scrollWidth 1739                 -> 299px horizontal overflow

The last two tabs and the + button are off-screen and unclickable.

Threshold sweep at 1440x900 (real-length unit names):

units overflows the nav overflows the viewport
≤ 7 no 0
8 yes (39px) 0
9 yes 141px
10 yes 299px

The new hideWorkers setting reduces the tab count, but it does not fix this: a deployment with 8+ non-worker Sparks (or with the setting off) still overflows.

Fix

Three declarations on .pill-nav plus one dnd-kit strategy swap:

change why
flex-wrap: wrap tabs wrap onto further rows instead of being painted outside the container
flex: 1 1 auto1 1 0 hypothetical main size drops to 0, so the header stays on one line (10 units: header 151px → 85px) and the nav wraps internally instead
border-radius: 50px23px at the 45.5px single-row height the browser already clamps 50px to 22.75px, so the one-row look is unchanged; it just stops the multi-row nav from becoming a giant stadium
horizontalListSortingStrategyrectSortingStrategy the horizontal strategy only translates items along X, so a drag across rows previews in the wrong place; the rect strategy handles wrapped/grid layouts

I deliberately did not use horizontal scrolling: seeing every machine at a glance is the point of this bar, and a scroller hides units behind an edge.

Verification

  • tsc --noEmit clean; npm test 190 passed / 0 failed.
  • Ran the server against fake configs of 2 / 8 / 10 / 16 units at viewport widths 1920 / 1600 / 1440 / 1280 / 1024 / 800: horizontal overflow is 0 in every cell, all tabs and the + button inside the nav. 10 units wrap to 2 rows at 1440, 16 units to 3.
  • No regression below the threshold: with 2 units the nav box, every child's left/top/width, and the header height are value-for-value identical to before at 1024 / 1280 / 1440 / 1920. Only the computed border-radius string changes (50px → 23px), which renders the same.
  • Drag-reorder across rows: with 16 units, dragging a row-1 tab past a row-3 tab lands in the right slot and persists via POST /api/sparks/reorder.
  • < 768px uses the hamburger branch and never renders .pill-nav — unaffected (checked at 600px).
  • Running on a 10-unit deployment since this was written; no visual or behavioural change other than the tabs staying on the page.

https://claude.ai/code/session_01K8Uebe5LQVjrAMkWXacCXd

…arks

With more than ~7 units the tab pills (all shrink-0 / nowrap) ran past the
nav's rounded container and, from 9 units on, past the right edge of the
page itself: at 1440x900 with 10 Sparks the document scrolled 299px wide and
the last two tabs plus the + button were unreachable.

- .pill-nav wraps onto further rows, so every tab stays inside the nav.
- flex-basis 0 keeps the header itself on one line (previously the nav and
  the settings/theme controls each wrapped onto their own header row).
- border-radius 23px == the old fully-rounded look at the 45.5px one-row
  height, and stays sane once the nav is 2+ rows.
- rectSortingStrategy replaces horizontalListSortingStrategy so drag-reorder
  animates correctly across rows.

Verified with 2/8/10/16 units at 1920/1440/1280/1024/800px: no overflow, and
with <=7 units the layout geometry is byte-identical to before.

Claude-Session: https://claude.ai/code/session_01K8Uebe5LQVjrAMkWXacCXd
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