Theming in MUI v5

Photo by RetroSupply on Unsplash

Theming in MUI v5

Material-UI is now MUI! 馃ぉ

If you are following Frontend for some time you might already know the migration of Material UI brand to MUI.

And Yes! I am copying the direct heading from the announcement made by the team behind MUI on 16 Sept 2021 of a new chapter in their brand evolution. With this, a ton of features are to be added to MUI.

In this blog, we will explore the features added to Theming in MUI and changes from Material UI v4.

All MUI components have basic default theming to them, but to create custom themes we manipulate every component using ThemeProvider

Adding MUI ThemeProvider 馃槆

In the root of our in order to use custom themes we need to wrap all our components within MUI鈥檚 ThemeProvider.

We use createTheme hook provided by @mui/material to create a theme to pass onto all the components and all the child components will be styled by the theme automatically.

import { createTheme } from "@mui/material";
import { ThemeProvider } from "@mui/material";
import { CssBaseline } from "@mui/material";
import NavBar from "../../features/nav/NavBar";
const theme = createTheme()

export default function app()
{
return (
<ThemeProvider theme={theme}>
    <CssBaseline />
    <NavBar />
  </ThemeProvider>

)

}

Replacing Default Theme to create Custom MUI Theme 馃

import { createTheme } from "@mui/material";
import { ThemeProvider } from "@mui/material";
import { CssBaseline } from "@mui/material";
import NavBar from "../../features/nav/NavBar";
import red from "@mui/material/colors/red";
import orange from "@mui/material/colors/orange";

const theme = (mode) => createTheme(({
    palette: {
      mode: 'light',
      primary: {
        main: orange[500]
      }
      secondary: {
        light: red[500],
        main: red[700],
        dark: red[900],
        contrastText: grey[50]
      }}}))

export default function app()
{
return (
<ThemeProvider theme={theme}>
    <CssBaseline />
    <NavBar />
  </ThemeProvider>

)

}

Alongside common colors, we can use text objects for text component. background object is used to handle the background color of the app.

We can set the dark or light mode using the mode keyword instead of using type in v4.

action object can be used to define the color for actions like hover, active, or focus.

Spacing 馃挭

The app should have uniform spacing across all components. By normalizing margins and spacings, each component ends up with equal spacing. And this is what is taken care of in spacing.

Initially, in theme, we can set the spacing value to desired pixels. And utilize this in sx props or styled-components.

Example Code

shape: {
      borderRadius: 20
    },
    spacing: 4

<Box sx={{m: 6, // margin: 24px (6 * theme.spacing)}}>

In MUI v5 theme.spacingnow returns single values with px units by default. This change improves the integration with styled-components & emotion.

//before
theme.spacing(2) => 16
//after
theme.spacing(2) => '16px'

Typography 馃槒

MUI gives us typography component to style all of the text using different variants including global fonts settings.

typography: {
  fontFamily: ["Roboto", "Lato", "Sans Serif"],
  fontSize: 16,
  fontWeightRegular: 400,
  fontWeightBold: 700,
  lineHeight: 1.5,
  h1: {
    fontFamily: "Lato",
    color: grey[100],
    fontSize: "6rem",
    fontWeight: 400,
    lineHeight: 1.167,
    lettingSpacing: "-0.01562em"
  },
  body1: {
    color: grey[800],
    fontSize: "2rem",
    fontWeight: 400
  }
},

Component Overrides and Default Theme styling using MUI Themes 馃槜

In the theme, we can override the default theme directly within a components object. Previously in v4, this used to be props key however now it is changed and is merged within components keyword and is implemented using defaultProps.

We just need to precede the component name with Mui word and then change it鈥檚 default props. Basically we can set the default props of any component by setting them in theme and using appropriate global classnames.

components: {
  MuiButton: {
    defaultProps: {
      color: "warning",
      size: "small",
      disableElevation: true,
      variant: "contained"
            style: {
        shadow: "1px 1px grey"
      },
      sx: {
        borderRadius: 2,
        p: 5
      }

    }
  }
}

This changes the default props of the Button component of MUI. We can also override the style and sx prop of each component.

Global style overrides 馃コ

Now if we want to change style(override them) then one can use the theme's styleOverrides key to potentially change every single style injected by MUI into the DOM.

components: {
    // Name of the component
    MuiButton: {
      styleOverrides: {
        // Name of the slot
        root: {
          // Some CSS
          fontSize: '1rem',
        },
      },
    },
  },

We can also override the look of all the component instances by adjusting theme configuration variables

const theme = createTheme({
  typography: {
    button: {
      fontSize: '1rem',
    },
  },
});

Responsive Font 馃

There is also a neat feature in MUI themes to make responsive fonts we pass the theme object in responsiveFontSizes() hook

import { createTheme, responsiveFontSizes } from '@mui/material/styles';

let theme = createTheme();
theme = responsiveFontSizes(theme);

And rest of the code is the same. This feature is great to have a responsive styling using MUI.

Adding new component variants 馃槼

This is one of the new features in MUI v5 and one which is widely appreciated.

So now using variants key we can add new variants to MUI components in components section. These new variants can specify what style the component should have when specific props are applied.

const theme = createTheme({
  components: {
    MuiButton: {
      variants: [
        {
          props: { variant: 'dashed' },
          style: {
            textTransform: 'none',
            border: `2px dashed ${blue[500]}`,
          },
        },
        {
          props: { variant: 'dashed', color: 'secondary' },
          style: {
            border: `4px dashed ${red[500]}`,
          },
        },
      ],
    },
  },
});

Here we create a new variant dashed for Button component of MUI.

This can be used quite easily in code by specifying the variant name.

<Button variant="dashed" color="secondary" sx={{ m: 1 }}>
    Secondary
  </Button>

This link can be referred to for custom variants available right now. While if custom variants are not present then we can use wrapper components the same as that implemented in v4.

[RFC] Support custom variants in the theme 路 Issue #21749 路 mui/material-ui

In Conclusion 馃ジ

These are the basics of implementing theming in MUI v5 and the changes and features added. In the next articles, we will see how to migrate from Material UI v4 to MUI v5 and explore styling solutions in MUI v5 and utilize them for dynamic styling.