Skip to content

Commit 6a340d7

Browse files
committed
Improve applyStyles docs
1 parent 9057a52 commit 6a340d7

File tree

3 files changed

+123
-66
lines changed

3 files changed

+123
-66
lines changed

docs/data/material/customization/css-theme-variables/configuration.md

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -128,30 +128,34 @@ For SSR (server-side rendering) applications, Material UI can not detected user
128128

129129
To prevent the issue, you need to ensure that there is no usage of `theme.palette.mode === 'dark'` in your code base.
130130

131-
If you have such a condition, replace it with the [`theme.applyStyles()`](#appling-dark-styles) function:
131+
If you have such a condition, replace it with the `theme.applyStyles()` function:
132132

133133
```diff
134134
import Card from '@mui/material/Card';
135135

136136
function App() {
137137
return (
138138
<Card
139-
sx={(theme) => ({
139+
- sx={(theme) => ({
140140
- backgroundColor: theme.palette.mode === 'dark' ? '#000' : '#fff',
141141
- '&:hover': {
142142
- backgroundColor: theme.palette.mode === 'dark' ? '#333' : '#f5f5f5',
143143
- },
144-
+ backgroundColor: '#fff',
145-
+ '&:hover': {
146-
+ backgroundColor: '#f5f5f5',
147-
+ ...theme.applyStyles('dark', {
148-
+ backgroundColor: '#333',
149-
+ }),
144+
- })}
145+
+ sx={(theme) => ([
146+
+ {
147+
+ backgroundColor: '#fff'
148+
+ '&:hover': {
149+
+ backgroundColor: '#f5f5f5',
150+
+ },
150151
+ },
151-
+ ...theme.applyStyles('dark', {
152+
+ theme.applyStyles('dark', {
152153
+ backgroundColor: '#000',
154+
+ '&:hover': {
155+
+ backgroundColor: '#333',
156+
+ },
153157
+ }),
154-
})}
158+
+ ])}
155159
/>
156160
);
157161
}

docs/data/material/customization/css-theme-variables/usage.md

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -48,36 +48,28 @@ If you want to be able to manually toggle modes, see the guide to [toggling dark
4848

4949
## Applying dark styles
5050

51-
To customize styles for dark mode, use `theme.applyStyles()` function.
52-
This utility function will return the right selector.
51+
To customize styles for dark mode, use the [`theme.applyStyles()` function](/material-ui/customization/dark-mode/#api).
52+
This function returns an object which key is the mode selector and value is the styles object.
5353

5454
The example below shows how to customize the Card component for dark mode:
5555

5656
```js
5757
import Card from '@mui/material/Card';
5858

5959
<Card
60-
sx={(theme) => ({
61-
backgroundColor: theme.vars.palette.background.default,
62-
...theme.applyStyles('dark', {
60+
sx={(theme) => [
61+
{
62+
backgroundColor: theme.vars.palette.background.default,
63+
},
64+
theme.applyStyles('dark', {
6365
boxShadow: 'none', // remove the box shadow in dark mode
6466
}),
65-
})}
67+
]}
6668
/>;
6769
```
6870

6971
:::warning
70-
Do not use `theme.palette.mode` to switch between light and dark styles—this produces an [unwanted flickering effect](/material-ui/customization/dark-mode/#dark-mode-flicker).
71-
72-
```js
73-
<Card
74-
sx={{
75-
// 🚫 this will cause flickering
76-
backgroundColor: theme.palette.mode === 'dark' ? '' : '',
77-
}}
78-
/>
79-
```
80-
72+
Do not use `theme.palette.mode` to switch between light and dark styles—this produces an [unwanted flickering effect](/material-ui/customization/css-theme-variables/configuration/#preventing-ssr-flickering).
8173
:::
8274

8375
## Using theme variables
@@ -94,17 +86,17 @@ This `vars` object mirrors the structure of a serializable theme, with each valu
9486
}));
9587
```
9688

97-
For **TypeScript**, the typings are not enabled by default.
98-
Follow the [TypeScript setup](#typescript) to enable the typings.
89+
For **TypeScript**, the typings are not enabled by default.
90+
Follow the [TypeScript setup](#typescript) to enable the typings.
9991

100-
:::success
101-
If the components need to render outside of the `CssVarsProvider`, add fallback to the theme object.
92+
:::success
93+
If the components need to render outside of the `CssVarsProvider`, add fallback to the theme object.
10294

103-
```js
104-
backgroundColor: (theme.vars || theme).palette.primary.main;
105-
```
95+
```js
96+
backgroundColor: (theme.vars || theme).palette.primary.main;
97+
```
10698

107-
:::
99+
:::
108100

109101
- **Native CSS**: if you can't access the theme object, for example in a pure CSS file, you can use [`var()`](https://developer.mozilla.org/en-US/docs/Web/CSS/var) directly:
110102

@@ -263,3 +255,7 @@ declare module '@mui/material/styles' {
263255
## Next steps
264256

265257
If you need to support system preference and manual selection, check out the [advanced configuration](/material-ui/customization/css-theme-variables/configuration/)
258+
259+
```
260+
261+
```

docs/data/material/customization/dark-mode/dark-mode.md

Lines changed: 88 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -186,20 +186,22 @@ With the `styled` function:
186186
```jsx
187187
import { styled } from '@mui/material/styles';
188188

189-
const MyComponent = styled('div')(({ theme }) => ({
190-
color: '#fff',
191-
backgroundColor: theme.palette.primary.main,
192-
...theme.applyStyles('dark', {
189+
const MyComponent = styled('div')(({ theme }) => [
190+
{
191+
color: '#fff',
192+
backgroundColor: theme.palette.primary.main,
193+
'&:hover': {
194+
boxShadow: theme.shadows[3],
195+
backgroundColor: theme.palette.primary.dark,
196+
},
197+
},
198+
theme.applyStyles('dark', {
193199
backgroundColor: theme.palette.secondary.main,
194-
}),
195-
'&:hover': {
196-
boxShadow: theme.shadows[3],
197-
backgroundColor: theme.palette.primary.dark,
198-
...theme.applyStyles('dark', {
200+
'&:hover': {
199201
backgroundColor: theme.palette.secondary.dark,
200-
}),
201-
},
202-
}));
202+
},
203+
}),
204+
]);
203205
```
204206

205207
With the `sx` prop:
@@ -208,19 +210,19 @@ With the `sx` prop:
208210
import Button from '@mui/material/Button';
209211

210212
<Button
211-
sx={[
212-
(theme) => ({
213+
sx={(theme) => [
214+
{
213215
color: '#fff',
214216
backgroundColor: theme.palette.primary.main,
215-
...theme.applyStyles('dark', {
216-
backgroundColor: theme.palette.secondary.main,
217-
}),
218217
'&:hover': {
219218
boxShadow: theme.shadows[3],
220219
backgroundColor: theme.palette.primary.dark,
221-
...theme.applyStyles('dark', {
222-
backgroundColor: theme.palette.secondary.dark,
223-
}),
220+
},
221+
},
222+
theme.applyStyles('dark', {
223+
backgroundColor: theme.palette.secondary.main,
224+
'&:hover': {
225+
backgroundColor: theme.palette.secondary.dark,
224226
},
225227
}),
226228
]}
@@ -229,6 +231,72 @@ import Button from '@mui/material/Button';
229231
</Button>;
230232
```
231233

234+
### API
235+
236+
`theme.applyStyles(mode, styles) => CSSObject`
237+
238+
Apply styles for a specific mode.
239+
240+
#### Arguments
241+
242+
- `mode` (`'light' | 'dark'`) - The mode for which the styles should be applied.
243+
- `styles` (`CSSObject`) - An object which contains the styles to be applied for the specified mode.
244+
245+
#### Returns
246+
247+
A `CSSObject` which key is the mode selector and value is the styles object: `{ [modeSelector]: styles }`.
248+
249+
By default, the `modeSelector` is `'@media (prefers-color-scheme: light)'` for light mode and `'@media (prefers-color-scheme: dark)'` for dark mode.
250+
251+
### Specificity
252+
253+
Styles applied with `theme.applyStyles()` have higher specificity than the styles defined outside of it.
254+
This means that to override styles applied with it (via the `styled` function or `sx` prop), you need to use `theme.applyStyles()` as well:
255+
256+
```jsx
257+
const BaseButton = styled('button')(({ theme }) =>
258+
theme.applyStyles('dark', {
259+
backgroundColor: 'white',
260+
}),
261+
);
262+
263+
const AliceblueButton = styled(BaseButton)({
264+
backgroundColor: 'aliceblue', // In dark mode, backgroundColor will be white as theme.applyStyles() has higher specificity
265+
});
266+
267+
const PinkButton = styled(BaseButton)(({ theme }) =>
268+
theme.applyStyles('dark', {
269+
backgroundColor: 'pink', // In dark mode, backgroundColor will be pink
270+
}),
271+
);
272+
```
273+
274+
### Overriding applyStyles
275+
276+
If you need to override `theme.applyStyles()`, you can do so by providing a custom function.
277+
A case in which you might need to do it is to return a string instead of an object so it can be used inside template literals:
278+
279+
```js
280+
const theme = createTheme({
281+
// ...
282+
applyStyles: function (key: string, styles: any) {
283+
// return a string instead of an object
284+
return `@media (prefers-color-scheme: %{key}) & {${styles}}`;
285+
},
286+
});
287+
288+
// This allows to use theme.applyStyles() inside template literals
289+
const StyledButton = styled('button')`
290+
${theme.applyStyles('dark', `
291+
background: white;
292+
`
293+
)}
294+
`;
295+
```
296+
297+
When overriding `theme.applyStyles()`, you have complete control over its arguments and return value.
298+
Please review the [source code](https://github.com/mui/material-ui/blob/HEAD/packages/mui-system/src/createTheme/applyStyles.ts) to understand how the default implementation works before overriding it.
299+
232300
### Codemod
233301

234302
We provide codemods to migrate your codebase from using `theme.palette.mode` to use `theme.applyStyles()`.
@@ -242,17 +310,6 @@ npx @mui/codemod@latest v6.0.0/theme-v6 <path/to/theme-file>
242310

243311
> Run `v6.0.0/theme-v6` against the file that contains the custom `styleOverrides`. Ignore this codemod if you don't have a custom theme.
244312
245-
### API
246-
247-
`theme.applyStyles(mode, styles) => CSSObject`
248-
249-
Apply styles for a specific mode.
250-
251-
#### Arguments
252-
253-
- `mode` (`'light' | 'dark'`) - The mode for which the styles should be applied.
254-
- `styles` (`CSSObject`) - An object which contains the styles to be applied for the specified mode.
255-
256313
## Dark mode flicker
257314

258315
### The problem

0 commit comments

Comments
 (0)