Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add RTL support #2890

Merged
merged 49 commits into from
Feb 14, 2020
Merged

Add RTL support #2890

merged 49 commits into from
Feb 14, 2020

Conversation

corinagum
Copy link
Contributor

@corinagum corinagum commented Feb 7, 2020

Fixes #1976
Fixes #2902

Changelog Entry

  • Resolves #1976. Added RTL support with localization for Hebrew and Arabic, by @corinagum, in PR #2890

Description

Implement the ability to display languages (such as Arabic, Urdu, etc) in Right-to-Left UI.

What is Right to Left, Left to Right, and Bidirectional Support?

  • Right-to-Left (RTL) is the UI implementation of displaying an app differently according to the language (human language, i.e. English or Arabic) of the app. For example, Arabic is a RTL language, and therefore an app in Arabic will ideally mirror* the English version of the UI to fit the directional flow of the language's script.
  • Left-to-Right (LTR) follows the directional flow of languages like English
  • Bidirectional support (or BiDi) allows for both RTL and LTR (Left-to-Right) support within a single app, depending on the language of the content being displayed.

(*) 'Mirror' in this article is not meant literally. In UI rules of BiDi, not every aspect or component will be mirrored, and the rules dictating those decisions will be discussed below.

Why do we want Web Chat to support this?

  • According to the Ethnologue of language studies, there are over 615 million speakers of RTL languages worldwide, which accounts for roughly 8% of the population
  • There have been an increasing number of requests for Web Chat to support RTL or RTL languages. Below are some of those requests AND community-provided pull requests related to RTL languages:
    • #1976 - external participants indicating a desire for this feature
    • #2369 - ar-AR
      • Note: ar-AR is not an official language code, so this one will not be implemented.
    • #1548 he-IL
      • stale implementation of RTL from an active Web Chat user - this will be used and credited as a starting block for our changes
    • #2477 ar-JO
    • #2593 ar-EG

Pros

  • Fits very neatly into Microsoft's mission of enabling the planet to achieve more
  • Implementation time and difficulty appears relatively low
  • We have a number of requests from customers that would like this feature
  • Some of the work has been done already in the RTL PR #2369

Cons

  • Until Adaptive Cards and react-film video and audio have RTL support, Web Chat's RTL experience will not be fully functional
    • However, I believe that Web Chat having RTL support will encourage the Adaptive Cards team to also implement the feature
  • This is not a feature that will benefit 'most users' of Web Chat (80:20 rule)

Web Chat dependencies that need RTL Support:

  1. HTML <video> and <audio> (not currently supported)
  2. YouTube & vimeo embed (not currently supported)
  • Adaptive Cards (UNOFFICIALLY supported)
    • Request
    • Proposal
    • Adaptive Cards team tentatively has RTL support proposed for AC 1.3 (Build 2020), but this is not finalized and may be bumped, as of 10/25/1019
  1. Markdown (supported) - works as expected when dir attribute is set to 'rtl'
  2. React Film (supported)

Steps for implementing bi-directional support

Order of detection for script direction:

  • Allow Web Chat implementer to manually set prop (e.g. dir: auto (default)) to: ltr or rtl in renderWebChat props
  • Detect RTL settings based off of app's language

Implementation steps as they apply to Web Chat

  • Set Web Chat prop indicating app's direction, based off data from "Order of detection for script direction" - this property will affect the entirety of Web Chat
  • Set Web Chat's root container's Basic Transcript and Basic Sendbox dir attribute depending on what was detected in 'Order of detection for script direction'
  • Flip right and left padding/spacing properties as needed
  • Flip / use rtl versions of icons as needed
    a. Icons showing direction need to be flipped
    b. Icons that show 'right hand use' do not need to be flipped
  • Adopt localization from stale PRs listed above
  • Add useDirection documentation to HOOKS.md
  • Update LOCALIZATION.md
  • Test all browsers

Icons/animations that need to be mirrored

  • Airplane (signifying moving forward or proceeding to next part of conversation)
  • Typing indicator animation (follow the directional flow of the script)
  • Carousel - react-film has been updated with a dir prop and/or automatic direction detection (See dependencies section above)
  • Spinner animation - I believe that spinners, going clockwise, are meant to represent the passage of time, and therefore should NOT be mirrored. Anecdotal and completely non-scientific information would point to a spinner remaining clockwise in RTL UI. No official-looking sources found on this topic
  • Sound slider SHOULD be mirrored - Audio / Video see dependencies above
  • Media CONTROLS SHOULD NOT be mirrored HTML5 does not support rtl for <video> or <audio> see dependencies above

Situations to test

  • HTML Videos - should be rendered by browser, but sound bar should be flipped
  • Audio - should be rendered by browser, but sound bar should be flipped
  • YouTube & vimeo - test that layout is correct
  • Adaptive Cards
  • Text activity - alignment
  • Switching languages between LTR and RTL
  • Download attachment - alignment
  • Connectivity Status component (icon Location and alignment)
  • Bubble nubs
  • react-film
    • SuggestedActions
    • CarouselFilmStrip
    • Carousel Layout
  • ScrollToEnd button
  • Timestamp - number / date order / alignment
  • Send status component / Send failed retry
  • Markdown content - alignment
  • Samples - alignment
  • Verify all card (legacy) formats work with RTL
  • To IC3 team: Ask for card support priority
  • Avatar / Initials
  • Ensure that Hosted Web Chat is able to specify RTL/Language like CDN and npm
  • Have RTL Language speaker sign off with RTL Language bot - Test as many browsers as possible
  • RTL documentation

Tests added to Mock Bot (still waiting on Arabic strings)

Mock Bot

  • Greeting card
  • Carousel
  • File attachment
  • Markdown

Offline Mock Bot

  • Greeting card
  • Carousel
  • [ ] File attachment
  • Markdown

Known internal issues

  • Fixed: component added offscreen <div> which created erroneous scrollbar in RTL mode

Web features we will not use / Non-universal browser support

  • text-align: 'start/end' - Not supported in Edge (or Internet Explorer)
  • match-parent is only supported by Chrome and Firefox
  • <bdo>

Documentation / Guidance / Data

@compulim
Copy link
Contributor

compulim commented Feb 10, 2020

window.WebChat.renderWebChat(
  {
    directLine: window.WebChat.createDirectLine({ token }),
    locale: 'ar-EG'
  },
  document.getElementById('webchat')
);

image

image

@corinagum
Copy link
Contributor Author

image

image

@compulim thanks, got it fixed :)

@corinagum corinagum changed the title 1976 rtl Add RTL support Feb 11, 2020
Copy link
Contributor

@compulim compulim left a comment

Choose a reason for hiding this comment

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

Looks great. Very high quality. You must spent quite a lot of time proof-reading your own code.

docs/HOOKS.md Outdated Show resolved Hide resolved
packages/component/src/Activity/CarouselLayout.js Outdated Show resolved Hide resolved
packages/component/src/Activity/CarouselLayout.js Outdated Show resolved Hide resolved
packages/component/src/Activity/StackedLayout.js Outdated Show resolved Hide resolved
packages/component/src/hooks/useDirection.js Outdated Show resolved Hide resolved
packages/playground/src/App.js Show resolved Hide resolved
const directLine = useMemo(() => createDirectLine({ token }), []);
const store = useMemo(
() =>
createStore({}, () => next => action => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe improve this one using a button bar + onhashchange later.

const res = await fetch('https://webchat-mockbot.azurewebsites.net/directline/token', { method: 'POST' });
const { token } = await res.json();

window.WebChat.renderWebChat(
Copy link
Contributor

Choose a reason for hiding this comment

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

We could use a button bar + onhashchange later.

@corinagum corinagum merged commit 7415e74 into microsoft:master Feb 14, 2020
@cwhitten
Copy link
Member

whoo hoo!

@geea-develop
Copy link
Contributor

geea-develop commented Feb 14, 2020

WOW Thanks @corinagum! cant wait to try it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants