Skip to content

Align text to the left by default in LTR on iOS - #59004

Open
YevheniiKotyrlo wants to merge 1 commit into
react:mainfrom
YevheniiKotyrlo:fix/ios-natural-alignment-ltr
Open

YevheniiKotyrlo wants to merge 1 commit into
react:mainfrom
YevheniiKotyrlo:fix/ios-natural-alignment-ltr

Conversation

@YevheniiKotyrlo

@YevheniiKotyrlo YevheniiKotyrlo commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Summary:

Follow-up to #57634. A <Text> that declares no textAlign now aligns to the right in an RTL layout on iOS, but in an LTR layout its paragraph style still carries NSTextAlignmentNatural, which UIKit resolves against the app's localization rather than the paragraph (NSTextAlignment.natural: "the default alignment associated with the current localization of the app"). So when the app runs in a right-to-left language, text in an LTR subtree, such as a direction: 'ltr' view, is drawn flush right on iOS and flush left on Android.

RCTNSTextAttributesFromTextAttributes now resolves the alignment whenever the paragraph's layout direction is known, not only when it is RTL, so an undeclared alignment follows the start of the layout direction in both directions. RCTIsParagraphStyleEffectivelySame already compares a natural alignment as the start of the layout direction, so the drawn alignment now matches what it assumes. Text inputs are unaffected: their text attributes carry no layout direction, so a UITextField keeps aligning to its own view.

Changelog:

[IOS] [FIXED] - Align text to the left by default in LTR when textAlign is not set, whatever the app's language

Test Plan:

  • RCTAttributedTextUtilsTest: testUndeclaredTextAlignmentResolvesWithLayoutDirection fails on main (an LTR paragraph gets no paragraph style) and passes with the change; testUndeclaredTextAlignmentWithoutLayoutDirectionStaysNatural passes on both. React-RCTFabric's Tests spec passes on an iOS 18.0 simulator, 56 tests with 0 failures, run with :testspecs => ['Tests'] and RCTParagraphComponentViewTests.mm excluded because it does not compile under CocoaPods.
  • RNTester › Text › Text Align with RTL (direction: 'ltr', its initial state) on an iPhone 16 simulator, iOS 18.0, launched with Xcode's right-to-left pseudolanguage (-AppleTextDirection YES -NSForceRightToLeftWritingDirection YES), before and after: the pair. Only the two auto (default) lines move, from flush right to flush left; the left, center, right and justify lines are pixel-identical.
  • node scripts/clang-format.js --check passes.

A paragraph that declares no textAlign gets an explicit alignment on iOS
only when its layout direction is right to left (react#57634). In a left-to-right
layout the paragraph style keeps NSTextAlignmentNatural, which UIKit resolves
against the app's localization rather than the paragraph, so in an app
running in a right-to-left language a left-to-right subtree is drawn flush
right while Android draws it flush left.

Resolve the alignment whenever the paragraph's layout direction is known,
which is what RCTIsParagraphStyleEffectivelySame already assumes when it
compares paragraph styles.
@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 12, 2026
@YevheniiKotyrlo

Copy link
Copy Markdown
Contributor Author

Device evidence — before / after

UNFIXED — under a right-to-left app language, the two auto (default) lines in this direction: 'ltr' box are drawn flush right.

FIXED — they are drawn flush left, the start of their layout direction; the declared left, center, right and justify lines do not move.

before — main at 1c6e0c7738 after — with this PR

iPhone 16 simulator, iOS 18.0, RNTester › Text › Text Align with RTL in its initial LTR state, launched with -AppleTextDirection YES -NSForceRightToLeftWritingDirection YES, one session. Only the rows of the two auto (default) lines differ: the English line's ink spans x 653–1176 before and 2–524 after, the Arabic line's 370–1176 and 2–808, of a 1179-px row.

@YevheniiKotyrlo
YevheniiKotyrlo marked this pull request as ready for review October 12, 2026 05:05
@facebook-github-tools facebook-github-tools Bot added the Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. label Oct 12, 2026

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. Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant