material-ui: [system] unstable_classNameGenerator does not support multiple scopes
Duplicates
- I have searched the existing issues
Latest version
- I have tested the latest version
Current behavior 😯
I am migrating to MUI v5 and I found some issues with styles collisions. On our projects, we use a micro front-end structure. That is, we have a Shell application and several micro-frontends which consume a custom library with differents components (like a custom table, custom breadcrumb, dropdown, etc.). This library that is consumed by all the micro frontends and shell is created with Storybook.
Before this migration, our collision issues were fixed with createGenerateClassName. On each micro-frontend, we used to have at the root this declaration:
const microfrontOne = createGenerateClassName({
seed: "microfrontOne ",
});
...
return (
<StylesProvider generateClassName={microfrontOne }>
....
</StylesProvider>
Also, on our custom library, we used to have the same stylesProvider tag to make each component have its own name:
const sidebar = createGenerateClassName({
seed: "sidebar",
});
export const SideBar: React.FC= () => {
<StylesProvider generateClassName={sidebar}>
...
</StylesProvider>
In this way, the styles of each component were correctly set and there was no chance to overlap.
All the microsites and the Shell imports Material FROM the library, so they all have the same version.
With the new library upgrade, the createGenerateClassName was deprecated so this behavior was no longer possible. I tried with unstable_classNameGenerator because I don’t find a better solution (TBH I don’t like to use something that has unstable on its name), but this does not work on the library with Storybook. As I already mention, I need to custom EACH component that I have in order to avoid styles collision. As the unstable_classNameGenerator is designed to be global, this does not work for me.
I can’t provide reproduction to this issue because there are several projects involved, but basically, I think that the issue is that I can’t provide specific tags for a specific component. I can bring more information if it is needed, please let me know. I really want this to be fixed because if it is not, I can’t use the new version of Material UI anymore.
Expected behavior 🤔
Have a way to give a custom tag to a React Component (not global to the app)
Steps to reproduce 🕹
No response
Context 🔦
No response
Your environment 🌎
No response
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 2
- Comments: 23 (14 by maintainers)
The solution to the initial question is here https://github.com/mui/material-ui/issues/29856#issuecomment-981855337.
From my perspective:
classNameGeneratorwas introduced to solve a style class names conflict problem. It can also be used to personalize your brand.unstable_classNameGeneratoris about personalizing your brand. To work, it needs to be a singleton, that has a called before any of the components are imported. It’s unstable because we are not sure poeple need to customize the brand in the first place.I see two opportunities for improvements:
@siriwatknp I would expect no issues. I believe it’s only a problem with
@mui/stylesbecause there are two elements with the.jss21class name on the DOM. This is because JSS uses a class name counter, so the apps need to be configured so two counters don’t conflict. But with emotion, it’s a hash-based class name, so it only colid if the styles are identical, not if the style rule index is the same (1, 2, 3, … 21, etc.). In any case, a reproduction will tell us this for sure.@oliviertassinari thanks for pointing this out. This is a note to @BiancaArtola for clarity,
@mui/stylesv5 is exactly the same engine (JSS) that you are using in v4, however in@mui/materialv5 we have changed the default engine from JSS to emotion so the styles generated when you render a component is by emotion (there is a way to change to styled-components).From what I read in the discussion above, you still need to use
@mui/stylesfor style customization. I hope this helps.Lastly, this means that @BiancaArtola will face the issue if you want to migrate JSS (
@mui/styles) to emotion | styled-components. cc @oliviertassinari@BiancaArtola You should still be able to import
createGenerateClassNamefrom@mui/styles. We only removed it from@mui/material.@mnajdova Here is my idea to fix this issue.
Problem
Solution
Create react context for ClassName so that it can create a scope for each part of the application and communicate with the components under those trees. The components need to use the hook to get the class name generator function and use it via
ownerState.generateClassName. However, the theming part won’t be able to use componentClasses.Since
createThemecan be called anywhere, this is the developer’s responsibility to handle the class name styling.This is my POC branch: https://github.com/mui-org/material-ui/compare/master...siriwatknp:fix/multi-class-name-gen
Hi. Thanks for creating the issue. Can you create a codesandbox that directly shows the error? You can fork this template: https://codesandbox.io/s/mui-issue-latest-s2dsx