I'm using Material UI in react. Let's say I have this component with these styles:
const useStyles = makeStyles(theme => ({
outerDiv: {
backgroundColor: theme.palette.grey[200],
padding: theme.spacing(4),
'&:hover': {
cursor: 'pointer',
backgroundColor: theme.palette.grey[100]
}
},
addIcon: (props: { dragActive: boolean }) => ({
height: 50,
width: 50,
color: theme.palette.grey[400],
marginBottom: theme.spacing(2)
})
}));
function App() {
const classes = useStyles();
return (
<Grid container>
<Grid item className={classes.outerDiv}>
<AddIcon className={classes.addIcon} />
</Grid>
</Grid>
);
}
I want to change the style of addIcon
when hovering over outerDiv
using the styles above.
Here's my example.
Below is an example of the correct syntax for v4 ("& $addIcon"
nested within &:hover
). Further down are some v5 examples.
import * as React from "react";
import { render } from "react-dom";
import { Grid, makeStyles } from "@material-ui/core";
import AddIcon from "@material-ui/icons/Add";
const useStyles = makeStyles(theme => ({
outerDiv: {
backgroundColor: theme.palette.grey[200],
padding: theme.spacing(4),
'&:hover': {
cursor: 'pointer',
backgroundColor: theme.palette.grey[100],
"& $addIcon": {
color: "purple"
}
}
},
addIcon: (props: { dragActive: boolean }) => ({
height: 50,
width: 50,
color: theme.palette.grey[400],
marginBottom: theme.spacing(2)
})
}));
function App() {
const classes = useStyles();
return (
<Grid container>
<Grid item className={classes.outerDiv}>
<AddIcon className={classes.addIcon} />
</Grid>
</Grid>
);
}
const rootElement = document.getElementById("root");
render(<App />, rootElement);
Related documentation and answers:
For those who have started using Material-UI v5, the example below implements the same styles but leveraging the new sx
prop.
import Grid from "@mui/material/Grid";
import { useTheme } from "@mui/material/styles";
import AddIcon from "@mui/icons-material/Add";
export default function App() {
const theme = useTheme();
return (
<Grid container>
<Grid
item
sx={{
p: 4,
backgroundColor: theme.palette.grey[200],
"&:hover": {
backgroundColor: theme.palette.grey[100],
cursor: "pointer",
"& .addIcon": {
color: "purple"
}
}
}}
>
<AddIcon
className="addIcon"
sx={{
height: "50px",
width: "50px",
color: theme.palette.grey[400],
mb: 2
}}
/>
</Grid>
</Grid>
);
}
Here's another v5 example, but using Emotion's styled
function rather than Material-UI's sx
prop:
import Grid from "@mui/material/Grid";
import { createTheme, ThemeProvider } from "@mui/material/styles";
import AddIcon from "@mui/icons-material/Add";
import styled from "@emotion/styled/macro";
const StyledAddIcon = styled(AddIcon)(({ theme }) => ({
height: "50px",
width: "50px",
color: theme.palette.grey[400],
marginBottom: theme.spacing(2)
}));
const StyledGrid = styled(Grid)(({ theme }) => ({
padding: theme.spacing(4),
backgroundColor: theme.palette.grey[200],
"&:hover": {
backgroundColor: theme.palette.grey[100],
cursor: "pointer",
[`${StyledAddIcon}`]: {
color: "purple"
}
}
}));
const theme = createTheme();
export default function App() {
return (
<ThemeProvider theme={theme}>
<Grid container>
<StyledGrid item>
<StyledAddIcon />
</StyledGrid>
</Grid>
</ThemeProvider>
);
}
And one more v5 example using Emotion's css prop:
/** @jsxImportSource @emotion/react */
import Grid from "@mui/material/Grid";
import { createTheme, ThemeProvider } from "@mui/material/styles";
import AddIcon from "@mui/icons-material/Add";
const theme = createTheme();
export default function App() {
return (
<ThemeProvider theme={theme}>
<Grid container>
<Grid
item
css={(theme) => ({
padding: theme.spacing(4),
backgroundColor: theme.palette.grey[200],
"&:hover": {
backgroundColor: theme.palette.grey[100],
cursor: "pointer",
"& .addIcon": {
color: "purple"
}
}
})}
>
<AddIcon
className="addIcon"
css={(theme) => ({
height: "50px",
width: "50px",
color: theme.palette.grey[400],
marginBottom: theme.spacing(2)
})}
/>
</Grid>
</Grid>
</ThemeProvider>
);
}