Skip to content

fix(app): right-panel titlebar seam — alignment, stable toggle, drag-resize sync#887

Merged
Astro-Han merged 5 commits into
devfrom
claude/fix-titlebar-right-seam
May 25, 2026
Merged

fix(app): right-panel titlebar seam — alignment, stable toggle, drag-resize sync#887
Astro-Han merged 5 commits into
devfrom
claude/fix-titlebar-right-seam

Conversation

@Astro-Han

@Astro-Han Astro-Han commented May 24, 2026

Copy link
Copy Markdown
Owner

Summary

Three connected fixes for the right-panel titlebar seam, reported post-release as a follow-up to #880. All three only become visible together: once the seam aligns, the toggle slide and the drag-resize lag become readable.

  1. macOS seam misalignment (8px) — original report.
  2. Toggle slides 320px when panel opens — surfaced after fix chore: v1.1 polish — skills, panel fixes, README SEO #1 made the now-aligned seam clearly visible.
  3. Drag-resize seam drifts — surfaced after fix feat: split desktop panel and thread locale into skills #2 made the corner stable; while dragging the body and the titlebar slot moved at different speeds.

Fix 1 — macOS seam alignment

padding-inline: 8pxpadding-inline-start: 8px on the macOS [data-component="titlebar-shell"] rule.

The symmetric 8px padding pushed the right rail (and the tabs slot pinned to its right edge) 8px inboard of the viewport. The right-panel <aside> directly below sits in a sibling layout tree without that padding, so its border-left reached the actual viewport edge — the two border-ls ended up 8px apart on macOS. Windows has no equivalent rule and was already correct.

The titlebar comment block in #880 explicitly assumed the right rail's outer edge = viewport.right — true on Windows, false on macOS. The toggle's existing pr-2 now provides the closed-state 8px inset directly (matching macOS native toolbar conventions for the rightmost control), without doubling up with the rail's own padding.

Fix 2 — Stable toggle position across open/close

#pawwork-titlebar-right changed from in-flow flex sibling of the tabs slot to absolute-positioned at the rail's top-right corner (right-2 on macOS, right-0 on Windows).

PR #880's structural layout made the toggle a flex sibling, so opening the panel pushed it left by --right-panel-width over the 240ms transition. That slide read as visually jarring once fix #1 aligned the seam and the motion became readable against the now-continuous border-l.

The toggle visually overlaps the tabs slot's rightmost area when open, but they don't collide in practice — Kobalte's Tabs.List sizes to content (~150px for 1-4 chips, observed 146.5px in the regression test debug dump), leaving the trailing + button in the middle of the panel column with empty space at the corner for the toggle to float in.

Fix 3 — Drag-resize seam sync

New effect in SessionSidePanel mirrors props.size.active() to a data-resizing-right-panel attribute on <desktop-shell>. Matching CSS rule in index.css disables the shell's transition while the attribute is present.

Root cause: while dragging the panel resize handle, the body's <aside> inline width snapped to each pointermove (its transition is gated on the session-scope props.size.active()), but --right-panel-width on the desktop shell kept its 240ms cubic-bezier transition because the shell's gate uses state.sizing — a layout.tsx-local flag scoped to the sidebar resize handler only. The two sides of the seam moved at different speeds; one led, one trailed.

The attribute-bridge approach avoids plumbing session-scope sizing state into the global layout context — the bridge stays one attribute wide and one CSS rule shallow. The 120ms timeout in createSizing re-enables the transition shortly after the user lets go, so the open/close animation still uses the full 240ms cubic-bezier curve.

Regression tests

Two new assertions in titlebar-right-rail-contract.spec.ts:

Related Issue

None — post-release regression report; no separate GitHub issue filed.

Human Review Status

Pending

Review Focus

  • packages/app/src/components/titlebar.tsx — the right rail restructure (absolute-positioned toggle + the long comment block above explaining why). The Tabs.List content-width observation is load-bearing for the no-collision claim; if a future change makes the strip fill the slot, the toggle and + would overlap.
  • packages/app/src/pages/session/session-side-panel.tsx — the imperative createEffect that mirrors sizing state to the DOM attribute. The alternative was lifting createSizing into the layout context; this is the smaller change.
  • packages/app/src/index.css — both new rules (padding-inline-start on macOS titlebar, [data-resizing-right-panel] transition reset).

Risk Notes

How To Verify

bun run test:e2e:local titlebar-right-rail-contract.spec.ts  → 5/5 pass
bun run snap right-panel-titlebar                            → 1 passed; grid PNG shows toggle at corner, seam continuous in light + dark
bun run lint                                                 → clean
bun --cwd packages/app run typecheck                         → clean

Manual Electron (mac) verification: toggle stable across open/close, drag-resize seam moves as one continuous line.

Screenshots or Recordings

Snap grid at docs/design/preview/screenshots/right-panel-titlebar.png (local-only per docs/ exclusion) shows the toggle at the viewport corner in both light + dark, with the seam continuous from titlebar top through the right-panel body's left edge.

Checklist

  • Type label (bug)
  • Routing labels (app, ui)
  • Priority label (P2)
  • Human Review Status set to Pending
  • Linked the related context (no issue; references fix(app): restore titlebar toggle visual contract after PR #878 #880 follow-up)
  • Described review focus and risks
  • Replaced How To Verify with real steps and results
  • No unrelated refactors, deps, or generated files
  • Manually checked visible UI via snap regrid + Electron dev
  • Considered macOS / Windows impact
  • Reviewed final diff for unrelated changes
  • Targeting dev; title is Conventional Commits in English

Summary by CodeRabbit

  • Bug Fixes
    • Fixed misalignment between the titlebar and right-panel borders during resizing.
    • Eliminated visual drift during active right-panel drag-resize, including macOS unified-titlebar seam and spacing adjustments to keep the right-rail toggle stable.
  • Tests
    • Added a contract test to verify titlebar and right-panel border alignment consistency.

Review Change Stack

…macOS

PR #880 declared the seam fixed ("panel border-l flush with titlebar
slot border-l, seam continuous") but a post-release regression report
showed the two border-l's are offset by 8px on macOS only.

## Root cause

`[data-component="titlebar-shell"][data-shell-os="macos"]` in
`packages/app/src/index.css` carried a symmetric `padding-inline: 8px`,
which pushed the titlebar's right rail (and therefore the tabs slot
pinned to its right edge) 8px inboard of the viewport. The right-panel
`<aside>` directly below sits in a sibling layout tree without that
padding, so its body's `border-left` reached the actual viewport edge
— the two `border-l`s ended up 8px apart, breaking the seam.

The titlebar comment in PR #880 explicitly assumed the right rail's
outer edge = viewport.right ("`pr-2` lives on `#pawwork-titlebar-right`
… so it reads as 'toggle inset from viewport edge' when closed and
'gap between toggle and tabs border-l' when open"). That assumption
was true on Windows (no equivalent padding rule) but false on macOS.

Snap target `right-panel-titlebar` was supposed to catch this — its
own comment names the seam as the contract — but the 8px x-axis offset
slipped through visual review.

## Fix

`padding-inline: 8px` → `padding-inline-start: 8px`. The toggle's
existing `pr-2` provides the closed-state inset from the viewport
edge (8px instead of 16px, which matches macOS native toolbar
conventions for the rightmost control).

## Regression test

Added `tabs slot border-l aligns horizontally with the right-panel
body border-l` to `titlebar-right-rail-contract.spec.ts`. Asserts
`|tabs.left - body.left| < 1px` (sub-pixel tolerance for Retina
rounding). Confirmed red→green: with the old `padding-inline: 8px`
the test fails with `Received: 8`; with the fix it passes.

## Verified

- `bun run test:e2e:local titlebar-right-rail-contract.spec.ts` — 4/4
  pass (including the new x-axis seam assertion)
- `bun run snap right-panel-titlebar` — passes, grid PNG shows the
  light + dark seam continuous from titlebar top to viewport bottom
- `bun run lint` — clean
- `bun --cwd packages/app run typecheck` — clean

Follow-up to PR #880, addresses the post-release regression report.
@Astro-Han Astro-Han added bug Something isn't working app Application behavior and product flows ui Design system and user interface P2 Medium priority labels May 24, 2026
@github-actions github-actions Bot removed the ui Design system and user interface label May 24, 2026
@coderabbitai

coderabbitai Bot commented May 24, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@Astro-Han, we couldn't start this review because you've used your available PR reviews for now.

Your plan includes 1 review of capacity. Refill in 20 minutes and 23 seconds.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more review capacity refills, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than trial, open-source, and free plans. In all cases, review capacity refills continuously over time.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 28782330-be4a-43fd-9bab-3c5b7482706f

📥 Commits

Reviewing files that changed from the base of the PR and between f30627d and 3f85427.

📒 Files selected for processing (1)
  • packages/app/e2e/session/titlebar-right-rail-contract.spec.ts
📝 Walkthrough

Walkthrough

Adjusts titlebar right-rail layout and macOS titlebar padding, mirrors right-panel drag-resize state to the desktop shell to disable transitions during resizing, and adds an E2E contract test that asserts the titlebar tabs and right-panel body left borders align within 1px.

Changes

Titlebar-right-rail seam alignment

Layer / File(s) Summary
Titlebar right-rail geometry and positioning
packages/app/src/components/titlebar.tsx
Right-rail children changed to a geometry-stable layout: rail container made relative; right toggle absolutely vertically centered and inset via right-2/right-0; #pawwork-titlebar-tabs now conditionally adds padding-right when tabsRailActive.
Mirror right-panel resize state to desktop shell
packages/app/src/pages/session/session-side-panel.tsx
Adds a Solid effect that sets/removes data-resizing-right-panel on [data-component="desktop-shell"] when the right panel is actively resizing on desktop and ensures cleanup on unmount.
Desktop-shell transition gate and macOS padding
packages/app/src/index.css
Adds desktop-shell[data-resizing-right-panel] { transition: none !important } and changes macOS titlebar-shell padding from padding-inline: 8px to padding-inline-start: 8px with an expanded seam comment.
E2E seam alignment contract test
packages/app/e2e/session/titlebar-right-rail-contract.spec.ts
New Playwright test opens session and right panel, measures getBoundingClientRect().left of #pawwork-titlebar-tabs and [data-component="right-panel-body"], and asserts their left-offset difference is < 1px.

Sequence Diagram

sequenceDiagram
  participant Session as Session (E2E / User)
  participant SessionSidePanel as SessionSidePanel
  participant DesktopShell as Desktop Shell (DOM)
  participant Titlebar as Titlebar component
  participant CSS as Stylesheet

  Session->>SessionSidePanel: start drag-resize right panel
  SessionSidePanel->>DesktopShell: set data-resizing-right-panel attribute
  DesktopShell->>CSS: transition disabled via attribute
  SessionSidePanel->>Titlebar: layout unchanged during resize (no seam shift)
  Titlebar->>Session: visual seam shows aligned left borders
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

Possibly related PRs

  • Astro-Han/pawwork#878: Modifies titlebar and right-rail geometry and tests; closely related to the seam and test adjustments in this PR.
  • Astro-Han/pawwork#880: Adjusts titlebar right-rail/tab-slot geometry; overlaps with layout changes here.
  • Astro-Han/pawwork#412: Related to right-panel resize lifecycle and events; overlaps with resize mirroring behavior.

Suggested labels

P1, desktop

Poem

🐰 A little seam once split the view,
I nudged the padding, aligned the two.
A test hops in to count each line,
Now borders meet, one perfect sign. ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title precisely summarizes the three coordinated fixes: macOS seam alignment, stable toggle positioning, and drag-resize synchronization—all clearly related to the main changes across CSS, components, and side-panel logic.
Description check ✅ Passed The description is comprehensive and complete. It covers all required sections: clear summary of three fixes with rationale, related context (reference to #880, no separate issue), human review status (Pending), detailed review focus with file-specific guidance, thorough risk notes including platform impact and visual side effects, verified testing results with actual commands and outcomes, and a screenshot reference. All mandatory checklist items are ticked, with conditional items properly addressed (UI changes verified, platform impact considered, relevant surfaces called out).
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/fix-titlebar-right-seam

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested priority: P2 (includes user-path files (packages/app/src/index.css)).

P1/P0 are reserved for maintainer confirmation. Please relabel manually if this is a release blocker, security issue, data-loss risk, or updater/runtime failure.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request fixes a visual alignment issue on macOS where the titlebar tabs slot was offset from the right-panel body due to symmetric padding. The fix involves changing the titlebar's padding to be start-only and adding a regression test to ensure horizontal alignment. Feedback was provided regarding the new E2E test, specifically recommending the use of expect.poll to prevent flakiness caused by CSS transitions when the panel opens.

Comment thread packages/app/e2e/session/titlebar-right-rail-contract.spec.ts Outdated
@github-actions

github-actions Bot commented May 24, 2026

Copy link
Copy Markdown

Perf delta summary

Comparator: pass

Profile / Scenario interaction median interaction worst long task max tbt frame gap p95 frame gap max jank count cls status
default / homepage-cold 24 -> 24 (0) 56 -> 32 (-24) 90 -> 73 (-17) 40 -> 23 (-17) 33.4 -> 33.4 (0) 149.9 -> 149.9 (0) 4 -> 4 (0) 0 -> 0 (0) pass
default / long-session-input-lag 48 -> 48 (0) 48 -> 48 (0) 0 -> 0 (0) 0 -> 0 (0) 16.7 -> 16.7 (0) 16.8 -> 16.8 (0) 0 -> 0 (0) 0 -> 0 (0) pass
default / session-streaming-long 40 -> 40 (0) 72 -> 64 (-8) 0 -> 0 (0) 0 -> 0 (0) 16.8 -> 16.8 (0) 33.3 -> 33.3 (0) 0 -> 0 (0) 0 -> 0 (0) pass
default / tool-call-expand 40 -> 40 (0) 40 -> 40 (0) 0 -> 0 (0) 0 -> 0 (0) 16.7 -> 16.7 (0) 16.7 -> 16.7 (0) 0 -> 0 (0) 0 -> 0 (0) pass
default / tool-default-open-heavy-bash 16 -> 16 (0) 16 -> 24 (+8) 98 -> 63 (-35) 64 -> 24 (-40) 49.9 -> 49.9 (0) 100 -> 116.8 (+16.8) 2 -> 3 (+1) 0.004 -> 0.004 (0) pass
default / terminal-side-panel-open 48 -> 48 (0) 56 -> 48 (-8) 0 -> 0 (0) 0 -> 0 (0) 33.4 -> 33.3 (-0.1) 33.4 -> 33.3 (-0.1) 0 -> 0 (0) 0 -> 0 (0) pass
default / session-scroll-reading 16 -> 16 (0) 16 -> 32 (+16) 0 -> 0 (0) 0 -> 0 (0) 33.3 -> 33.3 (0) 33.3 -> 33.3 (0) 0 -> 0 (0) 0 -> 0 (0) pass
low-end / session-scroll-reading-long 0 -> 0 (0) 0 -> 0 (0) 52 -> 53 (+1) 2 -> 3 (+1) 33.3 -> 33.3 (0) 49.9 -> 50 (+0.1) 0 -> 0 (0) 0 -> 0 (0) pass
low-end / session-timeline-recompute 40 -> 40 (0) 40 -> 40 (0) 0 -> 0 (0) 0 -> 0 (0) 33.3 -> 33.3 (0) 33.4 -> 33.4 (0) 0 -> 0 (0) 1.075 -> 1.075 (0) pass
low-end / concurrent-shimmer-extreme 0 -> 0 (0) 0 -> 0 (0) 0 -> 0 (0) 0 -> 0 (0) 16.7 -> 16.7 (0) 16.8 -> 16.8 (0) 0 -> 0 (0) 0 -> 0 (0) pass

Two follow-ups to the macOS seam fix earlier in this PR, both surfaced
once the alignment seam was visibly continuous and motion against it
became readable:

## 1. Stable toggle position (replaces #880's slide)

PR #880 made the right utility toggle an in-flow flex sibling of the
titlebar tabs slot, so opening the right panel pushed the toggle left
by `--right-panel-width` over the 240ms transition. The slide read as
visually jarring once the seam was aligned and the motion became
visible against the now-continuous border-l.

Fix: `#pawwork-titlebar-right` is now absolute-positioned to the
rail's top-right corner (`right-2` on macOS, `right-0` on Windows),
so its x-coordinate stays at `viewport.right - 8px` regardless of
panel state. The tabs slot is the only flex sibling and pins to the
rail's right edge as before; the toggle visually overlaps the tabs
slot's rightmost area but in practice doesn't collide — Kobalte's
`Tabs.List` sizes to content (~150px for 1-4 chips), leaving the
trailing `+` button in the middle of the panel column with empty
space at the corner for the toggle to float in.

Regression test `right utility toggle keeps the same x-position across
open/close` in `titlebar-right-rail-contract.spec.ts`: asserts
`|toggle.right(open) - toggle.right(closed)| < 12px`. Pre-fix this
came back `Received: 229.25` (the full panel-width displacement);
post-fix it's within sub-pixel rounding.

## 2. Drag-resize seam sync

While dragging the panel resize handle, the body's `<aside>` inline
`width` snapped to each pointermove (its transition is gated on the
session-scope `props.size.active()`), but `--right-panel-width` on
the desktop shell kept its 240ms cubic-bezier transition because the
shell's gate uses `state.sizing` — a layout.tsx-local flag scoped to
the sidebar resize handler only. The two sides of the seam moved at
different speeds; one led, one trailed, visibly drifting apart.

Fix: a small effect in `SessionSidePanel` mirrors
`props.size.active()` to a `data-resizing-right-panel` attribute on
`<desktop-shell>`. A CSS rule in `index.css` matches the attribute
and disables the shell's transition while the user is dragging. This
avoids plumbing session-scope sizing state into the global layout
context — the bridge stays one attribute wide and one CSS rule
shallow. The 120ms timeout in `createSizing` re-enables the
transition shortly after the user lets go, so the open/close
animation still uses the full 240ms cubic-bezier curve.

## Verified

- `bun run test:e2e:local titlebar-right-rail-contract.spec.ts`
  — 5/5 pass (incl. the new x-position-stability assertion)
- `bun run snap right-panel-titlebar` — passes; grid PNG shows
  toggle at corner in both states, seam continuous
- `bun run lint` — clean
- `bun --cwd packages/app run typecheck` — clean
- Manual Electron verification (mac): toggle stable across open/close,
  drag-resize seam moves as one continuous line.
@github-actions github-actions Bot added the ui Design system and user interface label May 24, 2026
@Astro-Han Astro-Han changed the title fix(app): align titlebar tabs slot border-l with right-panel body on macOS fix(app): right-panel titlebar seam — alignment, stable toggle, drag-resize sync May 24, 2026
Three review items from the post-#887 review thread, all verified and
fixed.

## P1 — tabs slot reserves explicit right-edge for absolute toggle

Reviewer flagged: the right utility toggle is absolute-positioned over
the rightmost area of the tabs slot, while the `+` add-tab button
lives in the portalled Tabs.List. If `+` ever reaches the slot's
right edge, clicks meant for it get intercepted by the toggle's
hit-target.

Verified: today the collision doesn't happen — Kobalte's Tabs.List
renders at content-width (~150px for 1-4 chips, measured 192.5px in
DEBUG dump) instead of the `width: 100%` declared in tabs.css, so
the `+` sits ~180px clear of the toggle. But that's a CSS coincidence,
not a contract. Any future change (consumer `w-full`, tabs.css
refactor, Kobalte upgrade) makes the list fill the slot and collapses
the safety margin.

Fix: `#pawwork-titlebar-tabs` slot now declares
`padding-right: 44px` (toggle 30 + viewport inset 8 + gap 4 + 2px
buffer for Tabs.List internal `px-1`) when `tabsRailActive()`.
Physical `padding-right` matches the physical `right-2`/`right-0`
on the toggle so RTL stays consistent. The reserve makes the
no-collision guarantee independent of Tabs.List's intrinsic sizing.

Title comment block on the slot rewritten to explain the reserve
instead of the CSS-coincidence it replaces.

## P2 — sizing effect no longer leaks data-resizing-right-panel

Reviewer flagged: the effect that mirrors `props.size.active()` to
`data-resizing-right-panel` early-returns on `!isDesktop()` without
removing the attribute, and has no `onCleanup` to remove it on
unmount. Because the CSS rule that reads the attribute uses
`transition: none !important`, a leak would silently kill the
shell's open/close transitions until the next page load.

Three leak paths closed:
1. `isDesktop()` flips false mid-drag — effect now always
   `removeAttribute` first, then optionally re-sets only when
   desktop AND active. Early-return after the cleanup is safe.
2. Component unmounts with active=true (navigation away from
   session) — `onCleanup` always removes the attribute regardless
   of state.
3. Stale attribute from previous instance — same "always clear
   first" pattern handles this too.

Did NOT take reviewer's "more optimal: use layout state instead of
querySelector global DOM" because lifting session-scope sizing into
the layout context expands this hotfix PR into a refactor; tracked
separately (see future follow-up).

## P3 — tests now cover the user-visible "+" contract

Reviewer flagged: the existing toggle-position test asserted only
that the toggle exists, not that `+` is clickable; the test comment
claimed "open/closed are two DOM nodes" but the actual implementation
keeps one node and absolute-positions its container; `waitForTimeout(300)`
is brittle.

Fixed:
- Toggle-position test comment rewritten — explicitly notes one DOM
  node, absolute-positioned, so pre/post toggle.right are pixel-
  identical (tolerance tightened from 12px to 1px).
- `waitForTimeout(300)` replaced with `expect.poll` for
  toggle-right stability (two consecutive reads within sub-pixel).
- New test `+ add-tab button stays clickable and does not close
  the panel`: clicks `+`, asserts panel stays open AND dropdown
  menu opens. Uses raw `page.locator` instead of `getByRole` for
  the toggle check because Kobalte's DropdownMenu marks the rest
  of the page `inert` while open and `getByRole` filters it.
- New test `+ stays clickable even if Tabs.List is forced to fill
  the slot (collision guard)`: runtime-injects
  `[data-slot="tabs-list"] { width: 100% !important }` via
  `page.addStyleTag`, then asserts (a) plus.right < toggle.left
  geometrically and (b) the click still opens dropdown without
  closing panel. This is the fortification test that proves the P1
  reserve actually protects against the future-CSS scenario.
- New test `data-resizing-right-panel attribute does not leak when
  viewport drops below the desktop breakpoint mid-resize state`:
  manually sets the attribute, flips viewport below 768px,
  asserts attribute is removed. Pins the P2 cleanup contract.

## Verified

- `bun run test:e2e:local titlebar-right-rail-contract.spec.ts`
  — 8/8 pass (3 original + 1 from earlier #887 work + 1 toggle-position
  + 2 "+" overlap + 1 P2 leak)
- `bun run snap right-panel-titlebar` — grid PNG unchanged
  (padding-end reserve is invisible because content fits well within
  the available space)
- `bun run lint` — clean
- `bun --cwd packages/app run typecheck` — clean
@Astro-Han

Astro-Han commented May 24, 2026

Copy link
Copy Markdown
Owner Author

Addressed all three review items; verification passes.

P1 — accepted direction, hardened with codex-refined number

Fact correction: the reviewer's premise that "Tabs.List is width: 100%" doesn't hold in practice — Kobalte actually renders at content-width (DEBUG dumped 192.5px, not 380), leaving ~180px between + and the toggle, so no collision today.

But the reviewer's "this is a fragile dependency" call is correct: today's no-collision is a CSS coincidence, and the moment Tabs.List becomes 100% it collides.

Going with option A, but not the reviewer's 36px — after consulting codex, used 44px (toggle 30 + right-2 8 + gap 4 + 2 buffer for Tabs.List's own px-1). Physical padding-right stays paired with physical right-2/right-0 (RTL doesn't get half-flipped). Only applied when tabsRailActive().

Added 2 e2e tests:

  • + add-tab button stays clickable and does not close the panel — directly asserts the user-visible contract
  • + stays clickable even if Tabs.List is forced to fill the slot (collision guard) — runtime-injects width: 100% !important to simulate the reviewer's "future scenario", asserts both geometry and behavior

Not accepted: "drop the toggle stability fix, keep only the macOS padding fix" — that would walk back a product contract the user explicitly chose.

P2 — real bug, fixed as reviewer described

All three leak paths closed:

  1. isDesktop() flipping false mid-resize: effect now unconditionally removeAttribute first, then decides whether to re-set.
  2. Component unmounting while still active: added onCleanup to unconditionally clear.
  3. Stale attribute from a previous instance: same "always clear first" pattern as chore: v1.1 polish — skills, panel fixes, README SEO #1.

Added e2e: data-resizing-right-panel attribute does not leak when viewport drops below the desktop breakpoint mid-resize state, simulates attribute residue + viewport shrink and asserts the attribute gets cleared.

Not accepted: "better to use layout state than to write the DOM globally via querySelector" — that would lift session-scope createSizing into layout context and expand this PR's scope. The same session-scope-state pattern is already used in several places; consolidating it is a separate refactor and gets tracked separately.

P3 — all accepted

  • Removed the misleading comment claiming "open/closed are two DOM nodes" (leftover from an intermediate version; the toggle has always lived in #pawwork-titlebar-right, just absolute-positioned now)
  • waitForTimeout(300)expect.poll waiting for toggle.right to be stable across two consecutive reads
  • Tolerance tightened from 12px to 1px (same DOM node, absolute positioning — should be sub-pixel consistent)
  • Added a click test covering the user-visible + path
  • Used page.locator instead of getByRole to find the toggle — when the DropdownMenu opens, Kobalte marks the rest inert and getByRole filters the toggle out

Verification

bun run test:e2e:local titlebar-right-rail-contract.spec.ts  → 8/8 passed
bun run snap right-panel-titlebar                            → passed; no visual regression
bun run lint                                                 → clean
bun --cwd packages/app run typecheck                         → clean

New commit: 281ed42

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/app/e2e/session/titlebar-right-rail-contract.spec.ts (1)

302-305: ⚡ Quick win

Use a data-attribute selector in injected CSS instead of an ID selector.

Switching this injected selector to a stable data attribute keeps the test aligned with the suite’s selector policy.

Selector update
-        `#pawwork-titlebar-tabs` [data-slot="tabs-list"] {
+        [data-shell-slot="tabs-portal"] [data-slot="tabs-list"] {
           width: 100% !important;
           flex-grow: 1 !important;
         }

As per coding guidelines, "Use data-component, data-action, or semantic roles for selectors instead of CSS class names or IDs".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/app/e2e/session/titlebar-right-rail-contract.spec.ts` around lines
302 - 305, Replace the injected ID selector in the CSS string passed to
page.addStyleTag with a stable data-attribute selector; specifically, in the
content string where it currently uses "`#pawwork-titlebar-tabs`
[data-slot=\"tabs-list\"]", change the ID part to a data attribute such as
"[data-component=\"pawwork-titlebar-tabs\"]" (or the project's canonical data
attribute) so the selector becomes "[data-component=\"pawwork-titlebar-tabs\"]
[data-slot=\"tabs-list\"]"; update the CSS string inside the page.addStyleTag
call accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/app/e2e/session/titlebar-right-rail-contract.spec.ts`:
- Around line 194-201: Ensure the test normalizes the right-panel toggle state
before measuring "closed": query the toggle button (page.getByRole("button", {
name: "Right utility panel" })) and read its aria-expanded state, and if it is
"true" invoke the toggle (use the same click path or helper toggleRight()) to
force it closed, then call toggleRight() to sample the closed state; update the
test around toggleRight() to perform this precondition check and only then
assert expect(closed).not.toBeNull().

---

Nitpick comments:
In `@packages/app/e2e/session/titlebar-right-rail-contract.spec.ts`:
- Around line 302-305: Replace the injected ID selector in the CSS string passed
to page.addStyleTag with a stable data-attribute selector; specifically, in the
content string where it currently uses "`#pawwork-titlebar-tabs`
[data-slot=\"tabs-list\"]", change the ID part to a data attribute such as
"[data-component=\"pawwork-titlebar-tabs\"]" (or the project's canonical data
attribute) so the selector becomes "[data-component=\"pawwork-titlebar-tabs\"]
[data-slot=\"tabs-list\"]"; update the CSS string inside the page.addStyleTag
call accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 3dbef095-c4b4-4a88-93be-ded718accd60

📥 Commits

Reviewing files that changed from the base of the PR and between 251b8df and 281ed42.

📒 Files selected for processing (4)
  • packages/app/e2e/session/titlebar-right-rail-contract.spec.ts
  • packages/app/src/components/titlebar.tsx
  • packages/app/src/index.css
  • packages/app/src/pages/session/session-side-panel.tsx

Comment thread packages/app/e2e/session/titlebar-right-rail-contract.spec.ts Outdated
Toggle moved to absolute right-2 in this PR; the closed-state inset
comment still pointed at the removed pr-2 utility.
@Astro-Han

Copy link
Copy Markdown
Owner Author

P3 follow-up: stale pr-2 reference in the macOS titlebar comment fixed in f30627d — comment now points at the absolute right-2/right-0 that replaced it.

- x-axis seam test: poll for steady state instead of reading
  immediately after open. Panel aside width and shell
  --right-panel-width both run 240ms transitions on panel open/close,
  and data-resizing-right-panel only gates drag, so mid-flight
  sub-pixel drift could bust the <1px tolerance.

- toggle x-position test: normalize aria-expanded to false before
  sampling the closed state, instead of relying on the e2e harness
  default. Same lookup uses page.locator (DropdownMenu marks the rest
  inert when open, breaking getByRole).
@Astro-Han Astro-Han merged commit 8647fb5 into dev May 25, 2026
27 checks passed
@Astro-Han Astro-Han deleted the claude/fix-titlebar-right-seam branch May 25, 2026 02:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app Application behavior and product flows bug Something isn't working P2 Medium priority ui Design system and user interface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant