@mui/system 5.6.2 → 5.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/Box/Box.d.ts +18 -1
  2. package/Box/Box.js +26 -0
  3. package/Box/Box.spec.d.ts +1 -1
  4. package/CHANGELOG.md +225 -0
  5. package/ThemeProvider/ThemeProvider.d.ts +7 -1
  6. package/ThemeProvider/ThemeProvider.js +9 -2
  7. package/createBox.js +0 -26
  8. package/createBox.spec.d.ts +1 -1
  9. package/createStyled.js +3 -1
  10. package/createTheme/createSpacing.d.ts +10 -10
  11. package/cssVars/createCssVarsProvider.d.ts +25 -0
  12. package/cssVars/createCssVarsProvider.js +74 -57
  13. package/cssVars/createCssVarsProvider.spec.d.ts +1 -1
  14. package/cssVars/createGetCssVar.d.ts +5 -5
  15. package/cssVars/cssVarsParser.d.ts +70 -70
  16. package/cssVars/cssVarsParser.js +11 -9
  17. package/cssVars/getInitColorSchemeScript.d.ts +40 -12
  18. package/cssVars/getInitColorSchemeScript.js +4 -3
  19. package/cssVars/index.d.ts +2 -2
  20. package/cssVars/useCurrentColorScheme.d.ts +53 -50
  21. package/cssVars/useCurrentColorScheme.js +17 -7
  22. package/esm/Box/Box.js +25 -0
  23. package/esm/ThemeProvider/ThemeProvider.js +9 -2
  24. package/esm/createBox.js +0 -25
  25. package/esm/createStyled.js +3 -1
  26. package/esm/cssVars/createCssVarsProvider.js +76 -57
  27. package/esm/cssVars/cssVarsParser.js +11 -9
  28. package/esm/cssVars/getInitColorSchemeScript.js +4 -3
  29. package/esm/cssVars/useCurrentColorScheme.js +17 -7
  30. package/esm/spacing.js +3 -1
  31. package/esm/style.js +7 -1
  32. package/index.js +1 -1
  33. package/index.spec.d.ts +1 -1
  34. package/legacy/Box/Box.js +25 -0
  35. package/legacy/ThemeProvider/ThemeProvider.js +9 -2
  36. package/legacy/createBox.js +0 -25
  37. package/legacy/createStyled.js +3 -1
  38. package/legacy/cssVars/createCssVarsProvider.js +83 -55
  39. package/legacy/cssVars/cssVarsParser.js +11 -7
  40. package/legacy/cssVars/getInitColorSchemeScript.js +6 -3
  41. package/legacy/cssVars/useCurrentColorScheme.js +20 -9
  42. package/legacy/index.js +1 -1
  43. package/legacy/spacing.js +3 -1
  44. package/legacy/style.js +5 -1
  45. package/modern/Box/Box.js +25 -0
  46. package/modern/ThemeProvider/ThemeProvider.js +9 -2
  47. package/modern/createBox.js +0 -25
  48. package/modern/createStyled.js +3 -1
  49. package/modern/cssVars/createCssVarsProvider.js +76 -55
  50. package/modern/cssVars/cssVarsParser.js +11 -9
  51. package/modern/cssVars/getInitColorSchemeScript.js +4 -3
  52. package/modern/cssVars/useCurrentColorScheme.js +17 -7
  53. package/modern/index.js +1 -1
  54. package/modern/spacing.js +1 -1
  55. package/modern/style.js +7 -1
  56. package/package.json +5 -5
  57. package/spacing.js +3 -1
  58. package/style.js +7 -1
  59. package/styleFunctionSx/styleFunctionSx.d.ts +3 -1
  60. package/styleFunctionSx/styleFunctionSx.spec.d.ts +1 -1
@@ -1,50 +1,53 @@
1
- export declare type Mode = 'light' | 'dark' | 'system';
2
- export declare type SystemMode = Exclude<Mode, 'system'>;
3
- export interface State<SupportedColorScheme extends string> {
4
- /**
5
- * User selected mode.
6
- * Note: on the server, mode is always undefined
7
- */
8
- mode: Mode | undefined;
9
- /**
10
- * Only valid if `mode: 'system'`, either 'light' | 'dark'.
11
- */
12
- systemMode: SystemMode | undefined;
13
- /**
14
- * The color scheme for the light mode.
15
- */
16
- lightColorScheme: SupportedColorScheme;
17
- /**
18
- * The color scheme for the dark mode.
19
- */
20
- darkColorScheme: SupportedColorScheme;
21
- }
22
- export declare type Result<SupportedColorScheme extends string> = State<SupportedColorScheme> & {
23
- /**
24
- * The current application color scheme. It is always `undefined` on the server.
25
- */
26
- colorScheme: SupportedColorScheme | undefined;
27
- /**
28
- * `mode` is saved to internal state and localStorage
29
- * If `mode` is null, it will be reset to the defaultMode
30
- */
31
- setMode: (mode: Mode | null) => void;
32
- /**
33
- * `colorScheme` is saved to internal state and localStorage
34
- * If `colorScheme` is null, it will be reset to the defaultColorScheme (light | dark)
35
- */
36
- setColorScheme: (colorScheme: SupportedColorScheme | Partial<{
37
- light: SupportedColorScheme | null;
38
- dark: SupportedColorScheme | null;
39
- }> | null) => void;
40
- };
41
- export declare function getSystemMode(mode: undefined | string): SystemMode | undefined;
42
- export declare function getColorScheme<SupportedColorScheme extends string>(state: State<SupportedColorScheme>): SupportedColorScheme | undefined;
43
- export default function useCurrentColorScheme<SupportedColorScheme extends string>(options: {
44
- defaultLightColorScheme: SupportedColorScheme;
45
- defaultDarkColorScheme: SupportedColorScheme;
46
- supportedColorSchemes: Array<SupportedColorScheme>;
47
- defaultMode?: Mode;
48
- modeStorageKey?: string;
49
- colorSchemeStorageKey?: string;
50
- }): Result<SupportedColorScheme>;
1
+ export declare type Mode = 'light' | 'dark' | 'system';
2
+ export declare type SystemMode = Exclude<Mode, 'system'>;
3
+ export interface State<SupportedColorScheme extends string> {
4
+ /**
5
+ * User selected mode.
6
+ * Note: on the server, mode is always undefined
7
+ */
8
+ mode: Mode | undefined;
9
+ /**
10
+ * Only valid if `mode: 'system'`, either 'light' | 'dark'.
11
+ */
12
+ systemMode: SystemMode | undefined;
13
+ /**
14
+ * The color scheme for the light mode.
15
+ */
16
+ lightColorScheme: SupportedColorScheme;
17
+ /**
18
+ * The color scheme for the dark mode.
19
+ */
20
+ darkColorScheme: SupportedColorScheme;
21
+ }
22
+ export declare type Result<SupportedColorScheme extends string> = State<SupportedColorScheme> & {
23
+ /**
24
+ * The current application color scheme. It is always `undefined` on the server.
25
+ */
26
+ colorScheme: SupportedColorScheme | undefined;
27
+ /**
28
+ * `mode` is saved to internal state and localStorage
29
+ * If `mode` is null, it will be reset to the defaultMode
30
+ */
31
+ setMode: (mode: Mode | null) => void;
32
+ /**
33
+ * `colorScheme` is saved to internal state and localStorage
34
+ * If `colorScheme` is null, it will be reset to the defaultColorScheme (light | dark)
35
+ */
36
+ setColorScheme: (colorScheme: SupportedColorScheme | Partial<{
37
+ light: SupportedColorScheme | null;
38
+ dark: SupportedColorScheme | null;
39
+ }> | null) => void;
40
+ };
41
+ export declare function getSystemMode(mode: undefined | string): SystemMode | undefined;
42
+ export declare function getColorScheme<SupportedColorScheme extends string>(state: State<SupportedColorScheme>): SupportedColorScheme | undefined;
43
+ interface UseCurrentColoSchemeOptions<SupportedColorScheme extends string> {
44
+ defaultLightColorScheme: SupportedColorScheme;
45
+ defaultDarkColorScheme: SupportedColorScheme;
46
+ supportedColorSchemes: Array<SupportedColorScheme>;
47
+ defaultMode?: Mode;
48
+ modeStorageKey?: string;
49
+ colorSchemeStorageKey?: string;
50
+ storageWindow?: Window | null;
51
+ }
52
+ export default function useCurrentColorScheme<SupportedColorScheme extends string>(options: UseCurrentColoSchemeOptions<SupportedColorScheme>): Result<SupportedColorScheme>;
53
+ export {};
@@ -81,7 +81,8 @@ function useCurrentColorScheme(options) {
81
81
  defaultDarkColorScheme,
82
82
  supportedColorSchemes = [],
83
83
  modeStorageKey = _getInitColorSchemeScript.DEFAULT_MODE_STORAGE_KEY,
84
- colorSchemeStorageKey = _getInitColorSchemeScript.DEFAULT_COLOR_SCHEME_STORAGE_KEY
84
+ colorSchemeStorageKey = _getInitColorSchemeScript.DEFAULT_COLOR_SCHEME_STORAGE_KEY,
85
+ storageWindow = typeof window === 'undefined' ? undefined : window
85
86
  } = options;
86
87
  const joinedColorSchemes = supportedColorSchemes.join(',');
87
88
  const [state, setState] = React.useState(() => {
@@ -98,6 +99,10 @@ function useCurrentColorScheme(options) {
98
99
  setState(currentState => {
99
100
  const newMode = !mode ? defaultMode : mode;
100
101
 
102
+ if (mode === currentState.mode) {
103
+ return currentState;
104
+ }
105
+
101
106
  if (typeof localStorage !== 'undefined') {
102
107
  localStorage.setItem(modeStorageKey, newMode);
103
108
  }
@@ -110,7 +115,7 @@ function useCurrentColorScheme(options) {
110
115
  }, [modeStorageKey, defaultMode]);
111
116
  const setColorScheme = React.useCallback(value => {
112
117
  if (!value || typeof value === 'string') {
113
- if (value && !supportedColorSchemes.includes(value)) {
118
+ if (value && !joinedColorSchemes.includes(value)) {
114
119
  console.error(`\`${value}\` does not exist in \`theme.colorSchemes\`.`);
115
120
  } else {
116
121
  setState(currentState => {
@@ -137,7 +142,7 @@ function useCurrentColorScheme(options) {
137
142
  return newState;
138
143
  });
139
144
  }
140
- } else if (value.light && !supportedColorSchemes.includes(value.light) || value.dark && !supportedColorSchemes.includes(value.dark)) {
145
+ } else if (value.light && !joinedColorSchemes.includes(value.light) || value.dark && !joinedColorSchemes.includes(value.dark)) {
141
146
  console.error(`\`${value}\` does not exist in \`theme.colorSchemes\`.`);
142
147
  } else {
143
148
  setState(currentState => {
@@ -162,7 +167,7 @@ function useCurrentColorScheme(options) {
162
167
  localStorage.setItem(`${colorSchemeStorageKey}-dark`, value.dark);
163
168
  }
164
169
  }
165
- }, [colorSchemeStorageKey, supportedColorSchemes, defaultLightColorScheme, defaultDarkColorScheme]);
170
+ }, [joinedColorSchemes, colorSchemeStorageKey, defaultLightColorScheme, defaultDarkColorScheme]);
166
171
  const handleMediaQuery = React.useCallback(e => {
167
172
  if (state.mode === 'system') {
168
173
  setState(currentState => (0, _extends2.default)({}, currentState, {
@@ -224,9 +229,14 @@ function useCurrentColorScheme(options) {
224
229
  }
225
230
  };
226
231
 
227
- window.addEventListener('storage', handleStorage);
228
- return () => window.removeEventListener('storage', handleStorage);
229
- }, [setColorScheme, setMode, modeStorageKey, colorSchemeStorageKey, joinedColorSchemes, defaultMode]);
232
+ if (storageWindow) {
233
+ // For syncing color-scheme changes between iframes
234
+ storageWindow.addEventListener('storage', handleStorage);
235
+ return () => storageWindow.removeEventListener('storage', handleStorage);
236
+ }
237
+
238
+ return undefined;
239
+ }, [setColorScheme, setMode, modeStorageKey, colorSchemeStorageKey, joinedColorSchemes, defaultMode, storageWindow]);
230
240
  return (0, _extends2.default)({}, state, {
231
241
  colorScheme,
232
242
  setMode,
package/esm/Box/Box.js CHANGED
@@ -1,3 +1,28 @@
1
+ import PropTypes from 'prop-types';
1
2
  import createBox from '../createBox';
2
3
  const Box = createBox();
4
+ process.env.NODE_ENV !== "production" ? Box.propTypes
5
+ /* remove-proptypes */
6
+ = {
7
+ // ----------------------------- Warning --------------------------------
8
+ // | These PropTypes are generated from the TypeScript type definitions |
9
+ // | To update them edit the d.ts file and run "yarn proptypes" |
10
+ // ----------------------------------------------------------------------
11
+
12
+ /**
13
+ * @ignore
14
+ */
15
+ children: PropTypes.node,
16
+
17
+ /**
18
+ * The component used for the root node.
19
+ * Either a string to use a HTML element or a component.
20
+ */
21
+ component: PropTypes.elementType,
22
+
23
+ /**
24
+ * The system prop that allows defining system overrides as well as additional CSS styles.
25
+ */
26
+ sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object])
27
+ } : void 0;
3
28
  export default Box;
@@ -38,7 +38,14 @@ function ThemeProvider(props) {
38
38
  });
39
39
  }
40
40
 
41
- process.env.NODE_ENV !== "production" ? ThemeProvider.propTypes = {
41
+ process.env.NODE_ENV !== "production" ? ThemeProvider.propTypes
42
+ /* remove-proptypes */
43
+ = {
44
+ // ----------------------------- Warning --------------------------------
45
+ // | These PropTypes are generated from the TypeScript type definitions |
46
+ // | To update them edit the d.ts file and run "yarn proptypes" |
47
+ // ----------------------------------------------------------------------
48
+
42
49
  /**
43
50
  * Your component tree.
44
51
  */
@@ -47,7 +54,7 @@ process.env.NODE_ENV !== "production" ? ThemeProvider.propTypes = {
47
54
  /**
48
55
  * A theme object. You can provide a function to extend the outer theme.
49
56
  */
50
- theme: PropTypes.oneOfType([PropTypes.object, PropTypes.func]).isRequired
57
+ theme: PropTypes.oneOfType([PropTypes.func, PropTypes.object]).isRequired
51
58
  } : void 0;
52
59
 
53
60
  if (process.env.NODE_ENV !== 'production') {
package/esm/createBox.js CHANGED
@@ -2,7 +2,6 @@ import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3
3
  const _excluded = ["className", "component"];
4
4
  import * as React from 'react';
5
- import PropTypes from 'prop-types';
6
5
  import clsx from 'clsx';
7
6
  import styled from '@mui/styled-engine';
8
7
  import defaultStyleFunctionSx, { extendSxProp } from './styleFunctionSx';
@@ -33,29 +32,5 @@ export default function createBox(options = {}) {
33
32
  theme: theme
34
33
  }, other));
35
34
  });
36
- process.env.NODE_ENV !== "production" ? Box.propTypes
37
- /* remove-proptypes */
38
- = {
39
- // ----------------------------- Warning --------------------------------
40
- // | These PropTypes are generated from the TypeScript type definitions |
41
- // | To update them edit the d.ts file and run "yarn proptypes" |
42
- // ----------------------------------------------------------------------
43
-
44
- /**
45
- * @ignore
46
- */
47
- children: PropTypes.node,
48
-
49
- /**
50
- * The component used for the root node.
51
- * Either a string to use a HTML element or a component.
52
- */
53
- component: PropTypes.elementType,
54
-
55
- /**
56
- * @ignore
57
- */
58
- sx: PropTypes.oneOfType([PropTypes.object, PropTypes.array, PropTypes.func])
59
- } : void 0;
60
35
  return Box;
61
36
  }
@@ -142,7 +142,9 @@ export default function createStyled(input = {}) {
142
142
  if (styleOverrides) {
143
143
  const resolvedStyleOverrides = {};
144
144
  Object.entries(styleOverrides).forEach(([slotKey, slotStyle]) => {
145
- resolvedStyleOverrides[slotKey] = typeof slotStyle === 'function' ? slotStyle(props) : slotStyle;
145
+ resolvedStyleOverrides[slotKey] = typeof slotStyle === 'function' ? slotStyle(_extends({}, props, {
146
+ theme
147
+ })) : slotStyle;
146
148
  });
147
149
  return overridesResolver(props, resolvedStyleOverrides);
148
150
  }
@@ -1,28 +1,22 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3
3
  import { formatMuiErrorMessage as _formatMuiErrorMessage } from "@mui/utils";
4
- const _excluded = ["colorSchemes"],
5
- _excluded2 = ["colorSchemes"],
6
- _excluded3 = ["components"];
4
+ const _excluded = ["colorSchemes", "components"];
7
5
  import * as React from 'react';
8
6
  import PropTypes from 'prop-types';
9
- import { GlobalStyles } from '@mui/styled-engine';
10
7
  import { deepmerge, unstable_useEnhancedEffect as useEnhancedEffect } from '@mui/utils';
11
- import createSpacing from '../createTheme/createSpacing';
12
- import createBreakpoints from '../createTheme/createBreakpoints';
8
+ import { GlobalStyles } from '@mui/styled-engine';
13
9
  import cssVarsParser from './cssVarsParser';
14
10
  import ThemeProvider from '../ThemeProvider';
15
- import getInitColorSchemeScript, { DEFAULT_ATTRIBUTE, DEFAULT_MODE_STORAGE_KEY } from './getInitColorSchemeScript';
11
+ import getInitColorSchemeScript, { DEFAULT_ATTRIBUTE, DEFAULT_COLOR_SCHEME_STORAGE_KEY, DEFAULT_MODE_STORAGE_KEY } from './getInitColorSchemeScript';
16
12
  import useCurrentColorScheme from './useCurrentColorScheme';
17
13
  import createGetCssVar from './createGetCssVar';
18
14
  import { jsx as _jsx } from "react/jsx-runtime";
19
15
  import { jsxs as _jsxs } from "react/jsx-runtime";
20
16
  export const DISABLE_CSS_TRANSITION = '*{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}';
21
17
  export default function createCssVarsProvider(options) {
22
- var _baseTheme$breakpoint;
23
-
24
18
  const {
25
- theme: baseTheme = {},
19
+ theme: defaultTheme = {},
26
20
  defaultMode: desisgnSystemMode = 'light',
27
21
  defaultColorScheme: designSystemColorScheme,
28
22
  disableTransitionOnChange: designSystemTransitionOnChange = false,
@@ -31,10 +25,8 @@ export default function createCssVarsProvider(options) {
31
25
  shouldSkipGeneratingVar,
32
26
  resolveTheme
33
27
  } = options;
34
- const systemSpacing = createSpacing(baseTheme.spacing);
35
- const systemBreakpoints = createBreakpoints((_baseTheme$breakpoint = baseTheme.breakpoints) != null ? _baseTheme$breakpoint : {});
36
28
 
37
- if (!baseTheme.colorSchemes || typeof designSystemColorScheme === 'string' && !baseTheme.colorSchemes[designSystemColorScheme] || typeof designSystemColorScheme === 'object' && !baseTheme.colorSchemes[designSystemColorScheme == null ? void 0 : designSystemColorScheme.light] || typeof designSystemColorScheme === 'object' && !baseTheme.colorSchemes[designSystemColorScheme == null ? void 0 : designSystemColorScheme.dark]) {
29
+ if (!defaultTheme.colorSchemes || typeof designSystemColorScheme === 'string' && !defaultTheme.colorSchemes[designSystemColorScheme] || typeof designSystemColorScheme === 'object' && !defaultTheme.colorSchemes[designSystemColorScheme == null ? void 0 : designSystemColorScheme.light] || typeof designSystemColorScheme === 'object' && !defaultTheme.colorSchemes[designSystemColorScheme == null ? void 0 : designSystemColorScheme.dark]) {
38
30
  console.error(`MUI: \`${designSystemColorScheme}\` does not exist in \`theme.colorSchemes\`.`);
39
31
  }
40
32
 
@@ -52,34 +44,28 @@ export default function createCssVarsProvider(options) {
52
44
 
53
45
  function CssVarsProvider({
54
46
  children,
55
- theme: themeProp = {},
47
+ theme: themeProp = defaultTheme,
56
48
  prefix = designSystemPrefix,
57
49
  modeStorageKey = DEFAULT_MODE_STORAGE_KEY,
50
+ colorSchemeStorageKey = DEFAULT_COLOR_SCHEME_STORAGE_KEY,
58
51
  attribute = DEFAULT_ATTRIBUTE,
59
52
  defaultMode = desisgnSystemMode,
60
53
  defaultColorScheme = designSystemColorScheme,
61
54
  disableTransitionOnChange = designSystemTransitionOnChange,
62
- enableColorScheme = designSystemEnableColorScheme
55
+ enableColorScheme = designSystemEnableColorScheme,
56
+ storageWindow = typeof window === 'undefined' ? undefined : window,
57
+ documentNode = typeof document === 'undefined' ? undefined : document,
58
+ colorSchemeNode = typeof document === 'undefined' ? undefined : document.documentElement,
59
+ colorSchemeSelector = ':root'
63
60
  }) {
64
- const {
65
- colorSchemes: baseColorSchemes = {}
66
- } = baseTheme,
67
- restBaseTheme = _objectWithoutPropertiesLoose(baseTheme, _excluded);
61
+ const hasMounted = React.useRef(false);
68
62
 
69
63
  const {
70
- colorSchemes: colorSchemesProp = {}
71
- } = themeProp,
72
- restThemeProp = _objectWithoutPropertiesLoose(themeProp, _excluded2);
73
-
74
- const hasMounted = React.useRef(false); // eslint-disable-next-line prefer-const
75
-
76
- let _deepmerge = deepmerge(restBaseTheme, restThemeProp),
77
- {
64
+ colorSchemes = {},
78
65
  components = {}
79
- } = _deepmerge,
80
- mergedTheme = _objectWithoutPropertiesLoose(_deepmerge, _excluded3);
66
+ } = themeProp,
67
+ restThemeProp = _objectWithoutPropertiesLoose(themeProp, _excluded);
81
68
 
82
- const colorSchemes = deepmerge(baseColorSchemes, colorSchemesProp);
83
69
  const allColorSchemes = Object.keys(colorSchemes);
84
70
  const defaultLightColorScheme = typeof defaultColorScheme === 'string' ? defaultColorScheme : defaultColorScheme.light;
85
71
  const defaultDarkColorScheme = typeof defaultColorScheme === 'string' ? defaultColorScheme : defaultColorScheme.dark;
@@ -96,7 +82,9 @@ export default function createCssVarsProvider(options) {
96
82
  defaultLightColorScheme,
97
83
  defaultDarkColorScheme,
98
84
  modeStorageKey,
99
- defaultMode
85
+ colorSchemeStorageKey,
86
+ defaultMode,
87
+ storageWindow
100
88
  });
101
89
 
102
90
  const resolvedColorScheme = (() => {
@@ -113,22 +101,21 @@ export default function createCssVarsProvider(options) {
113
101
  return colorScheme;
114
102
  })();
115
103
 
104
+ let theme = restThemeProp;
116
105
  const {
117
106
  css: rootCss,
118
107
  vars: rootVars,
119
108
  parsedTheme
120
- } = cssVarsParser(mergedTheme, {
109
+ } = cssVarsParser(theme, {
121
110
  prefix,
122
111
  basePrefix: designSystemPrefix,
123
112
  shouldSkipGeneratingVar
124
113
  });
125
- mergedTheme = _extends({}, parsedTheme, {
114
+ theme = _extends({}, parsedTheme, {
126
115
  components,
127
116
  colorSchemes,
128
117
  prefix,
129
118
  vars: rootVars,
130
- spacing: themeProp.spacing ? createSpacing(themeProp.spacing) : systemSpacing,
131
- breakpoints: themeProp.breakpoints ? createBreakpoints(themeProp.breakpoints) : systemBreakpoints,
132
119
  getCssVar: createGetCssVar(prefix)
133
120
  });
134
121
  const styleSheet = {};
@@ -142,10 +129,16 @@ export default function createCssVarsProvider(options) {
142
129
  basePrefix: designSystemPrefix,
143
130
  shouldSkipGeneratingVar
144
131
  });
145
- mergedTheme.vars = deepmerge(mergedTheme.vars, vars);
132
+ theme.vars = deepmerge(theme.vars, vars);
146
133
 
147
134
  if (key === resolvedColorScheme) {
148
- mergedTheme = _extends({}, mergedTheme, parsedScheme);
135
+ theme = _extends({}, theme, parsedScheme);
136
+
137
+ if (theme.palette) {
138
+ // assign runtime mode & colorScheme
139
+ theme.palette.mode = mode;
140
+ theme.palette.colorScheme = resolvedColorScheme;
141
+ }
149
142
  }
150
143
 
151
144
  const resolvedDefaultColorScheme = (() => {
@@ -161,54 +154,54 @@ export default function createCssVarsProvider(options) {
161
154
  })();
162
155
 
163
156
  if (key === resolvedDefaultColorScheme) {
164
- styleSheet[':root'] = css;
157
+ styleSheet[colorSchemeSelector] = css;
165
158
  } else {
166
- styleSheet[`[${attribute}="${key}"]`] = css;
159
+ styleSheet[`${colorSchemeSelector === ':root' ? '' : colorSchemeSelector}[${attribute}="${key}"]`] = css;
167
160
  }
168
161
  });
169
162
  React.useEffect(() => {
170
- if (colorScheme) {
163
+ if (colorScheme && colorSchemeNode) {
171
164
  // attaches attribute to <html> because the css variables are attached to :root (html)
172
- document.documentElement.setAttribute(attribute, colorScheme);
165
+ colorSchemeNode.setAttribute(attribute, colorScheme);
173
166
  }
174
- }, [colorScheme, attribute]);
167
+ }, [colorScheme, attribute, colorSchemeNode]);
175
168
  useEnhancedEffect(() => {
176
- if (!mode || !enableColorScheme) {
169
+ if (!mode || !enableColorScheme || !colorSchemeNode) {
177
170
  return undefined;
178
171
  }
179
172
 
180
- const priorColorScheme = document.documentElement.style.getPropertyValue('color-scheme'); // `color-scheme` tells browser to render built-in elements according to its value: `light` or `dark`
173
+ const priorColorScheme = colorSchemeNode.style.getPropertyValue('color-scheme'); // `color-scheme` tells browser to render built-in elements according to its value: `light` or `dark`
181
174
 
182
175
  if (mode === 'system') {
183
- document.documentElement.style.setProperty('color-scheme', systemMode);
176
+ colorSchemeNode.style.setProperty('color-scheme', systemMode);
184
177
  } else {
185
- document.documentElement.style.setProperty('color-scheme', mode);
178
+ colorSchemeNode.style.setProperty('color-scheme', mode);
186
179
  }
187
180
 
188
181
  return () => {
189
- document.documentElement.style.setProperty('color-scheme', priorColorScheme);
182
+ colorSchemeNode.style.setProperty('color-scheme', priorColorScheme);
190
183
  };
191
- }, [mode, systemMode, enableColorScheme]);
184
+ }, [mode, systemMode, enableColorScheme, colorSchemeNode]);
192
185
  React.useEffect(() => {
193
186
  let timer;
194
187
 
195
- if (disableTransitionOnChange && hasMounted.current) {
188
+ if (disableTransitionOnChange && hasMounted.current && documentNode) {
196
189
  // credit: https://github.com/pacocoursey/next-themes/blob/b5c2bad50de2d61ad7b52a9c5cdc801a78507d7a/index.tsx#L313
197
- const css = document.createElement('style');
198
- css.appendChild(document.createTextNode(DISABLE_CSS_TRANSITION));
199
- document.head.appendChild(css); // Force browser repaint
190
+ const css = documentNode.createElement('style');
191
+ css.appendChild(documentNode.createTextNode(DISABLE_CSS_TRANSITION));
192
+ documentNode.head.appendChild(css); // Force browser repaint
200
193
 
201
- (() => window.getComputedStyle(document.body))();
194
+ (() => window.getComputedStyle(documentNode.body))();
202
195
 
203
196
  timer = setTimeout(() => {
204
- document.head.removeChild(css);
197
+ documentNode.head.removeChild(css);
205
198
  }, 1);
206
199
  }
207
200
 
208
201
  return () => {
209
202
  clearTimeout(timer);
210
203
  };
211
- }, [colorScheme, disableTransitionOnChange]);
204
+ }, [colorScheme, disableTransitionOnChange, documentNode]);
212
205
  React.useEffect(() => {
213
206
  hasMounted.current = true;
214
207
  return () => {
@@ -227,12 +220,12 @@ export default function createCssVarsProvider(options) {
227
220
  },
228
221
  children: [/*#__PURE__*/_jsx(GlobalStyles, {
229
222
  styles: {
230
- ':root': rootCss
223
+ [colorSchemeSelector]: rootCss
231
224
  }
232
225
  }), /*#__PURE__*/_jsx(GlobalStyles, {
233
226
  styles: styleSheet
234
227
  }), /*#__PURE__*/_jsx(ThemeProvider, {
235
- theme: resolveTheme ? resolveTheme(mergedTheme) : mergedTheme,
228
+ theme: resolveTheme ? resolveTheme(theme) : theme,
236
229
  children: children
237
230
  })]
238
231
  });
@@ -249,6 +242,21 @@ export default function createCssVarsProvider(options) {
249
242
  */
250
243
  children: PropTypes.node,
251
244
 
245
+ /**
246
+ * The node used to attach the color-scheme attribute
247
+ */
248
+ colorSchemeNode: PropTypes.any,
249
+
250
+ /**
251
+ * The CSS selector for attaching the generated custom properties
252
+ */
253
+ colorSchemeSelector: PropTypes.string,
254
+
255
+ /**
256
+ * localStorage key used to store `colorScheme`
257
+ */
258
+ colorSchemeStorageKey: PropTypes.string,
259
+
252
260
  /**
253
261
  * The initial color scheme used.
254
262
  */
@@ -264,6 +272,11 @@ export default function createCssVarsProvider(options) {
264
272
  */
265
273
  disableTransitionOnChange: PropTypes.bool,
266
274
 
275
+ /**
276
+ * The document to attach the attribute to
277
+ */
278
+ documentNode: PropTypes.any,
279
+
267
280
  /**
268
281
  * Indicate to the browser which color scheme is used (light or dark) for rendering built-in UI
269
282
  */
@@ -279,6 +292,12 @@ export default function createCssVarsProvider(options) {
279
292
  */
280
293
  prefix: PropTypes.string,
281
294
 
295
+ /**
296
+ * The window that attaches the 'storage' event listener
297
+ * @default window
298
+ */
299
+ storageWindow: PropTypes.any,
300
+
282
301
  /**
283
302
  * The calculated theme object that will be passed through context.
284
303
  */
@@ -15,16 +15,18 @@
15
15
  * assignNestedKeys(source, ['palette', 'secondary'], 'var(--palette-secondary)')
16
16
  * console.log(source) // { palette: { primary: 'var(--palette-primary)', secondary: 'var(--palette-secondary)' } }
17
17
  */
18
- export const assignNestedKeys = (obj, keys, value) => {
18
+ export const assignNestedKeys = (obj, keys, value, arrayKeys = []) => {
19
19
  let temp = obj;
20
20
  keys.forEach((k, index) => {
21
21
  if (index === keys.length - 1) {
22
- if (temp && typeof temp === 'object') {
22
+ if (Array.isArray(temp)) {
23
+ temp[Number(k)] = value;
24
+ } else if (temp && typeof temp === 'object') {
23
25
  temp[k] = value;
24
26
  }
25
27
  } else if (temp && typeof temp === 'object') {
26
28
  if (!temp[k]) {
27
- temp[k] = {};
29
+ temp[k] = arrayKeys.includes(k) ? [] : {};
28
30
  }
29
31
 
30
32
  temp = temp[k];
@@ -44,14 +46,14 @@ export const assignNestedKeys = (obj, keys, value) => {
44
46
  */
45
47
 
46
48
  export const walkObjectDeep = (obj, callback, shouldSkipPaths) => {
47
- function recurse(object, parentKeys = []) {
49
+ function recurse(object, parentKeys = [], arrayKeys = []) {
48
50
  Object.entries(object).forEach(([key, value]) => {
49
51
  if (!shouldSkipPaths || shouldSkipPaths && !shouldSkipPaths([...parentKeys, key])) {
50
52
  if (value !== undefined && value !== null) {
51
53
  if (typeof value === 'object' && Object.keys(value).length > 0) {
52
- recurse(value, [...parentKeys, key]);
54
+ recurse(value, [...parentKeys, key], Array.isArray(value) ? [...arrayKeys, key] : arrayKeys);
53
55
  } else {
54
- callback([...parentKeys, key], value, object);
56
+ callback([...parentKeys, key], value, arrayKeys);
55
57
  }
56
58
  }
57
59
  }
@@ -118,7 +120,7 @@ export default function cssVarsParser(theme, options) {
118
120
  const css = {};
119
121
  const vars = {};
120
122
  const parsedTheme = {};
121
- walkObjectDeep(theme, (keys, value) => {
123
+ walkObjectDeep(theme, (keys, value, arrayKeys) => {
122
124
  if (typeof value === 'string' || typeof value === 'number') {
123
125
  if (typeof value === 'string' && value.match(/var\(\s*--/)) {
124
126
  // for CSS variable, apply prefix or remove basePrefix from the variable
@@ -136,11 +138,11 @@ export default function cssVarsParser(theme, options) {
136
138
  Object.assign(css, {
137
139
  [cssVar]: getCssValue(keys, value)
138
140
  });
139
- assignNestedKeys(vars, keys, `var(${cssVar})`);
141
+ assignNestedKeys(vars, keys, `var(${cssVar})`, arrayKeys);
140
142
  }
141
143
  }
142
144
 
143
- assignNestedKeys(parsedTheme, keys, value);
145
+ assignNestedKeys(parsedTheme, keys, value, arrayKeys);
144
146
  }, keys => keys[0] === 'vars' // skip 'vars/*' paths
145
147
  );
146
148
  return {
@@ -5,12 +5,13 @@ export const DEFAULT_COLOR_SCHEME_STORAGE_KEY = 'mui-color-scheme';
5
5
  export const DEFAULT_ATTRIBUTE = 'data-mui-color-scheme';
6
6
  export default function getInitColorSchemeScript(options) {
7
7
  const {
8
- enableSystem,
8
+ enableSystem = false,
9
9
  defaultLightColorScheme = 'light',
10
10
  defaultDarkColorScheme = 'dark',
11
11
  modeStorageKey = DEFAULT_MODE_STORAGE_KEY,
12
12
  colorSchemeStorageKey = DEFAULT_COLOR_SCHEME_STORAGE_KEY,
13
- attribute = DEFAULT_ATTRIBUTE
13
+ attribute = DEFAULT_ATTRIBUTE,
14
+ colorSchemeNode = 'document.documentElement'
14
15
  } = options || {};
15
16
  return /*#__PURE__*/_jsx("script", {
16
17
  // eslint-disable-next-line react/no-danger
@@ -34,7 +35,7 @@ export default function getInitColorSchemeScript(options) {
34
35
  colorScheme = localStorage.getItem('${colorSchemeStorageKey}-dark') || '${defaultDarkColorScheme}';
35
36
  }
36
37
  if (colorScheme) {
37
- document.documentElement.setAttribute('${attribute}', colorScheme);
38
+ ${colorSchemeNode}.setAttribute('${attribute}', colorScheme);
38
39
  }
39
40
  } catch (e) {} })();`
40
41
  }