Skip to content

fix(mobile): PR tab switches no longer leave Liquid Glass behind - #26041

Merged
maria-rcks merged 3 commits into
pingdotgg:mainfrom
camchis:fix/mobile-pr-tab-glass
Oct 31, 2026
Merged

maria-rcks merged 3 commits into
pingdotgg:mainfrom
camchis:fix/mobile-pr-tab-glass

Conversation

@camchis

@camchis camchis commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Problem

On iOS 26, switching pull request tabs can leave the Liquid Glass selection lens floating in the wrong place. It slides along below the tab bar, or over the title and author row, warping the content underneath until it settles.

Each tab is a separate list that stays mounted while hidden, and each renders its own native segmented control. Tapping a segment starts UIKit's glass lens on the outgoing tab's control. That tab is then hidden with opacity: 0, but UIKit draws the lens outside that opacity, so it keeps animating at the hidden control's position. The incoming tab's list usually rests at a different offset, so the lens lands away from the visible control.

Reproduce by opening a PR with a short Activity tab, scrolling Overview partway so the tabs are still visible, and tapping Activity, then Overview.

Change

Only the visible tab mounts the segmented control. Hidden tabs keep a 32pt spacer, so every tab's header stays the same height. The tapped control unmounts on the switch and takes its lens with it, wherever each list happens to be scrolled.

The tab bar now snaps to the new selection instead of sliding the lens, matching the tab content, which already swaps instantly. Keeping the slide would require every tab to rest at exactly the same scroll offset. LegendList clamps and adjusts those offsets independently (short tabs, first visits), so that would be fragile.

Scope and approval

This is a focused fix for an obvious visual defect: the glass should never appear away from the control the user tapped. It fits the small bug-fix exception in CONTRIBUTING.md. The change is limited to PullRequestRouteScreen.tsx. Android renders the shared React Native control, which hides with its tab; it gets the same spacer behavior with no visible difference.

Verification

iPhone 17 Pro simulator, iOS 26.5, freshly built development client and isolated backend:

  • Reproduced on pingdotgg/t3code#26035 (one-item Activity tab): after tapping Activity, the glass pill and a second, distorted label slid along below the visible control. The same scripted run on the fix shows no lens away from the control in either direction.
  • Also reproduced the lens offset on #26031, and confirmed the header and tab bar render normally after switching both ways.
  • Mobile vp run typecheck, targeted lint and formatting: passed.

Android and iPad were not separately exercised. The header can still shift between tabs when LegendList clamps a short tab's offset; that is a separate, pre-existing issue and is not changed here.

Screenshots: before → after

Same moment after tapping Activity:

Before: glass pill floats below the tab bar and warps the activity filter row After: no glass outside the visible tab control

Before

The glass lens slides along below the tab bar and warps "2 hidden".

before.mp4

After

No lens outside the visible control in either direction.

after.mp4

Model and harness: Claude Opus 5.5 in Claude Code (T3 Code).

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XS 0-9 changed lines (additions + deletions). labels Oct 27, 2026
@camchis
camchis marked this pull request as ready for review October 27, 2026 17:31
@coderabbitai

coderabbitai Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Walkthrough

On iOS, the pull-request tab header renders the segmented control only for the visible tab. Other tabs render a 32-point spacer. On non-iOS platforms, the segmented control continues to render.

Changes: Visible-tab rendering

Layer / File(s) Summary
Conditional segmented control
apps/mobile/src/features/pull-requests/PullRequestRouteScreen.tsx
On iOS, the visible tab renders the segmented control and hidden tabs render a 32-point spacer. On other platforms, the segmented control renders.

Priority: Low

Estimated code review effort: 1 (Trivial) | ~5 minutes

Change: Bug fix

Possibly related PRs

Suggested reviewers: juliusmarminge

Merge Risk: Minimal · up to 1db63

The selected iOS tab retains its control while hidden tabs render spacers. No merge-blocking risk was identified.

Pre-merge checks: Passed 4
Check name Status Explanation
Title check Passed The title clearly and concisely describes the main mobile fix for the Liquid Glass artifact during pull request tab switches.
Description check Passed The description covers the problem, reproduction steps, technical change, scope and approval rationale, verification results, platform limitations, and before/after visual evidence. It is complete and…
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.
Full details: Description check

Explanation

The description covers the problem, reproduction steps, technical change, scope and approval rationale, verification results, platform limitations, and before/after visual evidence. It is complete and relevant to the changeset.

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

Usage-based review receipt

Note

This review was completed with usage-based billing: files reviewed beyond your plan's included limits are billed at $0.25/file. View usage-based billing.

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

Copy link
Copy Markdown
Collaborator

Note

Written by gpt-6.1-sol on behalf of Maria

thanks @camchis. the active-control mount is the smallest fix for the displaced UIKit lens, so i kept your implementation and commit, merged current main, and pushed two sizing corrections:

  • use an exact 32-point iOS spacer. mobile's rem: 14 makes h-8 28 points, which let hidden headers overwrite the shared header measurement with a shorter height.
  • keep Android's controls mounted. their height grows with text size, and Android does not have this UIKit lens bug.

verification: Blacksmith vp run check:changed passed formatting, lint, both knip passes, affected mobile/scripts typechecks, and the existing compiler tests (5 passed). two independent code reviews approve 1db63723cbede26ed63e52bf6958dd2c14c6b325, with no remaining findings. no new test files were added for this visual defect.

unverified: fresh iOS 26 reproduction, before/after screenshots and interaction recording, Android runtime, and iPad. the device tool returned "Agent device access is turned off for this environment." Chrome cannot exercise UIKit's native segmented control. your existing native evidence remains in the PR body; it predates these corrections and is not current-head proof. before merging, exercise Overview → Activity → Overview at differing scroll offsets on iOS, confirm no displaced glass and stable header/file jumps, and check Android with enlarged text.

CI: all 29 reported checks are green on this head. GitHub reports MERGEABLE / CLEAN; CodeRabbit reports no merge-blocking risk.

handoff blocker: the final bot review surfaced https://git.cafe/pingdotgg/t3code/pulls/27269, which addresses the same UIKit control lifecycle with a persistent overlay. i missed that focused overlap in my initial search before pushing. i am stopping further changes here so Maria can choose between the approaches; this PR should not be treated as independently ready to merge. https://git.cafe/pingdotgg/t3code/pulls/27269 was left untouched.

@intergalacticspacehighway

Copy link
Copy Markdown

I just saw this. It was opened before my PR, #27269, which fixes the same glitch in a different way.

  • This PR: only the visible tab mounts the control. The change is small, and the pill jumps to the new tab instantly so the bouncy glass animation ends instantly.

  • fix(mobile): remove tab control flicker on iOS PR screen #27269: one shared control above the tab lists takes the taps, so the native iOS 26 glass slide stays. It needs more code but animation continues fully.

Here they are side by side on the same simulator. Happy to close mine! it's a nit and depends on the preference! 😄

Left: this PR. Right: #27269.

side-by-side.mp4

Copy link
Copy Markdown
Collaborator

Note

Written by gpt-6.1-sol on behalf of Maria

Verified in a real dev environment

no changed runtime behavior could be verified on this linux boat vm. this is an unverifiable result, not a passing verification.

inspected the description, discussion, complete diff, commit authors, exact head 1db63723cbede26ed63e52bf6958dd2c14c6b325, and reported checks. the pr is open; its three pr commits are by camchis and maria-rcks, with none by juliusmarminge or t3dotgg. git.cafe number: 26041. all 29 reported ci checks pass, which does not prove this visual fix.

runtime prerequisite transcript:

$ uname -s
Linux
$ device_list
Agent device access is turned off for this environment.

Not verified

main reproduction, current-head before/after screenshots, interaction recording, and nearby native behavior could not be exercised. the only changed file is the native mobile pull-request screen. the changed branch runs on ios; Android retains the existing controls. chrome cannot render the UIKit segmented control or reproduce its iOS 26 Liquid Glass lens.

no dev server, provider turn, worktree installation, or code change was made after discovering this native-device blocker. those steps would not exercise the affected client path here. no fresh visual evidence is available; the existing pr media is historical evidence, not verification from this run.

required follow-up on an enabled iOS 26 device: reproduce Overview → Activity → Overview at differing scroll offsets on main, repeat on this exact head, and capture matching before/after images plus a short recording. check the Guide tab when enabled, header sizing and file jumps, and Android with enlarged text. real Codex gpt-6.1-sol turns through the native client also remain unverified. no other pr was touched.

Copy link
Copy Markdown
Collaborator

Note

Written by gpt-6.1-sol on behalf of Maria

Verified in a real dev environment

no changed runtime behavior was verified in this run. result: unverifiable. inspected the description, discussion, complete diff and commit authors for head 1db63723cbede26ed63e52bf6958dd2c14c6b325. the pr is open, with no pr commits by juliusmarminge or t3dotgg. git.cafe number is 26041. all 29 reported ci checks pass; these are not runtime proof.

prerequisite checks on this linux vm:

uname -s: Linux
xcrun: unavailable
device_list: Agent device access is turned off for this environment.

Not verified

main reproduction, current-head ios 26 Liquid Glass behavior, matching before/after captures, recording, Guide switching, header sizing, file jumps and Android enlarged-text behavior remain unverified. the only changed file is the native mobile pr screen, and the changed conditional applies only on ios. its compact control is a 32-point T3NativeControls native view. chrome cannot exercise UIKit or its glass lens; Android retains the existing control mounting.

no worktree installs, dev servers, provider turns or code changes were made after confirming the native-device blocker. a web Codex turn would not verify this client path. no fresh visual evidence was captured or uploaded. existing pr media is historical evidence, not proof from this run.

follow-up requires an enabled ios 26 device: reproduce Overview → Activity → Overview at different scroll offsets on main, repeat on this exact head, record the transition and check Guide, header sizing and file jumps. real Codex gpt-6.1-sol turns through the native client and Android runtime also remain unverified. no other pr was touched.

Copy link
Copy Markdown
Collaborator

Note

Written by gpt-6.1-sol on behalf of Maria

Verified on Android emulator (API 35) against a real dev server

no runtime verification was performed. the verification brief requires stopping if the change is ios-only, and the current diff meets that condition.

inspected the complete diff, discussion, reviews, commit authors and status at head 1db63723cbede26ed63e52bf6958dd2c14c6b325. the pr is open. the only code change is in PullRequestRouteScreen.tsx: Platform.OS !== "ios" || section === tab preserves the existing segmented-control mounting on android and changes hidden-tab mounting only on ios. all 29 reported ci checks pass; this is not runtime proof.

Not verified

ios cannot run on this linux vm. the ios 26 UIKit Liquid Glass defect, current-head fix, before/after screenshots, interaction recording and neighboring native behaviors remain unverified. an android run cannot exercise the changed conditional branch or UIKit lens.

per the brief's ios-only stop condition, no emulator, dev server, Metro, install, pairing or Codex turns were started. no code or branch was changed, and no fresh media was captured. verification requires an ios 26 device running this exact head against a real dev server.

@maria-rcks
maria-rcks merged commit 5d46778 into pingdotgg:main Oct 31, 2026
29 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XS 0-9 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants