'How to use conditional styles with MUI v5 using emotion styled

I'm migrating from MUI v4 to v5. In v4 I was using clsx with TextField to add conditional styles.

export const useStyles = makeStyles((theme: Theme) =>
  createStyles({
    root: {
      // ...
    },
    valid: {
      "& fieldset": {
        borderColor: theme.palette.success.main,
        borderWidth: 2
      }
    }
  })
);

const classes = useStyles();
<TextField
  {...props}
  className={clsx(classes.root, { [classes.valid]: isValid })}
/>

I'm trying to find a similar approach in MUI v5. Is there any alternative for conditional styles in MUI v5 other than with clsx and makestyles.

Let me know if more information is required.



Solution 1:[1]

There are multiple ways to do that:

1. Conditional operator

Use this if you want to conditionally set a property based on a boolean value.

const Box1 = styled(Box, {
  shouldForwardProp: (prop) => prop !== "showBorder"
})(({ showBorder }) => ({
  border: showBorder ? "solid red 5px" : "none"
}));
<Box1 />
<Box1 showBorder />

2. Dictionary

Use this if you want to conditionally set a property based on multiple values.

import { styled, darken } from "@mui/material/styles";

const colors = {
  hauntedForest: "#0b5b38",
  redLust: "#b20608",
  spaceExplorer: "#1244a1",
  default: "#000000"
};

const Box2 = styled(Box, {
  shouldForwardProp: (prop) => prop !== "variant"
})(({ variant }) => ({
  backgroundColor: colors[variant] ?? colors.default,
  border: "5px solid " + darken(colors[variant] ?? colors.default, 0.3)
}));
<Box2 variant="hauntedForest" />
<Box2 variant="redLust" />
<Box2 variant="spaceExplorer" />
<Box2 />

3. Short-circuit evaluation + Spread operator

Use this if you want to conditionally set multiple properties.

const Box3 = styled(Box, {
  shouldForwardProp: (prop) => prop !== "isFancy" && prop !== "isFancyBorder"
})(({ theme, isFancy, isFancyBorder }) => ({
  ...(isFancy && {
    borderRadius: theme.shape.borderRadius,
    boxShadow: "0 4px 6px gray, 0 1px 3px rgba(0, 0, 0, 0.08)",
    backgroundImage: "linear-gradient(90deg, #be5af7, #165b91)"
  }),
  ...(isFancyBorder && {
    backgroundColor: "transparent",
    border: "5px solid transparent",
    borderImage: "linear-gradient(90deg, #be5af7, #165b91)",
    borderImageSlice: 1
  })
}));
<Box3 isFancy />
<Box3 isFancyBorder />

All of the methods above can also be applied when using sx props since they use JS object to describe the styles.

Live Demo

Codesandbox Demo

Solution 2:[2]

This seem to work for me

Using sx

sx={{ px: variable ? 8 : null }}

sx with breakpoint

sx={{ px: { md: variable ? 8 : null } }}

prop

 <Typography align={variable ? 'center' : 'inherit'}>

Using className

    className={`class-name ${
      variable
        ? 'class-name'
        : null
    }`}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2