Skip to content

Support inline views in Text with lineHeight - #59420

Open
jasozh wants to merge 2 commits into
react:mainfrom
jasozh:export-D126795867
Open

jasozh wants to merge 2 commits into
react:mainfrom
jasozh:export-D126795867

Conversation

@jasozh

@jasozh jasozh commented Oct 23, 2026

Copy link
Copy Markdown
Contributor

Summary:
Fixes the issue described in #48727, where adding inline views and images into Text when line height is specified results in the image clipping and overflowing the parent container.

Root Cause

On Android, CustomLineHeightSpan uses the line's merged font metrics fm to set the line's ascent/descent so text clamps to lineHeight. However, the calculation assumes fm only describes text whereas in reality, it also includes the height of inline views/images. As a result, taller images are also clamped to lineHeight and overflow.

Additionally, because StaticLayout seeds each line with the previous line's adjusted font metrics when a text run wraps, the lines after the inline view also inherit its height and get misplaced baselines. The result is that wrapped text following an inline image appear unusually squashed.

On iOS, lineHeight sets both minimumLineHeight and maximumLineHeight so TextKit clamps every line to the same height, even for lines with a taller inline view/image.

Additionally, RCTApplyBaselineOffset lifts the text with NSBaselineOffset to center it in the line, but for inline views, this is computed from the unlifted baseline, causing images to sit below the text baseline.

This PR

For Android, modify CustomLineHeightSpan so that if the text includes an inline view, we use TextPaint to re-derive fm via measureTextRun() for every line. This means fm only describes text during the chooseHeight() calculation, and each line is unaffected by wrapping issues. Then, raise the line's ascent/top to fit the inline view.

For iOS, set RCTTextLayoutManager as a NSLayoutManagerDelegate if an inline view exists so the layout manager calls layoutManagerShouldSetLineFragmentRect() which grows the line to match the height of the inline view. Separately, modify the baseline shift so that attachments match the text baseline.

All changes are gated behind the fixTextInlineViewLineHeight flag.

Changelog: [General][Fixed] - Inline views in Text with lineHeight no longer overflow the text

Differential Revision: D126795867

Summary:
Add a new RNTester example in TextInlineView that reproduces the issue where setting a line height for Text breaks expected CSS behavior with inline views and images.

Changelog: [Internal]

Differential Revision: D126542681
Summary:
Fixes the issue described in [react#48727](react#48727), where adding inline views and images into Text when line height is specified results in the image clipping and overflowing the parent container.

### Root Cause

On Android, CustomLineHeightSpan uses the line's merged font metrics `fm` to set the line's ascent/descent so text clamps to `lineHeight`. However, the calculation assumes `fm` only describes text whereas in reality, it also includes the height of inline views/images. As a result, taller images are also clamped to `lineHeight` and overflow.

Additionally, because `StaticLayout` seeds each line with the previous line's adjusted font metrics when a text run wraps, the lines after the inline view also inherit its height and get misplaced baselines. The result is that wrapped text following an inline image appear unusually squashed.

On iOS, `lineHeight` sets both `minimumLineHeight` and `maximumLineHeight` so TextKit clamps every line to the same height, even for lines with a taller inline view/image.

Additionally, `RCTApplyBaselineOffset` lifts the text with `NSBaselineOffset` to center it in the line, but for inline views, this is computed from the unlifted baseline, causing images to sit below the text baseline.

### This PR

For Android, modify CustomLineHeightSpan so that if the text includes an inline view, we use `TextPaint` to re-derive `fm` via `measureTextRun()` for every line. This means `fm` only describes text during the `chooseHeight()` calculation, and each line is unaffected by wrapping issues. Then, raise the line's ascent/top to fit the inline view.

For iOS, set `RCTTextLayoutManager` as a `NSLayoutManagerDelegate` if an inline view exists so the layout manager calls `layoutManagerShouldSetLineFragmentRect()` which grows the line to match the height of the inline view. Separately, modify the baseline shift so that attachments match the text baseline.

All changes are gated behind the `fixTextInlineViewLineHeight` flag.

Changelog: [General][Fixed] - Inline views in Text with lineHeight no longer overflow the text

Differential Revision: D126795867
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Oct 23, 2026
@meta-codesync

meta-codesync Bot commented Oct 23, 2026

Copy link
Copy Markdown

@jasozh has exported this pull request. If you are a Meta employee, you can view the originating Diff in D126795867.

@github-actions

Copy link
Copy Markdown

Visual regression

1 visual difference(s) at 10de712f212b. Visual differences need maintainer approval. Review the report, then apply visual-change-approved.

ios switch/custom-colors/toggled: Changed, 11804 px (0.474%)

diff

Expected and Captured
Expected Captured
expected captured

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

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. meta-exported p: Facebook Partner: Facebook Partner

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant