How to implement conditional styles in MUI v5 sx prop

Viewed 14090

Looking for clever conditional styles in MUI5's sx prop. One example I have played with is:

const statusStyle = (status) => {
  switch (status) {
    case "aborted":
      return "#D66460";
      break;
    case "queue":
      return "#6685F0";
      break;
    case "processing":
      return "#F0E666";
      break;
    default:
      return "#60D660";
  }
};

<TableRow
  key={job.job}
  sx={{ color: statusStyle(status) }}
>

But I'm wondering if someone has come up with something more elegant?

3 Answers

If it's just a simple mapping with a primitive key, you can use an object:

const statusColors = {
  aborted: '#D66460',
  queue: '#6685F0',
  processing: '#F0E666',
}
sx={{ color: statusColors[job.status] ?? defaultColor }}

If you want to pass a style object conditionally, you can use the spread syntax ..., this is how the MUI team apply the styles to the components with different variants and states:

sx={{
  color: defaultColor,
  backgroundColor: defaultBgcolor,
  ...(job.status === 'aborted' && {
    color: color1,
    backgroundColor: bgcolor1,
  }),
  ...(job.status === 'queue' && {
    color: color2,
    backgroundColor: bgcolor2,
  }),
  ...(job.status === 'processing' && {
    color: color3,
    backgroundColor: bgcolor3,
  }),
}}

This seem to work for me

const [emailStatus, setEmailStatus] = useState('');
  const [emailStatusText, setEmailStatusText] = useState('');
  const [isEmailSubmitted, setIsEmailSubmitted] = useState(false);

...

return response.json().then((data) => {
            const { success, error } = data;
            setEmailStatus(success ? 'success' : 'error');
            setEmailStatusText(success || error);
            return data;
          });

...

{isEmailSubmitted && (
              <Typography
                sx={{
                  textAlign: 'left',
                  color:
                    emailStatus === 'success'
                      ? theme.palette.success.main
                      : theme.palette.error.main,
                }}
              >
                {emailStatusText}
              </Typography>
            )}

Use their triggers

For example, on a scroll:

import useScrollTrigger from '@mui/material/useScrollTrigger';

//...

const trigger = useScrollTrigger({
disableHysteresis: true,
threshold: 38,
});

//...

<Topbar
colorInvert={trigger ? false : colorInvert}/>
Related