React + Material UI - 覆盖组件中的 MuiTheme withStyles

React + Material UI - Overriding MuiTheme in component withStyles

我正在使用 Material UI 和 React。试图覆盖使用全局主题设置的 TextField 组件样式。我已经为应用程序中的所有 TextField 组件设置了一个全局主题。

相关代码:

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>
        )
    }

现在,在其中一个组件中,我为 TextField 使用了一个图标,并希望下划线也位于该图标下方。为此,我试图覆盖提供的主题,但它不起作用。来自 theme-engine 的样式已应用,但本地覆盖不起作用。

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
            )
        }
}

所以问题是,我想保留自定义全局主题,但也在我的组件中覆盖它的某些部分。任何意见表示赞赏。

我看到了几个问题:

  • 您不应在 root 下嵌套 underline 规则。您应该能够删除外部 root
  • 为了引用其他规则(例如 $disabled$error$focused),需要在传递给 [=17 的样式对象中定义这些规则=]
  • withStyles生成的类是TextField包裹的Input组件的类,所以需要通过InputProps 属性

下面是您需要的语法的工作示例。我没有尝试评估这些样式是否按照您的意图进行,但它们肯定被应用了。

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);