mui / material-ui

Material UI: Ready-to-use foundational React components, free forever. It includes Material UI, which implements Google's Material Design.
https://mui.com/material-ui/
MIT License
92.44k stars 31.84k forks source link

[material-ui] Composing a theme with multiple `experimental_extendTheme` calls throws error #42516

Open jcohen14 opened 1 month ago

jcohen14 commented 1 month ago

Steps to reproduce

Link to live example: https://codesandbox.io/p/sandbox/mui-extendtheme-chaining-bug-6j9mps

Steps:

  1. create any new react project & install MUI
  2. call experimental_extendTheme more than once, and passing in a Theme object for any of the calls

Current behavior

Chaining calls to experimental_extendTheme results in the following error:

MUI: `vars` is a private field used for CSS variables support. Please use another name.

Expected behavior

Should work without throwing an error. Matching createTheme functionality.

Context

Chaining calls to "compose" a theme object as described in the 2nd example here (but with the new extendTheme experimental feature instead)

Your environment

I just copied the codesandbox files to my machine to get these specs, not sure if that matters. Error still shows up when running it on my machine instead of codesandbox.

System: OS: macOS 14.5 Binaries: Node: 20.9.0 - ~/.nvm/versions/node/v20.9.0/bin/node npm: 10.1.0 - ~/.nvm/versions/node/v20.9.0/bin/npm pnpm: 8.5.0 - /usr/local/bin/pnpm Browsers: Chrome: 125.0.6422.113 Edge: Not Found Safari: 17.5 npmPackages: @emotion/react: 11.11.4 => 11.11.4 @emotion/styled: 11.11.5 => 11.11.5 @mui/base: 5.0.0-beta.40 @mui/core-downloads-tracker: 5.15.19 @mui/material: 5.15.19 => 5.15.19 @mui/private-theming: 5.15.14 @mui/styled-engine: 5.15.14 @mui/system: 5.15.15 @mui/types: 7.2.14 @mui/utils: 5.15.14 => 5.15.14 @types/react: 18.2.38 => 18.2.38 react: 18.2.0 => 18.2.0 react-dom: 18.2.0 => 18.2.0 typescript: 4.4.4 => 4.4.4

Search keywords: cssvars experimental_extendTheme extendtheme css variables experimental

siriwatknp commented 3 weeks ago

Why do you need to call extendTheme based on the existing theme? It's not designed to be used like this. If you need multiple themes, they should be independent or you should extract shared tokens.

const tokens = { … };
cons theme1 = extendTheme(tokens);
const theme2 = extendTheme(tokens);
jcohen14 commented 3 weeks ago

It's not designed to be used like this

Is it not supposed to mimic createTheme? According to the docs here:

When the value for a theme option is dependent on another theme option, you should compose the theme in steps.


let theme = createTheme({
  palette: {
    primary: {
      main: '#0052cc',
    },
    secondary: {
      main: '#edf2ff',
    },
  },
});

theme = createTheme(theme, {
  palette: {
    info: {
      main: theme.palette.secondary.main,
    },
  },
});

The app I'm trying to migrate from createTheme to extendTheme uses this idea of constructing the theme in steps. I know it's still experimental but the docs kind of imply that extendTheme and createTheme can be 1:1 swapped for each other