9

I have some Text element with dynamically loaded text. It's an RTL language (Hebrew) text mixed with some English.

  1. When the first char is English, it automatically sets to LTR direction.
  2. When the first char is Hebrew, it automatically sets to RTL direction.

I'm not happy with that behavoir!

I'd like to set the element to be RTL anyway. Always.

In CSS that would be very simple: text-align: right; direction: rtl;

How can I achieve the same in React Native?

Poni
  • 11,061
  • 25
  • 80
  • 121

5 Answers5

5

When I had this problem (of individual lines of text in RTL language being incorrectly treated as LTR becuase they start with non-transliterated LTR text or numbers), I dealt with it using Unicode direction marker characters.

Here they are (they're the invisible characters between the quotes):

These change the behaviour you're seeing, explicitly saying how the text should be treated rather than letting the system assume.

How you apply these is up to you. I mostly did it with regex find-replace insertions in the source content, but you could do something like this (untested), making a swap-in replacement for useTranslation's t function that wraps the text in the appropriate Unicode control character:

import { I18nManager } from 'react-native'
// assuming you're using i18n hooks
import { useTranslation } from 'react-i18next'

const rtlMarkerChar = '‏'
const ltrMarkerChar = '‎'
const directionChar = I18nManager.isRTL ? rtlMarkerChar : ltrMarkerChar

// Use instead of `useTranslation` to force text right on RTL and left on LTR
// regardless of the initial character of the particular snippet of text
export const useLocaleAlignedText = () => {
  const { t } = useTranslation()
  return (key) => `${directionChar}${t(key)}`
}

// For example, this should be consistently RTL or LTR regardless of content
const SomeComponent = ({ contentKey }) => {
  const t = useLocaleAlignedText()
  return <Text>{t(contentKey)}</Text>
}

Be warned that the above might not work where your content contains newline characters, you might need to inject the control characters at the start of each line. This was one of the reasons I chose to inject the characters into the source material; but be warned also, that's hard work and easy to make mistakes.

user56reinstatemonica8
  • 32,576
  • 21
  • 101
  • 125
3

To handle RTL for Text, Use style alignSelf: 'flex-start'

Example react-native:

<View> 
   <Text style={styles.headersText}>{headerTitle}</Text>  
</View> 

StyleSheet.create({ headersText: {
      alignSelf: 'flex-start', // <- Here Handle RTL for Text
      paddingHorizontal: 16,
      paddingTop: 14,
      color: 'black',
      fontSize: 13,
    },   
});
Ahmed Lotfy
  • 3,806
  • 26
  • 28
1

There is a couple of ways to do the text RTL in react native and it depends on what you prefer and what is your use case:-

Option 1: useing alignSelf: 'flex-start' style property, for example

<Text style={{alignSelf: "flex-start"}}>your text here</Text>

This approach is a text language sensitive and will make the text align and language writing direction depend on the text language itself, i.e. if the text was in English then the text will be LTR as a direction and the whole text will be aligned at the left but if the text is in Arabic it will be RTL as a direction and the whole text will be aligned at the right automatically.

Option 2: As the React Native Text docs you can use these style properties writingDirection: "rtl" for IOS and textAlign: "justify" for Android, for example:

import { I18nManager, Text } from "react-native";
<Text style={{
    writingDirection: I18nManager.isRTL ? "rtl" : "ltr", //OR "auto"
    textAlign: "justify"
   }}>
your text here
</Text>

In this approach using justify for Android it will not be text language sensitive, instead, it will be the app I18nManager.isRTL sensitive and it will align the text depending on it regardless if the text is in Arabic or English just will use the app direction state. it will be only language writing direction sensitive unlike option 1, but for IOS you should write a condition that provides the dynamic value as the example above. so this approach is preferable if you don't want to show a mess of text especially if you have both languages at the same view, i.e. if you have two different descriptions one in English and one in Arabic at the same view but you want to make both texts at the same level of text aligning for the design practices.

Anas
  • 1,000
  • 11
  • 18
0

I did this with :

textAlign:'right'

your Text should have this style.

Mahdi
  • 526
  • 2
  • 5
  • 16
0

This worked for me:


    <Text style={{alignSelf: "flex-start"}}>
        {text}
    </Text>

BTW, if you wanna force RTL for the entire project you could just write something like this and run it in your main App component:

import { I18nManager } from "react-native";

const App = () => {
  . . . . . . . . 
  const rtl = () => {
    if (I18nManager.isRTL === false) {
      I18nManager.allowRTL(true);
      I18nManager.forceRTL(true);
    }
  };
  . . . . . . . . 
}
Itay
  • 398
  • 2
  • 14