Skip to content
This repository has been archived by the owner on Mar 4, 2020. It is now read-only.

feat(Text): introduce dir attribute to support RTL #5

Merged
merged 8 commits into from
Nov 23, 2018

Conversation

kuzhelov
Copy link
Contributor

This proposal is aimed on introducing proper text rendering in RTL mode. Its idea consists of two points:

  • introduce dir="auto" attribute value to the text rendered by Text component
  • from now on ensure that all components that are about rendering text information as part of their presentation should use Text component to wrap this textual part

@levithomason
Copy link
Member

As another option, could we just make dir=auto a default prop for all components? From a usability perspective, it would be ideal if we didn't require every string to use the Text component.

@brianespinosa
Copy link
Collaborator

As another option, could we just make dir=auto a default prop for all components? From a usability perspective, it would be ideal if we didn't require every string to use the Text component.

Yes. And lots of additional markup just to have RTL support in other components.

If we add dir prop to all components, it might also make sense to later make some sort of RTLProvider component that uses the context API where we can define the dir in the provider and all components will now have access to it.

@levithomason
Copy link
Member

If we add dir prop to all components, it might also make sense to later make some sort of RTLProvider component that uses the context API where we can define the dir in the provider and all components will now have access to it.

Indeed, we actually have an rtl prop right now in the Provider itself. It determines whether the regular CSS in JS renderer is used or the RTL CSS in JS renderer.

@kuzhelov
Copy link
Contributor Author

using Text (and, what is more important, dir="auto") is important for mainly components that contain text information - especially in those cases where this text is bidirectional (bidi). It won't be enough just to setup RTL Fela renderer for these cases.

@jurokapsiar
Copy link
Contributor

Levi, do I understand correctly that after you proposed change, the dir='auto' would appear on each DOM rendered by the UIComponent? I don't think we want that. Sites typically use dir='rtl' on the <html> or <body> element to provide the default direction of the page. This will cause all elements to flip from left to right (typical example is a left-side pane becoming right-side, switching order of ok/cancel buttons and so on). On the elements that contain text we actually want to use dir='auto' which will then tell the browser to detect the direction based on the text itself.

@levithomason
Copy link
Member

Can we define what "elements that contain text" means exactly?

Just Text

<span>Text only</span>

This element has text only, no child elements.

Text > empty inline child

<span>Text only with <i class="an icon"></i></span>

This element has text, but also has a i element which is common for icons.

Text > inline child > text

<span>Text only with <span>more text</span>.

This element has text, but also has a child element which contains only text.

Text > button child > text

<span>Text only with <button>technically text?</button>.

Are buttons also considered to be text?


Nearly every component contains text as some descendant. Where exactly should we be adding the dir attribute for proper accessibility in the tree?

@jurokapsiar
Copy link
Contributor

typically if it is a combination of text+icon, the dir='rtl/ltr' on body takes care of properly setting the order of these two. dir='auto'`` should be used for text nodes:

If you don't know the direction of the phrase
When text will be added at run time to your HTML page you may not be able to predict the base direction of the injected text in advance. To handle this eventuality you have two options.

If the phrase is tightly wrapped by an element already, you could just add dir="auto" to that element. This directionally isolates the element's text and looks at the first strong character to determine what base direction to apply.

Otherwise, wrap the phrase in a bdi element (or in a span element with dir set to auto, if you prefer.) Without a dir attribute, the bdi element behaves as if dir="auto" had been applied.

https://www.w3.org/International/articles/inline-bidi-markup/

Text inside of the button might need dir='auto' for example in cases where you have team names as button texts. In that case the direction of the text itself need to be different depending on the content language.

Text inside of the button can be bidirectional, for example "Join team " where Join team would be translated to Hebrew/Arabic but the team name would be english. We are however not solving this case in this PR - most typically these texts come from parametrized translations, so that would be an advanced use case for our i18n story.

@levithomason
Copy link
Member

The concern I have had with this PR is that it seems to conflate the styling purpose of the Text component with the RTL concerns. The Text component is about styling text. RTL to me seems to encompass more than just text and therefore perhaps its own mechanism or component.

Text inside of the button might need dir='auto' for example in cases where you have team names as button texts. In that case the direction of the text itself need to be different depending on the content language.

Would the markup then look like this?:

<button dir='auto'>
  Join Team
</button>

If we introduce the changes proposed in the PR, we'd end up with this:

<button>
  <span dir='auto'>Join Team</span>
</button>

@jurokapsiar
Copy link
Contributor

jurokapsiar commented Aug 2, 2018

From RTL point of view both examples are equal. However, the second one renders one more element which is unnecessary. Is there a generic way to achieve 2? And for that case, please note that we will also need to support

<button><span dir='auto'>Join</span><span dir='auto'>{team name in arabic/hebrew}</span><button>

@kuzhelov kuzhelov added the needs author feedback Author's opinion is asked label Aug 22, 2018
@levithomason levithomason added this to kuzhelov in Core Team Nov 16, 2018
@levithomason
Copy link
Member

@jurokapsiar can you please post the final update here on this PR so we can implement it? Thanks...

@jurokapsiar
Copy link
Contributor

In general, we need to get to a state where the text nodes are inside of elements that have dir='auto' attribute. This allows the browser to detect the text direction.

If the text is composed of multiple parts (typically a translation with parameters), each of the parts needs to be separated in <span dir='auto'> element. This is however out of scope for Stardust and should be handled in the i18n layer of the application.

Requirements:

  • use Text component to render any text inside of standard Stardust components
  • Text component renders <span dir='auto>{content}</span> if the type of content is a string
  • if user provides HTML/React nodes as an input for the component content, the user is responsible for adding dir='auto' by himself. This needs to be documented
  • revisit applying of truncateStyle in buttonStyles.ts - it needs to be applied even if the content contains <span> or other elements

@codecov
Copy link

codecov bot commented Nov 21, 2018

Codecov Report

Merging #5 into master will increase coverage by 0.01%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master       #5      +/-   ##
==========================================
+ Coverage    88.3%   88.32%   +0.01%     
==========================================
  Files          42       42              
  Lines        1454     1456       +2     
  Branches      186      212      +26     
==========================================
+ Hits         1284     1286       +2     
  Misses        165      165              
  Partials        5        5
Impacted Files Coverage Δ
src/components/Text/Text.tsx 100% <100%> (ø) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 14ea899...6cf6ac2. Read the comment docs.

@kuzhelov kuzhelov added 🚀 ready for review and removed needs author feedback Author's opinion is asked labels Nov 23, 2018
@kuzhelov
Copy link
Contributor Author

kuzhelov commented Nov 23, 2018

button styles are left for the separate PR as this is the issue not directly related to this PR. Also, we need the following PR to be merged first to ensure that styles will be applied to children Text: #496

Dedicated issue for Button styles is created: #520 .


const hasChidlren = childrenExist(children)

const maybeDirAuto = !hasChidlren && typeof content === 'string' ? { dir: 'auto' } : null
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hasChidlren -> hasChildren

@kuzhelov kuzhelov changed the title [RFC] feat(Text): introduce dir attribute to support RTL feat(Text): introduce dir attribute to support RTL Nov 23, 2018
@kuzhelov kuzhelov merged commit f190e0b into master Nov 23, 2018
@kuzhelov kuzhelov deleted the rfc/text-rtl-support branch November 23, 2018 13:32
@jurokapsiar jurokapsiar mentioned this pull request Dec 11, 2018
3 tasks
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
No open projects
Core Team
  
kuzhelov
Development

Successfully merging this pull request may close these issues.

None yet

8 participants