-
-
Notifications
You must be signed in to change notification settings - Fork 32.5k
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
[styled-engine] Fix style overrides variants type #45478
base: master
Are you sure you want to change the base?
[styled-engine] Fix style overrides variants type #45478
Conversation
Netlify deploy previewhttps://deploy-preview-45478--material-ui.netlify.app/ Bundle size report |
@@ -42,7 +42,7 @@ const items = [ | |||
const Chip = styled(MuiChip)(({ theme }) => ({ | |||
variants: [ | |||
{ | |||
props: ({ selected }) => selected, | |||
props: ({ selected }) => !!selected, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have to fix this because the type of selected
is boolean | undefined
.
Should we loosen the type like of props? to be () => boolean | null | undefined
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't mind the !!
to cast into boolean
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this mean this is a breaking change?
| ComponentSelector | ||
| Keyframes | ||
| SerializedStyles | ||
| CSSPropertiesWithMultiValues |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a myth to me. If not adding CSSPropertiesWithMultiValues
explicitly as a union, the spec fail for recreating nested theme.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you mean with "myth"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At first, I thought that CSSObject
is enough because it extends CSSPropertiesWithMultiValues
. However, if I excluded CSSPropertiesWithMultiValues
from the union type, I got this error from createTheme.spec
:

Here is the full error:
Argument of type 'Theme' is not assignable to parameter of type 'Omit<ThemeOptions, "components"> & Pick<CssVarsThemeOptions, "colorSchemes" | "defaultColorScheme" | "components"> & { ...; }'.
Type 'Theme' is not assignable to type 'Pick<CssVarsThemeOptions, "colorSchemes" | "defaultColorScheme" | "components">'.
Types of property 'components' are incompatible.
Type 'Components<BaseTheme> | undefined' is not assignable to type 'Components<Omit<Theme, "palette" | "components"> & CssVarsTheme> | undefined'.
Type 'Components<BaseTheme>' is not assignable to type 'Components<Omit<Theme, "palette" | "components"> & CssVarsTheme>'.
Types of property 'MuiAlert' are incompatible.
Type '{ defaultProps?: Partial<AlertProps> | undefined; styleOverrides?: Partial<OverridesStyleRules<keyof AlertClasses, "MuiAlert", BaseTheme>> | undefined; variants?: { ...; }[] | undefined; } | undefined' is not assignable to type '{ defaultProps?: Partial<AlertProps> | undefined; styleOverrides?: Partial<OverridesStyleRules<keyof AlertClasses, "MuiAlert", Omit<Theme, "palette" | "components"> & CssVarsTheme>> | undefined; variants?: { ...; }[] | undefined; } | undefined'.
Type '{ defaultProps?: Partial<AlertProps> | undefined; styleOverrides?: Partial<OverridesStyleRules<keyof AlertClasses, "MuiAlert", BaseTheme>> | undefined; variants?: { ...; }[] | undefined; }' is not assignable to type '{ defaultProps?: Partial<AlertProps> | undefined; styleOverrides?: Partial<OverridesStyleRules<keyof AlertClasses, "MuiAlert", Omit<Theme, "palette" | "components"> & CssVarsTheme>> | undefined; variants?: { ...; }[] | undefined; }'.
Types of property 'styleOverrides' are incompatible.
Type 'Partial<OverridesStyleRules<keyof AlertClasses, "MuiAlert", BaseTheme>> | undefined' is not assignable to type 'Partial<OverridesStyleRules<keyof AlertClasses, "MuiAlert", Omit<Theme, "palette" | "components"> & CssVarsTheme>> | undefined'.
Type 'Partial<OverridesStyleRules<keyof AlertClasses, "MuiAlert", BaseTheme>>' is not assignable to type 'Partial<OverridesStyleRules<keyof AlertClasses, "MuiAlert", Omit<Theme, "palette" | "components"> & CssVarsTheme>>'.
Types of property 'root' are incompatible.
Type 'Interpolation<AlertProps & Record<string, unknown> & { ownerState: AlertProps & Record<string, unknown>; } & { theme: BaseTheme; }>' is not assignable to type 'Interpolation<AlertProps & Record<string, unknown> & { ownerState: AlertProps & Record<string, unknown>; } & { theme: Omit<Theme, "palette" | "components"> & CssVarsTheme; }>'.
Type 'CSSObject & { variants?: { props: Partial<AlertProps & Record<string, unknown> & { ownerState: AlertProps & Record<string, unknown>; } & { ...; }> | ((props: Partial<...> & { ...; }) => boolean); style: CSSObject | ((args: { ...; }) => CSSObject); }[] | undefined; }' is not assignable to type 'Interpolation<AlertProps & Record<string, unknown> & { ownerState: AlertProps & Record<string, unknown>; } & { theme: Omit<Theme, "palette" | "components"> & CssVarsTheme; }>'.
Type 'CSSObject & { variants?: { props: Partial<AlertProps & Record<string, unknown> & { ownerState: AlertProps & Record<string, unknown>; } & { ...; }> | ((props: Partial<...> & { ...; }) => boolean); style: CSSObject | ((args: { ...; }) => CSSObject); }[] | undefined; }' is not assignable to type 'Keyframes'.
Type 'CSSObject & { variants?: { props: Partial<AlertProps & Record<string, unknown> & { ownerState: AlertProps & Record<string, unknown>; } & { ...; }> | ((props: Partial<...> & { ...; }) => boolean); style: CSSObject | ((args: { ...; }) => CSSObject); }[] | undefined; }' is missing the following properties from type '{ name: string; styles: string; anim: number; toString: () => string; }': name, styles, animts(2345)
I don't fully understand why.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error is not related too much to the type that's being added, this is suspicious, let me check it again locally and I will report back.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on this type: https://github.com/mui/material-ui/blob/master/packages/mui-material/src/styles/createTheme.ts#L38 the error is expected in my opinion. The issue is that in createTheme, we return this type: https://github.com/mui/material-ui/blob/master/packages/mui-material/src/styles/createThemeNoVars.d.ts#L82 which has different definition for components
than the input of createTheme
. We should probably loosen the input type for createTheme
, to accept a Theme
, if we are allowing this use-case. We should also make sure that all proposed options from https://mui.com/material-ui/customization/theming/#nesting-the-theme are type safe.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for taking a look at this @siriwatknp! 😊
I have a couple of questions
| Keyframes | ||
| SerializedStyles | ||
| CSSPropertiesWithMultiValues | ||
| (CSSObject & { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a benefit in inlining the variants here instead of defining it separately?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is required, otherwise variants
is not type-safety. You can try in this Playground
Hey @siriwatknp! I took a look at this, and I managed to remove The
|
I suggest not removing it as it will introduce another issue for people who read const theme = createTheme({
component: { … }
})
console.log(theme.components); // << TS error. Also, removing the |
…esWithMultiValues" This reverts commit daa9579.
@siriwatknp I closed #45346 in favor of this PR, lets move forward with this solution @mnajdova may I ask you to review this? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will report soon with my findings.
@@ -42,7 +42,7 @@ const items = [ | |||
const Chip = styled(MuiChip)(({ theme }) => ({ | |||
variants: [ | |||
{ | |||
props: ({ selected }) => selected, | |||
props: ({ selected }) => !!selected, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this mean this is a breaking change?
@@ -218,6 +218,7 @@ const theme = createTheme(); | |||
variants: [ | |||
{ | |||
props: ({ ownerState }) => ownerState.color === 'primary', | |||
style: {}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wasn't style required before?
| ComponentSelector | ||
| Keyframes | ||
| SerializedStyles | ||
| CSSPropertiesWithMultiValues |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error is not related too much to the type that's being added, this is suspicious, let me check it again locally and I will report back.
Closes #45275
The issue is that
Omit<CSSOthersObject, 'variants'>
doesn't work as expected asCSSOthersObject
is a mapped type, whichOmit
has known issues with:In a nutshell: By design,
Omit
won't remove variants fromCSSOthersObject
, so the type defined inCSSObjectWithVariants
is not used.Solution and discussion below