Skip to content

Commit d7a608e

Browse files
Fix text wrapping in absolutely positioned elements on Android
Summary: ## Context On Android TV, text inside absolutely-positioned Views wraps unexpectedly when the computed width from Yoga is fractional. This manifests as "Keep watching" breaking to two lines in the exit dialog when the button text is focused (rendered via an absolutely-positioned overlay for color animation). The root cause is a rounding mismatch in React Native's Android TextLayoutManager: `desiredWidth` (the text's needed width) uses `ceil()` (rounds up), but `layoutWidth` in `EXACTLY` and `AT_MOST` modes uses `floor()` (rounds down). When Yoga passes a fractional width (e.g. 258.5px), the container gets `floor(258.5) = 258px` but the text needs `ceil(258.3) = 259px`, causing a 1px shortfall that triggers wrapping. ## Root Cause Using `floor` in `TextLayoutManager.kt` for `EXACTLY` and `AT_MOST` modes causes the width of the text container to be too narrow and line wrap. ## Fix Changes `floor(width).toInt()` to `ceil(width).toInt()` in both `YogaMeasureMode.EXACTLY` and `YogaMeasureMode.AT_MOST` branches of `TextLayoutManager.createLayout()`. This ensures that when Yoga provides a fractional pixel width, the text layout gets enough space rather than being truncated by 1px. ## Notes This was confirmed a problem with an absolutely positioned style with that had `left:0, right:0` applied. Width sizing was confirmed to be the issue when `left:-1, right:-1` resolved the issue. Further investigation found this fix in text sizing. Only the EXACTLY is needed for Airwave, but it's probably best to have proper values for each case. Differential Revision: D102920508
1 parent 7128482 commit d7a608e

1 file changed

Lines changed: 2 additions & 2 deletions

File tree

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -637,8 +637,8 @@ internal object TextLayoutManager {
637637

638638
val layoutWidth =
639639
when (widthYogaMeasureMode) {
640-
YogaMeasureMode.EXACTLY -> floor(width).toInt()
641-
YogaMeasureMode.AT_MOST -> min(desiredWidth, floor(width).toInt())
640+
YogaMeasureMode.EXACTLY -> ceil(width).toInt()
641+
YogaMeasureMode.AT_MOST -> min(desiredWidth, ceil(width).toInt())
642642
else -> desiredWidth
643643
}
644644
return buildLayout(

0 commit comments

Comments
 (0)