fix(harness): keep the rail's footer panels and plan card readable at a narrow rail - #703
fix(harness): keep the rail's footer panels and plan card readable at a narrow rail#703devin-ai-integration[bot] wants to merge 7 commits into
Conversation
…rapping its rows matchWidth pins the panel to the rail's width, so at RAIL_MIN labels like "Open Sapiom dashboard" wrapped inside a fixed-height row and read as overlapping items. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
Match the studio rail reference: the footer menu never matches its trigger. It takes --menu-w with a 240px floor and its rows stay one line, so dragging the rail to its minimum no longer wraps labels over each other.
The rest of the studio rail reference's footer-menu anatomy: right-bottom beside the rail (harness's right-end + besideRef) and the roomier menu well, so the panel gets its own ground instead of floating on the rail's footprint.
…wn width Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…ar of it Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Browser-verified: rail footer panels at
|
| panel | x | width | clears rail | inside viewport |
|---|---|---|---|---|
profile-menu |
184 | 256 | ✅ | ✅ |
settings-popover |
184 | 320 | ✅ | ✅ |
All 5 profile rows report height: 30 with no text clipping and no overlap.
Recording of the full run:
Regression checks
- Wide rail (320px): profile menu
x:324 w:256, settings popoverx:324 w:320, bottom edges aligned to the footer row. - Dark and light mode at both rail widths.
- Escape and outside-click dismissal both still work.
- Settings controls usable (telemetry toggle flips, editor select opens, popover stays open).
- Narrow browser window (888px app viewport): uncropped, rows single-line.
- Full harness suite: 321 passed (
popover-crop6/6,dismiss10/10).
⚠️ Two things a reviewer should know
- Mock mode never renders "Check for updates" or "Disconnect" in the profile menu — the first is desktop-host-gated, the second lives in the settings popover. Those two (the longest labels in the original report) were not visually verified here; worth one look in the Electron app.
getBoundingClientRect()cannot detect this bug. Onorigin/mainthe rows still report clean, non-overlapping 30px boxes while the text visibly spills over the neighbouring row — the row height is fixed and the wrapped text paints outside its own box. Layout assertions for this need to be pixel-based or usescrollWidth > clientWidth.
…er the Upgrade pill Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…ormatting Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Browser-verified: plan-card readout truncation at
|
| state | clipped | readout right | Upgrade left | clears pill |
|---|---|---|---|---|
| pre-fix CSS | ❌ | 114.4 | 59.8 | ❌ (−54.6px) |
| this PR | ✅ | 51.8 | 59.8 | ✅ (+8px) |
Light mode at 180px, and the full readout at a normal rail
Light mode at 180px — identical geometry (51.8 vs 59.8, clipped):
Rail reset to its 320px default — full $12.40 / $50 back, scrollWidth === clientWidth === 164:
Also checked
Upgradestill hit-testable at 180px → lands on/settings?tab=billing.⋯overflow menu still opens at 180px with both billing links, dismisses on Escape.- Restoring
HEAD'sstyles.cssafter the A/B removes the overlap again; tree left clean. rail-footer-cards.spec.ts: 7 passed, incl.keeps the readout clear of the Upgrade pill at the rail's minimum width.- The narrow width was seeded (
sapiom-harness-pane-widths→{"rail":180}+ reload, the same mechanism the spec uses) rather than dragged in this run; the drag reached 180 in the earlier run on this branch.
⚠️ Two notes for a reviewer
- The truncation is more aggressive than
$12.4…— at 180px the copy column is only ~24px, so it
rendersFr…/$1…. The overlap is fixed, but the readout conveys no information at the minimum
width and there's notitle/tooltip fallback. Worth deciding whether the card should instead wrap the
CTA, hide the readout below a threshold, or expose the value on hover. - The
Upgradeanchor istarget="_blank"but the click navigated the same tab in the plain SPA.
The CTA works; the spec only asserts the attribute, never a real click.
Primary change type
Problem and motivation
Reported in #studio-feedback: the rail's profile menu paints its rows on top of each other. The panel opens with
AnchoredPopover'smatchWidth, so it inherited the rail's width — draggable down toRAIL_MIN(180px), narrower than "Open Sapiom dashboard" — and every long label wrapped inside a fixed 30px row and spilled over its neighbour.Summary and scope
Takes the answer the studio rail reference already gives (
design-eng/sapiom-studio/src/styles/rail.css): a rail footer panel is its own surface and never matches its trigger.Three things, all the reference's: its own width, its own ground (
right-end+besideRefis this repo's spelling of the reference'sright-bottom— a panel on the rail's own footprint reads as nothing having happened), and the roomier menu well. Row height becomes a floor rather than a cap, so a row that grows pushes the next one down instead of over it;AnchoredPopover's existing measured pass keeps the panel inside the viewport.railRefis now passed intoProfileRow— the rail's right edge is the one the panel must clear, exactly as the⋯history flyer already does. The settings popover shares the footer trigger and the same failure mode, so it takes the same treatment at the reference's own320px/280px.The same drag exposed the footer's plan card (reported with a screenshot): its copy column shrinks correctly, but only the plan name clipped — the money readout kept its full width and painted under the
Upgradepill. It now truncates like the name above it, so the row degrades to$12.4…rather than to two overlapping strings; the CTA never moves.Related work
Related issue or discussion: Slack #studio-feedback ("menu elements are overlapping")
Validation
Tests and documentation
web/e2e/popover-crop.spec.tsgains a case at the rail's minimum width that asserts each row is one line tall, that no label overflows its row, that rows stay vertically ordered, and that the panel holds its own readable width and clears the rail's right edge; the settings-popover case now asserts the same width floor and rail clearance.web/e2e/rail-footer-cards.spec.tsgains the plan-card equivalent: at the same width the readout must end before theUpgradepill starts and must be ellipsised rather than overflowing. Reverting either CSS fix fails its test (measured, not assumed). No docs change: no user-facing behavior beyond the fix.Compatibility and release impact
.changeset/profile-menu-narrow-rail.md,@sapiom/harnesspatch).Security
AI assistance
Written by Devin; the cause was traced in
WorkflowsRail.tsx/AnchoredPopover.tsx, the fix mirrors the design-eng studio rail, and it is verified by the commands above plus a regression test confirmed to fail without the change.Checklist
CONTRIBUTING.md, and this contribution follows the direct-PR or issue-first policy.Link to Devin session: https://app.devin.ai/sessions/82c2067ac57342c4b21d948b507f3f23
Requested by: @ratataque