Skip to content

refactor(mobile): expose native menus through a shared Menu API - #19265

Merged
juliusmarminge merged 2 commits into
t3/mobile-ds-input-actionsfrom
t3/mobile-ds-menus
Oct 15, 2026
Merged

juliusmarminge merged 2 commits into
t3/mobile-ds-input-actionsfrom
t3/mobile-ds-menus

Conversation

@juliusmarminge

@juliusmarminge juliusmarminge commented Oct 14, 2026 •

Copy link
Copy Markdown
Member

Design-system progress

API adoption and Pen rendering are tracked separately. This is cumulative through this PR, not a claim that all native renderers are finished.

Pen component After this PR
Host / native theme Colors only; native typography and shapes left
List / Section / Row Shared RN rows; native Form / ListItems left
Toggle Native switches; Android checkmark treatment left
Segmented Later in stack
Menu Native API; exact Pen styling unverified
Sheet Later in stack
Dialog Later in stack
SearchField Shared API; native Android search left
Button / IconButton Android native; standalone iOS native rendering left
Chip Shared RN chip; native Android variants left
Toast Later in stack
FAB Later in stack
Toolbar Later in stack
AppBar Later in stack
Picker / Slider / Stepper Partial; iOS native slider and picker family left
Progress / EmptyState Later in stack
Typography / shapes / motion Later in stack
Split / list-detail / rail Deferred broader layout work

Custom Appearance cards stay. Segmented controls stay native. Composer, thread-row and task-tray redesigns remain deferred.

Menus were exposed through ControlPillMenu and often imported from ControlPill, despite accepting arbitrary triggers. Expose Menu and MenuProps directly and migrate all mobile consumers to that module.

Keep the iOS native context menu, Android anchored Compose menu, editor anchoring, nested actions, disabled/destructive states and long-press suppression intact. Media menus inside Android modals retain their native MenuView exception.

Validation: Mobile typecheck passed. Opened native menus and selected the destructive item on iOS 27 and Android 17; both opened the confirmation and cancelled correctly. Targeted lint retains the existing ref-in-event-handler warning in the unchanged long-press implementation.

The internal popup renderer is named MenuPopup with its Android implementation in MenuPopup.android.tsx; app code does not import a Material-prefixed wrapper.

Model: GPT-6.1. Harness: Codex.

Captured from the actual parent branch and the integrated new layers, with Iris dark selected. Search and menu rendering is intentionally preserved. The added Prompt catalog button moves the example menu trigger.

iOS native menu

Before After
Before iOS native menu After iOS native menu

Android anchored menu

Before After
Before Android anchored menu After Android anchored menu

Devin Review

@juliusmarminge
juliusmarminge added this pull request to stack #19267 October 14, 2026 05:58
@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 14, 2026
@juliusmarminge juliusmarminge added the macroscope-review Opt PRs made by unvouched contributors in for Macroscope review. Vouched contributors auto-reviews label Oct 14, 2026
@github-actions

github-actions Bot commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ℹ️ No successful main baseline artifact is available yet. This run establishes the initial measurement.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire — 5.0 KiB — 6.8 KiB ✅
Codex Thread snapshot wire — 3.8 KiB — 4.9 KiB ✅
Codex Live turn WebSocket wire — 1.2 KiB — 2.0 KiB ✅
Codex Live turn WebSocket decoded — 20.9 KiB — 29.3 KiB ✅
Codex Live turn messages — 2 — 8 ✅
Claude Total thread wire — 5.0 KiB — 6.8 KiB ✅
Claude Thread snapshot wire — 3.8 KiB — 4.9 KiB ✅
Claude Live turn WebSocket wire — 1.2 KiB — 2.0 KiB ✅
Claude Live turn WebSocket decoded — 21.2 KiB — 29.3 KiB ✅
Claude Live turn messages — 2 — 8 ✅

Baseline: unavailable · PR result: d8b9b71 · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 108.5 KiB
  • Claude decoded thread snapshot: 108.8 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@juliusmarminge
juliusmarminge marked this pull request as ready for review October 14, 2026 06:07
macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Oct 14, 2026
@macroscopeapp

macroscopeapp Bot commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at dcda47e

Macroscope's review found this PR approvable — This is a repository-wide mobile menu naming and import migration, with the existing iOS, Android, popup, long-press, and modal-specific behavior preserved. The broad file count reflects caller updates rather than new runtime logic or a product-default change.

No code changes detected at d8b9b71. Prior analysis still applies.

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

@coderabbitai

coderabbitai Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Path: .coderabbit.config.ts
  • Review profile: CHILL
  • Plan: Team
  • Run ID: bce77218-f92d-454c-a3ab-362c49221149
📥 Commits

Reviewing files that changed from the base of the PR and between dcda47e and d8b9b71.

📒 Files selected for processing: 3
  • apps/mobile/src/features/pull-requests/PullRequestListFilters.tsx
  • apps/mobile/src/features/pull-requests/PullRequestRouteScreen.tsx
  • apps/mobile/src/features/threads/ThreadQueueControl.tsx

Included review availability: This review used your included allowance. 4 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 10 reviews per hour.

📝 Walkthrough

The mobile app replaces ControlPillMenu and ControlPillMenuProps with Menu and MenuProps. It also renames the Android popup component and props type to MenuPopup and MenuPopupProps. Existing menu actions and callbacks remain in place, including the Android modal path that uses MenuView.

Changes: Mobile Menu Rename

Layer / File(s) Summary
Rename shared menu components and props
apps/mobile/src/components/Menu*, apps/mobile/src/components/Menu.types.ts, apps/mobile/src/components/MediaActionsMenu.tsx, apps/mobile/src/components/ControlPill.tsx, apps/mobile/src/components/ComposerToolbar.tsx, apps/mobile/src/components/CopyTextButton.tsx
The shared menu component and props type are renamed. MediaActionsMenu uses Menu on its default path and retains MenuView for Android modal use. Related comments change, and ControlPill no longer re-exports ControlPillMenu.
Rename the Android menu popup
apps/mobile/src/components/AndroidAnchoredMenu.tsx, apps/mobile/src/components/MenuPopup*
The popup component and props type are renamed to MenuPopup and MenuPopupProps. AndroidAnchoredMenu uses MenuPopup in both popup and inline-overlay branches.
Update shared component call sites
apps/mobile/src/components/ComposerAttachmentButton.tsx, apps/mobile/src/components/ScreenHeader.android.tsx, apps/mobile/src/features/browser/BrowserTabMenu.tsx, apps/mobile/src/features/cloud/T3ConnectProfilePage.tsx, apps/mobile/src/features/development/ComponentCatalogScreen.tsx, apps/mobile/src/features/devices/DevicePreviewRouteScreen.tsx, apps/mobile/src/features/files/AttachmentFileScreen.tsx
These components use Menu instead of ControlPillMenu. Their existing actions, handlers, and triggers remain in place.
Update home and thread menus
apps/mobile/src/features/home/MaterialThreadListToolbar.tsx, apps/mobile/src/features/home/thread-swipe-actions.tsx, apps/mobile/src/features/threads/*
Home and thread menus use Menu. Related callback types use Menu props. Existing actions and handlers remain unchanged.
Update pull-request menus and action types
apps/mobile/src/features/pull-requests/*
Pull-request menus use Menu, and related action types use MenuProps. Existing titles, actions, selection handling, and triggers remain in place.
Update settings, usage, and workspace menus
apps/mobile/src/features/settings/SettingsScheduledTasksRouteScreen.tsx, apps/mobile/src/features/settings/components/SettingsEnvironmentFilterHeader.tsx, apps/mobile/src/features/usage/UsageRouteScreen.tsx, apps/mobile/src/features/workspace/ListFilterMenu.tsx
Settings, usage, and workspace menus use Menu. The workspace action prop now uses MenuProps; existing actions and event handling remain.

Priority: ⬇️ Low

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

Change: Refactor

Suggested reviewers: pixpmusic

Merge Risk: ⚪ Minimal · up to d8b9b

The menu rename preserves the platform-specific implementations and updates consumers to the new API. No actionable merge-blocking risk is evident.

Pre-merge checks: Passed 3 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Description check Warning The description explains the problem, implementation, verification results, preserved behavior, and includes before-and-after UI screenshots. It does not provide the required Scope and approval inform… Add the Scope and approval section. Link the triaged issue or maintainer approval with the approval comment, or explain why this focused refactor qualifies for an exemption.
Passed Passed checks: 3 passed
Check name Status Explanation
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.
Title check Passed The title clearly summarizes the main change: exposing native mobile menus through a shared Menu API.
Full details: Description check

Explanation

The description explains the problem, implementation, verification results, preserved behavior, and includes before-and-after UI screenshots. It does not provide the required Scope and approval information, such as a linked issue, maintainer approval, or a documented exemption.

  • Fix all pre-merge checks with AI
✨ Finishing Touches: 💡 1
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
🛠️ Fix failing CI checks: 💡
  • Commit to this branch
  • 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.

@juliusmarminge
juliusmarminge removed this pull request from stack #19267 October 15, 2026 20:15
@juliusmarminge
juliusmarminge added this pull request to stack #20021 October 15, 2026 20:16
@juliusmarminge
juliusmarminge removed this pull request from stack #20021 October 15, 2026 20:55
@juliusmarminge
juliusmarminge added this pull request to stack #20030 October 15, 2026 20:55
@juliusmarminge
juliusmarminge merged commit d5ae09a into main Oct 15, 2026
36 of 54 checks passed
@juliusmarminge
juliusmarminge deleted the t3/mobile-ds-menus branch October 15, 2026 22:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

macroscope-review Opt PRs made by unvouched contributors in for Macroscope review. Vouched contributors auto-reviews 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