Search code examples
reactjsmaterial-uiemotion

MUI v5 passing props to CSS theme using styled()


Previously, in Material-UI v4, I had this bit of code

const { customPadding } = props;
const classes = useStyles({
    padding: customPadding,
} as any);

To pass props to the classes of an element.

But v5 uses emotion instead of JSS, where I do something like this instead.

const StyledContainer = styled(Container)(({theme}: any) => ({
    [`&.${classes.FullPageLayoutRoot}`]: (props: any) => ({
        minHeight: `calc(100vh - ${appBarHeight}px - ${theme.spacing(1)} - 1px)`,
        display: 'flex',
    }),

    [`&.${classes.middle}`]: {
        alignItems: 'center',
    },

    [`& .${classes.paper}`]: (props: any) => ({
        backgroundColor: grey[800],
        marginBottom: theme.spacing(1),
        padding: theme.spacing(props.padding),
        minWidth: '100%',
    })
}));

...

return(
    <StyledContainer maxWidth={maxWidth} fixed className={clsx(classes.FullPageLayoutRoot, {
        [classes.middle]: middle,
    })}>
        <Paper className={clsx(classes.paper, classes.padding, className)} {...PaperProps} >
            {content}
        </Paper>
    </StyledContainer>
)

How would I accomplish this in Material-UI v5?


Solution

  • They're passed along with the theme property in the callback:

    const MyDiv = styled("div", {
      // indicate that this prop name should be used to conditionally
      // style the component only and should not be spread to the DOM element.
      shouldForwardProp: (propName) => propName !== "isRed"
    })(({ theme, isRed }) => ({
      backgroundColor: isRed ? "red" : theme.palette.primary.main
    }));
    
    export default function ThemeUsage() {
      return (
        <MyDiv isRed>Styled div with theme</MyDiv>
      );
    }
    

    Live Demo

    Codesandbox Demo