问题
I'm using Material-Ui in my React Project !
i followed the steps in the documentation to allow RTL in my project and all work fine !
except the TextField Component
LTR DIRECTION :
RTL DIRECTION
Like you see ! the problem is with the label still in left ( the input text work fine )
App.js file
import React, {useState} from 'react';
//i18n
import {withTranslation} from "react-i18next";
import './i18n';
//jss
import { create } from 'jss';
import rtl from 'jss-rtl';
import { StylesProvider, jssPreset } from '@material-ui/core/styles';
// Configure JSS
const jss = create({ plugins: [...jssPreset().plugins, rtl()] });
function App(props) {
// initialize Language
const { i18n } = props;
const [ prefLang, setPrefLang] = useState(i18n.language);
let theme =createMuiTheme({
palette : {
primary : {
main : '#ed5ac0',
},
},
typography : {
fontFamily : "lalezar, cursive",
h3 : {
fontSize : 1.4,
},
h4 : {
fontSize : 1.5
},
fontAwseomeSize : {
xs : "14px",
sm : "14px",
md : "16px"
},
responsiveFont : {
xs : "20px",
sm : "12.5px",
md : "14px"
},
highLight : {
md : "25px"
},
subHighLight : {
md : "18px"
}
},
}
);
return (
<BrowserRouter>
<LangContext.Provider
value ={{
prefLang,
setPrefLang
}}
>
<CssBaseline/>
<ThemeProvider theme={theme}>
<StylesProvider jss={jss}>
<Grid dir={(prefLang === "ar") ? "rtl" : "ltr"}>
{/*<AppHeader/>*/}
<ContentRouter/>
</Grid>
</StylesProvider>
</ThemeProvider>
</LangContext.Provider>
</BrowserRouter>
);
}
export default withTranslation()(App);
My Form Component
const LoginForm = () => {
return (
<>
<Backdrop style={{ zIndex : 999 , color : theme.palette.primary.main}} open={backdrop} >
<CircularProgress color="inherit" />
</Backdrop>
<form onSubmit={formik.handleSubmit} style={{width: "100%", marginTop: "20px"}}>
{ userNotFound ? <Alert style={{marginBottom : "20px"}} variant="outlined" severity="error">
This is an error alert — check it out!
</Alert> : null}
<TextField
id="identifier"
name="identifier"
onChange={formik.handleChange}
value={formik.values.identifier}
label={t('formIdentifier')}
fullWidth
/>
{formik.touched.identifier && formik.errors.identifier ?
(
<Alert style={{ marginTop :"10px"}} variant="outlined" severity="error">{formik.errors.identifier}</Alert>
) : null}
<TextField
style={{marginTop: "50px"}}
id="password"
name="password"
type="password"
onChange={formik.handleChange}
value={formik.values.password}
label={t('formPassword')}
fullWidth
/>
{formik.touched.password && formik.errors.password ?
(
<Alert style={{ marginTop :"10px"}} variant="outlined" severity="error">{formik.errors.password}</Alert>
) : null}
<Button type="submit" color="primary">{t('login')}</Button>
</form>
</>
);
};
My Theme.js File
import createMuiTheme from "@material-ui/core/styles/createMuiTheme";
let theme =createMuiTheme({
direction : 'rtl',
palette : {
primary : {
main : '#ed5ac0',
},
},
typography : {
fontFamily : "Merienda One, sans-serif",
h3 : {
fontSize : 1.4,
},
h4 : {
fontSize : 1.5
},
fontAwseomeSize : {
xs : "14px",
sm : "14px",
md : "16px"
},
responsiveFont : {
xs : "20px",
sm : "12.5px",
md : "14px"
},
highLight : {
md : "40px"
}
},
}
);
export default theme;
Any suggestion to make the label RTL ?
回答1:
The documentation you linked to contains three steps for rtl support:
- Set the
dir
attribute on thebody
element.
In my example below, this is handled by the following:
React.useLayoutEffect(() => {
document.body.setAttribute("dir", isRtl ? "rtl" : "ltr");
}, [isRtl]);
- Set the
direction
in the theme.
In my example below, I am toggling between two themes:
const ltrTheme = createMuiTheme({ direction: "ltr" });
const rtlTheme = createMuiTheme({ direction: "rtl" });
...
<ThemeProvider theme={isRtl ? rtlTheme : ltrTheme}>
...
</ThemeProvider>
- Install the jss-rtl plugin.
For performance reasons it is important to avoid re-rendering StylesProvider
, so this should not be in a component with state that can change and therefore trigger a re-render. In my own app, I have the StylesProvider
element in my index.js
file as the first element inside the call to react-dom render
.
import rtl from "jss-rtl";
import {
StylesProvider,
jssPreset
} from "@material-ui/core/styles";
// Configure JSS
const jss = create({ plugins: [...jssPreset().plugins, rtl()] });
export default function App() {
return (
<StylesProvider jss={jss}>
<AppContent />
</StylesProvider>
);
}
The example below includes a TextField
and you can see that the label's position toggles correctly.
import React from "react";
import { create } from "jss";
import rtl from "jss-rtl";
import {
StylesProvider,
jssPreset,
ThemeProvider,
createMuiTheme
} from "@material-ui/core/styles";
import CssBaseline from "@material-ui/core/CssBaseline";
import TextField from "@material-ui/core/TextField";
import Button from "@material-ui/core/Button";
import Box from "@material-ui/core/Box";
// Configure JSS
const jss = create({ plugins: [...jssPreset().plugins, rtl()] });
const ltrTheme = createMuiTheme({ direction: "ltr" });
const rtlTheme = createMuiTheme({ direction: "rtl" });
function AppContent() {
const [isRtl, setIsRtl] = React.useState(false);
React.useLayoutEffect(() => {
document.body.setAttribute("dir", isRtl ? "rtl" : "ltr");
}, [isRtl]);
return (
<ThemeProvider theme={isRtl ? rtlTheme : ltrTheme}>
<CssBaseline />
<Box m={2}>
<TextField label={isRtl ? "بريد الكتروني او هاتف" : "Email or Phone"} />
<br />
<br />
Current Direction: {isRtl ? "rtl" : "ltr"}
<br />
<Button onClick={() => setIsRtl(!isRtl)}>Toggle direction</Button>
</Box>
</ThemeProvider>
);
}
export default function App() {
return (
<StylesProvider jss={jss}>
<AppContent />
</StylesProvider>
);
}
In addition, I have a later answer that discusses flipping icons: material-ui icons won't flip when I change to RTL.
回答2:
Another solution I've found to set this for specific component is to add it via native JS after component is rendered.
First I created a ref to the input element:
const inputRef = createRef()
<TextField inputRef={inputRef} />
Then added a useEffect hook to perform once on each render:
useEffect(() => {
if(inputRef)
inputRef.current.dir = 'auto'
}, [])
Not the most beautiful code, but it sure works 😉
来源:https://stackoverflow.com/questions/62799638/material-ui-textfield-not-affected-with-the-rtl-direction