Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Separate themes for Mui and styled components #28979

Closed
2 tasks done
janKozie1 opened this issue Oct 11, 2021 · 4 comments
Closed
2 tasks done

Separate themes for Mui and styled components #28979

janKozie1 opened this issue Oct 11, 2021 · 4 comments
Labels
package: styled-engine-sc Specific to styled-components support: Stack Overflow Please ask the community on Stack Overflow v5.x migration

Comments

@janKozie1
Copy link

janKozie1 commented Oct 11, 2021

Recently, I've been trying to migrate the app I'm working on from v4 to v5.
Since Mui now offers support for different styling engines, I wanted to use the one dedicated for styled components (because that's my preferred way of styling components)

Until now, I had a separate theme for styled components - the one that I used for writing custom styles, and one for Mui (which wasn't used while styling - it was only filled with values from the first theme where applicable, to reduce the amount of styles i would have to write).

Since the theme i was using so far is not compatible with Mui's theme, I would like to keep both themes isolated until i can migrate my old theme.

  • The issue is present in the latest release.
  • I have searched the issues of this repository and believe that this is not a duplicate.

Current Behavior 😯

Themes provided by ThemeProvider from @mui/material/styles and ThemeProvider from styled-components get merged, no matter in which order they are rendered. Since my old theme has fields with the same keys as the one generated by Mui, it leads to errors, because some fields are missing in the merged theme.

Expected Behavior 🤔

According to https://mui.com/guides/interoperability/#theme, the themes should be isolated, if Mui's ThemeProvider gets rendered first. This would allow me to migrate the theme separately

Steps to Reproduce 🕹

(i'm not sure how to reproduce it on codesandbox, so I'm providing link to repo with minimal code showing the issue)

Steps:

  1. clone https://github.com/janKozie1/mui-sc-issue
  2. install dependencies
  3. run npm start

Your Environment 🌎

  System:
    OS: macOS 10.15.7
  Binaries:
    Node: 14.15.0 - /usr/local/bin/node
    Yarn: 1.22.10 - /usr/local/bin/yarn
    npm: 6.14.8 - /usr/local/bin/npm
  Browsers:
    Chrome: 94.0.4606.81
    Edge: Not Found
    Firefox: 89.0.2
    Safari: 14.0.1
  npmPackages:
    @mui/core:  5.0.0-alpha.50 
    @mui/lab: latest => 5.0.0-alpha.50 
    @mui/material: latest => 5.0.3 
    @mui/private-theming:  5.0.1 
    @mui/styled-engine:  5.0.1 
    @mui/styled-engine-sc: latest => 5.0.3 
    @mui/system:  5.0.3 
    @mui/types:  7.0.0 
    @mui/utils:  5.0.1 
    @types/react: latest => 17.0.27 
    react: latest => 17.0.2 
    react-dom: latest => 17.0.2 
    styled-components: latest => 5.3.1 
    typescript: latest => 4.4.3 
@janKozie1 janKozie1 added the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Oct 11, 2021
@mnajdova
Copy link
Member

mnajdova commented Oct 12, 2021

@janKozie1 it is intentional that we have the same theme in the styled-components context. You are correct, but looks like styled-components does not merges deeply, just spreads the objects. See https://github.com/styled-components/styled-components/blob/main/packages/styled-components/src/models/ThemeProvider.tsx#L44. I could fix the code with this diff:

index 964d86c..cb0b9c5 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -1,7 +1,7 @@
 import Container from '@mui/material/Container';
 import AppBar from '@mui/material/AppBar';
-
-import { createTheme, ThemeProvider as MuiThemeProvider } from '@mui/material/styles';
+import { deepmerge } from '@mui/utils';
+import { createTheme, ThemeProvider as MuiThemeProvider, Theme } from '@mui/material/styles';
 import { StyledEngineProvider } from '@mui/styled-engine';
 import styled, { ThemeProvider as StyledThemeProvider } from 'styled-components';

@@ -11,7 +11,7 @@ const StyledNormalComponent = styled.div`
   background-color: ${({theme}) => theme.palette.blue.light};
 `

-const muiTheme = createTheme({})
+const muiTheme = createTheme()
 const scTheme = {
   palette: {
     blue: {
@@ -24,7 +24,7 @@ export default function App() {
   return (
     <StyledEngineProvider injectFirst>
       <MuiThemeProvider theme={muiTheme}>
-        <StyledThemeProvider theme={scTheme}>
+        <StyledThemeProvider theme={(outerTheme: Theme) => deepmerge(outerTheme, scTheme)}>
           <Container maxWidth="sm">
             <AppBar>
               content

This way the structures of both themes are merged together. You should note that if the custom theme overlaps somehow, whatever is defined in it would override the mui theme.


You may want to extract this merged theme on the top and use just one ThemeProvider in the end.

@mnajdova mnajdova added package: styled-engine-sc Specific to styled-components support: Stack Overflow Please ask the community on Stack Overflow v5.x migration and removed status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels Oct 12, 2021
@janKozie1
Copy link
Author

Thank you for the investigation! I imagine this solution will work as long as the datatypes on corresponding fields are possible to merge. I will prefix my old theme so that i can migrate it gradually

@mrkrlli
Copy link

mrkrlli commented Dec 8, 2021

Is it possible to keep an emotion/styled-components theme truly isolated from the MUI theme?

in the docs it says:

If you are already using a custom theme with styled-components or emotion, it might not be compatible with MUI's theme specification. If it's not compatible, you need to render MUI's ThemeProvider first. This will ensure the theme structures are isolated. This is ideal for the progressive adoption of MUI's components in the codebase.

However as noted above, this seems to just overwrite the MUI theme where there are naming conflicts with the custom emotion/styled-components theme.

We're looking to continue with how this worked in MUI 4. MUI components inherit the default MUI theme, and our custom emotion/styled-components theme for any overrides.

However once we bring in our custom theme in the emotion theme provider, MUI components no longer get the default MUI theme and break. We add in the MUI theme provider before our custom theme provider, but some MUI components are still broken b/c of naming conflicts between themes.

@mrkrlli
Copy link

mrkrlli commented Dec 9, 2021

Here's a code repro: https://codesandbox.io/s/0ob9j?file=/index.tsx

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
package: styled-engine-sc Specific to styled-components support: Stack Overflow Please ask the community on Stack Overflow v5.x migration
Projects
None yet
Development

No branches or pull requests

3 participants