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

MuiTextField (v5) not overridden by custom theme when imported from separate package. #29151

Closed
2 tasks done
bertom opened this issue Oct 19, 2021 · 19 comments
Closed
2 tasks done
Labels
component: text field This is the name of the generic UI component, not the React module! status: waiting for author Issue with insufficient information

Comments

@bertom
Copy link

bertom commented Oct 19, 2021

  • 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 😯

We have an app with a custom theme and a Themeprovider. Next to that we have a separate package containing components based on MUI components. (All v5)

When we import the wrapped Button Component from the package, the theme gets applied correctly.
When we import the wrapped Textfield Component from the package, The theme gets applied partly.
When I use the same TextField Component form inside the App (not from package, but copied inside the App), The Theme gets applied differently.

The component:

import React from "react";
import {
  TextField as MUITextField,
  TextFieldProps as MUITextFieldProps,
} from "@mui/material";

type TextFieldProps = MUITextFieldProps & {
  isLoading?: boolean;
};

const TextField = ({ ...props }: TextFieldProps) => {
  const inputLabelProps = {
    disableAnimation: true,
    shrink: false,
  };
  const inputProps = {
    size: props.size,
  };

  return (
    <MUITextField
      label="Outlined"
      variant="outlined"
      InputLabelProps={inputLabelProps}
      InputProps={inputProps}
      {...props}
    />
  );
};

TextField.displayName = "TextField";

export { TextField };

The Theme overrides applied correctly:

MuiInputLabel = {
  styleOverrides: {
    root: {
      transform: "translate(0, 0) scale(1)",
      position: "relative",
      fontSize: fontSize.ft14,
      marginBottom: spacing.sp4,
    },
  },
}

The Theme overrides applied incorrectly:

MuiOutlinedInput = {
  styleOverrides: {
    notchedOutline: {
      border: `1px solid ${transparentPalette.black15}`,
    },
    root: {
      fontFamily: fontFamily.primary,
      outline: "6px solid orange",
      MuiInputBase: {
        root: {
          fontFamily: fontFamily.primary,
          background: "red",
        },
      },
    },
    input: {
      fontFamily: fontFamily.primary,
    },
  },
}

These overrides result into this:
image

The first Component is imported from a package and has custom theme applied to the MuiLabel, but default theme applied to MuiOutlinedInput.
The second component is the same component, but imported locally, it has default theming on the MuiLabel, and custom theme styles applied to MuiOutlinedInput.

Expected Behavior 🤔

Overrides should be the same for all, and also applied in the same way to all 'nested` MUI components (which is the case in MuiTextField). Regardless if the component is imported or not.

Code sandbox

https://codesandbox.io/s/vigilant-mccarthy-wu823

Your Environment 🌎

    System:
    OS: macOS 11.6
  Binaries:
    Node: 14.17.0 - /usr/local/bin/node
    Yarn: 1.22.10 - /usr/local/bin/yarn
    npm: 6.14.13 - /usr/local/bin/npm
  Browsers:
    Chrome: 94.0.4606.81
    Edge: Not Found
    Firefox: Not Found
    Safari: 15.0
@bertom bertom added the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Oct 19, 2021
@mnajdova
Copy link
Member

It looks like the same issue as in #29126, which is related to the InputBase component. Did you face the issue with other components too?

@mnajdova mnajdova added component: text field This is the name of the generic UI component, not the React module! status: waiting for author Issue with insufficient information and removed status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels Oct 19, 2021
@mnajdova
Copy link
Member

If it is not the same issue, please provide a CodeSandbox, or a link to a repository where we can take a look on the issue.

@bertom
Copy link
Author

bertom commented Oct 21, 2021

It is not the same issue, we are using ThemeProvider from MUI.
The issue is that some parts of the theme overrides are no applied to components that are imported from another library.

I will provide a sandbox soon

@LongLiveCHIEF
Copy link

I'm getting the same behavior from MuiSlider. It is picking up values from the ThemeProvider that's wrapping the entire app, but not the nested ThemeProvider that is a closer ancestor to the slider itself.

When I put the styleoverrides into the highest level themeprovider theme, all the styles apply properly.

Can't codesandbox atm, because our firewall is blocking the rendering side of condesandbox for some reason.

@bertom
Copy link
Author

bertom commented Oct 25, 2021

Please find the codesandbox here: https://codesandbox.io/s/vigilant-mccarthy-wu823

@LongLiveCHIEF
Copy link

Looks like the popover is affected as well.

@mnajdova
Copy link
Member

Can you maybe provide a sandbox of how exactly are you nesting the themes? There could be something wrong with that I suppose. It’s unclear from the issue shown in the sandbox that it is not the same bug

@bertom
Copy link
Author

bertom commented Oct 26, 2021

In my case I am only using 1 theme

@LongLiveCHIEF
Copy link

Can you maybe provide a sandbox of how exactly are you nesting the themes? There could be something wrong with that I suppose. It’s unclear from the issue shown in the sandbox that it is not the same bug

Our firewall has been doing weird stuff with the various sandbox sites in the last week, so I'm working on it. Let me ask this though, is the syntax below the correct syntax for styleOverrides for the Slider? The confusion I'm getting is that all the docs reference the guide on style overrides and default props, but the term 'slots' and 'classes' are used differently in different places and are a bit ambiguous as a result.

There is no example that shows a good theme styleOverride for something like a Popover/Slider that has "slots" (or is a non-trivial component), so the problem might not be related, and might just be PEBKAC.

Here's what I've done with my slider and popover in the nested theme, but neither takes hold. However both work when I put them in the outer theme:

export const customInnerTheme = createTheme({
  components: {
    MuiPopover: {
      styleOverrides: {
        paper: {
          opacity: '0.5'
        }
      }
    },
    MuiSlider: {
      styleOverrides: {
        root: {
          //styles
        }
      }
    }
  }
})

I'll try to get a sandbox repro to you ASAP and we can figure out if this is a bug, user error, or a different issue entirely.

@mnajdova
Copy link
Member

@bertom I can't tell what is wrong without looking at the code of the component. If it works in the Button but not the OutlinedInput probably something differs in your custom implementation of the components.

@LongLiveCHIEF the overrides look correct.

@bertom
Copy link
Author

bertom commented Oct 29, 2021

@mnajdova Exactly. The components that come from the package are exactly identical as the ones that are created in the sandbox. (I literally copy-pasted them). Yet some parts, behave differently.
As you can see, in the 1st example, the OutlinedInput is getting a hashed CSS class that has the correct values, the second example gets another CSS class that has values from the default theme :
Screenshot 2021-10-29 at 12 12 38

@mnajdova
Copy link
Member

mnajdova commented Nov 3, 2021

From debugging the codesandbox seems like the theme that the OutlinedInput receives in the component coming from the different package is different, for example, it doesn't have the components definition to the custom theme. We had recent fix around this in #29157 Are you using the latest version of @mui/material there?

@bertom
Copy link
Author

bertom commented Nov 4, 2021

we are using @mui/material 5.0.1. But when I upgrade the sandbox to 5.0.6 the issue sill persists. I think the issue is very similar though.

@mnajdova
Copy link
Member

mnajdova commented Nov 5, 2021

Can you upgrade to @mui/material to v5.0.6 so that you have the fix introduced in #29157?

@bertom
Copy link
Author

bertom commented Nov 9, 2021

@mnajdova I updated the package to @mui/material 5.0.6 and the issue is indeed fixed: https://codesandbox.io/s/vigilant-mccarthy-wu823?file=/src/theme.ts

@bertom bertom closed this as completed Nov 9, 2021
@bertom
Copy link
Author

bertom commented Dec 6, 2021

@mnajdova I have found a similar issue with the Box component:
When imported from a library, the sx props do not take into account the theme and have default theme values, while the local Box component (exactly the same) takes value from the custom theme.
I have updated the sandbox with an example: https://codesandbox.io/s/vigilant-mccarthy-wu823?file=/src/theme.ts

@bertom bertom reopened this Dec 6, 2021
@mnajdova
Copy link
Member

mnajdova commented Dec 7, 2021

@bertom taking a look. It's probably similar issue to the TextField. Just to confirm it is not happening with other components right?

@mnajdova
Copy link
Member

mnajdova commented Dec 7, 2021

If I need to guess what is the problem, I would assume this should be the fix:

index 6d3bc979e1..328d63b863 100644
--- a/packages/mui-material/src/Box/Box.js
+++ b/packages/mui-material/src/Box/Box.js
@@ -1,14 +1,12 @@
 import { createBox } from '@mui/system';
+import styled from '../styles/styled';
 import { unstable_ClassNameGenerator as ClassNameGenerator } from '../utils';
-import { createTheme } from '../styles';
-
-const defaultTheme = createTheme();

 /**
  * @ignore - do not document.
  */
 const Box = createBox({
-  defaultTheme,
+  styled,
   defaultClassName: 'MuiBox-root',
   generateClassName: ClassNameGenerator.generate,
 });
diff --git a/packages/mui-system/src/createBox.js b/packages/mui-system/src/createBox.js
index 96b04f290d..0620ea83ad 100644
--- a/packages/mui-system/src/createBox.js
+++ b/packages/mui-system/src/createBox.js
@@ -1,16 +1,14 @@
 import * as React from 'react';
 import PropTypes from 'prop-types';
 import clsx from 'clsx';
-import styled from '@mui/styled-engine';
+import styledEngineStyled from '@mui/styled-engine';
 import styleFunctionSx, { extendSxProp } from './styleFunctionSx';
-import useTheme from './useTheme';

 export default function createBox(options = {}) {
-  const { defaultTheme, defaultClassName = 'MuiBox-root', generateClassName } = options;
+  const { defaultClassName = 'MuiBox-root', generateClassName, styled = styledEngineStyled } = options;
   const BoxRoot = styled('div')(styleFunctionSx);

   const Box = React.forwardRef(function Box(inProps, ref) {
-    const theme = useTheme(defaultTheme);
     const { className, component = 'div', ...other } = extendSxProp(inProps);

     return (
@@ -21,7 +19,6 @@ export default function createBox(options = {}) {
           className,
           generateClassName ? generateClassName(defaultClassName) : defaultClassName,
         )}
-        theme={theme}
         {...other}
       />
     );
diff --git a/packages/mui-system/src/createBox.test.js b/packages/mui-system/src/createBox.test.js
index 93df9e8ffb..8eaf8b2cc4 100644
--- a/packages/mui-system/src/createBox.test.js
+++ b/packages/mui-system/src/createBox.test.js
@@ -13,13 +13,6 @@ describe('createBox', () => {
     expect(container.firstChild).to.have.class('MuiBox-root');
   });

-  it('should use defaultTheme if provided', () => {
-    const Box = createBox({ defaultTheme: { palette: { primary: { main: 'rgb(255, 0, 0)' } } } });
-
-    const { container } = render(<Box color="primary.main">Content</Box>);
-    expect(container.firstChild).toHaveComputedStyle({ color: 'rgb(255, 0, 0)' });
-  });
-
   it('should use theme from Context if provided', () => {
     const Box = createBox({ defaultTheme: { palette: { primary: { main: 'rgb(255, 0, 0)' } } } });

The problem is that, we already have a test for this inside the Box.test.js. Here it is:
https://github.com/mui-org/material-ui/blob/master/packages/mui-material/src/Box/Box.test.js#L25 + it would be a breaking change. On the other hand, I can't even create a test for this, so I cannot justify the change.

@bertom could you help with providing a test. The codesandbox is not helpful as the component used there is hidden behind a private package.

@bertom
Copy link
Author

bertom commented Dec 7, 2021

@bertom taking a look. It's probably similar issue to the TextField. Just to confirm it is not happening with other components right?

No, for now I only saw this behavior in the Box component.

It looks indeed like this is the issue.
I'd be happy to help with a test, please let me know what exactly you need for that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: text field This is the name of the generic UI component, not the React module! status: waiting for author Issue with insufficient information
Projects
None yet
Development

No branches or pull requests

4 participants