fix(web): prevent sidebar shelf animations from overlapping headers#25384

merged2
main
GitHub fork: fix/sidebar-shelf-overlap
opened9d agobyBbrandon-julio-t
View on GitHubTwo-way sync enabledPR last imported 3d ago

Expanding the bottom-anchored Working shelf briefly moves its rows over the stationary Snoozed and Settled headers, superimposing thread text and section labels. Track shelf expansion changes in the existing layout effect and reset list motion for those changes. The chevron still animates, and ordinary thread moves keep their existing motion.

Closes #25383.

Before

The second Working row crosses both lower section headers during the 150 ms transition.

https://github.com/user-attachments/assets/ca0d66df-2e2b-4642-83f7-b73cce2027ed

Before: Working rows overlap Snoozed and Settled at 60 ms into expansion

After

At the corresponding 60 ms checkpoint, the chevron is still animating and the last Working row ends 1 px above Snoozed. No row crosses either lower header.

https://github.com/user-attachments/assets/220a94c8-e810-44e4-9771-2cf4b26e9162

After: the same 60 ms checkpoint keeps Working rows clear of both headers

Both recordings show a normal toggle cycle, then hold an opening at 60 ms for inspection. Before holds the original row animation; after holds the chevron transition because shelf-toggle row translation is skipped. The timing of the initial cycles is unchanged. Evidence uses anonymous demo titles and local display states in the same Chromium web client at 1440 × 900.

Verification

  • Reproduced the reported desktop recording on upstream bfc7177f9f54. At 60 ms, the second Working row occupied y=738.23–820.23 px, intersecting Snoozed at y=750–782 and Settled at y=783–815. After the fix it ends at y=749, above Snoozed at y=750.
  • Expanded/collapsed Working, Snoozed, and Settled on desktop and at a 390 × 844 web viewport; checked keyboard activation and shelf state after reload.
  • Settled a local demo thread and observed ordinary list-motion animations, confirming thread moves still animate.
  • vp run check:changed: formatting, lint, knip, affected package type checks, and 108 tests passed. The commit hook also passed.
  • macOS Electron and the native mobile client were not separately tested. The original report supplies macOS desktop evidence; verification here used the shared web sidebar in Chromium.

Submitted under the small, focused obvious-bug exception in CONTRIBUTING.md: this repairs visible row/header collisions during an existing shelf toggle. The fix is confined to the existing layout effect; before/after captures provide the visual regression evidence.

Snoozed above Settled: explicit follow-up verification

The same defect also occurs when expanding Snoozed above Settled. Reproduced on unpatched upstream at 30 ms: the Snoozed row extends 24.59 px into the Settled header. On this PR's existing commit, the row ends 1 px above Settled and no row translation or exit clone is created during shelf toggles.

CaseBeforeAfter
Desktop, Working shelf visibleSnoozed overlaps SettledNo overlap
Desktop, Working shelf disabledSnoozed overlaps SettledNo overlap
Narrow web, 390 × 844Snoozed overlaps SettledNo overlap

Also verified Settled expansion reveals all 4 demo threads below its header, and collapsing Snoozed and Settled updates the disclosure state correctly without animated rows crossing headers. Checked both desktop and narrow web layouts. No additional code change was needed: shelfExpansionKey already includes Working, Snoozed, and Settled.

Before, paused at 30 ms:

Before: expanding Snoozed overlaps the Settled header at 30 ms

After, at the matching checkpoint:

After: Snoozed remains separated from Settled at the matching checkpoint

— Brandon Julio Thenaro

Implemented with GPT-6.1-Sol in T3 Code through the Codex harness.

Checks

23 successful · 13 skipped
All checks passed
406b8cc

Added 1 commit

  • fix(web): prevent sidebar shelf animations from overlapping headers44e9c17
Synced from GitHub

Approvability

Verdict: Approved at 44e9c17

Macroscope's review found this PR approvable — This is a focused one-file fix that prevents sidebar rows from animating across lower section headers during shelf expansion while preserving ordinary list animations. It introduces no new capability, product-default change, schema change, or static-analysis suppression.

You can add or adjust custom eligibility rules. Learn more.

Synced from GitHub

Review in Change Stack →

No actionable comments were generated in the recent review.

External image Recent review info
External image Run configuration
External image Commits

Reviewing files that changed from the base of the PR and between 44e9c17dfecbce7f628073b0d8c3a4fbbb465a03 and 406b8cc15f531cf4bf01ce917148045ec674ce69.

External image Files selected for processing: 1
  • apps/web/src/components/Sidebar.tsx

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 3 remain after this review.

Walkthrough

The sidebar tracks expansion changes across the Working, Snoozed, and Settled shelves. It enables list motion only when the expansion state is unchanged and animation is enabled.

Changes: Sidebar shelf motion

Layer / File(s)Summary
Shelf transition motion gate
apps/web/src/components/Sidebar.tsx
The sidebar stores the combined shelf expansion state. The layout effect suppresses list motion when that state changes and otherwise retains the existing animation condition.

Estimated code review effort: 2 (Simple) | ~8 minutes

Change: Bug fix · Severity of issue fixed: Low

Suggested labels: bugfix

Suggested reviewers: juliusmarminge

Merge Risk: External image Minimal · up to 406b8

The reported sidebar overlap is addressed without introducing a remaining actionable merge risk.

Pre-merge checks: Passed 4
Check nameStatusExplanation
Title checkPassedThe title names the change and its purpose: a fix that stops sidebar shelf animations from overlapping section headers. The raw summary and objectives both describe tracking shelf expansion in the exi…
Description checkPassedThe description follows the template's main sections. It gives the problem and the change, and it links issue #25383 under Scope and approval. It cites the small, focused obvious-bug exception and des…
Linked Issues checkPassedIssue #25383 requires thread rows and section headers to remain separate during shelf expansion and collapse. In apps/web/src/components/Sidebar.tsx, the layout effect tracks workingShelfExpanded,…
Out of Scope Changes checkPassedThe whole-PR diff changes only the sidebar list-motion effect and adds shelf-expansion state tracking. These changes directly support issue #25383. No unrelated changes appear in the reviewed diff.
Full details: Title check

Explanation

The title names the change and its purpose: a fix that stops sidebar shelf animations from overlapping section headers. The raw summary and objectives both describe tracking shelf expansion in the existing layout effect and resetting list motion for those changes, which matches the title. The title is specific and conventional, and it describes the primary change.

Full details: Description check

Explanation

The description follows the template's main sections. It gives the problem and the change, and it links issue #25383 under Scope and approval. It cites the small, focused obvious-bug exception and describes the fix as confined to the existing layout effect. Verification is detailed and includes before/after screenshots and recordings, with a note on what was not tested (macOS Electron and the native mobile client). The template's HTML comment about the agent model is also filled in. The description is mostly complete and specific, so it passes. A reviewer may still want to confirm that the exception claim meets CONTRIBUTING.md, since the description asserts it without linking the approval.

Full details: Linked Issues check

Explanation

Issue #25383 requires thread rows and section headers to remain separate during shelf expansion and collapse. In apps/web/src/components/Sidebar.tsx, the layout effect tracks workingShelfExpanded, snoozedShelfExpanded, and settledShelfExpanded. It disables list-row motion when any shelf state changes, while the existing list motion setting remains active when shelf states are unchanged. This addresses the transient header collision without disabling ordinary thread motion.

Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

Added 1 commit

  • fix(web): sync shelf animation fix with main406b8cc

Note

Written by gpt-6.1-sol on behalf of Maria

merged current main (d92c437baa19) into the existing contributor branch, preserving the original commit and shelf-expansion gate. the only conflict was main's layout-effect lint annotation; both were retained. the final diff remains one file, +9/-2. no additional abstraction or behavior change was needed.

verification at 406b8cc15f53:

  • reproduced the overlap on current main: at 30 ms, snoozed row 2 ends at y=821.77 while settled starts at y=783. after the fix, the last snoozed row ends at y=782, leaving a 1 px gap.
  • blacksmith vp run check:changed d92c437baa19409f99416a44f748f148f4317c65 passed formatting, lint, knip, affected typechecks, 128 existing tests, and sidebar react compiler coverage.
  • real chrome client: working toggles during a free replay-provider turn; snoozed and settled expansion/collapse at 1440×900 and 390×844; enter/space activation and persistence after reload in dark mode. settling a thread still creates ordinary row animations. separate chevron motion is retained.
  • two independent read-only reviews found no issues at this head.
  • unverified: native macos electron and native mobile. this change is confined to the shared web sidebar; no provider, transport, or contract changes.

the recordings show normal toggle cycles followed by a held 30 ms checkpoint. matching anonymous projection fixtures isolate the visual bug; replay turns and settling were exercised separately through the real client/server path. uploaded clips were played and scrubbed in chrome. inline animations below are gif exports of those same clips.

before on current main: snoozed rows cross the settled header at 30 ms

after: snoozed rows end above the settled header at 30 ms

before: shelf toggle cycles and held overlap checkpoint

after: shelf toggle cycles and clear headers at the matching checkpoint

Note

Written by gpt-6.1-sol on behalf of Maria

Verified in a real dev environment

verified as-is at 406b8cc15f531cf4bf01ce917148045ec674ce69 on this linux boat vm. no code changes or pushes were needed.

  • reproduced on freshly fetched github/main (e5909e53c3) in a separate worktree, then installed and ran the exact pr head. only one dev server ran at a time.
  • used repository playwright with /usr/bin/google-chrome, actual client clicks and typing, a project pointing at /home/user/t3code, and real codex gpt-6.1-sol turns through the local proxy. created and snoozed/settled threads through the app. copied that app-created development state between stopped servers for matching captures. no mocks, fixtures, replay provider, or demo data.
  • at 30 ms into snoozed expansion on main, row 1 spans y=797.18–833.18 and row 2 spans y=834.18–870.18, crossing settled at y=820–852. on this head the rows span y=746–782 and y=783–819, leaving 1 px above settled. shelf toggles retain chevron motion and create no row translations.
  • expanded/collapsed working during a real codex terminal call (timeout 45 sleep 35), then observed the provider response working shelf complete. and its return to the inbox. working rows stayed above snoozed and settled. ordinary completion and settling still produced real list-motion translations and exit animations.
  • checked snoozed and settled mouse toggles, enter/space activation, persisted expansion after reload, and the 390 × 844 narrow web sidebar in dark mode. desktop captures use 1440 × 900 in light mode.
  • blacksmith vp run check:changed d92c437baa19409f99416a44f748f148f4317c65 passed formatting, lint, knip, both affected typechecks, all 128 existing sidebar tests, and sidebar react compiler coverage. the worker needed git history and chromium installed before the final passing run. existing ci reports 29 successful checks.

before and after below use the same app-created shelf data. elapsed labels naturally advanced between runs. the recordings show normal toggle cycles followed by an explicitly held 30 ms animation checkpoint. loading lead-ins were trimmed. uploaded videos were played to completion and seeked in chrome. the inline recordings are gif exports of those clips.

before on main: snoozed rows cross the settled header at 30 ms

after on pr head: both snoozed rows stay above settled at 30 ms

before: shelf toggle cycles and held overlap checkpoint

after: shelf toggle cycles and clear headers at the matching checkpoint

Not verified

native electron on macos/windows and native ios/android were not available on this linux vm. remote/relay/tunnel connections and other providers were not exercised. this diff changes only the shared web sidebar layout effect, with no provider, transport, contract, or native-mobile changes.