-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
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
[material-ui] Merge CssVarsProvider
into ThemeProvider
#43115
Conversation
…-css-vars-provider
…-css-vars-provider
Netlify deploy previewhttps://deploy-preview-43115--material-ui.netlify.app/ TabList: parsed: +20.17% , gzip: +15.83% Bundle size reportDetails of bundle changes (Toolpad) |
…-css-vars-provider
This reverts commit 2603b25.
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 implementation looks good, left some initial feedback.
@@ -2,20 +2,18 @@ | |||
import * as React from 'react'; | |||
import { unstable_createCssVarsProvider as createCssVarsProvider, SxProps } from '@mui/system'; | |||
import styleFunctionSx from '@mui/system/styleFunctionSx'; | |||
import extendTheme, { SupportedColorScheme, CssVarsTheme } from './extendTheme'; | |||
import createThemeWithVars, { SupportedColorScheme, CssVarsTheme } from './createThemeWithVars'; |
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.
We should use the public API as much as possible, e.g. createTheme({ cssVariables: true })
, as this is how users would use it.
const { | ||
CssVarsProvider, | ||
useColorScheme, | ||
getInitColorSchemeScript: deprecatedGetInitColorSchemeScript, | ||
} = createCssVarsProvider<SupportedColorScheme, typeof THEME_ID>({ | ||
themeId: THEME_ID, | ||
theme: defaultTheme, | ||
theme: createThemeWithVars, |
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's the motivation from changing from defaultTheme to a create theme function usage? Do we plan to have two default themes, one with vars and one without?
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 performance improvement. The previous behavior will create a default theme when you import the component but with this change, it will be called when the component is rendered.
Also, the previous behavior will always create a default theme even if the user passes in a custom theme. With this change, the default theme won't be created if the user provides a custom theme.
const theme = createTheme({ | ||
cssVariables: false, | ||
colorSchemes: { light: true }, | ||
palette: { mode: 'dark' }, | ||
}); |
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 should this generate, I am a bit confused. Is this even a valid input?
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 case test a default dark app with light mode.
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.
It's similar to:
createTheme({
cssVariables: false,
colorSchemes: { dark: true },
palette: { mode: 'light' },
});
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 should this generate, I am a bit confused. Is this even a valid input?
Yes, you can think of having the provided palette
as the default color scheme. The reason I go with this path is to support the existing palette customization so we don't have to change much docs.
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 I understand:
The palette
values will continue working the same way as before, but the values will also be copied into colorSchemes
Is that correct?
If it's correct, what's the use of copying the palette values into the color schemes? In other words, how is theme.colorSchemes
going to be used in our codebase or in users codebases when cssVariables: false
?
Is the idea to use colorSchemes
from now on and eventually stop using palette?
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 palette values will continue working the same way as before, but the values will also be copied into colorSchemes Is that correct?
Yes, that's my purpose. My intention is that the colorSchemes
is a new feature to create a second and more color schemes. palette
is considered a default color scheme and will continue to work at least in v6.
If it's correct, what's the use of copying the palette values into the color schemes? In other words, how is theme.colorSchemes going to be used in our codebase or in users codebases when cssVariables: false?
Got it. The ThemeProvider
contains a state that store a user selected mode, a part of the theme is calculated from theme.colorSchemes[selectedMode]
. For example, when user is in dark mode, the theme that passed through context will be:
{
…theme.colorSchemes.dark,
typography: …,
spacing: …,
breakpoints: …,
}
We have to do this so that it still work with apps that use values from theme.palette.*
when switching between modes.
Is the idea to use colorSchemes from now on and eventually stop using palette?
"use colorSchemes from now on" Yes, but "eventually stop using palette" could be, it will be clearer in v6 when people start using it.
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 makes sense to me 👌🏼
When we discuss the v7 theme structure, we can discuss the plan for theme.palette
.
@@ -23,6 +56,60 @@ describe('createTheme', () => { | |||
expect(theme.palette.secondary.main).to.equal(green.A400); | |||
}); | |||
|
|||
describe('CSS variables', () => { | |||
it('should have a light as a default colorScheme if only `palette` is provided', () => { |
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.
Ah nice, this means we can use the old theme structure and still have vars generated. This is great!
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.
Yes, that's one of the goal.
By the end of the guide, can we have an example we can share that has everything set up. There are quite a few things that needs to be generated as expected, e.g. setting both light and dark color schemes etc. I feel like the guide is not complete and hard to follow. |
We are referencing some old APIs/ways to do things. Should we update this page reflecting the latest changes? |
Still uses the old |
I am removing this page. It's considered a new feature, so I don't think |
That page is about configuring the feature. To see light and dark color schemes, I think it should be in the usage guide, I will add some example to https://deploy-preview-43130--material-ui.netlify.app/material-ui/customization/css-theme-variables/usage/. |
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.
Hey Jun! Good work, it looks like a headache-inducing task to merge these 😅 but it's looking great overall 😊
My main question about the logic is here: #43115 (comment)
c6a36ea
to
9ca6e73
Compare
@DiegoAndai My idea is to merge this PR first to release this week to test that everything is working as expected and then let the DevEx team review the docs PR, is that okay with you? |
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.
@siriwatknp that makes sense to me, I have two more questions:
closes #43033
Summary of the change
ThemeProvider
becomes a wrapper that renders either a ThemeContext or a CssVarsProvider based on thetheme.colorSchemes
node.createTheme
becomes a wrapper that calls either the previouscreateTheme
orextendTheme
based on the user input.The default
createTheme()
does not come with CSS variables by default.It has to be enabled with
{ cssVariables: true }
flag.The palette customization still works, see the different scenario in the demo below
mode
fromuseColorScheme
hook is undefined at hydration phase.Demo
The sandbox below demonstrates use cases for using the new ThemeProvider.
https://codesandbox.io/p/sandbox/material-ui-cra-ts-forked-6tjzq2?file=%2Fsrc%2Fdemos%2FDarkApp.tsx
Improvements
CssVarsProvider
are independent of CSS variables.For example,
disableTransitionOnChange
,useColorScheme
hook, and system preference.This is a demo for using these features without generating CSS variables.