mui / material-ui

Material UI: Comprehensive React component library that implements Google's Material Design. Free forever.
https://mui.com/material-ui/
MIT License
93.86k stars 32.26k forks source link

[Typography] The last theme in use overrides the generated CSS #20151

Closed dfernandez-asapp closed 4 years ago

dfernandez-asapp commented 4 years ago

With multiple ThemeProvider tags, the last theme in use will override the MuiTypography CSS classes.

Current Behavior 😯

In the following code:

      <ThemeProvider theme={defaultTheme}>
        <Typography variant="h5">This should use Roboto</Typography>
      </ThemeProvider>
      <ThemeProvider theme={customTheme}>
        <Typography variant="h5">This uses cursive</Typography>
      </ThemeProvider>

The style of the first h5 will use the style defined in customTheme.

By looking at the HTML, what I see is that the CSS classes for Typography are not dynamic. So the new styles for the second variant overrides the styles of the first:

Generated HTML code:

<style data-jss="" data-meta="MuiTypography">
.MuiTypography-root {
  margin: 0;
}
.MuiTypography-body2 {
  font-size: 0.875rem;
  font-family: "Roboto", "Helvetica", "Arial", sans-serif;
  font-weight: 400;
  line-height: 1.43;
  letter-spacing: 0.01071em;
}
/* OMITTED ... */
</style>
<style data-jss="" data-meta="MuiTypography">
.MuiTypography-root {
  margin: 0;
}
.MuiTypography-body2 {
  font-size: 0.875rem;
  font-family: cursive;
  font-weight: 400;
  line-height: 1.43;
}
/* OMITTED ... */
</style>

Expected Behavior 🤔

The component should reflect the theme provided by the ThemeProvider, without affecting global styles.

Steps to Reproduce 🕹

https://codesandbox.io/s/goofy-haze-8nxd7?fontsize=14&hidenavigation=1&theme=dark

Steps:

  1. Create two themes with different fonts using createMuiTheme
  2. Wrap a Typography component with one theme
  3. Wrap another Typography component with the other theme
  4. Both Typography components will use the settings from the last theme.

Context 🔦

Your Environment 🌎

Tech Version
Material-UI v4.9.5
React v16.13.0
Browser Chrome
dfernandez-asapp commented 4 years ago

As a workaround, if you nest the ThemeProvider object it works:

<ThemeProvider theme={theme1}>
   <Typography>Style 1</Typography>
   <ThemeProvider theme={theme2}>
        <Typography>Style 2</Typography>
   </ThemeProvider>
</ThemeProvider>
oliviertassinari commented 4 years ago

Duplicate of #15914