Netanel Vaknin
Netanel Vaknin

Reputation: 1153

How to configure RTL (Right to Left) support in Material UI version 5

I updated my app to Material-UI version 5 from version 4 and the RTL support is not working anymore.

I looked at the docs and followed each of the steps:

https://mui.com/guides/right-to-left/

The actual result is the application is still LTR (You can look at the TextField component in the Codesandbox link below).

The expected result is the app should be RTL.

And still, The RTL support is not working.

In addition, I created an example version in Codesandbox :

https://codesandbox.io/s/issue-with-rtl-in-material-ui-v5-jtii6?file=/src/index.js

I'll appreciate your help in finding what is the problem.

Thanks.

Upvotes: 9

Views: 6676

Answers (4)

I placed my component (in my case TableContainer) within a div with direction: 'rtl' as prop. the direction of TableContainer also changed to 'rtl' :)

Upvotes: 0

Ilham Meidi
Ilham Meidi

Reputation: 1

For MUI 5 need to import rtlPlugin from 'stylis-plugin-rtl'; and import createCache from '@emotion/cache';

Here's the code:

import React, { useState } from 'react';
import { makeStyles } from 'tss-react/mui';
import { ThemeProvider, createTheme } from '@mui/material/styles';
import { CacheProvider } from '@emotion/react';
import createCache from '@emotion/cache';
import rtlPlugin from 'stylis-plugin-rtl';
import { prefixer } from 'stylis';

const isBrowser = typeof document !== 'undefined';
let insertionPoint;

if (isBrowser) {
  const emotionInsertionPoint = document.querySelector(
    'meta[name="emotion-insertion-point"]',
  );
  insertionPoint = emotionInsertionPoint ?? undefined;
}

const cacheRTL = createCache({
  key: 'mui-style-rtl',
  stylisPlugins: [prefixer, rtlPlugin],
  insertionPoint,
});

export const ThemeContext = React.createContext(undefined);

function ThemeWrapper(props) {
  const theme = useState({
    direction: 'rtl' 
  });
  const muiTheme = createTheme(theme);
  const { children } = props;

  return (
    <CacheProvider value={cacheRTL}>
      <ThemeProvider theme={muiTheme}>
        <div>
          <ThemeContext.Provider>
            {children}
          </ThemeContext.Provider>
        </div>
      </ThemeProvider>
    </CacheProvider>
  );
}

export default ThemeWrapperMapped;

Here's the implementation in my project https://github.com/ilhammeidi/dandelion-starter/blob/master/app/containers/App/ThemeWrapper.js

Upvotes: 0

Itay
Itay

Reputation: 429

It took me a while to handle this issue! I eventually used document.dir + all of MUI's docs instructions.

Here's my code live in CodeSandbox (it toggles direction + MUI language + date-pickers + theme-mode): https://codesandbox.io/p/sandbox/quizzical-zhukovsky-lvq2fs?file=%2Fsrc%2FSupportedLocales.ts%3A10%2C33

I wrote a very long article about it: https://medium.com/@itayperry91/react-and-mui-change-muis-theme-mode-direction-and-language-including-date-pickers-ad8e91af30ae

enter image description here

enter image description here

Upvotes: 1

Mohammad Taheri
Mohammad Taheri

Reputation: 474

I had this problem using Persian language. But it's answer is too easy. you just need some simple steps. My Example environment is:

  1. "react": "^18.2.0"
  2. "react-dom": "^18.2.0"

Lets do it:

Step 1: install below packages (I give you exact versions to be sure it works in case of future updates):

  • "@emotion/react": "^11.9.3"
  • "@emotion/styled": "^11.9.3"
  • "@mui/icons-material": "^5.8.4"
  • "@mui/material": "^5.9.1"
  • "stylis": "^4.1.1"
  • "stylis-plugin-rtl": "^2.1.1"

hint: this is my package.json file:

enter image description here

Step 2: Change direction of html tag in public/index.html like this:

`<html lang="fa" dir="rtl">`

Step 3: Add below section in index.js file:

3-1 : required imports:

import {createTheme, ThemeProvider} from '@mui/material/styles';
import rtlPlugin from 'stylis-plugin-rtl';
import {prefixer} from 'stylis';
import {CacheProvider} from '@emotion/react';
import createCache from '@emotion/cache';

3-2 : required cache:

const cacheRtl = createCache({
   key: 'muirtl',
   stylisPlugins: [prefixer, rtlPlugin],
});

3-3 : required theme:

const theme = createTheme({
  direction: 'rtl',
});

3-4: This is Final Step in which you wrap two wrapper around your component like this:

<CacheProvider value={cacheRtl}>
  <ThemeProvider theme={theme}>
    <App/>
  </ThemeProvider>
</CacheProvider>

Finally, your completed index.js file should be exactly like this:

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import {createTheme, ThemeProvider} from '@mui/material/styles';
import rtlPlugin from 'stylis-plugin-rtl';
import {prefixer} from 'stylis';
import {CacheProvider} from '@emotion/react';
import createCache from '@emotion/cache';

const cacheRtl = createCache({
  key: 'muirtl',
  stylisPlugins: [prefixer, rtlPlugin],
});
const theme = createTheme({
  direction: 'rtl',
});

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <CacheProvider value={cacheRtl}>
    <ThemeProvider theme={theme}>
      <App/>
    </ThemeProvider>
  </CacheProvider>
);

Now your Entire application is rtl. I show you an persian example with images to see this:

Change your App.jsx component like this:

import React from 'react';
import {Autocomplete, Box, TextField} from "@mui/material";

const App = () => {
  return (
    <Box m={2}>
      <Autocomplete
        sx={{width: 300}}
        options={iranStates}
        onChange={(event, value) => console.log(value)}
        renderInput={(params) => <TextField {...params} label={"لیست استانها"}/>}/>
    </Box>
  );
};

export default App;

const iranStates = [
  "آذربایجان شرقی",
  "آذربایجان غربی",
  "اردبیل",
  "اصفهان",
  "البرز",
  "ایلام",
  "بوشهر",
  "تهران",
  "چهارمحال و بختیاری",
]

and see the result:

enter image description here

Upvotes: 25

Related Questions