[Button] Migrate styles to emotion#24107
Conversation
|
@material-ui/core: parsed: +0.74% , gzip: +0.56% |
| let getByRole; | ||
|
|
||
| expect(() => { | ||
| const { getByRole: getByRoleLocal } = render(<Button startIcon={<span>icon</span>}>Hello World</Button>); |
There was a problem hiding this comment.
Emotion throws this error when ":first-child" is used. The error is shown when startIcon od endIcon is used.
There was a problem hiding this comment.
Is it because emotion injects <style> elements in the page when SSR isn't configured?
There was a problem hiding this comment.
There was a problem hiding this comment.
Exactly, but as we are following the advanced SSR configuration - https://emotion.sh/docs/ssr#advanced-approach we should be fine.
There was a problem hiding this comment.
Managed to avoid the warning with 745e163. See comment - #24107 (comment)
| <Button startIcon={<span>icon</span>}>Hello World</Button>, | ||
| ); | ||
| getByRole = getByRoleLocal; | ||
| }).toErrorDev( |
There was a problem hiding this comment.
@eps1lon am I using the toErrorDev correctly here? If I have this expected error in both tests as it's done currently, the tests are failing with https://app.circleci.com/pipelines/github/mui-org/material-ui/30240/workflows/2f2f8de6-1ef0-48e1-9962-9baa4d91821e/jobs/206347
If I remove the toErrorDev in the second test, then it is failing with
19) <Button />
should render a button with endIcon:
Expected test not to call console.error()
If the warning is expected, test for it explicitly by using the toErrorDev() matcher.
Test location:
D:\workspace\material-ui\packages\material-ui\src\Button\Button.test.js
console.error message:
The pseudo class ":first-child" is potentially unsafe when doing server-side rendering. Try changing it to ":first-of-type".
Stack:
...
Should I clear the errors in between somewhere or?
There was a problem hiding this comment.
Is emotion deduplicating errors at the module level or something?
I wouldn't worry about it since we don't want to ship that warning anyway. SSR should not have any warnings or errors by default.
There was a problem hiding this comment.
Fixed the warning with 745e163 I've replaced the '& > *:first-child' selctor with '& > *:nth-of-type(1)' to avoid this warning. The result should be identical.
There was a problem hiding this comment.
The result should be identical.
More or less 😁 https://codepen.io/oliviertassinari/pen/oNYBeEd
|
Regarding the argos change - https://www.argos-ci.com/mui-org/material-ui/builds/6382 seems like we are fixing a previous issue with these changes |
|
I found it is a breaking change in our code. The problem is related to CSS priority. It seems like CSS is injected in the wrong order |
|
How to make sure MUI styles (despite JSS or emotion) is always inserted before developer styles (despite JSS or emotion)? I can't find a workaround, is there an official guide for it? @oliviertassinari |
|
Well I write a dirty workaround const workaround = document.createElement('div')
document.body.insertBefore(workaround, null)
const shadowMap = new WeakMap<HTMLStyleElement, HTMLStyleElement>()
document.head.insertBefore = new Proxy(document.head.insertBefore, {
apply(f, target, [dom, before]) {
if (target === document.head && dom instanceof HTMLStyleElement) {
if (shadowMap.has(before)) before = shadowMap.get(before)
const meta = dom.getAttribute('data-meta')
if (meta && meta.startsWith('makeStyle')) {
workaround.appendChild(dom)
const shadow = document.createElement('style')
shadowMap.set(dom, shadow)
Reflect.apply(f, target, [shadow, before])
Object.defineProperty(dom, 'parentNode', {
get() {
return document.head
},
})
return dom
}
}
return Reflect.apply(f, target, [dom, before])
},
}) |
|
@Jack-Works you need to use the |
I used it but it doesn't work. The problem here is both JSS and emotion can have user styles and MUI styles. |
Yes, it cannot work if you use both style engines for overrides randomly. I would suggest if you plan to migrate to the new overrides technique, to do it step by step as we migrate the components. If you don't want to do it iterativly, I'd suggest keeping the JSS overrides and migrate in the end to emotion. The problematic thing could be the theme overrides, as those are already using emotion. Is this the problem you are facing? |
|
I'm not quite clear. My workaround works for me currently. I'll continue to use it until makeStyles moved to emotion. |
Mind that we are removing makeStyles progressively (v6), there are no plans to port this API to emotion/sc. |
Wait, all of our custom CSS are written in makeStyles, how can we migrate? that work is too heavy if it cannot be done with a codemod |
|
@Jack-Works react-jss provides the same API, it will be the simplest path for developers that want a quick-win. But we won't drop the API before v6 so you have time. |
|
Ok I found another problem. MenuItem is based on ButtonBase. And now the CSS order in our app causes problem:
|
@Jack-Works It's what we recommend, so far. I have updated #24229 to mention it, in hindsight. |

This PR migrates the
Button's styles to emotion. In addition, it fixes #24045 - it's adding global class names for the default values of thesizeandcolorprops.