material-ui: [theme] Fails when combining @chakra-ui/react and @material-ui/core

TypeError: undefined is not a function

It fails here: https://github.com/mui-org/material-ui/blob/next/packages/material-ui/src/Autocomplete/Autocomplete.js#L340

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

Current Behavior 😯

<Autocomplete /> component can’t be opened.

Expected Behavior šŸ¤”

<Autocomplete /> should work with chakra and material ui 😃

Steps to Reproduce šŸ•¹

https://codesandbox.io/s/frosty-browser-694e6?file=/src/App.js

Steps:

  1. Try to open Autocomplete component

Context šŸ”¦

I am using @material-ui/core and @chakra-ui/react in the same application (which might not be the best but that is a different topic). Looks like with the release of version 5 and some changes to the theme/styling the Autocomplete component broke.

Your Environment šŸŒŽ

`npx @material-ui/envinfo`
System:
    OS: macOS 10.15.7
  Binaries:
    Node: 15.12.0 - ~/.nvm/versions/node/v15.12.0/bin/node
    Yarn: 1.12.3 - /usr/local/bin/yarn
    npm: 7.6.3 - ~/.nvm/versions/node/v15.12.0/bin/npm
  Browsers:
    Chrome: 89.0.4389.128
    Edge: Not Found
    Firefox: 86.0
    Safari: 14.0.2

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 5
  • Comments: 27 (15 by maintainers)

Commits related to this issue

Most upvoted comments

This is like cake. Move inside the chakra user interface. The problem will be solved. 🐧

import "./styles.css";
import AutoComplete from "@material-ui/core/Autocomplete";
import TextField from "@material-ui/core/TextField";
import { ThemeProvider } from "@material-ui/core/styles";
import { createMuiTheme } from "@material-ui/core/styles";
import { ChakraProvider, extendTheme } from "@chakra-ui/react";

const muiTheme = createMuiTheme();
const theme = extendTheme();

export default function App() {
  return (
    <ChakraProvider theme={theme} resetCSS>
      <ThemeProvider theme={muiTheme}>
        <div className="App">
          <h1>Hello CodeSandbox</h1>
          <h2>Start editing to see some magic happen!</h2>
          <AutoComplete
            id="combo-box-demo"
            options={[{ title: "a" }, { title: "b" }, { title: "c" }]}
            getOptionLabel={(option) => option.title}
            renderInput={(params) => (
              <TextField {...params} label="Combo box" variant="outlined" />
            )}
          />
        </div>
      </ThemeProvider>
    </ChakraProvider>
  );
}

Sandbox link: https://codesandbox.io/s/eloquent-hopper-e2upeh?file=/src/App.js:0-1026

This issue is still present for latest mui and Chakra-ui version. If someone has found a solution, I’m interested.

Hey everyone, I have a POC for the solution.

All you have to do is put the theme of Material UI inside a special id that we provide from the library. Here are some examples:

Chakra + Material UI

import { ChakraProvider, extendTheme, Button } from "@chakra-ui/react";
import { THEME_IDENTIFIER, createTheme } from '@mui/material/styles';
import MuiButton from '@mui/material/Button';

const theme = extendTheme(…your custom theme for chakra);

const muiTheme = createTheme(…your custom theme for Material UI);

<ChakraProvider theme={{ …theme, [THEME_IDENTIFIER]: muiTheme }}>
  <MuiButton> Hey, it works! </MuiButton>
</ChakraProvider>

Whenever you access the theme via styled, useTheme, or sx prop from @mui/material/styles, you will get the Material UI’s theme as if the themes are independent.

I’ve come up with a solution, and it’s pretty simple:

  1. Wrap your app in both theme providers at the same time.
  2. Join your ChakraUI and MaterialUI theme together using some sort of deepMerge function.
  3. It works!

The end code will look something like this:


const theme = deepMerge(muiTheme, chakraTheme);

const App = () => {
  return <ChakraProvider theme={theme} resetCSS>
    <ThemeProvider theme={theme}>
      <EverythingElse/>
    </ThemeProvider>
  </ChakraProvider>
}

This works because MaterialUI and ChakraUI both use ThemeUI-based themes, so they are technically compatible. Some things are not used in the same way, but they don’t break each other where it matters, so for the transition between MaterialUI and ChakraUI, it will be more than enough IMO.

Theme scoping is introduced in v5.12.0, here is the doc on how to use it with Theme UI šŸ¾.

cc @castrosuellenx

I had a look at the theme conflicts, I couldn’t see any, so a deep merge between the two seems enough. https://codesandbox.io/s/musing-nightingale-7hnd9?file=/src/App.js

import { deepmerge } from "@material-ui/utils";
import { createTheme } from "@material-ui/core/styles";
import { ChakraProvider, extendTheme } from "@chakra-ui/react";

const muiTheme = createTheme();
const chakraTheme = extendTheme();

const theme = deepmerge(chakraTheme, muiTheme);

As far as I know, we can’t. We use the same context so the styled() API can use the theme of Material-UI and so we don’t have to provide the theme prop everywhere.

These are all descriptive facts about the current state. This isn’t helpful unless you think the current implementation is perfect.

What we’re interested in is better behavior. And the current behavior is not ok and goes against one of the initial goals that we were explicitly concerned with styled-components.

To be clear: We need to investigate how we can use a separate context. Affecting existing context is quite problematic.

Thank you for your fast responses, but looks like the solution from @mnajdova only works in my skeleton example, as soon as you integrate an component from chakra-ui it also fails probably for the reasons that @oliviertassinari pointed out.

@oliviertassinari Regarding your question why I need to use both libraries I can easily tell you that the project I’m working on started using chakra-ui but at some point we needed the look and feel of the material ui form elements so I hooked that one in. But when I browse through the codebase I can see that we mostly use the <Box /> and <Flex /> components for layout things. I guess I’ll just replicate those and will kick out chakra for now. 😃

I’ve switched the providers, and added second the ThemeProvider coming from Material-UI and it works - https://codesandbox.io/s/focused-meninsky-uj9js?file=/src/App.js:663-664 Both libraries are using emotion’s ThemeProvider, but expect and create different theme structure. If you would like to use both libraries, I’d suppose you need to take care of making sure that the theme that you use in the end is compatible with both libraries.

Hey everyone, I have a POC for the solution.

All you have to do is put the theme of Material UI inside a special id that we provide from the library. Here are some examples:

Chakra + Material UI

import { ChakraProvider, extendTheme, Button } from "@chakra-ui/react";
import { THEME_IDENTIFIER, createTheme } from '@mui/material/styles';
import MuiButton from '@mui/material/Button';

const theme = extendTheme(…your custom theme for chakra);

const muiTheme = createTheme(…your custom theme for Material UI);

<ChakraProvider theme={{ …theme, [THEME_IDENTIFIER]: muiTheme }}>
  <MuiButton> Hey, it works! </MuiButton>
</ChakraProvider>

Whenever you access the theme via styled, useTheme, or sx prop from @mui/material/styles, you will get the Material UI’s theme as if the themes are independent.

Hey @siriwatknp this solution can be used on v5.11.15 ?

If not, can we properly document this issue? Theme conflicts should be mentioned more explicitly. Especially coming from MUI 4, where having a custom emotion theme works fine.

We should definitely update the docs on this. It works differently than how it did in v4. I will create a PR for the docs next week.

Interesting issue. It’s a case we discussed a long time ago when we talked about the migration to emotion/styled components. Basically, it’s about how our theme structure might conflict with the one existing apps have. So I don’t think that it’s specific to Chakra-UI.

As @mnajdova said, it’s unlikely we can easily solve this. The only alternative I can think of is to remove the styled engine theme provider from our ThemeProvider and forward the theme with a prop. I guess this would bring back to the question @eps1lon asked not too long ago on https://github.com/mui-org/material-ui/pull/25776/files

@fel1xw I would love to learn more about the incentive for using both libraries. Is there something that Material-UI could do, in its long-term roadmap to remove the requirement?