Skip to content

fix(mobile): iOS rename prompt text field no longer overflows the dialog - #22569

Draft
saphid wants to merge 3 commits into
pingdotgg:mainfrom
saphid:fix/mobile-rename-dialog-input-overflow
Draft

saphid wants to merge 3 commits into
pingdotgg:mainfrom
saphid:fix/mobile-rename-dialog-input-overflow

Conversation

@saphid

@saphid saphid commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Problem

On an iPhone running iOS 26 (Nightly build), the Rename thread prompt rendered its text field shifted past the alert's trailing edge. On the simulator, the same overflow appears when the alert lays out again while open (see Evidence). The field's left edge sits inside the card, but its right side runs past the alert. Every iOS Dialog.prompt uses this alert: Rename thread (thread list context menu) and Link pull request (PR and git sheets). The iOS implementation used React Native's Alert.prompt, which is a stock UIAlertController with addTextFieldWithConfigurationHandler, so the layout comes from UIKit and we can't fix it from JS.

Repro: on iOS 26 (Nightly), long-press a thread on Home and choose Rename.

Expected: the input sits inside the dialog, like Android's Compose dialog.

Change

  • Dialog.tsx (iOS): prompt now hands the request to an in-app dialog in the new DialogHost.tsx, mounted at the app root where Dialog.Host was. Keeping the UI in DialogHost means modules that only call Dialog.alert don't pull native UI modules into their unit tests. The dialog is a transparent fade Modal with a GlassSurface card, an AppTextInput, and Cancel and primary buttons. These are the same building blocks and tokens the command palette uses. alert and confirm still use native Alert.
  • A React Native Modal presents from its nearest view controller, and the root controller can't present over a native form sheet. So hosts register as a stack: the most recently mounted one presents. ThreadPullRequestsSheet and GitOverviewSheet mount DialogSheetHost, because Link pull request opens from those sheets. On Android, DialogHost.android.tsx re-exports the existing Compose host and DialogSheetHost is a no-op because Compose dialogs open in their own window.
  • Robustness: a second tap can't confirm twice. Content scrolls when a long message and large text don't fit above the keyboard. Buttons stack vertically at large Dynamic Type sizes.

Scope and approval

No prior issue. I think this qualifies as a small, focused fix for an obvious visual bug in an existing control, with no change to product behavior. The prompts keep the same callers, options, and callback semantics. The sheet host is only there because the in-app prompt has to present over sheets.

Verification

  • Current integration (ea2f2e5, 2026-10-23): retained main's sheet headers/toolbars alongside the dialog sheet hosts and main's test pruning. All three retained dialog tests, mobile typecheck, scoped lint and formatting pass; required hosted checks pass on this commit. Native captures and broader test counts below belong to the explicitly identified earlier revisions. No new native session was run; this PR remains draft pending acceptance.
  • Full mobile suite (vp test run --project unit --project react): 289 files pass. The new DialogHost.test.tsx covers that an edited value is confirmed exactly once under a double tap, and that a mounted sheet host presents before the root host, falling back to the root host after the sheet unmounts. The existing Android dialog test still passes.
  • tsc-rs --noEmit in apps/mobile is clean. vp lint reports no new warnings. The web Cannot find module 'mermaid' typecheck error also reproduces on main without this change; fix(web): main typecheck passes again after the Mermaid switch to pele #22570 and test(web): drop the Mermaid warmup that imports a removed package #22571 address it.
  • iOS Simulator run on an iPhone 17 Pro, dark appearance, against an isolated dev backend with synthetic fixture threads. Base is the merge base fe414eb and candidate is this PR's head 8253ac3, on the same dev client build with Metro switched between worktrees. See Evidence below.
  • Not checked: a physical iOS 26 device, the Link pull request entry in the Linked pull requests sheet (it needs a thread that already has a linked PR, and only the Git sheet entry was exercised), and Android.

Evidence

MP4s are real-time simctl recordVideo captures. GIFs are 8 fps derivatives, sped up as labelled. The long-press was sent as a pointer hold in the Simulator window, and the menu's Rename item was activated with an accessibility press. Thread data is synthetic.

Rename thread: normal flow (iOS 26.5 Simulator)

The simulator did not reproduce the overflow reported from iOS 26 Nightly on a device. On a fresh presentation, base renders Alert.prompt with the field inside the alert on both iOS 26.5 and iOS 27.0. On iOS 27.0 that also held at XXXL text size. These GIFs show the same flow on base and candidate: long-press, Rename, edit, confirm, title updated in the list. Candidate selects the current title on focus, so the full new title is typed instead of appended.

Before (base fe414eb): native Alert.prompt. No overflow on this simulator.

Before, base fe414eb, iOS 26.5 Simulator: long-press thread, Rename opens the native alert prompt, append " fix", Rename updates the list title

After (candidate 8253ac3): the in-app prompt opens from the long-press context menu after the menu dismisses, and the confirmed title shows in the list.

After, candidate 8253ac3, iOS 26.5 Simulator: long-press thread, Rename opens the in-app prompt, type the new title, Rename updates the list title

Before recording · After recording

Rename thread: field overflows after a relayout (iOS 27.0 Simulator)

The same overflow shows on the simulator when the alert lays out again while it's open. In this run the Dynamic Type size changes to XXXL and back with the prompt open (simctl ui content_size). This trigger is different from the reported one; the reported one didn't reproduce here.

Before (base fe414eb): after the size change, the UIAlertController text field shifts right and runs past the alert's trailing edge. It stays that way while typing and confirming.

Before, base fe414eb, iOS 27.0 Simulator: after a text size change the alert text field overflows the trailing edge

After (candidate 8253ac3): the same size change re-lays the in-app dialog, with stacked buttons at XXXL, and the field stays inside the card.

After, candidate 8253ac3, iOS 27.0 Simulator: the same text size change keeps the field inside the dialog

Field after the size change, full resolution:

Before detail: base alert text field extends past the right edge of the alert

After detail: candidate dialog text field sits inside the card with equal margins

Before recording · After recording

Link pull request over the Git sheet (candidate, iOS 26.5 Simulator)

From thread → Git → More, tapping Link pull request presents the prompt on top of the native form sheet. Typing 42 works, and Cancel returns to the sheet. Nothing was linked.

Candidate 8253ac3: Link pull request prompt presents over the Git sheet, accepts input, Cancel returns to the sheet

Recording

Written with Claude Opus 5.5 in Claude Code (T3 Code harness).

🤖 Generated with Claude Code

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Oct 21, 2026
saphid and others added 2 commits October 21, 2026 00:06
On iOS 26, UIAlertController lays out its text field past the alert's
trailing edge, so Alert.prompt-based prompts (Rename thread, Link pull
request) render a misaligned input. Present iOS prompts in-app through
Dialog.Host instead, keeping native alerts and confirms.

A React Native Modal presents from its nearest view controller, which
cannot present over a native form sheet, so the PR and git sheets mount
their own Dialog.SheetHost; the most recently mounted host presents.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Move the iOS prompt UI into DialogHost so modules that only call Dialog
alerts don't pull GlassSurface and native modules into their tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@saphid
saphid force-pushed the fix/mobile-rename-dialog-input-overflow branch from f5fdb9a to 8253ac3 Compare October 21, 2026 00:07

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100-499 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant