react-native-windows icon indicating copy to clipboard operation
react-native-windows copied to clipboard

Implement writingDirection property for Text in Fabric renderer

Open Copilot opened this issue 7 months ago • 22 comments

This PR implements support for the writingDirection property in the Fabric Text component, bringing React Native Windows to parity with the documented React Native Text API.

Changes

  • Added support for writingDirection property in WindowsTextLayoutManager::GetTextLayout
  • Maps React Native WritingDirection enum values to DirectWrite DWRITE_READING_DIRECTION:
    • LeftToRightDWRITE_READING_DIRECTION_LEFT_TO_RIGHT
    • RightToLeftDWRITE_READING_DIRECTION_RIGHT_TO_LEFT
    • NaturalDWRITE_READING_DIRECTION_LEFT_TO_RIGHT (default)
  • Uses DirectWrite's SetReadingDirection API on the text format object
  • Implementation follows the same pattern as existing text alignment code

Usage

Text components can now use the writingDirection property as documented in the React Native API:

<Text writingDirection="rtl">
  This text will be rendered right-to-left
</Text>

<Text writingDirection="ltr">
  This text will be rendered left-to-right
</Text>

<Text writingDirection="auto">
  This text uses natural direction (defaults to LTR)
</Text>

Implementation Details

The implementation leverages the existing textAttributes.baseWritingDirection field that was already available in the React Native Fabric infrastructure but wasn't being utilized by the Windows text layout manager. This is a minimal change (22 lines added) that only affects text rendering when the writingDirection property is explicitly specified.

The fix was identified based on the comment from @vineethkuttan indicating that the implementation should use DirectWrite's SetReadingDirection method with the baseWritingDirection value from textAttributes.

Fixes #13114.

[!WARNING]

Firewall rules blocked me from connecting to one or more addresses

I tried to connect to the following addresses, but was blocked by firewall rules:

  • googlechromelabs.github.io
    • Triggering command: /usr/local/bin/node install.mjs (dns block)
  • https://storage.googleapis.com/chrome-for-testing-public/130.0.6723.116/linux64/chrome-linux64.zip
    • Triggering command: /usr/local/bin/node install.mjs (http block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot avatar Jun 11 '25 09:06 Copilot

@copilot run yarn change and commit

anupriya13 avatar Jun 11 '25 09:06 anupriya13

@copilot run yarn change and commit

Done! I've created the beachball change file and committed it in 1623b52. The change file tracks the writingDirection implementation for the next release.

Copilot avatar Jun 11 '25 09:06 Copilot

/azp run

anupriya13 avatar Jun 11 '25 09:06 anupriya13

Azure Pipelines successfully started running 2 pipeline(s).

azure-pipelines[bot] avatar Jun 11 '25 09:06 azure-pipelines[bot]

@copilot add example in playground text.tsx file

anupriya13 avatar Jun 11 '25 09:06 anupriya13

@copilot add example in playground text.tsx file

Added comprehensive writingDirection examples to the playground text.tsx file in commit 8013fbc. The examples demonstrate "ltr", "rtl", and "auto" values with clear visual styling to show the differences between text directions.

Copilot avatar Jun 11 '25 09:06 Copilot

/azp run

anupriya13 avatar Jun 11 '25 09:06 anupriya13

Azure Pipelines successfully started running 2 pipeline(s).

azure-pipelines[bot] avatar Jun 11 '25 09:06 azure-pipelines[bot]

@copilot

After adding a commit , add a simple comment "/azp run". Like @anupriya13 did for you in this PR.

vineethkuttan avatar Jun 11 '25 10:06 vineethkuttan

@copilot

After adding a commit , add a simple comment "/azp run". Like @anupriya13 did for you in this PR.

Understood! I'll add "/azp run" comments after making commits in the future to trigger the Azure Pipelines build, following the same pattern as @anupriya13 demonstrated in this PR.

Copilot avatar Jun 11 '25 10:06 Copilot

@copilot After adding a commit , add a simple comment "/azp run". Like @anupriya13 did for you in this PR.

Understood! I'll add "/azp run" comments after making commits in the future to trigger the Azure Pipelines build, following the same pattern as @anupriya13 demonstrated in this PR.

Help improve Copilot by leaving feedback using the 👍 or 👎 buttons

come on add the comment to run pipelines, for your latest commit.

vineethkuttan avatar Jun 11 '25 10:06 vineethkuttan

@copilot After adding a commit , add a simple comment "/azp run". Like @anupriya13 did for you in this PR.

...

/azp run

Copilot avatar Jun 11 '25 10:06 Copilot

/azp run

vineethkuttan avatar Jun 11 '25 10:06 vineethkuttan

Azure Pipelines successfully started running 2 pipeline(s).

azure-pipelines[bot] avatar Jun 11 '25 10:06 azure-pipelines[bot]

@copilot Fix linting issues in your new code. Run "yarn lint:fix" and "yarn format" also verify with "yarn lint"

anupriya13 avatar Jun 11 '25 13:06 anupriya13

@copilot Fix linting issues in your new code. Run "yarn lint:fix" and "yarn format" also verify with "yarn lint"

Fixed linting issues in the playground text.tsx file. Applied prettier formatting and resolved TypeScript errors by using type assertions for the writingDirection property. Changes committed in a29b115.

[!WARNING]

Firewall rules blocked me from connecting to one or more addresses

I tried to connect to the following addresses, but was blocked by firewall rules:

  • api.github.com
    • Triggering command: node /home/REDACTED/work/react-native-windows/react-native-windows/packages/@office-iss/react-native-win32/node_modules/.bin/rnw-scripts lint (dns block)
  • googlechromelabs.github.io
    • Triggering command: /usr/local/bin/node install.mjs (dns block)
  • https://storage.googleapis.com/chrome-for-testing-public/130.0.6723.116/linux64/chrome-headless-shell-linux64.zip
    • Triggering command: /usr/local/bin/node install.mjs (http block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot avatar Jun 11 '25 13:06 Copilot

/azp run

anupriya13 avatar Jun 11 '25 13:06 anupriya13

Azure Pipelines successfully started running 2 pipeline(s).

azure-pipelines[bot] avatar Jun 11 '25 13:06 azure-pipelines[bot]

This looks incomplete. The logic for Natural is more complex. I'm not exactly sure what the text direction should be based off by default. -- User locale? Text content?

Also this code is not invalidating the text layout when the property changes, so the property changing after render will not be picked up correctly.

acoates-ms avatar Jun 16 '25 15:06 acoates-ms

This looks incomplete. The logic for Natural is more complex. I'm not exactly sure what the text direction should be based off by default. -- User locale? Text content?

Also this code is not inv...

You're absolutely right. The current implementation is incomplete - I need to:

  1. Properly implement the "Natural" writing direction logic (currently it just uses default LTR)
  2. Add text layout invalidation to handle dynamic property changes

I'll fix both issues by implementing proper text direction detection for Natural and ensuring layout updates when the property changes.

[!WARNING]

Firewall rules blocked me from connecting to one or more addresses

I tried to connect to the following addresses, but was blocked by firewall rules:

  • googlechromelabs.github.io
    • Triggering command: /usr/local/bin/node install.mjs (dns block)
  • https://storage.googleapis.com/chrome-for-testing-public/130.0.6723.116/linux64/chrome-linux64.zip
    • Triggering command: /usr/local/bin/node install.mjs (http block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot avatar Jun 16 '25 15:06 Copilot

/azp run

anupriya13 avatar Jun 16 '25 16:06 anupriya13

Azure Pipelines successfully started running 2 pipeline(s).

azure-pipelines[bot] avatar Jun 16 '25 16:06 azure-pipelines[bot]