How do I style a material-ui Icon which was passed as prop

£可爱£侵袭症+ 提交于 2019-12-24 03:43:30

问题


I'm writing a custom Material UI React component which I want to pass an Icon into as a prop. However I want to style the icon when I get it and make it a minimum width and height.

Here's a simplified version of what I'm trying to do. I want to apply the iconStyle to the icon passed in as props.statusImage but can't figure out how.

import PropTypes from "prop-types";
import { makeStyles } from "@material-ui/styles";

const useStyles = makeStyles({
  iconStyle: {
    minWidth: 100,
    minHeight: 100
  }
});

function MyComponentWithIconProps(props) {
  const styles = useStyles();

  return <div>{props.statusImage}</div>;
}

MyComponentWithIconProps.propTypes = {
  statusImage: PropTypes.element
};

export default MyComponentWithIconProps;

I use the component like this

import {Done} from "@material-ui/icons";
<MyComponentWithIconProps statusImage={<Done/>}

Code Sandbox : https://codesandbox.io/s/jovial-fermi-dmb0p

I've also tried wrapping the supplied Icon in another Icon element and attempting to style that. However that didn't work and seems sort of 'hacky' anyway.


回答1:


There are three main alternatives:

  1. Pass in the element type of the icon rather than an element (e.g. Done instead of <Done/>) and then add the className as you render the element (this is the approach in Fraction's answer).
  2. Clone the element in order to add the className prop to it.
  3. Put a class on the parent element and target the appropriate child type (e.g. svg).

Approach 1:

index.js

import React from "react";
import ReactDOM from "react-dom";
import { Done } from "@material-ui/icons";
import MyComponentWithIconProps from "./MyComponentWithIconProps";

function App() {
  return (
    <div className="App">
      <MyComponentWithIconProps statusImage={Done} />
    </div>
  );
}

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

MyComponentWithIconProps.js

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

const useStyles = makeStyles({
  iconStyle: {
    minWidth: 100,
    minHeight: 100
  }
});

function MyComponentWithIconProps(props) {
  const styles = useStyles();
  const StatusImage = props.statusImage;
  return (
    <div>
      <StatusImage className={styles.iconStyle} />
    </div>
  );
}

MyComponentWithIconProps.propTypes = {
  statusImage: PropTypes.element
};

export default MyComponentWithIconProps;


Approach 2:

index.js

import React from "react";
import ReactDOM from "react-dom";
import { Done } from "@material-ui/icons";
import MyComponentWithIconProps from "./MyComponentWithIconProps";

function App() {
  return (
    <div className="App">
      <MyComponentWithIconProps statusImage={<Done />} />
    </div>
  );
}

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

MyComponentWithIconProps.js

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

const useStyles = makeStyles({
  iconStyle: {
    minWidth: 100,
    minHeight: 100
  }
});

function MyComponentWithIconProps(props) {
  const styles = useStyles();
  const styledImage = React.cloneElement(props.statusImage, {
    // Using clsx to combine the new class name with any existing ones that may already be on the element
    className: clsx(styles.iconStyle, props.statusImage.className)
  });
  return <div>{styledImage}</div>;
}

MyComponentWithIconProps.propTypes = {
  statusImage: PropTypes.element
};

export default MyComponentWithIconProps;


Approach 3:

index.js

import React from "react";
import ReactDOM from "react-dom";
import { Done } from "@material-ui/icons";
import MyComponentWithIconProps from "./MyComponentWithIconProps";

function App() {
  return (
    <div className="App">
      <MyComponentWithIconProps statusImage={<Done />} />
    </div>
  );
}

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

MyComponentWithIconProps.js

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

const useStyles = makeStyles({
  iconStyle: {
    "& > svg": {
      minWidth: 100,
      minHeight: 100
    }
  }
});

function MyComponentWithIconProps(props) {
  const styles = useStyles();
  return <div className={styles.iconStyle}>{props.statusImage}</div>;
}

MyComponentWithIconProps.propTypes = {
  statusImage: PropTypes.element
};

export default MyComponentWithIconProps;




回答2:


Pass the icon like this:

<MyComponentWithIconProps statusImage={Done} />

then use it as follows:

return <div><props.statusImage className={styles.iconStyle} /></div>;



回答3:


I would do like this:

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

const useStyles = makeStyles({
  iconStyle: {
    minWidth: 100,
    minHeight: 100,
    color: "red"
  }
});

function MyComponentWithIconProps(props) {
  const styles = useStyles();

  return <div className={styles.iconStyle}>{props.statusImage}</div>;
}

MyComponentWithIconProps.propTypes = {
  statusImage: PropTypes.element
};

export default MyComponentWithIconProps;


来源:https://stackoverflow.com/questions/58878858/how-do-i-style-a-material-ui-icon-which-was-passed-as-prop

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!