Reputation: 1450
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.
Upvotes: 15
Views: 19071
Reputation: 476
Now, you can style the icon prop directly with sx
:
<EleIcon sx={{ height: '2.5vh', width: '2.5vw' }} />
EleIcon
is the icon passed to my component
Upvotes: 1
Reputation: 880
Try this solution. Worked for me perfectly
Component
import MyLocationIcon from '@mui/icons-material/MyLocation';
<TextInputComp Icon={MyLocationIcon} />
Component code
function TextInputComp(p: any) {
const {Icon } = p;
return (
<Icon fontSize={'large'} />
)
}
Upvotes: 0
Reputation: 81166
There are three main alternatives:
Done
instead of <Done/>
) and then add the className
as you render the element (this is the approach in Fraction's answer).className
prop to it.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;
Upvotes: 23
Reputation: 12993
Pass the icon like this:
<MyComponentWithIconProps statusImage={Done} />
then use it as follows:
return <div><props.statusImage className={styles.iconStyle} /></div>;
Upvotes: 3
Reputation: 2472
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;
Upvotes: 0