I'm wrapping MUI's Chip
component so that I can pass in values other than "primary" and "secondary" for the colors
prop. I also want to maintain the hover effect if the chip is clickable so that the chip transitions to a different color when the cursor is over it. The colors are passed in as props, so it's easy enough to set the backgroundColor
and color
:
<Chip
style={{
backgroundColor: props.backgroundColor,
color: props.color
}}
/>
However, since I'd also like to pass in the hover color as a prop, I'd need to do something like this:
<Chip
style={{
backgroundColor: props.backgroundColor,
color: props.color,
'&:hover': {
backgroundColor: props.hoverBackgroundColor,
color: props.hoverColor
}
}}
/>
However, the &:hover
(as far as I know) can't be used inside of the style
prop. Typically, the &:hover
would be used inside of a styles object that is passed into withStyles
, but I'm not able to access props from in there. Any suggestions?
Where the props are used to set the initial state of the Component is a general anti-pattern of React. This implies that the state of the component is tied to the props of the component. The issue with doing this is that the constructor is only ever called once in the life cycle of the component.
To pass props, add them to the JSX, just like you would with HTML attributes. To read props, use the function Avatar({ person, size }) destructuring syntax.
Use state to store the data your current page needs in your controller-view. Use props to pass data & event handlers down to your child components. These lists should help guide you when working with data in your components.
You can achieve this by creating your own custom chip component. In order to be able to use props to control the styling, you can use the makeStyles
. The makeStyles
function returns a hook that can accept an object parameter for providing variables to your styles.
Here's a possible CustomChip implementaton:
import React from "react";
import Chip from "@material-ui/core/Chip";
import { makeStyles } from "@material-ui/core/styles";
import { emphasize } from "@material-ui/core/styles/colorManipulator";
const useChipStyles = makeStyles({
chip: {
color: ({ color }) => color,
backgroundColor: ({ backgroundColor }) => backgroundColor,
"&:hover, &:focus": {
backgroundColor: ({ hoverBackgroundColor, backgroundColor }) =>
hoverBackgroundColor
? hoverBackgroundColor
: emphasize(backgroundColor, 0.08)
},
"&:active": {
backgroundColor: ({ hoverBackgroundColor, backgroundColor }) =>
emphasize(
hoverBackgroundColor ? hoverBackgroundColor : backgroundColor,
0.12
)
}
}
});
const CustomChip = ({
color,
backgroundColor,
hoverBackgroundColor,
...rest
}) => {
const classes = useChipStyles({
color,
backgroundColor,
hoverBackgroundColor
});
return <Chip className={classes.chip} {...rest} />;
};
export default CustomChip;
The styling approach (including the use of the emphasize
function to generate the hover and active colors) is based on the approach used internally for Chip
.
This can then be used like this:
<CustomChip
label="Custom Chip 1"
color="green"
backgroundColor="#ccf"
onClick={() => {
console.log("clicked 1");
}}
/>
<CustomChip
label="Custom Chip 2"
color="#f0f"
backgroundColor="#fcc"
hoverBackgroundColor="#afa"
onClick={() => {
console.log("clicked 2");
}}
/>
Here's a CodeSandbox demonstrating this:
Here's a Material-UI v5 version of the example:
import Chip from "@material-ui/core/Chip";
import { styled } from "@material-ui/core/styles";
import { emphasize } from "@material-ui/core/styles";
import { shouldForwardProp } from "@material-ui/system";
function customShouldForwardProp(prop) {
return (
prop !== "color" &&
prop !== "backgroundColor" &&
prop !== "hoverBackgroundColor" &&
shouldForwardProp(prop)
);
}
const CustomChip = styled(Chip, { shouldForwardProp: customShouldForwardProp })(
({ color, backgroundColor, hoverBackgroundColor }) => ({
color: color,
backgroundColor: backgroundColor,
"&:hover, &:focus": {
backgroundColor: hoverBackgroundColor
? hoverBackgroundColor
: emphasize(backgroundColor, 0.08)
},
"&:active": {
backgroundColor: emphasize(
hoverBackgroundColor ? hoverBackgroundColor : backgroundColor,
0.12
)
}
})
);
export default CustomChip;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With