question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Issue with bullet RTL

See original GitHub issue

I first off want to say, great package! I ran in to a bit of a problem and I am not sure how to resolve it.

I have an RTL layout with an RTL language. As React-Native auto aligns RTL languages to the right, my parsed HTML is aligned to the right. But the bullets seems to stay on the left. I have tried alignText: 'right' on the baseFontStyle with no luck.

Here is the screenshot of what I am getting.

https://ibb.co/NZyCkjM

Thanks

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:6
  • Comments:7

github_iconTop GitHub Comments

4reactions
jsamrcommented, Apr 17, 2021

🚀 Experimental support for ol and ul RTL mode has been shipped in the last foundry pre-release (6.0.0-alpha.23)
See #430 for install instructions.

import React from 'react';
import { ScrollView } from 'react-native';
import RenderHTML from 'react-native-render-html';

const html = `
<ul dir="rtl">
  <li>يقوم اتحاد شبكة الويب العالمية (W3C) 
  بتطوير معايير دولية للويب و HTML و
  CSS وغير ذلك الكثير.</li>
  <li>يقوم اتحاد شبكة الويب العالمية (W3C) 
  بتطوير معايير دولية للويب و HTML و
  CSS وغير ذلك الكثير.</li>
  <li>يقوم اتحاد شبكة الويب العالمية (W3C) 
  بتطوير معايير دولية للويب و HTML و
  CSS وغير ذلك الكثير.</li>
  <li>يقوم اتحاد شبكة الويب العالمية (W3C) 
  بتطوير معايير دولية للويب و HTML و
  CSS وغير ذلك الكثير.</li>
</ul>
`;

const renderersProps = {
  // Experimental RTL support is only available for list elements.
  ol: { enableExperimentalRtl: true },
  ul: { enableExperimentalRtl: true }
};

const tagsStyles = {
  // We need to reverse default styles for RTL
  ul: { paddingLeft: 0, paddingRight: 30 },
  ol: { paddingLeft: 0, paddingRight: 30 }
};

export default function App() {
  return (
    <ScrollView style={{ flexGrow: 1 }}>
      <RenderHTML
        source={{ html }}
        tagsStyles={tagsStyles}
        renderersProps={renderersProps}
      />
    </ScrollView>
  );
}

Remarks:

  • Notice the required dir="rtl" attribute. CSS rule “direction: rtl” will also work.
  • Default UA styles set padding left for ol and ul.
SHOW RESULT

Screenshot_1618695613

Now, just to show you the new capabilities of this version, let’s implement arabic-indic support:

import React from 'react';
import { ScrollView } from 'react-native';
import RenderHTML from 'react-native-render-html';
import arabicIndic from '@jsamr/counter-style/presets/arabicIndic';

const html = `
<ol dir="rtl" style="list-style-type: arabic-indic;">
  <li>يقوم اتحاد شبكة الويب العالمية (W3C) 
  بتطوير معايير دولية للويب و HTML و
  CSS وغير ذلك الكثير.</li>
  <li>يقوم اتحاد شبكة الويب العالمية (W3C) 
  بتطوير معايير دولية للويب و HTML و
  CSS وغير ذلك الكثير.</li>
  <li>يقوم اتحاد شبكة الويب العالمية (W3C) 
  بتطوير معايير دولية للويب و HTML و
  CSS وغير ذلك الكثير.</li>
  <li>يقوم اتحاد شبكة الويب العالمية (W3C) 
  بتطوير معايير دولية للويب و HTML و
  CSS وغير ذلك الكثير.</li>
</ol>
`;

const renderersProps = {
  // Experimental RTL support is only available for list elements.
  ol: { enableExperimentalRtl: true },
  ul: { enableExperimentalRtl: true }
};

const tagsStyles = {
  // We need to reverse default styles for RTL
  ul: { paddingLeft: 0, paddingRight: 30 },
  ol: { paddingLeft: 0, paddingRight: 30 }
};

const customListStyleSpecs = {
  'arabic-indic': {
    type: 'textual',
    counterStyleRenderer: arabicIndic
  }
};

export default function App() {
  return (
    <ScrollView style={{ flexGrow: 1 }}>
      <RenderHTML
        source={{ html }}
        tagsStyles={tagsStyles}
        renderersProps={renderersProps}
        customListStyleSpecs={customListStyleSpecs}
      />
    </ScrollView>
  );
}
SHOW RESULT

Screenshot_1618696285

Check @jsamr/counter-style library for more presets and guides to implement arbitrary counter styles

4reactions
jsamrcommented, Apr 13, 2021

I’ve been exploring this issue a little bit for the foundry release (see #430), below are my findings.

I. RTL in the Web

The Web standards offer basically two ways to handle RTL typography.

  1. The HTML element dir attribute, with values ltr, rtl and auto (determined by text content).
  2. The inheritable CSS property direction, with values ltr and rtl. When both dir attribute and direction property are defined, the CSS property takes precedence.

When direction is set to rtl, the order of elements is the horizontal axis are reversed under those conditions:

  • In a flex formatting context, the container providing this context has a flexDirection set to row;
  • In an inline formatting context, elements are text nodes or have an outer display type set to inline-block.
  • Elements are children of an element which has an inner display type set to table-row.

In CSS, the box model of an element can be direction and writing-mode dependent thanks to the below shorthand properties and their longhand equivalents:

  • margin-inline,
  • padding-inline
  • border-inline
  • border-start-*-radius
  • border-end-*-radius
  • overflow-inline

The set of all these properties is referred to as CSS logical properties.

Back to lists now… This is how the style of UL elements is defined in Firefox stylesheet:

ul,
menu,
dir {
  display: block;
  list-style-type: disc;
  margin-block-start: 1em;
  margin-block-end: 1em;
  padding-inline-start: 40px;
}

Notice the padding-inline-start which guarantees that the marker (disc) will have a direction-dependent padding.

II. RTL in React Native

Unfortunately, RTL support in React Native is yet limited. As of React Native 0.64.0, I know three features:

  1. I18nManager.isRTL and I18nManager.forceRTL(/*bool*/). This export is not documented! I visited the source code and I found no comments. I found out about this feature in this article. Using forceRTL requires you to restart the application for the change to take effect. When active, it reverses the order of elements in a container with flexDirection: "row" set. Other implications of this setting must be investigated. If you had an opportunity to test, please post your findings below. Especially, are left and right style props reversed? Such as paddingLeft, marginLeft, borderTopLeftRadius … etc. Actually, I found out that the Yoga engine is RTL friendly (it only has start / end for horizontal directional rules), and React Native maps left → start and right → end, which is very confusing and prevent us from having “true left / right” directions support. See Right-to-Left Layout Support For React Native Apps.
  2. Layout direction style. Promising, but only works on iOS. On Android, the direction of text is automatically detected depending on content. This is equivalent to HTML elements dir attribute set to auto.
  3. Partial support for logical properties (on the inline axis, there is no support for vertical writing modes): Layout start, end, borderStart, borderEnd, marginStart, marginEnd, paddingStart, paddingEnd properties, which only applies to iOS when direction is set to 'rtl'. This is so confusing because as seen in 1., left and right directional rules are mapped to start / end in Yoga…

III. Foreseeable solutions

Short term: configurable lists layout

A new prop would force lists layouts to display RTL. When this prop is set to true, list item renderers will use flexDirection: "row-reversed" when I18nManager.isRTL value is false, and flexDirection: "row" otherwise. Left margins might be replaced with right margins (depending on our findings in II.1).

Long term: featured support in @native-html/css-parser

RTL support will be embedded in the CSS parser. The latter will be in charge of translating both CSS logical properties and react native logical properties to their physical equivalent depending on directional context and the current I18nManager.isRTL state. As seen in II.1, left / right will have to be reversed in RTL (so left will become right and vice-versa) to preserve the CSS semantics. So if one inline style specifies left: 10 and the app is in RTL mode, the rule will be translated to right: 10, which will render as a physical left spacing , that’s quite confusing 😫!

Such support is a substantial endeavor and won’t be available before version 7.0 of this library.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Bullet lists and numbered lists have problems with RTL ...
Description I used the demo editor and the bullet lists and numbered lists are not working properly with RTL languages while the other ......
Read more >
Solved: Bullets RTL - Adobe Support Community - 10251057
Solved: Hi, I'm trying to do a simple task such as paragraph of bullets, with my custom font and bullet point for every...
Read more >
html - Bullet Points Positioning with Arabic RTL direction
However with direction:rtl; I am unable to have all the bullet points on the right side. Some are more indented than others. Please...
Read more >
RTL in bullet points - Mailspring Community
I haven't found an option to create bullet points with RTL content, i.e. when you add bullet points the text remains on the...
Read more >
59889 – numbering/bullet alignment not switched to RTL when LTR ...
Notes: Issue #32203 discusses this problem and claims it was fixed. However the fix only applies when the document is started in RTL...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found