【问题标题】:React + Material UI - Overriding MuiTheme in component withStylesReact + Material UI - 在组件中覆盖 MuiTheme withStyles
【发布时间】:2019-10-06 23:57:37
【问题描述】:

我正在使用 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
            )
        }
}

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

【问题讨论】:

    标签: javascript reactjs material-ui higher-order-components


    【解决方案1】:

    我发现了一些问题:

    • 您不应将underline 规则嵌套在root 下。您应该可以删除外部的 root
    • 为了引用其他规则(例如$disabled$error$focused),需要在传递给withStyles 的样式对象中定义这些规则
    • withStyles生成的类是Input组件被TextField包裹的类,所以需要通过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);
    

    【讨论】:

    • 感谢您的意见。您的要点帮助我更多地了解了 withStyles HOC 的工作原理。
    猜你喜欢
    • 1970-01-01
    • 2019-06-14
    • 1970-01-01
    • 1970-01-01
    • 2018-04-11
    • 1970-01-01
    • 2021-06-06
    • 2021-02-19
    • 2019-01-14
    相关资源
    最近更新 更多