Successfully reported this slideshow.
Your SlideShare is downloading. ×

Do the right (to left) thing

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Loading in …3
×

Check these out next

1 of 136 Ad

Do the right (to left) thing

In 2017, Airbnb supported 27 languages and had developed robust translation tools that made it easy to add more. We launched Croatian in May with little overhead beyond setting up the new domain and translating phrases. However, this was not true for all new languages; our next most requested language, Hebrew, posed a unique challenge. Because it reads right-to-left, the entire Hebrew UI must be flipped. Browsers only handle reversing the DOM structure, but styling and interactions must be coded manually.

This talk covers the journey of enabling right-to-left languages on airbnb.com. Recently, Airbnb has moved to a React frontend and away from Sass to a CSS-in-JS paradigm. We developed a performant and cross-browser solution for RTL that leveraged a CSS-in-JS abstraction layer to isolate the logic from our codebase. Our efforts led us most of the way to launching in Arabic and Hebrew while requiring little effort from our product engineers and with minimal disruption to their work.

In 2017, Airbnb supported 27 languages and had developed robust translation tools that made it easy to add more. We launched Croatian in May with little overhead beyond setting up the new domain and translating phrases. However, this was not true for all new languages; our next most requested language, Hebrew, posed a unique challenge. Because it reads right-to-left, the entire Hebrew UI must be flipped. Browsers only handle reversing the DOM structure, but styling and interactions must be coded manually.

This talk covers the journey of enabling right-to-left languages on airbnb.com. Recently, Airbnb has moved to a React frontend and away from Sass to a CSS-in-JS paradigm. We developed a performant and cross-browser solution for RTL that leveraged a CSS-in-JS abstraction layer to isolate the logic from our codebase. Our efforts led us most of the way to launching in Arabic and Hebrew while requiring little effort from our product engineers and with minimal disruption to their work.

Advertisement
Advertisement

More Related Content

Recently uploaded (20)

Advertisement

Do the right (to left) thing

  1. 1. DotheRight(toLeft)Thing DirectionalContentinReact MAJA WICHROWSKA / 2018-05-17 / @MAJAPW 1 Do the Right (to Left) Thing (PDF) - May 20, 2018
  2. 2. DotheRight(toLeft)Thing DIRECTIONAL CONTENT IN REACT @majapw 2 Do the Right (to Left) Thing (PDF) - May 20, 2018
  3. 3. DotheRight(toLeft)Thing DIRECTIONAL CONTENT IN REACT Maha(‫)ماحا‬ Lives in New York City Studies English at NYU “A terminally pessimistic and culturally dispossessed teenager” Khalid(‫)خالد‬ Lives in Cairo, Egypt Getting an MBA from Cairo University “A chronic misfit with a creepy side-kick friend” @majapw 3 Do the Right (to Left) Thing (PDF) - May 20, 2018
  4. 4. DotheRight(toLeft)Thing DIRECTIONAL CONTENT IN REACT Maha(‫)ماحا‬ Lives in New York City Studies English at NYU “A terminally pessimistic and culturally dispossessed teenager” Khalid(‫)خالد‬ Lives in Cairo, Egypt Getting an MBA from Cairo University “A chronic misfit with a creepy side-kick friend” @majapw 4 Do the Right (to Left) Thing (PDF) - May 20, 2018
  5. 5. DotheRight(toLeft)Thing DIRECTIONAL CONTENT IN REACT @majapw 5 Do the Right (to Left) Thing (PDF) - May 20, 2018
  6. 6. DotheRight(toLeft)Thing DIRECTIONAL CONTENT IN REACT @majapw 6 Do the Right (to Left) Thing (PDF) - May 20, 2018
  7. 7. DotheRight(toLeft)Thing DIRECTIONAL CONTENT IN REACT @majapw 7 Do the Right (to Left) Thing (PDF) - May 20, 2018
  8. 8. DotheRight(toLeft)Thing DIRECTIONAL CONTENT IN REACT @majapw 8 Do the Right (to Left) Thing (PDF) - May 20, 2018
  9. 9. DotheRight(toLeft)Thing DIRECTIONAL CONTENT IN REACT •Why support right-to-left languages at all? •Why is it hard to do so? •What tools are already available? •How did we solve this problem at Airbnb? @majapw 9 Do the Right (to Left) Thing (PDF) - May 20, 2018
  10. 10. WHY SUPPORT RIGHT-TO-LEFT? @majapw 10 Do the Right (to Left) Thing (PDF) - May 20, 2018
  11. 11. ި‫ހ‬ެ‫ވ‬ި‫ދ‬ (Dhivehi) ‫دیلی‬ ‫آذربایجان‬ (Azeri) ‫کوردی‬ (Kurdish) ‫ִבִרית‬‫ע‬ (Hebrew) ‫فارسی‬ (Persian) ‫سنڌي‬ (Sindhi) ‫پښتو‬ (Pashto) ‫و‬ُ‫د‬‫ر‬ُ‫ا‬ (Urdu) ‫العربية‬ (Arabic) RTLLanguages WHAT’S OUT THERE? @majapw 11 Do the Right (to Left) Thing (PDF) - May 20, 2018
  12. 12. [http://www.internetworldstats.com/stats5.htm] ‫العربية‬ ARABIC ON THE WEB •58.7% of the Middle East is on the Internet. •Over 90% of the population of Qatar and the UAE have access to the Internet. •40% of the Arab Digital Generation uses the Internet for at least 5 hours a day. @majapw 12 Do the Right (to Left) Thing (PDF) - May 20, 2018
  13. 13. ‫العربية‬ ARABIC ON THE WEB •4-5% of Internet users speak Arabic. •Arabic-speaking Internet users have grown 7250% since 2000. •60% of Arabic speakers would prefer content in their own language. •Arabic speakers prefer blogging and other similar platforms so asto createthatArabiccontent. [http://www.internetworldstats.com/stats7.htm] @majapw 13 Do the Right (to Left) Thing (PDF) - May 20, 2018
  14. 14. ‫العربية‬ ARABIC ON THE WEB [https://w3techs.com/technologies/overview/content_language/all] [http://funredes.org/lc2017/] Only0.8%to3%
 oftopwebsites
 haveArabiccontent Atlas Mountains, Morocco @majapw 14 Do the Right (to Left) Thing (PDF) - May 20, 2018
  15. 15. WHY IS THIS HARD? @majapw 15 Do the Right (to Left) Thing (PDF) - May 20, 2018
  16. 16. Whyisthishard? .‫ﻣﺎﯾﺎ‬ ‫اﺳﻣﻲ‬ !‫ﻣرﺣﺑﺎ‬ @majapw 16 Do the Right (to Left) Thing (PDF) - May 20, 2018
  17. 17. Whyisthishard? .Maja ‫اﺳﻣﻲ‬ !‫ﻣرﺣﺑﺎ‬ BIDIRECTIONAL CONTENT @majapw 17 Do the Right (to Left) Thing (PDF) - May 20, 2018
  18. 18. Whyisthishard? .Maja ‫اﺳﻣﻲ‬ !‫ﻣرﺣﺑﺎ‬ .27 ‫ﯾوم‬ ‫أوﺻل‬ BIDIRECTIONAL CONTENT @majapw 18 Do the Right (to Left) Thing (PDF) - May 20, 2018
  19. 19. Whyisthishard? .Maja ‫اﺳﻣﻲ‬ !‫ﻣرﺣﺑﺎ‬ .27 ‫ﯾوم‬ ‫أوﺻل‬ USER-GENERATED CONTENT/INPUTS @majapw 19 Do the Right (to Left) Thing (PDF) - May 20, 2018
  20. 20. Whyisthishard? CUSTOM CSS STYLES @majapw 20 Do the Right (to Left) Thing (PDF) - May 20, 2018
  21. 21. Whyisthishard? ICONOGRAPHY/OTHER IMAGERY @majapw 21 Do the Right (to Left) Thing (PDF) - May 20, 2018
  22. 22. Whyisthishard? ICONOGRAPHY/OTHER IMAGERY @majapw 22 Do the Right (to Left) Thing (PDF) - May 20, 2018
  23. 23. Whyisthishard? @majapw 23 Do the Right (to Left) Thing (PDF) - May 20, 2018
  24. 24. GET THE GEAR* *TOOLS, LIBRARIES, WHATEVER @majapw 24 Do the Right (to Left) Thing (PDF) - May 20, 2018
  25. 25. Tools BUILT-IN GEAR dir=“ltr” dir=“rtl” dir=“auto” @majapw 25 Do the Right (to Left) Thing (PDF) - May 20, 2018
  26. 26. Tools BRUTALIST AIRBNB @majapw 26 Do the Right (to Left) Thing (PDF) - May 20, 2018
  27. 27. Tools BRUTALIST AIRBNB @majapw 27 Do the Right (to Left) Thing (PDF) - May 20, 2018
  28. 28. <DirectionProvider/> Sets the direction attribute based on a global language setting on a top-level node withDirection() Wraps individual components and consumes the direction as a prop, allowing for customization based on its value. @majapw react-with-direction 28 Do the Right (to Left) Thing (PDF) - May 20, 2018
  29. 29. render() { const { count } = this.state; return ( <div> {`Step ${count + 1}`} </div> ); } react-with-direction DirectionProvider @majapw 29 Do the Right (to Left) Thing (PDF) - May 20, 2018
  30. 30. render() { const { count } = this.state; return ( <div> {`Step ${count + 1}`} <IconChevronRight /> </div> ); } react-with-direction DirectionProvider @majapw 30 Do the Right (to Left) Thing (PDF) - May 20, 2018
  31. 31. render() { const { count } = this.state; return ( <div> {`Step ${count + 1}`} <IconChevronRight onClick={() => { this.setState({ count: (count + 1) % 100 }) } /> </div> ); } react-with-direction DirectionProvider @majapw 31 Do the Right (to Left) Thing (PDF) - May 20, 2018
  32. 32. <div dir=“rtl”> </div> render() { const { count } = this.state; return ( {`Step ${count + 1}`} <IconChevronRight onClick={() => { this.setState({ count: (count + 1) % 100 }) } /> ); } <DirectionProvider direction={DIRECTIONS.RTL}> </DirectionProvider> react-with-direction DirectionProvider @majapw 32 Do the Right (to Left) Thing (PDF) - May 20, 2018
  33. 33. <div dir=“rtl”> </div> render() { const { count } = this.state; return ( {`Step ${count + 1}`} <IconChevronRight onClick={() => { this.setState({ count: (count + 1) % 100 }) } /> ); } react-with-direction DirectionProvider @majapw 33 Do the Right (to Left) Thing (PDF) - May 20, 2018
  34. 34. export default function IconChevronNext({ ...props }) { ... } react-with-direction withDirection @majapw 34 Do the Right (to Left) Thing (PDF) - May 20, 2018
  35. 35. export default function IconChevronNext({ ...props }) { return <IconChevronRight {...props} />; } react-with-direction withDirection @majapw 35 Do the Right (to Left) Thing (PDF) - May 20, 2018
  36. 36. function IconChevronNext({ direction, ...props }) { return <IconChevronRight {...props} />; } export default withDirection(IconChevronNext); react-with-direction withDirection @majapw 36 Do the Right (to Left) Thing (PDF) - May 20, 2018
  37. 37. function IconChevronNext({ direction, ...props }) { if (direction === DIRECTIONS.RTL) { return <IconChevronLeft {...props} />; } return <IconChevronRight {...props} />; } export default withDirection(IconChevronNext); react-with-direction withDirection @majapw 37 Do the Right (to Left) Thing (PDF) - May 20, 2018
  38. 38. render() { const { count } = this.state; return ( <DirectionProvider direction={DIRECTIONS.RTL}> {`Step ${count + 1}`} <IconChevronNext onClick={() => { this.setState({ count: (count + 1) % 100 }) } /> </DirectionProvider> ); } react-with-direction WithDirection @majapw 38 Do the Right (to Left) Thing (PDF) - May 20, 2018
  39. 39. DIR=“LTR” ManualLabor @majapw 39 Do the Right (to Left) Thing (PDF) - May 20, 2018
  40. 40. DIR=“RTL” ManualLabor @majapw 40 Do the Right (to Left) Thing (PDF) - May 20, 2018
  41. 41. Whataboutstyle? AUTOMATED OPTIONS R2 (ded/R2) - a CSS LTR ∞ RTL converter for i18n friendly layouts css-flip (twitter/css-flip) - a CSS BiDi flipper rtlcss (MohammadYounes/rtlcss) - Framework for transforming CSS from LTR to RTL cssjanus (cssjanus/cssjanus) - Flip CSS stylesheets between left-to-right and right-to-left webpack-rtl-plugin (romainberger/webpack-rtl-plugin) - Webpack plugin to produce a rtl css bundle @majapw 41 Do the Right (to Left) Thing (PDF) - May 20, 2018
  42. 42. R2 (ded/R2) - a CSS LTR ∞ RTL converter for i18n friendly layouts css-flip (twitter/css-flip) - a CSS BiDi flipper rtlcss (MohammadYounes/rtlcss) - Framework for transforming CSS from LTR to RTL cssjanus (cssjanus/cssjanus) - Flip CSS stylesheets between left-to-right and right-to-left webpack-rtl-plugin (romainberger/webpack-rtl-plugin) - Webpack plugin to produce a rtl CSS bundle Whataboutstyle? AUTOMATED OPTIONS @majapw 42 Do the Right (to Left) Thing (PDF) - May 20, 2018
  43. 43. /* BookIt.js */ Backin2014… /* BookIt.scss */ @majapw 43 Do the Right (to Left) Thing (PDF) - May 20, 2018
  44. 44. Howdowestylemodular Reactcomponentswhile minimizingside-effects betweenthem? AModularSolution @majapw 44 Do the Right (to Left) Thing (PDF) - May 20, 2018
  45. 45. /* BookIt.js */ AModularSolution /* BookIt.scss */ @majapw 45 Do the Right (to Left) Thing (PDF) - May 20, 2018
  46. 46. /* BookIt.jsx */ AModularSolution /* BookIt.scss */ CSS-IN-JS @majapw 46 Do the Right (to Left) Thing (PDF) - May 20, 2018
  47. 47. AModularSolution CSS-IN-JS Aphrodite [https://www.github.com/khan/aphrodite] <Component/> @majapw 47 Do the Right (to Left) Thing (PDF) - May 20, 2018
  48. 48. AModularSolution CSS-IN-JS Aphrodite [https://www.github.com/khan/aphrodite] <Component/> 48 Do the Right (to Left) Thing (PDF) - May 20, 2018
  49. 49. AModularSolution CSS-IN-JS Aphrodite [https://www.github.com/khan/aphrodite] <Component/> compile-time 49 Do the Right (to Left) Thing (PDF) - May 20, 2018
  50. 50. compile-time AModularSolution CSS-IN-JS Aphrodite [https://www.github.com/khan/aphrodite] <Component/> Canyouhelpmeturnthese intosomethingIcanuse? { container: { display: ‘block’, margin: ‘8px 4px’, }, containerLarge: { margin: 16, }, } 50 Do the Right (to Left) Thing (PDF) - May 20, 2018
  51. 51. compile-time AModularSolution CSS-IN-JS Aphrodite [https://www.github.com/khan/aphrodite] <Component/> Here.Usethesereferences! { container: …, containerLarge: …, } 51 Do the Right (to Left) Thing (PDF) - May 20, 2018
  52. 52. compile-time AModularSolution CSS-IN-JS Aphrodite [https://www.github.com/khan/aphrodite] <Component/>Create 52 Do the Right (to Left) Thing (PDF) - May 20, 2018
  53. 53. compile-time AModularSolution CSS-IN-JS Aphrodite [https://www.github.com/khan/aphrodite] <Component/>Create run-time 53 Do the Right (to Left) Thing (PDF) - May 20, 2018
  54. 54. compile-time AModularSolution CSS-IN-JS Aphrodite [https://www.github.com/khan/aphrodite] <Component/>Create run-time Okay.NowIneedtoapply thesestylestoaDOMnode. [ styles.container, styles.containerLarge, ] Prettyplease,canyouhelp meagain?<3 54 Do the Right (to Left) Thing (PDF) - May 20, 2018
  55. 55. compile-time AModularSolution CSS-IN-JS Aphrodite [https://www.github.com/khan/aphrodite] <Component/>Create run-timeOfcourse!ThatiswhatIam herefor.Justusethis uniqueclassnameonthat node: .container_w7y05q-o_O- containerLarge_1l06a80 55 Do the Right (to Left) Thing (PDF) - May 20, 2018
  56. 56. AModularSolution compile-time CSS-IN-JS Aphrodite [https://www.github.com/khan/aphrodite] <Component/>Create run-time Resolve 56 Do the Right (to Left) Thing (PDF) - May 20, 2018
  57. 57. AModularSolution compile-time Abstraction CSS-IN-JS Aphrodite [https://www.github.com/khan/aphrodite] <Component/>Create run-time Resolve 57 Do the Right (to Left) Thing (PDF) - May 20, 2018
  58. 58. Aphrodite react-with-styles-interface-aphrodite react-with-styles compile-time Abstraction CSS-IN-JS Create run-time Resolve <Component/> @majapw 58 Do the Right (to Left) Thing (PDF) - May 20, 2018
  59. 59. JSS react-with-styles-interface-JSS compile-time Abstraction CSS-IN-JS Create run-time Resolve react-with-styles <Component/> @majapw 59 Do the Right (to Left) Thing (PDF) - May 20, 2018
  60. 60. react-with-styles-interface-react-native react-native compile-time Abstraction CSS-IN-JS Create run-time Resolve react-with-styles <Component/> @majapw 60 Do the Right (to Left) Thing (PDF) - May 20, 2018
  61. 61. CSS react-with-styles-interface-css compile-time Abstraction CSS-IN-JS Create run-time Resolve react-with-styles <Component/> @majapw 61 Do the Right (to Left) Thing (PDF) - May 20, 2018
  62. 62. Aphrodite react-with-styles-interface-aphrodite compile-time Abstraction CSS-IN-JS Create run-time Resolve react-with-styles <Component/> @majapw 62 Do the Right (to Left) Thing (PDF) - May 20, 2018
  63. 63. Aphrodite react-with-styles-interface-aphrodite react-with-styles compile-time Abstraction CSS-IN-JS Create run-time Resolve <Component/> @majapw 63 Do the Right (to Left) Thing (PDF) - May 20, 2018
  64. 64. Aphrodite react-with-styles-interface-aphrodite react-with-styles compile-time Abstraction CSS-IN-JS Create run-time Resolve <Component/> Canyouhelpmeturnthese intosomethingIcanuse? { container: { display: ‘block’, margin: ‘8px 4px’, }, containerLarge: { margin: 16, }, } @majapw 64 Do the Right (to Left) Thing (PDF) - May 20, 2018
  65. 65. Aphrodite react-with-styles-interface-aphrodite react-with-styles compile-time Abstraction CSS-IN-JS Create run-time Resolve <Component/> Letmetalktomy interfacerealquick! 65 Do the Right (to Left) Thing (PDF) - May 20, 2018
  66. 66. Aphrodite react-with-styles-interface-aphrodite react-with-styles compile-time Abstraction CSS-IN-JS Create run-time Resolve <Component/> Letmeseewhat Aphroditereturnsforthis situation. @majapw 66 Do the Right (to Left) Thing (PDF) - May 20, 2018
  67. 67. Aphrodite react-with-styles-interface-aphrodite react-with-styles compile-time Abstraction CSS-IN-JS Create run-time Resolve <Component/> Here.ThisiswhatIgot backfrommyinterface: { container: …, containerLarge: …, } Youcanaccessthis objectasaReactprop. @majapw 67 Do the Right (to Left) Thing (PDF) - May 20, 2018
  68. 68. Aphrodite react-with-styles-interface-aphrodite react-with-styles compile-time Abstraction CSS-IN-JS Create run-time Resolve <Component/> @majapw 68 Do the Right (to Left) Thing (PDF) - May 20, 2018
  69. 69. Aphrodite react-with-styles-interface-aphrodite react-with-styles compile-time Abstraction CSS-IN-JS Create run-time Resolve <Component/> Okay.NowIneedtoapply thesestylestoaDOMnode. [ styles.container, styles.containerLarge, ] Prettyplease,canyouhelp meagain?<3 @majapw 69 Do the Right (to Left) Thing (PDF) - May 20, 2018
  70. 70. Aphrodite react-with-styles-interface-aphrodite react-with-styles compile-time Abstraction CSS-IN-JS Create run-time Resolve <Component/> Cool.Letmeaskmy interfaceagain. @majapw 70 Do the Right (to Left) Thing (PDF) - May 20, 2018
  71. 71. Aphrodite react-with-styles-interface-aphrodite react-with-styles compile-time Abstraction CSS-IN-JS Create run-time Resolve <Component/> Ineedtocheckwith Aphroditeandgetback toyou!:) @majapw 71 Do the Right (to Left) Thing (PDF) - May 20, 2018
  72. 72. Aphrodite react-with-styles-interface-aphrodite react-with-styles compile-time Abstraction CSS-IN-JS Create run-time Resolve <Component/> Okay,somyinterface gavemeaclassnameso I’mjustgoingtogiveitto youlikethis:
 { className: ‘.container_64dfxr- O_o- containerLarge_875dk r’, } Youcanjustspreadthis onto your DOM node. @majapw 72 Do the Right (to Left) Thing (PDF) - May 20, 2018
  73. 73. Aphrodite react-with-styles-interface-aphrodite react-with-styles compile-time Abstraction CSS-IN-JS Create run-time Resolve <Component/> Ialsoneedtoapplythese dynamicstylestoanode. [{ backgroundImage: … left: 40, }] @majapw 73 Do the Right (to Left) Thing (PDF) - May 20, 2018
  74. 74. Aphrodite react-with-styles-interface-aphrodite react-with-styles compile-time Abstraction CSS-IN-JS Create run-time Resolve <Component/> Letmecheckwithmy interface. @majapw 74 Do the Right (to Left) Thing (PDF) - May 20, 2018
  75. 75. Aphrodite react-with-styles-interface-aphrodite react-with-styles compile-time Abstraction CSS-IN-JS Create run-time Resolve <Component/> Hmm.Aphrodite doesn’tknowhowto handledynamicstyle objects.…IguessIcould handleitmyself? @majapw 75 Do the Right (to Left) Thing (PDF) - May 20, 2018
  76. 76. Aphrodite react-with-styles-interface-aphrodite react-with-styles compile-time Abstraction CSS-IN-JS Create run-time Resolve <Component/> Here.Youcanjustusethis object: { style: { backgroundImage: …, left: 40, }, } @majapw 76 Do the Right (to Left) Thing (PDF) - May 20, 2018
  77. 77. Aphrodite react-with-styles-interface-aphrodite react-with-styles compile-time Abstraction CSS-IN-JS Create run-time Resolve <Component/> Okay,somyinterface gavemeastylesoI’mjust goingtogiveittoyoulike this:
 { style: …, } Youcanjustspreadthis ontoyourDOMnode. @majapw 77 Do the Right (to Left) Thing (PDF) - May 20, 2018
  78. 78. Aphrodite react-with-styles compile-time Abstraction CSS-IN-JS Create run-time Resolve <Component/> react-with-styles-interface-aphrodite @majapw 78 Do the Right (to Left) Thing (PDF) - May 20, 2018
  79. 79. •Handles all directional styles. •No changes to how developers write components. •Handles both Aphrodite-generated classnames and inline style objects. •Has minimal performance impact. AutomaticStyleFlippinginRWS IMPLEMENTATION REQUIREMENTS Petra, Jordan @majapw 79 Do the Right (to Left) Thing (PDF) - May 20, 2018
  80. 80. ATTEMPT #1 @majapw 80 Do the Right (to Left) Thing (PDF) - May 20, 2018
  81. 81. •Create happens at compile-time. •While resolvehappens at run-time, the method is defined once and exported as a singleton. Attempt#1 SOME IMPORTANT CONSIDERATIONS This means that we do not have access to directional context. @majapw 81 Do the Right (to Left) Thing (PDF) - May 20, 2018
  82. 82. •We can assume all our apps have a top-leveldir attribute that is set before the first render. •Aphrodite has a built-in plugin system to handle customstyleselectors. Attempt#1 THINGS WE CAN LEVERAGE @majapw 82 Do the Right (to Left) Thing (PDF) - May 20, 2018
  83. 83. LeverageAphrodite’splugin systemtocreatedescendent selectorsfordefaultstylesina [dir=“ltr”]contextandflipped stylesina[dir=“rtl”]context. Attempt#1 OUR CORE STRATEGY @majapw 83 Do the Right (to Left) Thing (PDF) - May 20, 2018
  84. 84. CSS-in-JS Attempt#1 USING APHRODITE’S PLUGIN SYSTEM CSS { container: { color: 'red', }, } .container_fesszw { color: red !important; } @majapw 84 Do the Right (to Left) Thing (PDF) - May 20, 2018
  85. 85. { container: { ‘:focus’: { color: 'purple', }, }, } CSS-in-JS Attempt#1 USING APHRODITE’S PLUGIN SYSTEM CSS .container_fesszw:focus { color: purple !important; } @majapw 85 Do the Right (to Left) Thing (PDF) - May 20, 2018
  86. 86. [dir=“rtl"] .container_fesszw { margin-left: 10px !important; } [dir="ltr"] .container_fesszw { margin-right: 10px !important; } CSS-in-JS Attempt#1 USING APHRODITE’S PLUGIN SYSTEM CSS { container: { _rtl: { marginLeft: 10, }, _ltr: { marginRight: 10, }, }, } @majapw 86 Do the Right (to Left) Thing (PDF) - May 20, 2018
  87. 87. Aphrodite react-with-styles-interface-aphrodite react-with-styles <Component/> Stylemeplz. [ styles.container, { left: 40 }, ] run-time Resolve 87 Do the Right (to Left) Thing (PDF) - May 20, 2018
  88. 88. Aphrodite react-with-styles-interface-aphrodite react-with-styles <Component/> Ofcourse.Letmeasktheinterface. 88 Do the Right (to Left) Thing (PDF) - May 20, 2018
  89. 89. Aphrodite react-with-styles-interface-aphrodite react-with-styles <Component/> [Before]Compile-timeStaticStyles Pass unchanged to Aphrodite. 89 Do the Right (to Left) Thing (PDF) - May 20, 2018
  90. 90. Aphrodite react-with-styles-interface-aphrodite react-with-styles <Component/> [Now]Compile-timeStaticStyles Pass unchanged to Aphrodite. Transform into _rtl/_ltrstyles by using Kent Dodds’ rtl-css-jslibrary. Enable our custom plugin in Aphrodite. 90 Do the Right (to Left) Thing (PDF) - May 20, 2018
  91. 91. Transform into _rtl/_ltrstyles by using Kent Dodds’ rtl-css-jslibrary. Enable our custom plugin in Aphrodite. [Now]Compile-timeStaticStyles Pass unchanged to Aphrodite. Aphrodite react-with-styles-interface-aphrodite react-with-styles <Component/> resolveStaticStyles(styles.container) 91 Do the Right (to Left) Thing (PDF) - May 20, 2018
  92. 92. [Now]Compile-timeStaticStyles Pass unchanged to Aphrodite. Aphrodite react-with-styles-interface-aphrodite react-with-styles <Component/> Transform into _rtl/_ltrstyles by using Kent Dodds’ rtl-css-jslibrary. Enable our custom plugin in Aphrodite. resolveStaticStyles({ __name: ‘.container_rbvzuy’, __definition: { color: ‘red’, float: ‘left’, }, }) 92 Do the Right (to Left) Thing (PDF) - May 20, 2018
  93. 93. [Now] Compile-time Static Styles Pass unchanged to Aphrodite. Transform into _rtl/_ltr-keyed styles by the interface using Kent Dodds’ rtl-css-js library. Enable our custom plugin in Aphrodite. Aphrodite react-with-styles-interface-aphrodite react-with-styles <Component/> resolveStaticStyles({ __name: ‘.container_rbvzuy’, __definition: { _ltr: { color: ‘red’, float: ‘left’, }, _rtl: rtlCSSJS({ color: ‘red’, float: ‘left’, }), }, }) 93 Do the Right (to Left) Thing (PDF) - May 20, 2018
  94. 94. [Now] Compile-time Static Styles Pass unchanged to Aphrodite. Transform into _rtl/_ltr-keyed styles by the interface using Kent Dodds’ rtl-css-js library. Enable our custom plugin in Aphrodite. Aphrodite react-with-styles-interface-aphrodite react-with-styles <Component/> Compile-time Created Styles Pass as is to Aphrodite Transform into _rtl/_ltr-keyed styles by the interface using Kent Dodds’ rtl-css-js library Pass into a version of Aphrodite with a custom plugin enabled resolveStaticStyles({ __name: ‘.container_rbvzuy’, __definition: { _ltr: { color: ‘red’, float: ‘left’, }, _rtl: { color: ‘red’, float: ‘right’, }, }, }) 94 Do the Right (to Left) Thing (PDF) - May 20, 2018
  95. 95. Aphrodite react-with-styles-interface-aphrodite react-with-styles <Component/> Here.SpreadthisontoyourDOMnode.
 { className: ‘.container_rbvzuy’, } [dir="rtl"] .container_rbvzuy { color: red !important; float: right !important; } [dir="ltr"] .container_rbvzuy { color: red !important; float: left !important; } 95 Do the Right (to Left) Thing (PDF) - May 20, 2018
  96. 96. Aphrodite react-with-styles-interface-aphrodite react-with-styles <Component/> Style me plz. [ styles.container, { left: 40 }, ] @majapw 96 Do the Right (to Left) Thing (PDF) - May 20, 2018
  97. 97. Aphrodite react-with-styles-interface-aphrodite react-with-styles <Component/> Ofcourse.Letmeasktheinterface. @majapw 97 Do the Right (to Left) Thing (PDF) - May 20, 2018
  98. 98. Aphrodite react-with-styles-interface-aphrodite react-with-styles <Component/> [Before]Run-timeDynamicStyles Pass inline styles unchanged back to RWS. @majapw 98 Do the Right (to Left) Thing (PDF) - May 20, 2018
  99. 99. Aphrodite react-with-styles-interface-aphrodite react-with-styles <Component/> [Now]Run-timeDynamicStyles Pass inline styles unchanged back to RWS. Transform styles into Aphrodite classnames.* Enable our custom plugin in Aphrodite. *Only do this for directional styles. @majapw 99 Do the Right (to Left) Thing (PDF) - May 20, 2018
  100. 100. [Now]Run-timeDynamicStyles Pass inline styles unchanged back to RWS. Transform styles into Aphrodite classnames.* Enable our custom plugin in Aphrodite. *Only do this for directional styles. Aphrodite react-with-styles-interface-aphrodite react-with-styles <Component/> { left: 40 } @majapw 100 Do the Right (to Left) Thing (PDF) - May 20, 2018
  101. 101. [Now]Run-timeDynamicStyles Pass inline styles unchanged back to RWS. Transform styles into Aphrodite classnames.* Enable our custom plugin in Aphrodite. *Only do this for directional styles. Aphrodite react-with-styles-interface-aphrodite react-with-styles <Component/> { __name: ‘inlineStyle_aov0j6’, __definition: { left: 40, }, } @majapw 101 Do the Right (to Left) Thing (PDF) - May 20, 2018
  102. 102. @majapw [Now]Run-timeDynamicStyles Pass inline styles unchanged back to RWS. Transform styles into Aphrodite classnames.* Enable our custom plugin in Aphrodite. *Only do this for directional styles. Aphrodite react-with-styles-interface-aphrodite react-with-styles <Component/> { __name: ‘inlineStyle_aov0j6’, __definition: { _ltr: { left: 40, }, _rtl: rtlCSSJS({ left: 40, }), }, } 102 Do the Right (to Left) Thing (PDF) - May 20, 2018
  103. 103. @majapw [Now]Run-timeDynamicStyles Pass inline styles unchanged back to RWS. Transform styles into Aphrodite classnames.* Enable our custom plugin in Aphrodite. *Only do this for directional styles. Aphrodite react-with-styles-interface-aphrodite react-with-styles <Component/> { __name: ‘inlineStyle_aov0j6’, __definition: { _ltr: { left: 40, }, _rtl: { right: 40, }, }, } 103 Do the Right (to Left) Thing (PDF) - May 20, 2018
  104. 104. [Now]Run-timeDynamicStyles Pass inline styles unchanged back to RWS. Transform styles into Aphrodite classnames.* Enable our custom plugin in Aphrodite. *Only do this for directional styles. Aphrodite react-with-styles-interface-aphrodite react-with-styles <Component/> resolveStaticStyles({ __name: ‘inlineStyle_aov0j6’, __definition: { _ltr: { left: 40, }, _rtl: { right: 40, }, }, }) 104 Do the Right (to Left) Thing (PDF) - May 20, 2018
  105. 105. Aphrodite react-with-styles-interface-aphrodite react-with-styles <Component/> Here.SpreadthisontoyourDOMnode.
 { className: ‘.inlineStyle_aov0j6’, } [dir="rtl"] .inlineStyle_aov0j6 { right: 40px !important; } [dir="ltr"] .inlineStyle_aov0j6 { left: 40px !important; } @majapw 105 Do the Right (to Left) Thing (PDF) - May 20, 2018
  106. 106. Attempt#1 SOME SUCCESS @majapw 106 Do the Right (to Left) Thing (PDF) - May 20, 2018
  107. 107. Attempt#1 SOME SUCCESS @majapw 107 Do the Right (to Left) Thing (PDF) - May 20, 2018
  108. 108. •Descendent selectors do not allow for context switching. •Descendent selectors coupled with shorthand/longhand styles cause specificity issues. •React 16 upgrade caused server/client mismatches due to the way we were initializing direction and transforming inline styles to classnames. Attempt#1 FAILURES @majapw 108 Do the Right (to Left) Thing (PDF) - May 20, 2018
  109. 109. ATTEMPT #2 @majapw 109 Do the Right (to Left) Thing (PDF) - May 20, 2018
  110. 110. Attempt#2 MODIFIED REQUIREMENTS •Handles all directional styles. •No changes to how developers write components. •Handles both Aphrodite-generated classnames and inline style objects. •Has minimal performance impact. @majapw 110 Do the Right (to Left) Thing (PDF) - May 20, 2018
  111. 111. •Handles all directional styles. •Changestohowdeveloperswritecomponentscaneasilybecodemodded. •Handles both Aphrodite-generated classnames and inline style objects. •Has minimal performance impact. •Handlesdirectionalcontextswitching. •Doesnotintroducespecificityissues. •Doesnotcauseaserver/clientmismatch. Attempt#2 MODIFIED REQUIREMENTS @majapw 111 Do the Right (to Left) Thing (PDF) - May 20, 2018
  112. 112. Usecontextualcreateand resolvemethodsbasedon direction. Attempt#2 OUR CORE STRATEGY @majapw 112 Do the Right (to Left) Thing (PDF) - May 20, 2018
  113. 113. compile-time Attempt#2 CONTEXTUAL METHODS Create run-time ResolveCreate Resolve @majapw 113 Do the Right (to Left) Thing (PDF) - May 20, 2018
  114. 114. compile-time Attempt#2 CONTEXTUAL METHODS CreateLTR CreateRTL run-time ResolveLTR ResolveRTLCreate Create Resolve Resolve @majapw 114 Do the Right (to Left) Thing (PDF) - May 20, 2018
  115. 115. compile-time Attempt#2 CONTEXTUAL METHODS CreateLTR CreateRTL run-time ResolveLTR ResolveRTL deferred to first render @majapw 115 Do the Right (to Left) Thing (PDF) - May 20, 2018
  116. 116. compile-time Attempt#2 CONTEXTUAL METHODS CreateLTR CreateRTL run-time ResolveLTR ResolveRTL deferred to first render passed down as a prop @majapw 116 Do the Right (to Left) Thing (PDF) - May 20, 2018
  117. 117. Aphrodite react-with-styles-interface-aphrodite react-with-styles compile-time Create run-time Resolve <Component/>Attempt#2 CONTEXTUAL METHODS Canyoucreatethese styles? { container: { color: ‘red’, float: ‘left’, }, } Thanks! @majapw 117 Do the Right (to Left) Thing (PDF) - May 20, 2018
  118. 118. Aphrodite react-with-styles-interface-aphrodite react-with-styles compile-time Create run-time Resolve <Component/> ItlookslikeI’minanRTL context.Letmecallmy interface’sRTL-specific createmethod. Attempt#2 CONTEXTUAL METHODS @majapw 118 Do the Right (to Left) Thing (PDF) - May 20, 2018
  119. 119. Aphrodite react-with-styles-interface-aphrodite react-with-styles compile-time Create run-time Resolve <Component/>Attempt#2 CONTEXTUAL METHODS Ooh,anRTLcontext!Let meflipthestylesbeforeI passthemtoAphrodite. { container: rtlCSSJS({ color: ‘red’, float: ‘left’, )} }, } @majapw 119 Do the Right (to Left) Thing (PDF) - May 20, 2018
  120. 120. Aphrodite react-with-styles-interface-aphrodite react-with-styles compile-time Create run-time Resolve <Component/>Attempt#2 CONTEXTUAL METHODS Ooh,anRTLcontext!Let meflipthestylesbeforeI passthemtoAphrodite. { container: { color: ‘red’, float: ‘right’, } }, } @majapw 120 Do the Right (to Left) Thing (PDF) - May 20, 2018
  121. 121. Aphrodite react-with-styles-interface-aphrodite react-with-styles compile-time Create run-time Resolve <Component/>Attempt#2 CONTEXTUAL METHODS Here.ThisiswhatIgot backfrommyinterface: { container: …, } Youcanaccessthis objectasaReactprop. @majapw 121 Do the Right (to Left) Thing (PDF) - May 20, 2018
  122. 122. Aphrodite react-with-styles-interface-aphrodite react-with-styles compile-time Create run-time Resolve <Component/>Attempt#2 CONTEXTUAL METHODS @majapw 122 Do the Right (to Left) Thing (PDF) - May 20, 2018
  123. 123. Aphrodite react-with-styles-interface-aphrodite react-with-styles compile-time Create run-time Resolve <Component/>Attempt#2 CONTEXTUAL METHODS Okay.NowIneedtoapply thesestylestoaDOMnode. [ styles.container, { left: 40, }, ] @majapw 123 Do the Right (to Left) Thing (PDF) - May 20, 2018
  124. 124. Aphrodite react-with-styles-interface-aphrodite react-with-styles compile-time Create run-time Resolve <Component/> Okay.NowIneedtoapply thesestylestoaDOMnode. [ styles.container, { left: 40, }, ] Attempt#2 CONTEXTUAL METHODS @majapw 124 Do the Right (to Left) Thing (PDF) - May 20, 2018
  125. 125. Aphrodite react-with-styles-interface-aphrodite react-with-styles compile-time Create run-time Resolve <Component/> ItlookslikeI’minanRTL context.Letmeusemy interface’sRTL-specific resolvemethod. Attempt#2 CONTEXTUAL METHODS @majapw 125 Do the Right (to Left) Thing (PDF) - May 20, 2018
  126. 126. Aphrodite react-with-styles-interface-aphrodite react-with-styles compile-time Create run-time Resolve <Component/>Attempt#2 CONTEXTUAL METHODS Sincewe’reinRTL-land, I’llflipthesestylesbefore passingthemback. @majapw 126 Do the Right (to Left) Thing (PDF) - May 20, 2018
  127. 127. Aphrodite react-with-styles-interface-aphrodite react-with-styles compile-time Create run-time Resolve <Component/>Attempt#2 CONTEXTUAL METHODS [ rtlCSSJS({ left: 40, }), ] @majapw 127 Do the Right (to Left) Thing (PDF) - May 20, 2018
  128. 128. Aphrodite react-with-styles-interface-aphrodite react-with-styles compile-time Create run-time Resolve <Component/>Attempt#2 CONTEXTUAL METHODS Hereyougo!Usethis: { style: { right: 40, }, } @majapw 128 Do the Right (to Left) Thing (PDF) - May 20, 2018
  129. 129. Aphrodite react-with-styles-interface-aphrodite react-with-styles compile-time Create run-time Resolve <Component/>Attempt#2 CONTEXTUAL METHODS Here.Spreadthisonto yourDOMnode.
 { style: { right: 40, }, } @majapw 129 Do the Right (to Left) Thing (PDF) - May 20, 2018
  130. 130. Attempt#2 CONTEXTUAL METHODS import { resolve, } from ‘react-with-styles’; function MyComponent({ styles }) { return ( <div {...resolve(styles.container)}> Hello World </div> ); } @majapw 130 Do the Right (to Left) Thing (PDF) - May 20, 2018
  131. 131. Attempt#2 CONTEXTUAL METHODS import { resolve, } from ‘react-with-styles’; function MyComponent({ styles }) { return ( <div {...resolve(styles.container)}> Hello World </div> ); } @majapw 131 Do the Right (to Left) Thing (PDF) - May 20, 2018
  132. 132. Attempt#2 CONTEXTUAL METHODS import { resolve, } from ‘react-with-styles’; function MyComponent({ resolve, styles }) { return ( <div {...resolve(styles.container)}> Hello World </div> ); } @majapw 132 Do the Right (to Left) Thing (PDF) - May 20, 2018
  133. 133. FinalResult SUCCESS! @majapw 133 Do the Right (to Left) Thing (PDF) - May 20, 2018
  134. 134. TrueLoveUnlocked MAHA & KHALID 4EVA @majapw 134 Do the Right (to Left) Thing (PDF) - May 20, 2018
  135. 135. airbnb/react-with-direction airbnb/react-with-styles kentcdodds/rtl-css-js Thankyou! @majapw 135 Do the Right (to Left) Thing (PDF) - May 20, 2018
  136. 136. 136 Do the Right (to Left) Thing (PDF) - May 20, 2018

×