覆盖Material-UI样式

时间:2019-09-30 19:51:20

标签: css reactjs material-ui

我发现了许多有关覆盖样式的文章,但与我遇到的问题完全不同。我正在创建样式化的Material-ui组件,并将其导入应用程序的不同部分。我希望能够从各个父级组件中覆盖一些样式。

我有一个按钮组件:

import React from "react";
import { makeStyles } from "@material-ui/styles";

const useStyles = makeStyles({
  buttonBlue: {
    background: "#09a1e2",
    border: "1px solid #09a1e2",
    borderRadius: "5px",
    color: "#ffffff",
    cursor: "pointer",
    fontSize: "1.25rem",
    padding: ".75rem 1.25rem .75rem 1.25rem",
    "&:hover": {
      backgroundColor: "#ffffff",
      color: "#09a1e2"
    }
  },
  buttonWhite: {
    background: "#ffffff",
    border: "1px solid #666666",
    borderRadius: "5px",
    cursor: "pointer",
    fontSize: "1rem",
    padding: ".5rem",
    width: "6rem",
    "&:hover": {
      backgroundColor: "#666666",
      color: "#ffffff"
    }
  }
});

const MediumButton = props => {
  const color = props.color;
  const classes = useStyles();
  return (
    <div>
      {color === "blue" ? (
        <button className={classes.buttonBlue}>{props.buttonText}</button>
      ) : (
        <button className={classes.buttonWhite}>{props.buttonText}</button>
      )}
    </div>
  );
};

export default MediumButton;

我将导入另一个组件。我想在我的新组件中覆盖其中一些样式,但是我不太清楚该怎么做。

这是我正在尝试的:

import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import { withContext } from "../../context/AppContext";
import MediumButton from "../components/MediumButton";

const useStyles = makeStyles({
    root : {
        display: "flex",
    },
    homeButton: {
        background: "white",
        border: "1px solid #09a1e2",
        borderRadius: "5px",
        color: "#09a1e2",
        cursor: "pointer",
        fontSize: "1.25rem",
        padding: ".5rem 3.25rem .5rem 3.25rem",
        textDecoration: 'none',
        "&:hover": {
            backgroundColor: "#ffffff",
            color: "#09a1e2"
        }

    }
});

const PageNotFound = () => {

  const classes = useStyles();
  return (
    <div className={classes.root}>

      <MediumButton className={classes.homeButton} />
    </div>
  );
};

export default withContext(PageNotFound);

我不确定需要调用什么来覆盖我在MediumButton组件上设置的样式。

2 个答案:

答案 0 :(得分:1)

自创建 MediumButton 以来,您可以决定如何允许其他组件覆盖默认样式。

选项1:

替换整个默认样式
是从父亲那里发送className属性(就像您一样),并在 MediumButton 中应用以下样式(如果提供):

const MediumButton = props => {
  const { className, color } = props;
  const classes = useStyles();

  return (
    <div>
      {color === "blue" ? (
        <button className={className || classes.buttonBlue}>{props.buttonText}</button>
      ) : (
        <button className={className || classes.buttonWhite}>{props.buttonText}</button>
      )}
    </div>
  );
};

Edit Invisible Backdrop

选项2:

仅替换所需的属性,并保留默认样式。
将additonalStyles属性发送到MediumButton,并以makeStyles处理它们:

import React from "react";
import { makeStyles } from "@material-ui/styles";

const useStyles = makeStyles({
  ........your other styles........
  additionalStyles: props => ({
    ...props
  }),
});

const MediumButton = props => {
  const { additionalStyles, color } = props;
  const classes = useStyles(additionalStyles);

  return (
    <div>
      {color === "blue" ? (
        <button className={`${classes.buttonBlue} ${classes.additionalStyles}`}>
          {props.buttonText}
        </button>
      ) : (
        <button className={`${classes.buttonWhite} ${classes.additionalStyles}`}>
          {props.buttonText}
        </button>
      )}
    </div>
  );
};

export default MediumButton;

Edit Invisible Backdrop

答案 1 :(得分:0)

如果您允许指定className属性,则可以将该CSS类另外应用到组件所应用的CSS类中(而不是而不是< / strong>,如Ido的选项1)所示。如果替代项是使用makeStyles创建的,则只要导入了组件之后,对替代项的makeStyles调用称为 ,它们就将取代默认样式。最后请提供答案,以获取有关这方面的更多详细信息-使用典型用法,就可以按照您想要的方式进行操作。

下面是一个可行的示例。有关我的示例MediumButton版本的其他方面,请注意:

  • 使用children而不是buttonText道具
  • 放置始终应用的通用样式(无论使用哪种color prop ) into a separate CSS class ( mediumButton`,它们都应相同)
  • button中未明确使用的所有其他道具传递到MediumButton元素。这样可以轻松传递事件处理程序(例如onClick)或button支持的其他属性(例如disabled),而无需在MediumButton中添加额外的代码来处理这些事件道具。
  • 使用clsx方便地组合多个类名。 clsx是在Material-UI内部使用的,因此不会增加捆绑包的大小。

MediumButton.js

import React from "react";
import { makeStyles } from "@material-ui/styles";
import clsx from "clsx";

const useStyles = makeStyles({
  mediumButton: {
    borderRadius: "5px",
    cursor: "pointer",
    fontSize: "1.25rem",
    padding: ".75rem 1.25rem .75rem 1.25rem",
    margin: 8
  },
  buttonBlue: {
    background: "#09a1e2",
    border: "1px solid #09a1e2",
    color: "#ffffff",
    "&:hover": {
      backgroundColor: "#ffffff",
      color: "#09a1e2"
    }
  },
  buttonWhite: {
    background: "#ffffff",
    border: "1px solid #666666",
    "&:hover": {
      backgroundColor: "#666666",
      color: "#ffffff"
    }
  }
});

const MediumButton = ({ className, children, color, ...other }) => {
  const classes = useStyles();
  return (
    <button
      {...other}
      className={clsx(
        classes.mediumButton,
        {
          [classes.buttonBlue]: color === "blue",
          [classes.buttonWhite]: color !== "blue"
        },
        className
      )}
    >
      {children}
    </button>
  );
};

export default MediumButton;

index.js

import React from "react";
import ReactDOM from "react-dom";
import { makeStyles } from "@material-ui/styles";

import MediumButton from "./MediumButton";

const useStyles = makeStyles({
  homeButton: {
    background: "white",
    color: "#09a1e2",
    border: "1px solid #09a1e2",
    padding: ".5rem 3.25rem .5rem 3.25rem",
    textDecoration: "none",
    "&:hover": {
      backgroundColor: "#ffffff",
      color: "#09a1e2"
    }
  }
});
function App() {
  const classes = useStyles();
  return (
    <div className="App">
      <MediumButton onClick={() => alert("You clicked me!")}>
        White Button
      </MediumButton>
      <MediumButton color="blue">Blue Button</MediumButton>
      <MediumButton className={classes.homeButton}>Home Button</MediumButton>
      <MediumButton className={classes.homeButton} color="blue">
        Blue Home Button
      </MediumButton>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Edit custom component style overrides

了解通过makeStyles生成的多个类分层时哪种样式将获胜的相关答案: