Repository: mui/material-ui (TypeScript)
Date: 2021-01-03 16:48:17+00:00
Task type: Bug Fix

Issue:
[component: styleOverrides] No longer working
In previous versions it worked fine, but now it's not working anymore

Here is the simulation of that behavior
https://codesandbox.io/s/globalthemeoverride-material-demo-forked-46yj7?file=/demo.js:0-760

Please help me, Thanks!


Issue discussion:

Solution patch:
diff --git a/packages/material-ui/src/Avatar/Avatar.js b/packages/material-ui/src/Avatar/Avatar.js
--- a/packages/material-ui/src/Avatar/Avatar.js
+++ b/packages/material-ui/src/Avatar/Avatar.js
@@ -8,11 +8,11 @@ import Person from '../internal/svg-icons/Person';
 import avatarClasses, { getAvatarUtilityClass } from './avatarClasses';
 
 const overridesResolver = (props, styles) => {
-  const { colorDefault, variant = 'circular' } = props;
+  const { styleProps } = props;
 
   return deepmerge(styles.root || {}, {
-    ...styles[variant],
-    ...(colorDefault && styles.colorDefault),
+    ...styles[styleProps.variant],
+    ...(styleProps.colorDefault && styles.colorDefault),
     [`& .${avatarClasses.img}`]: styles.img,
     [`& .${avatarClasses.fallback}`]: styles.fallback,
   });
diff --git a/packages/material-ui/src/Badge/Badge.js b/packages/material-ui/src/Badge/Badge.js
--- a/packages/material-ui/src/Badge/Badge.js
+++ b/packages/material-ui/src/Badge/Badge.js
@@ -24,28 +24,19 @@ const RADIUS_STANDARD = 10;
 const RADIUS_DOT = 4;
 
 const overridesResolver = (props, styles) => {
-  const {
-    color = 'default',
-    variant = 'standard',
-    anchorOrigin = {
-      vertical: 'top',
-      horizontal: 'right',
-    },
-    invisible,
-    overlap = 'rectangular',
-  } = props;
+  const { styleProps } = props;
 
   return deepmerge(styles.root || {}, {
     [`& .${badgeClasses.badge}`]: {
       ...styles.badge,
-      ...styles[variant],
+      ...styles[styleProps.variant],
       ...styles[
-        `anchorOrigin${capitalize(anchorOrigin.vertical)}${capitalize(
-          anchorOrigin.horizontal,
-        )}${capitalize(overlap)}`
+        `anchorOrigin${capitalize(styleProps.anchorOrigin.vertical)}${capitalize(
+          styleProps.anchorOrigin.horizontal,
+        )}${capitalize(styleProps.overlap)}`
       ],
-      ...(color !== 'default' && styles[`color${capitalize(color)}`]),
-      ...(invisible && styles.invisible),
+      ...(styleProps.color !== 'default' && styles[`color${capitalize(styleProps.color)}`]),
+      ...(styleProps.invisible && styles.invisible),
     },
   });
 };
diff --git a/packages/material-ui/src/Button/Button.js b/packages/material-ui/src/Button/Button.js
--- a/packages/material-ui/src/Button/Button.js
+++ b/packages/material-ui/src/Button/Button.js
@@ -10,30 +10,24 @@ import capitalize from '../utils/capitalize';
 import buttonClasses, { getButtonUtilityClass } from './buttonClasses';
 
 const overridesResolver = (props, styles) => {
-  const {
-    color = 'primary',
-    disableElevation = false,
-    fullWidth = false,
-    size = 'medium',
-    variant = 'text',
-  } = props;
+  const { styleProps } = props;
 
   return deepmerge(styles.root || {}, {
-    ...styles[variant],
-    ...styles[`${variant}${capitalize(color)}`],
-    ...styles[`size${capitalize(size)}`],
-    ...styles[`${variant}Size${capitalize(size)}`],
-    ...(color === 'inherit' && styles.colorInherit),
-    ...(disableElevation && styles.disableElevation),
-    ...(fullWidth && styles.fullWidth),
+    ...styles[styleProps.variant],
+    ...styles[`${styleProps.variant}${capitalize(styleProps.color)}`],
+    ...styles[`size${capitalize(styleProps.size)}`],
+    ...styles[`${styleProps.variant}Size${capitalize(styleProps.size)}`],
+    ...(styleProps.color === 'inherit' && styles.colorInherit),
+    ...(styleProps.disableElevation && styles.disableElevation),
+    ...(styleProps.fullWidth && styles.fullWidth),
     [`& .${buttonClasses.label}`]: styles.label,
     [`& .${buttonClasses.startIcon}`]: {
       ...styles.startIcon,
-      ...styles[`iconSize${capitalize(size)}`],
+      ...styles[`iconSize${capitalize(styleProps.size)}`],
     },
     [`& .${buttonClasses.endIcon}`]: {
       ...styles.endIcon,
-      ...styles[`iconSize${capitalize(size)}`],
+      ...styles[`iconSize${capitalize(styleProps.size)}`],
     },
   });
 };
diff --git a/packages/material-ui/src/ButtonBase/ButtonBase.js b/packages/material-ui/src/ButtonBase/ButtonBase.js
--- a/packages/material-ui/src/ButtonBase/ButtonBase.js
+++ b/packages/material-ui/src/ButtonBase/ButtonBase.js
@@ -11,11 +11,11 @@ import TouchRipple from './TouchRipple';
 import buttonBaseClasses from './buttonBaseClasses';
 
 const overridesResolver = (props, styles) => {
-  const { disabled, focusVisible } = props;
+  const { styleProps } = props;
 
   return deepmerge(styles.root || {}, {
-    ...(disabled && styles.disabled),
-    ...(focusVisible && styles.focusVisible),
+    ...(styleProps.disabled && styles.disabled),
+    ...(styleProps.focusVisible && styles.focusVisible),
   });
 };
 
diff --git a/packages/material-ui/src/Slider/Slider.js b/packages/material-ui/src/Slider/Slider.js
--- a/packages/material-ui/src/Slider/Slider.js
+++ b/packages/material-ui/src/Slider/Slider.js
@@ -26,32 +26,26 @@ export const sliderClasses = {
 };
 
 const overridesResolver = (props, styles) => {
-  const {
-    color = 'primary',
-    marks: marksProp = false,
-    max = 100,
-    min = 0,
-    orientation = 'horizontal',
-    step = 1,
-    track = 'normal',
-  } = props;
+  const { styleProps } = props;
 
   const marks =
-    marksProp === true && step !== null
-      ? [...Array(Math.floor((max - min) / step) + 1)].map((_, index) => ({
-          value: min + step * index,
-        }))
-      : marksProp || [];
+    styleProps.marksProp === true && styleProps.step !== null
+      ? [...Array(Math.floor((styleProps.max - styleProps.min) / styleProps.step) + 1)].map(
+          (_, index) => ({
+            value: styleProps.min + styleProps.step * index,
+          }),
+        )
+      : styleProps.marksProp || [];
 
   const marked = marks.length > 0 && marks.some((mark) => mark.label);
 
   return deepmerge(styles.root || {}, {
-    ...styles[`color${capitalize(color)}`],
+    ...styles[`color${capitalize(styleProps.color)}`],
     [`&.${sliderClasses.disabled}`]: styles.disabled,
     ...(marked && styles.marked),
-    ...(orientation === 'vertical' && styles.vertical),
-    ...(track === 'inverted' && styles.trackInverted),
-    ...(track === false && styles.trackFalse),
+    ...(styleProps.orientation === 'vertical' && styles.vertical),
+    ...(styleProps.track === 'inverted' && styles.trackInverted),
+    ...(styleProps.track === false && styles.trackFalse),
     [`& .${sliderClasses.rail}`]: styles.rail,
     [`& .${sliderClasses.track}`]: styles.track,
     [`& .${sliderClasses.mark}`]: styles.mark,
@@ -59,7 +53,7 @@ const overridesResolver = (props, styles) => {
     [`& .${sliderClasses.valueLabel}`]: styles.valueLabel,
     [`& .${sliderClasses.thumb}`]: {
       ...styles.thumb,
-      ...styles[`thumbColor${capitalize(color)}`],
+      ...styles[`thumbColor${capitalize(styleProps.color)}`],
       [`&.${sliderClasses.disabled}`]: styles.disabled,
     },
   });
diff --git a/packages/material-ui/src/Typography/Typography.js b/packages/material-ui/src/Typography/Typography.js
--- a/packages/material-ui/src/Typography/Typography.js
+++ b/packages/material-ui/src/Typography/Typography.js
@@ -20,7 +20,7 @@ const getTextColor = (color, palette) => {
 };
 
 const overridesResolver = (props, styles) => {
-  const { styleProps = {} } = props;
+  const { styleProps } = props;
 
   return deepmerge(styles.root || {}, {
     ...(styleProps.variant && styles[styleProps.variant]),


Test patch:
diff --git a/packages/material-ui/src/Avatar/Avatar.test.js b/packages/material-ui/src/Avatar/Avatar.test.js
--- a/packages/material-ui/src/Avatar/Avatar.test.js
+++ b/packages/material-ui/src/Avatar/Avatar.test.js
@@ -19,6 +19,7 @@ describe('<Avatar />', () => {
     muiName: 'MuiAvatar',
     testDeepOverrides: { slotName: 'fallback', slotClassName: classes.fallback },
     testVariantProps: { variant: 'foo' },
+    testStateOverrides: { prop: 'variant', value: 'rounded', styleKey: 'rounded' },
     skip: ['componentsProp'],
   }));
 
diff --git a/packages/material-ui/src/Button/Button.test.js b/packages/material-ui/src/Button/Button.test.js
--- a/packages/material-ui/src/Button/Button.test.js
+++ b/packages/material-ui/src/Button/Button.test.js
@@ -24,6 +24,7 @@ describe('<Button />', () => {
     muiName: 'MuiButton',
     testDeepOverrides: { slotName: 'label', slotClassName: classes.label },
     testVariantProps: { variant: 'contained', fullWidth: true },
+    testStateOverrides: { prop: 'size', value: 'small', styleKey: 'sizeSmall' },
     skip: ['componentsProp'],
   }));
 
diff --git a/packages/material-ui/src/Slider/Slider.test.js b/packages/material-ui/src/Slider/Slider.test.js
--- a/packages/material-ui/src/Slider/Slider.test.js
+++ b/packages/material-ui/src/Slider/Slider.test.js
@@ -39,6 +39,7 @@ describe('<Slider />', () => {
     muiName: 'MuiSlider',
     testDeepOverrides: { slotName: 'thumb', slotClassName: classes.thumb },
     testVariantProps: { color: 'primary', orientation: 'vertical' },
+    testStateOverrides: { prop: 'color', value: 'secondary', styleKey: 'colorSecondary' },
   }));
 
   it('should call handlers', () => {
diff --git a/packages/material-ui/src/Typography/Typography.test.js b/packages/material-ui/src/Typography/Typography.test.js
--- a/packages/material-ui/src/Typography/Typography.test.js
+++ b/packages/material-ui/src/Typography/Typography.test.js
@@ -20,6 +20,7 @@ describe('<Typography />', () => {
     refInstanceof: window.HTMLParagraphElement,
     muiName: 'MuiTypography',
     testVariantProps: { color: 'secondary', variant: 'dot' },
+    testStateOverrides: { prop: 'variant', value: 'h2', styleKey: 'h2' },
     skip: ['componentsProp'],
   }));
 
diff --git a/test/utils/describeConformanceV5.js b/test/utils/describeConformanceV5.js
--- a/test/utils/describeConformanceV5.js
+++ b/test/utils/describeConformanceV5.js
@@ -57,7 +57,38 @@ function testThemeComponents(element, getOptions) {
       expect(container.firstChild).to.have.attribute(testProp, 'testProp');
     });
 
-    it("respect theme's styleOverrides", () => {
+    it("respect theme's styleOverrides custom state", () => {
+      const { muiName, testStateOverrides } = getOptions();
+
+      if (!testStateOverrides) {
+        return;
+      }
+
+      const testStyle = {
+        marginTop: '13px',
+      };
+
+      const theme = createMuiTheme({
+        components: {
+          [muiName]: {
+            styleOverrides: {
+              [testStateOverrides.styleKey]: testStyle,
+            },
+          },
+        },
+      });
+
+      const { container } = render(
+        <ThemeProvider theme={theme}>
+          {React.cloneElement(element, {
+            [testStateOverrides.prop]: testStateOverrides.value,
+          })}
+        </ThemeProvider>,
+      );
+      expect(container.firstChild).to.toHaveComputedStyle(testStyle);
+    });
+
+    it("respect theme's styleOverrides slots", () => {
       const { muiName, testDeepOverrides } = getOptions();
 
       const testStyle = {