palantir / blueprint

A React-based UI toolkit for the web
https://blueprintjs.com/
Apache License 2.0
20.71k stars 2.17k forks source link

Right-to-left support #4760

Open abouolia opened 3 years ago

abouolia commented 3 years ago

Unfortunately Blueprint doesn't support RTL at all, we work on a product that supports some RTL languages, we're ready to put a huge effort to make all Blueprint components support RTL out of the box on the main repository, but this feature will add major changes to the code, let me give an example.

One of the biggest challenges, passing RTL state to all sub-components, that won't be done without a parent Provider wraps all Blueprint components.

Example:

<ThemeProvider>
  <Menu>
    <MenuItem />
  </Menu>
</ThemeProvider>

I wanted to know in case we sent a pull request that has major modifications, it will be reviewed and approved?

adidahiya commented 3 years ago

We have extremely basic support for RTL text documented in the typography section of the docs: https://blueprintjs.com/docs/#core/typography.right-to-left-text

I would be open to adding more robust RTL support to components. It could be done with React context and a theme provider, as we are moving towards a minimum dependency of React 16.8+ in Blueprint 4.0.

Before you send a PR, can you write a design proposal of what changes you wish to pursue and how you will do them? I'll leave comments on the proposal.

abouolia commented 3 years ago

To make Blueprintjs components library fully RTL supportive there are two sides we should think about. CSS RTL transformation and Passing direction context state

CSS RTL transformation My proposal about this issue is to depend on RTLCSS and postcss-rtlcss to build LTR/RTL rules, but this requires reviewing all components visually, after a quick test on my environment there are no a major problems, almost 98% of components don’t have any issue except to some places need some css and comments such as /! rtl:ignore /.

The disadvantage of LTR/RTL rules on the same stylesheet requires extra lines that are not used when using one direction, but currently there is no more elegant solution for CSS RTL transformation (after tons of search).

Passing direction context state The second issue is passing direction context state to all sub-components. First proposal: depending on React context and provider. e.g.

<ConfigProvider direction="rtl">
  <Menu>
      <MenuItem />
    </Menu>
</ConfigProvider> 

Second proposal: depending on closest DOM className. e.g.

<div|body class=”bp3-direction-rtl or bp3-direction--rtl”>
  <Menu>
    <MenuItem />
  </Menu>
</div|body>

with isRTLDirection()|isLTRDirection()utility to determine the direction based on closest DOM has the bp3-direction--rtl className. From my perspective, I prefer React context and provider solution, probably in the future there will be another global config state and to make all Blueprintjs direction reactive with state changing.