6

I've upgraded MUI from v4 to v5. However, I'm now having difficulties understanding how the theming works with the different theming solutions available. I don't really understand where to use the MUI theming/styling components and when to use the emotion ones.

In new components, I'm using the sx prop to apply styling, however I have quite a lot of components still using the createStyles/useStyles functions.

I currently have the following setup:

import {
  ThemeProvider as MuiThemeProvider,
  Theme,
  StyledEngineProvider,
  createTheme,
} from "@mui/material/styles";
import { ThemeProvider } from "@emotion/react";

declare module "@mui/material/styles" {
  interface Theme {
    mycompany: {
      primary: string;
    };
  }
  // allow configuration using `createTheme`
  interface ThemeOptions {
    mycompany: {
      primary: string;
    };
  }
}

declare module "@mui/styles/defaultTheme" {
  // eslint-disable-next-line @typescript-eslint/no-empty-interface
  interface DefaultTheme extends Theme {}
}

const theme = createTheme({
  mycompany: {
    primary: "#003366",
  },
});

const App = () => {
  return (
    <StyledEngineProvider injectFirst>
      <MuiThemeProvider theme={theme}>
        <ThemeProvider theme={theme}>
          <Router>
            ...
          </Router>
        </ThemeProvider>
      </MuiThemeProvider>
    </StyledEngineProvider>

How can I now use the theme.mycompany.primary value? I've tried it like this:

import { useTheme } from "@emotion/react";

const MyComponent = () => {
    const theme = useTheme();

    return (
      <Box sx={{backgroundColor: theme.mycompany.primary}}>
        ...
      </Box>

Are there any examples of projects using the new styling solution with typescript across multiple components in different files?

NearHuscarl
  • 66,950
  • 18
  • 261
  • 230
picklepick
  • 1,370
  • 1
  • 11
  • 24
  • Why're you have 2 `ThemeProvider`s in your code? – NearHuscarl Oct 19 '21 at 11:07
  • @NearHuscarl, that's what also confused me but I saw this in [this](https://dev.to/atonchev/material-ui-5-the-easiest-way-to-migrate-from-makestyles-to-emotion-1i9l) blog post about v4 -> v5 – picklepick Oct 19 '21 at 12:48
  • Most of the articles on dev.to are garbage, you should read the migration guide on the [official docs](https://mui.com/guides/migration-v4/#heading-mui-styles) instead, if you are using MUI APIs to style your component, you don't need another `ThemeProvider` from emotion. – NearHuscarl Oct 19 '21 at 12:53

1 Answers1

8

From the docs, useTheme should be imported from @mui/material/styles.

If you use sx prop, you should put your custom color code in the palette like this:

const theme = createTheme({
  palette: {
    mycompany: {
      primary: "#003366"
    }
  },
});

And reference the color in your component:

<Box sx={{ width: 30, height: 30, bgcolor: "mycompany.primary" }} />

If you're using styled you can add a callback where the theme is a property of the first param:

const MyComponent = styled(Box)(({ theme }) => {
  return {
    backgroundColor: theme.palette.mycompany.primary,
    width: 30,
    height: 30
  };
});

Live Demo

Codesandbox Demo

NearHuscarl
  • 66,950
  • 18
  • 261
  • 230
  • thank you! I'll take a look and if I get it working I'll accept. So you don't use the `useTheme()` hook at all? And what about the providers, which one do you use? – picklepick Oct 19 '21 at 12:47
  • @picklepick you can still use `useTheme` if you want, it still works (for example when integrating with third-party components). If you are using `styled`/`sx`, you can do that without `useTheme`. `useTheme` doesn't work in your question likely because you import from the wrong module, it should come from `@mui/material/styles`. – NearHuscarl Oct 19 '21 at 12:58
  • I created a [follow-up question](https://stackoverflow.com/questions/69631840/mui-v5-mui-material-styles-vs-emotion-react). The question is more 'meta' maybe you can help. – picklepick Oct 19 '21 at 13:35
  • I would like to add that this link referencing the performance of styled vs sx. https://stackoverflow.com/questions/68383046/is-there-a-performance-difference-between-the-sx-prop-and-the-makestyles-functio You should use styled for components that are reusable, sx sparingly and styles otherwise where you can't use sx. sx takes a performance hit (comparatively) to styled. – olminkow Oct 23 '21 at 17:33
  • @RookTKO See [this](https://stackoverflow.com/questions/68383046/is-there-a-performance-difference-between-the-sx-prop-and-the-makestyles-functio/68383383?noredirect=1#comment123185357_68383383) comment from Ryan regarding `sx` usage. It's good that you're being conscious about `sx` perf, but I don't think you should avoid using it, just be aware of the pitfalls that can potentially slow down your application and use the 'style injection' strategy from the docs to mitigate it. – NearHuscarl Oct 23 '21 at 20:24