Reputation: 3675
I am using Material UI with React. Trying to override the TextField
component style which has been setup using a global theme. I have setup a global theme for all TextField
components in the app.
Relevant code:
theme-engine.js
:
export const theme = brand => createMuiTheme({
palette: {
primary: {
main: Brand.getColors(brand).primary
},
secondary: {
main: Brand.getColors(brand).secondary
},
},
typography: {
fontFamily,
fontSize: 14,
htmlFontSize: 16
},
overrides: {
MuiInputBase: {
root: {
color: 'rgba(0, 0, 0, 0.87)',
fontSize: '14px',
fontFamily,
'&:after': {
borderBottom: Brand.getColors(brand).primary,
backgroundColor: Brand.getColors(brand).primary,
height: 1
},
'&:focused:not($disabled):not($error):before': {
borderBottom: Brand.getColors(brand).primary,
backgroundColor: Brand.getColors(brand).primary,
height: 1
},
'&$error:before': {
borderBottom: '#f44336',
backgroundColor: '#f44336',
height: 1
},
},
},
MuiInput: {
root: {
fontFamily
},
underline: {
'&:hover:not($disabled):not($error):not($focused):before': {
borderBottom: '#e0e0e0',
backgroundColor: '#e0e0e0',
height: 1
},
'&:not($disabled):not($error):after': {
borderBottom: Brand.getColors(brand).primary,
backgroundColor: Brand.getColors(brand).primary,
height: 1
},
'&$error:before': {
borderBottom: '#f44336',
backgroundColor: '#f44336',
height: 1
},
'&$error:after': {
borderBottom: '#f44336',
backgroundColor: '#f44336',
height: 1
},
},
},
MuiSvgIcon: {
colorPrimary: {
fill: '#74797b'
},
colorSecondary: {
fill: Brand.getColors(brand).primary,
}
},
}
});
container.js
:
render() {
return (
<MuiThemeProvider theme={theme(brand)}>
//stuff goes here
</MuiThemeProvider>
)
}
Now in one of the components, I am using an icon for the TextField
and want the underline to come under the icon as well. For that I am trying to override the provided theme, which isn't working. The styles from the theme-engine
are applied, but the local override isn't working.
some-component.js
import TextField from '@material-ui/core/TextField';
import {withStyles} from '@material-ui/core/styles';
const TextFieldIcon = withStyles(theme => ({
root: {
underline: {
color: 'red',
height: 4,
'&:before': {
borderBottom: `1px solid #e0e0e0`,
bottom: '-8px',
left: '-32px'
},
'&:hover:not($disabled):not($error):not($focused):before': {
borderBottom: 'red',
backgroundColor: 'red',
height: 1,
bottom: '-8px',
left: '-32px'
},
'&:not($disabled):not($error):after': {
height: 2,
bottom: '-8px',
left: '-32px'
},
'&$error:before': {
height: 1,
bottom: '-8px',
left: '-32px'
},
'&$error:after': {
height: 1,
bottom: '-8px',
left: '-32px'
},
},
}
}))(TextField);
class SomeComponent extends Component{
//Lifecycle methods to make your life easier....or difficult.
render(){
return(
<TextFieldIcon {...assign props and stuff} /> //Styles are not applied
)
}
}
So the question is, I want to keep the custom global theme, but also override some parts of it in my component. Any inputs appreciated.
Upvotes: 1
Views: 3325
Reputation: 80986
I see a few issues:
underline
rule nested under root
. You should be able to just remove the outer root
block$disabled
, $error
, and $focused
), those rules need to be defined within the styles object you pass to withStyles
withStyles
are the classes for the Input
component wrapped by TextField
, so you need to pass them via the InputProps
propertyBelow is a working example of the syntax you need. I have not tried to assess whether the styles are doing what you intend, but they are definitely being applied.
import React from "react";
import TextField from "@material-ui/core/TextField";
import { withStyles } from "@material-ui/core/styles";
const styles = theme => ({
underline: {
color: "red",
height: 4,
"&:before": {
borderBottom: `1px solid #e0e0e0`,
bottom: "-8px",
left: "-32px"
},
"&:hover:not($disabled):not($error):not($focused):before": {
borderBottom: "red",
backgroundColor: "red",
height: 1,
bottom: "-8px",
left: "-32px"
},
"&:not($disabled):not($error):after": {
height: 2,
bottom: "-8px",
left: "-32px"
},
"&$error:before": {
height: 1,
bottom: "-8px",
left: "-32px"
},
"&$error:after": {
height: 1,
bottom: "-8px",
left: "-32px"
}
},
disabled: {},
error: {},
focused: {}
});
const CustomTextField = ({ classes, ...other }) => {
return <TextField InputProps={{ classes: classes }} {...other} />;
};
export default withStyles(styles)(CustomTextField);
Upvotes: 1