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

Autocomplete custom styles get overwritten by MUI styles (v5) #30294

Open
2 tasks done
UnderTheMoonspell opened this issue Dec 20, 2021 · 16 comments
Open
2 tasks done

Autocomplete custom styles get overwritten by MUI styles (v5) #30294

UnderTheMoonspell opened this issue Dec 20, 2021 · 16 comments
Labels
component: autocomplete This is the name of the generic UI component, not the React module! support: question Community support but can be turned into an improvement

Comments

@UnderTheMoonspell
Copy link

UnderTheMoonspell commented Dec 20, 2021

Duplicates

  • I have searched the existing issues

Latest version

  • I have tested the latest version

Current behavior 😯

After upgrading to MUI5, the autocomplete options custom styles are loaded after the MUI styles which makes me use !important to override the styles.

image

Expected behavior 🤔

My styles should be loaded first like in other components in order to avoid the use of !important.

Your environment 🌎

`npx @mui/envinfo`
  System:
    OS: macOS 11.6.2
  Binaries:
    Node: 14.16.0 - ~/.nvm/versions/node/v14.16.0/bin/node
    Yarn: 1.22.10 - /usr/local/bin/yarn
    npm: 6.14.11 - ~/.nvm/versions/node/v14.16.0/bin/npm
  Browsers:
    Chrome: 96.0.4664.110
    Edge: Not Found
    Firefox: 93.0
    Safari: 15.2
  npmPackages:
    @emotion/react: ^11.5.0 => 11.5.0 
    @emotion/styled: ^11.3.0 => 11.3.0 
    @mui/core:  5.0.0-alpha.54 
    @mui/lab: ^5.0.0-alpha.54 => 5.0.0-alpha.54 
    @mui/material: ^5.1.0 => 5.1.0 
    @mui/private-theming:  5.1.0 
    @mui/styled-engine:  5.1.0 
    @mui/styles: ^5.1.0 => 5.1.0 
    @mui/system:  5.1.0 
    @mui/types:  7.1.0 
    @mui/utils:  5.1.0 
    @types/react: ^17.0.22 => 17.0.24 
    react: 17.0.2 => 17.0.2 
    react-dom: 17.0.2 => 17.0.2 
    typescript: ^4.4.3 => 4.4.3 
@UnderTheMoonspell UnderTheMoonspell added the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Dec 20, 2021
@mnajdova
Copy link
Member

You should use the .MuiAutocomplete-option subselector for adding overrides. Can you share a codesandbox of how you are overriding those? I can help resolve the problem.

@UnderTheMoonspell
Copy link
Author

UnderTheMoonspell commented Dec 21, 2021

I am already using that selector.

  <Autocomplete
    id={name}
    classes={{
      option: styles.menuItem,
      listbox: styles.menuList,
      noOptions: styles.noOptions,
      groupLabel: styles.headerItem,
    }} />

I forgot to mention I am using CSS modules, but the other components seem to be working fine. There was also a similar problem in a page where I was importing React-Select, but with the performance upgrades to the Selects in MUI5 I don't need React-Select anymore, so I solved it just by removing it.

This is my _app.page.tsx

    <StylesProvider injectFirst>
      <Head>
        <title>Web Onboarding</title>
      </Head>
      <div>
        <Component {...pageProps} />
      </div>
    </StylesProvider>

@UnderTheMoonspell
Copy link
Author

Actually this also happens in other components, like Select.

image

P.S.: This app was migrated from V4 according to the migration guide, and it was working as supposed before

@mnajdova
Copy link
Member

I am already using that selector.

You are not based on the code. You should use something like:

styles.css

 .listbox {
+  // Need to bump the specificity on the options
+  & .MuiAutocomplete-option {
+    // the menuItem styles
+ }
}
  <Autocomplete
    id={name}
    classes={{
-     option: styles.menuItem,
      listbox: styles.menuList,
      noOptions: styles.noOptions,
      groupLabel: styles.headerItem,
    }} />

If there are problems please create a codesandbox, otherwise, it's hard to iterate and verify that it works. cc @hbjORbj probably these are more opportunities for improving the migration guide.

@UnderTheMoonspell
Copy link
Author

UnderTheMoonspell commented Dec 21, 2021

So that's an intended change then? I never had to target '.Mui' selectors before, the classes property used to be enough to target exactly what I needed.

@mnajdova
Copy link
Member

Yes, we just haven't documented it correctly. I would assume the same would go for the select. If I was using CSS modules, I would always specify all styles with sub-selectors inside the root class name. It's simpler and there won't be any surprises.

@UnderTheMoonspell
Copy link
Author

@mnajdova ok thanks for the help :)

@UnderTheMoonspell
Copy link
Author

UnderTheMoonspell commented Dec 23, 2021

@mnajdova correct me if I'm wrong but this makes using compose way harder than before, since we can only use 1 level selectors, so .listbox .item { compose: etc from "./etc" } doesnt work anymore.

Also i was able to make this work, but in order to do it, this was what I had to do:

 <Autocomplete
  id={name}
  classes={{
    option: styles.menuItem,
    noOptions: styles.noOptions,
    groupLabel: styles.headerItem,
  }}
  ListboxProps={{ className: styles.menuList }} />

Seems way too convoluted. I tried to do it as you said but it didn't work. Heres a codesandbox showing the problem:

https://codesandbox.io/s/autocomplete-css-modules-demo-o1hsk

@mnajdova
Copy link
Member

Will check it tomorrow

@mnajdova
Copy link
Member

Here is a working example @UnderTheMoonspell https://codesandbox.io/s/autocomplete-css-modules-demo-forked-udjpj?file=/src/CssModulesSlider.module.css

You were close :) When you use CSS modules you need to specify the selector for the subclass and pass it along. Basically you are again passing all the classes as before, you just bump the specificity for the styles for the option, by rising the selector:

.listbox .option {
  // styles for the option
}

@mnajdova mnajdova added component: autocomplete This is the name of the generic UI component, not the React module! support: question Community support but can be turned into an improvement and removed status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels Dec 27, 2021
@UnderTheMoonspell
Copy link
Author

UnderTheMoonspell commented Dec 29, 2021

@mnajdova ok thanks for the help, this doesnt change the fact that it now becomes harder to use "composes" which is one of the nice features of CSS Modules.

Also I am having a very hard time trying to do the same for the Select component:

image

The highest specitivity here is Mui's and it's based on a MuiInput + MuiSelect. That MuiInput is not even costumizable as seen here:

image

And so, in my use case I have a base select component, which then I use to create, for example, a country select, but this makes overriding a nightmare (to be honest, as I see it, makes it impossible without using !important).

@mnajdova
Copy link
Member

It's not perfect that you need to bump the specificity here, we should work on improving the DX for customizing the Select overall. This is not specific to CSS modules. You would need to bump the specificity in this case.

@UnderTheMoonspell
Copy link
Author

@mnajdova how would I bump the specificity here?

@Cwittofur
Copy link

Cwittofur commented Mar 15, 2022

We are also experiencing the same issues. In MUI 4 our styled components would take priority over the base styles of the components. Now that we have to include even more specificity, it is quite a nightmare. Is there any way we can get this reverted so that styled components take priority? (We also converted from styled-components to emotion). Is there any plan to do this with a timeline? Our team is currently thinking of reverting back to MUI 4 until some of these issues are resolved in a better manner. This affects all of our components, not just autocomplete.

@mnajdova
Copy link
Member

@Cwittofur if you are using only emotion there shouldn't be any issues. You can even use the styled() utility from @mui/material/styles. Also, if you are using SSR, you will need to configure your project as shown in the examples projects. If you are using any other library for overrides, you would need to make sure the CSS injection order is correct - https://mui.com/guides/interoperability/#css-injection-order

If you can provide an example usage that you have, or create a simple codensadbox/repository to showcase the problem, I can help with it.

@tihuan
Copy link

tihuan commented Apr 13, 2022

We're probably missing something, but Dialog doesn't seem to append the custom styles at the end?

In this codesanbox, we create a custom Paper component and use it in Dialog:

const StyledPaper = styled(Paper)`
  background-color: pink;
  max-width: revert; // <-- doesn't work
  width: 1200px;
`;

<Dialog ... PaperComponent={StyledPaper}>
  ...
</Dialog>

But somehow our custom style rules are not appended at the end of the Paper class, so we can't override max-width:

Screen Shot 2022-04-13 at 10 47 29 AM

However, if we wrap our custom style with & { ... }, then the custom styles are in their own inline style tag, and thus works:

codesandbox

const StyledPaper = styled(Paper)`
  & { // <-- net change
      background-color: pink;
      max-width: revert; // <-- works now!
      width: 1200px;
  }
`;

Screen Shot 2022-04-13 at 11 00 47 AM

Question:

Is it normal that sometimes custom styles are appended at the end of the rules and sometimes it's not?

Our suspicion is that perhaps our custom styles are in the middle of the MuiDialog-paper css class, because Dialog adds more default MUI styles to its PaperComponent, thus overriding our custom StyledPaper. And if this is the intended behavior, is & { ... } the recommended solution?

Thank you!

CC: @mnajdova please kindly help take a look at this if possible, since resolving/clarifying this will help our company's design system MUIv5 roll out 😄 🙏

UPDATE: Created a separate issue for SEO!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: autocomplete This is the name of the generic UI component, not the React module! support: question Community support but can be turned into an improvement
Projects
None yet
Development

No branches or pull requests

4 participants