Skip to content

fix(mobile): Android composer renders DM Sans - #30230

Merged
juliusmarminge merged 4 commits into
mainfrom
fix/issue-30199
Nov 7, 2026
Merged

juliusmarminge merged 4 commits into
mainfrom
fix/issue-30199

Conversation

@juliusmarminge

@juliusmarminge juliusmarminge commented Nov 3, 2026 •

Copy link
Copy Markdown
Member

Problem

On Android, the composer (the "Ask anything" hint, typed text, and inline file/mention chips) rendered in Roboto while the chat body and the iOS composer render DM Sans. Reported in #30199.

Change

  • The Android composer's setFontFamily mapped every non-mono name to Typeface.DEFAULT, ignoring the DMSans-Regular the JS sends (iOS already honours it). It now resolves the name with ReactFontManager, the same lookup React Native and @expo/ui use. The module declares react-android for that import. The composer then recomputes its line spacing, because that spacing depends on the current font's metrics and props can arrive in any order.
  • The composer's inline context chips hardcoded sans-serif-medium. They now use DMSans-Medium, the weight the iOS chips use, through the same lookup. A build without the bundled font keeps sans-serif-medium.

The Android header is intentionally unchanged: native chrome stays on the system font on both platforms (the iOS header is SF). Configurable fonts are a separate, later change.

The Kotlin change alters the Android native fingerprint, so this reaches users with the next native build. iOS is unchanged (same native fingerprint on main and this branch).

Verification

  • vp run check:changed passes.
  • Android dev client built from this branch and run on a Pixel 9 emulator (API 36), same isolated backend and seeded thread on both sides; text and the AGENTS.md chip entered the same way. Crops are 1:1 from 1080×2424 captures.
Before (main) After
Composer before: typed text in Roboto, AGENTS.md chip in Roboto Medium Composer after: typed text in DM Sans, AGENTS.md chip in DM Sans Medium
  • A three-line draft is about 2.3 dp taller with the same line pitch, because DM Sans's line box is taller than Roboto's (1.302 em vs 1.172 em). The empty composer height is unchanged.

Not checked: large system text sizes, Android versions other than API 36, and the no-bundled-font fallback for chips on a device.

Written by Claude Opus 5.5 (Claude Code), with GPT-6.1 Sol (Codex) for review and captures, through T3 Code.

🤖 Generated with Claude Code

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:S 10-29 changed lines (additions + deletions). 📱 Native Change Changes the native fingerprint; merging blocks production OTAs until a new store build ships. labels Nov 3, 2026
@macroscopeapp

macroscopeapp Bot commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs Human Approval

Macroscope's review found this PR requires human approval — The Android composer now resolves configured fonts through ReactFontManager, and context chips automatically use bundled DM Sans. A human must confirm the default chip typography change, including its effect on text layout.

Notes:

  • No code objects were reviewed. Approvability was decided on eligibility alone.

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

@juliusmarminge juliusmarminge added bugfix Fix PR opened by an issue lead; enters the PR loop pr:gate-failed A land gate failed labels Nov 3, 2026
@coderabbitai

coderabbitai Bot commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

Explain Change →

No actionable comments were generated in the recent review.

Walkthrough

The Android composer resolves non-monospace font families through React Native’s font manager. The context chip uses DM Sans Medium when registered. The Android screen header applies the regular font family to its title and subtitle.

Changes: Android font rendering

Layer / File(s) Summary
Composer font resolution
apps/mobile/modules/t3-composer-editor/android/build.gradle, apps/mobile/modules/t3-composer-editor/android/src/main/java/expo/modules/t3composereditor/T3ComposerEditorView.kt, apps/mobile/modules/t3-composer-editor/android/src/main/java/expo/modules/t3composereditor/T3ContextChip.kt
The editor module adds the React Native Android dependency. The composer resolves non-monospace fonts through ReactFontManager and reapplies line height after setting the typeface. The context chip uses DMSans-Medium when registered and falls back to sans-serif-medium.
Header font family
apps/mobile/src/components/ui/AndroidScreenHeader.tsx
The header title and subtitle typography now use the regular font family.

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

Change: Bug fix · Severity of issue fixed: Low

Possibly related PRs

  • pingdotgg/t3code#21987: Updates Android composer font resolution through ReactFontManager and passes the selected composer font to the native editor.
  • pingdotgg/t3code#24925: Updates the font size and line height passed to the native composer.

Suggested reviewers: maria-rcks, shivamhwp

Merge Risk: Minimal · up to 6227a

The header and composer use the app’s font families; no merge-blocking issue was identified.

Pre-merge checks: Passed 3 · Inconclusive 1

Failed Failed checks: 1 inconclusive

Check name Status Explanation Resolution
Description check Inconclusive The description covers the required template sections. Problem states the Android composer renders Roboto while the iOS composer renders DM Sans, and it links the report. Change explains the setFontFa… Add a Scope and approval section. Link the triaged bug issue #30199 and state whether a maintainer approved the direction. If no maintainer approval exists, explain why this fix qualifies as a very small, focused fix of an obvious bug. The …
Passed Passed checks: 3 passed

Check name Status Explanation
Linked Issues check Passed [#30199] The Android header applies FONT_FAMILIES.regular to the title and subtitle. The composer resolves non-monospace fonts through ReactFontManager and reapplies line height. These changes add…
Out of Scope Changes check Passed [#30199] The header, composer font lookup, line-height update, and react-android dependency support the font fix. T3ContextChip.kt also applies DM Sans to composer chip text, with a platform-font …
Title check Passed The title names the main change: the Android composer now renders DM Sans. It uses the conventional commit form and matches the linked issue and the description. It also fits the changeset, which reso…
Full details: Linked Issues check

Explanation

[#30199] The Android header applies FONT_FAMILIES.regular to the title and subtitle. The composer resolves non-monospace fonts through ReactFontManager and reapplies line height. These changes address the reported DM Sans mismatch. The issue specifies no automated test requirement. The PR reports a passing related test file and Android visual checks.

Full details: Out of Scope Changes check

Explanation

[#30199] The header, composer font lookup, line-height update, and react-android dependency support the font fix. T3ContextChip.kt also applies DM Sans to composer chip text, with a platform-font fallback. This supports consistent composer typography. The incremental diff was unavailable, so the scope assessment uses the whole-PR summary and the reviewed chip file.

Full details: Title check

Explanation

The title names the main change: the Android composer now renders DM Sans. It uses the conventional commit form and matches the linked issue and the description. It also fits the changeset, which resolves composer fonts through ReactFontManager and switches chips to DMSans-Medium. The title omits the header change that the objectives mention, but the title does not need every detail.

Full details: Description check

Explanation

The description covers the required template sections. Problem states the Android composer renders Roboto while the iOS composer renders DM Sans, and it links the report. Change explains the setFontFamily fix, the ReactFontManager lookup, the react-android dependency, the line-spacing recompute, and the chip font change. Verification lists a passing check command, emulator before/after captures, and unchecked areas. Scope and approval is missing. The template asks for a linked triaged issue or maintainer approval, or an explanation of why a small obvious fix needs no prior issue. The description links issue #30199 only in the Problem section and does not state that the issue was triaged or that a maintainer approved the direction. It also does not explain why the change qualifies without prior approval. The template also asks for a model and harness line, and the description has one. The before/after images are embedded as links to external hosting, which the template accepts.

Resolution

Add a Scope and approval section. Link the triaged bug issue #30199 and state whether a maintainer approved the direction. If no maintainer approval exists, explain why this fix qualifies as a very small, focused fix of an obvious bug. The rest of the description meets the template, so no other changes are required.

Finishing Touches

Generate docstrings

  • Commit to this branch
  • Create a new PR
Generate unit tests (beta)

  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Recent review info

Run configuration

Commits

Reviewing files that changed from the base of the PR and between 4dae28a and 6227a9d.

Files selected for processing: 2

  • apps/mobile/modules/t3-composer-editor/android/src/main/java/expo/modules/t3composereditor/T3ComposerEditorView.kt
  • apps/mobile/modules/t3-composer-editor/android/src/main/java/expo/modules/t3composereditor/T3ContextChip.kt

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

juliusmarminge and others added 3 commits November 6, 2026 15:32
The Android screen header's Compose title and subtitle had no font family,
and the native composer mapped every non-mono family to Typeface.DEFAULT,
so both rendered in Roboto while chat text used DM Sans.

Pass DMSans-Regular to the header's Compose Text, and resolve the composer's
family through React Native's ReactFontManager, which holds the fonts
expo-font registers. The placeholder follows the editor's typeface.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Nov 6, 2026
Native chrome uses the system font on both platforms (the iOS header is SF),
so this PR only fixes the Android composer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@macroscopeapp
macroscopeapp Bot dismissed their stale review November 7, 2026 02:49

Dismissing prior approval to re-evaluate 7d68b93

@juliusmarminge juliusmarminge changed the title fix(mobile): Android header and composer render DM Sans fix(mobile): Android composer renders DM Sans Nov 7, 2026
@juliusmarminge
juliusmarminge merged commit 23bdb9e into main Nov 7, 2026
31 of 32 checks passed
@juliusmarminge
juliusmarminge deleted the fix/issue-30199 branch November 7, 2026 02:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix Fix PR opened by an issue lead; enters the PR loop 📱 Native Change Changes the native fingerprint; merging blocks production OTAs until a new store build ships. pr:gate-failed A land gate failed size:S 10-29 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