Repository: mui/material-ui (TypeScript)
Date: 2021-08-19 15:24:27+00:00
Task type: Bug Fix

Issue:
[theme] pseudo class overridden in variants
- [x] The issue is present in the latest release.
- [x] I have searched the [issues](https://github.com/mui-org/material-ui/issues) of this repository and believe that this is not a duplicate.

## Current Behavior 😯

When doing:

```jsx
const theme = createTheme({
  components: {
    MuiButton: {
      variants: [
        {
          props: { variant: "contained" },
          style: {
            "&.Mui-disabled": {
              opacity: 0.65
            }
          }
        },
        {
          props: { variant: "contained", color: "primary" },
          style: {
            "&.Mui-disabled": {
              color: "#fff",
              backgroundColor: "#f00"
            }
          }
        }
      ]
    }
  }
});
```

The disabled style doesn't combine.

<img width="103" alt="Capture d’écran 2021-06-23 à 12 53 59" src="https://user-images.githubusercontent.com/3165635/123085014-17e82b00-d422-11eb-8b9d-618e45fc98ef.png">


## Expected Behavior 🤔

The disabled style should combine.

<img width="98" alt="Capture d’écran 2021-06-23 à 12 53 54" src="https://user-images.githubusercontent.com/3165635/123085019-1a4a8500-d422-11eb-953d-b7a295fde3d0.png">

## Steps to Reproduce 🕹

Steps:

1. Open https://codesandbox.io/s/musing-darkness-2cd8d?file=/src/App.js:119-613

## Context 🔦

I have noticed the issue in #26813. The root issue is likely with: https://github.com/mui-org/material-ui/blob/46ebf5a08407254c00129e781dff69401510c01f/packages/material-ui-system/src/createStyled.js#L47


Issue discussion:
#26824 is not fixing this issue. proof: https://codesandbox.io/s/basicalerts-material-demo-forked-ywp7x?file=/demo.js
This seems to fix it:

```diff
diff --git a/packages/material-ui-system/src/createStyled.js b/packages/material-ui-system/src/createStyled.js
index 2b55fcf31f..aeac9dd9ef 100644
--- a/packages/material-ui-system/src/createStyled.js
+++ b/packages/material-ui-system/src/createStyled.js
@@ -33,7 +33,7 @@ const getVariantStyles = (name, theme) => {

 const variantsResolver = (props, styles, theme, name) => {
   const { styleProps = {} } = props;
-  let variantsStyles = {};
+  const variantsStyles = [];
   const themeVariants = theme?.components?.[name]?.variants;
   if (themeVariants) {
     themeVariants.forEach((themeVariant) => {
@@ -44,7 +44,7 @@ const variantsResolver = (props, styles, theme, name) => {
         }
       });
       if (isMatch) {
-        variantsStyles = { ...variantsStyles, ...styles[propsToClassKey(themeVariant.props)] };
+        variantsStyles.push(styles[propsToClassKey(themeVariant.props)]);
       }
     });
   }
```

Solution patch:
diff --git a/packages/material-ui-system/src/createStyled.js b/packages/material-ui-system/src/createStyled.js
--- a/packages/material-ui-system/src/createStyled.js
+++ b/packages/material-ui-system/src/createStyled.js
@@ -34,7 +34,7 @@ const getVariantStyles = (name, theme) => {
 
 const variantsResolver = (props, styles, theme, name) => {
   const { ownerState = {} } = props;
-  let variantsStyles = {};
+  const variantsStyles = [];
   const themeVariants = theme?.components?.[name]?.variants;
   if (themeVariants) {
     themeVariants.forEach((themeVariant) => {
@@ -45,7 +45,7 @@ const variantsResolver = (props, styles, theme, name) => {
         }
       });
       if (isMatch) {
-        variantsStyles = { ...variantsStyles, ...styles[propsToClassKey(themeVariant.props)] };
+        variantsStyles.push(styles[propsToClassKey(themeVariant.props)]);
       }
     });
   }


Test patch:
diff --git a/packages/material-ui-system/src/createStyled.test.js b/packages/material-ui-system/src/createStyled.test.js
--- a/packages/material-ui-system/src/createStyled.test.js
+++ b/packages/material-ui-system/src/createStyled.test.js
@@ -1,7 +1,12 @@
+import * as React from 'react';
 import { expect } from 'chai';
+import { ThemeProvider, createTheme } from '@material-ui/core/styles';
+import { createClientRender } from 'test/utils';
 import createStyled from './createStyled';
 
 describe('createStyled', () => {
+  const render = createClientRender();
+
   describe('displayName', () => {
     // These tests rely on implementation details (namely `displayName`)
     // Ideally we'd just test if the proper name appears in a React warning.
@@ -44,4 +49,55 @@ describe('createStyled', () => {
       expect(SomeMuiComponent).to.have.property('displayName', 'Styled(Component)');
     });
   });
+
+  describe('styles', () => {
+    it('styles of pseudo classes of variants are merged', () => {
+      const theme = createTheme({
+        components: {
+          MuiButton: {
+            variants: [
+              {
+                props: { variant: 'contained' },
+                style: {
+                  '&.Mui-disabled': {
+                    width: '300px',
+                  },
+                },
+              },
+              {
+                props: { variant: 'contained', color: 'primary' },
+                style: {
+                  '&.Mui-disabled': {
+                    height: '200px',
+                  },
+                },
+              },
+            ],
+          },
+        },
+      });
+      const styled = createStyled({});
+      const Button = styled('button', {
+        shouldForwardProp: (prop) => prop !== 'color' && prop !== 'contained',
+        name: 'MuiButton',
+        slot: 'Root',
+        overridesResolver: (props, styles) => styles.root,
+      })({
+        display: 'flex',
+      });
+
+      const { container } = render(
+        <ThemeProvider theme={theme}>
+          <Button color="primary" variant="contained" className="Mui-disabled">
+            Hello
+          </Button>
+        </ThemeProvider>,
+      );
+
+      expect(container.getElementsByTagName('button')[0]).toHaveComputedStyle({
+        width: '300px',
+        height: '200px',
+      });
+    });
+  });
 });