How to add RTL support for Material UI React
I think I found a solution to my own question, however feel free to add any enhancement or better solution.
Material UI is using jss-rtl by default and this last one is a wrapper for rtl-css-js. So there is no need to use rtl-css-js directly in since Material UI will do the job.
I changed my Parent App component to :
import React, { PureComponent } from "react";
import Routes from "./Routes";
import RTL from "./RTL";
// Redux
import { Provider } from "react-redux";
import store from "./app/store";
import LoadingBar from "react-redux-loading-bar";
import { themeObject, colors } from "./styling/theme";
class App extends PureComponent {
render() {
return (
<Provider store={store}>
<RTL>
<>
<LoadingBar
// className="loading"
style={{
backgroundColor: colors.primary[500],
height: themeObject.spacing.unit,
zIndex: 9999
}}
/>
<Routes />
</>
</RTL>
</Provider>
);
}
}
export default App;
And I added RTL component which will connect to Redux to define the correct theme with the right direction. I'm saving the language data in Redux, and according the this data I will define the theme provided for my application.
This is the RTL component :
import React, { PureComponent } from "react";
import PropTypes from "prop-types";
// Redux
import { connect } from "react-redux";
// CSS
import { MuiThemeProvider, createMuiTheme } from "@material-ui/core/styles";
import { create } from "jss";
import rtl from "jss-rtl";
import JssProvider from "react-jss/lib/JssProvider";
import { createGenerateClassName, jssPreset } from "@material-ui/core/styles";
// Theme
import { themeObject } from "./styling/theme";
// Helpers
import get from "lodash/get";
// Configure JSS
const jss = create({ plugins: [...jssPreset().plugins, rtl()] });
const generateClassName = createGenerateClassName();
const G_isRtl = document.body.getAttribute("dir") === "rtl";
class RTL extends PureComponent {
static propTypes = {
children: PropTypes.oneOfType([
PropTypes.array,
PropTypes.object,
PropTypes.node
]),
language: PropTypes.object
};
render() {
const { children, language } = this.props;
const isRtl = get(language, "rtl", G_isRtl);
const theme = createMuiTheme({
...themeObject,
direction: isRtl ? "rtl" : "ltr"
});
return (
<JssProvider jss={jss} generateClassName={generateClassName}>
<MuiThemeProvider theme={theme}>{children}</MuiThemeProvider>
</JssProvider>
);
}
}
const mapStateToProps = ({ classified }) => ({
language: classified.language
});
export default connect(mapStateToProps)(RTL);
All the children components now will switch between RTL and LTR according to the language and we can focus on only one layout, all the reversing job is done thanks to this Plugins.
Also I want to say folowing the instructions in the official documentation does not work for me ! Most of this solution that I found is based on the answer here.