@mui/system 5.6.4 → 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.
@@ -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,
@@ -8,7 +8,7 @@ import { deepmerge, unstable_useEnhancedEffect as useEnhancedEffect } from '@mui
8
8
  import { GlobalStyles } from '@mui/styled-engine';
9
9
  import cssVarsParser from './cssVarsParser';
10
10
  import ThemeProvider from '../ThemeProvider';
11
- 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';
12
12
  import useCurrentColorScheme from './useCurrentColorScheme';
13
13
  import createGetCssVar from './createGetCssVar';
14
14
  import { jsx as _jsx } from "react/jsx-runtime";
@@ -47,11 +47,16 @@ export default function createCssVarsProvider(options) {
47
47
  theme: themeProp = defaultTheme,
48
48
  prefix = designSystemPrefix,
49
49
  modeStorageKey = DEFAULT_MODE_STORAGE_KEY,
50
+ colorSchemeStorageKey = DEFAULT_COLOR_SCHEME_STORAGE_KEY,
50
51
  attribute = DEFAULT_ATTRIBUTE,
51
52
  defaultMode = desisgnSystemMode,
52
53
  defaultColorScheme = designSystemColorScheme,
53
54
  disableTransitionOnChange = designSystemTransitionOnChange,
54
- 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'
55
60
  }) {
56
61
  const hasMounted = React.useRef(false);
57
62
 
@@ -77,7 +82,9 @@ export default function createCssVarsProvider(options) {
77
82
  defaultLightColorScheme,
78
83
  defaultDarkColorScheme,
79
84
  modeStorageKey,
80
- defaultMode
85
+ colorSchemeStorageKey,
86
+ defaultMode,
87
+ storageWindow
81
88
  });
82
89
 
83
90
  const resolvedColorScheme = (() => {
@@ -147,54 +154,54 @@ export default function createCssVarsProvider(options) {
147
154
  })();
148
155
 
149
156
  if (key === resolvedDefaultColorScheme) {
150
- styleSheet[':root'] = css;
157
+ styleSheet[colorSchemeSelector] = css;
151
158
  } else {
152
- styleSheet[`[${attribute}="${key}"]`] = css;
159
+ styleSheet[`${colorSchemeSelector === ':root' ? '' : colorSchemeSelector}[${attribute}="${key}"]`] = css;
153
160
  }
154
161
  });
155
162
  React.useEffect(() => {
156
- if (colorScheme) {
163
+ if (colorScheme && colorSchemeNode) {
157
164
  // attaches attribute to <html> because the css variables are attached to :root (html)
158
- document.documentElement.setAttribute(attribute, colorScheme);
165
+ colorSchemeNode.setAttribute(attribute, colorScheme);
159
166
  }
160
- }, [colorScheme, attribute]);
167
+ }, [colorScheme, attribute, colorSchemeNode]);
161
168
  useEnhancedEffect(() => {
162
- if (!mode || !enableColorScheme) {
169
+ if (!mode || !enableColorScheme || !colorSchemeNode) {
163
170
  return undefined;
164
171
  }
165
172
 
166
- 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`
167
174
 
168
175
  if (mode === 'system') {
169
- document.documentElement.style.setProperty('color-scheme', systemMode);
176
+ colorSchemeNode.style.setProperty('color-scheme', systemMode);
170
177
  } else {
171
- document.documentElement.style.setProperty('color-scheme', mode);
178
+ colorSchemeNode.style.setProperty('color-scheme', mode);
172
179
  }
173
180
 
174
181
  return () => {
175
- document.documentElement.style.setProperty('color-scheme', priorColorScheme);
182
+ colorSchemeNode.style.setProperty('color-scheme', priorColorScheme);
176
183
  };
177
- }, [mode, systemMode, enableColorScheme]);
184
+ }, [mode, systemMode, enableColorScheme, colorSchemeNode]);
178
185
  React.useEffect(() => {
179
186
  let timer;
180
187
 
181
- if (disableTransitionOnChange && hasMounted.current) {
188
+ if (disableTransitionOnChange && hasMounted.current && documentNode) {
182
189
  // credit: https://github.com/pacocoursey/next-themes/blob/b5c2bad50de2d61ad7b52a9c5cdc801a78507d7a/index.tsx#L313
183
- const css = document.createElement('style');
184
- css.appendChild(document.createTextNode(DISABLE_CSS_TRANSITION));
185
- 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
186
193
 
187
- (() => window.getComputedStyle(document.body))();
194
+ (() => window.getComputedStyle(documentNode.body))();
188
195
 
189
196
  timer = setTimeout(() => {
190
- document.head.removeChild(css);
197
+ documentNode.head.removeChild(css);
191
198
  }, 1);
192
199
  }
193
200
 
194
201
  return () => {
195
202
  clearTimeout(timer);
196
203
  };
197
- }, [colorScheme, disableTransitionOnChange]);
204
+ }, [colorScheme, disableTransitionOnChange, documentNode]);
198
205
  React.useEffect(() => {
199
206
  hasMounted.current = true;
200
207
  return () => {
@@ -213,7 +220,7 @@ export default function createCssVarsProvider(options) {
213
220
  },
214
221
  children: [/*#__PURE__*/_jsx(GlobalStyles, {
215
222
  styles: {
216
- ':root': rootCss
223
+ [colorSchemeSelector]: rootCss
217
224
  }
218
225
  }), /*#__PURE__*/_jsx(GlobalStyles, {
219
226
  styles: styleSheet
@@ -235,6 +242,21 @@ export default function createCssVarsProvider(options) {
235
242
  */
236
243
  children: PropTypes.node,
237
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
+
238
260
  /**
239
261
  * The initial color scheme used.
240
262
  */
@@ -250,6 +272,11 @@ export default function createCssVarsProvider(options) {
250
272
  */
251
273
  disableTransitionOnChange: PropTypes.bool,
252
274
 
275
+ /**
276
+ * The document to attach the attribute to
277
+ */
278
+ documentNode: PropTypes.any,
279
+
253
280
  /**
254
281
  * Indicate to the browser which color scheme is used (light or dark) for rendering built-in UI
255
282
  */
@@ -265,6 +292,12 @@ export default function createCssVarsProvider(options) {
265
292
  */
266
293
  prefix: PropTypes.string,
267
294
 
295
+ /**
296
+ * The window that attaches the 'storage' event listener
297
+ * @default window
298
+ */
299
+ storageWindow: PropTypes.any,
300
+
268
301
  /**
269
302
  * The calculated theme object that will be passed through context.
270
303
  */
@@ -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
  }
@@ -63,7 +63,8 @@ export default function useCurrentColorScheme(options) {
63
63
  defaultDarkColorScheme,
64
64
  supportedColorSchemes = [],
65
65
  modeStorageKey = DEFAULT_MODE_STORAGE_KEY,
66
- colorSchemeStorageKey = DEFAULT_COLOR_SCHEME_STORAGE_KEY
66
+ colorSchemeStorageKey = DEFAULT_COLOR_SCHEME_STORAGE_KEY,
67
+ storageWindow = typeof window === 'undefined' ? undefined : window
67
68
  } = options;
68
69
  const joinedColorSchemes = supportedColorSchemes.join(',');
69
70
  const [state, setState] = React.useState(() => {
@@ -80,6 +81,10 @@ export default function useCurrentColorScheme(options) {
80
81
  setState(currentState => {
81
82
  const newMode = !mode ? defaultMode : mode;
82
83
 
84
+ if (mode === currentState.mode) {
85
+ return currentState;
86
+ }
87
+
83
88
  if (typeof localStorage !== 'undefined') {
84
89
  localStorage.setItem(modeStorageKey, newMode);
85
90
  }
@@ -92,7 +97,7 @@ export default function useCurrentColorScheme(options) {
92
97
  }, [modeStorageKey, defaultMode]);
93
98
  const setColorScheme = React.useCallback(value => {
94
99
  if (!value || typeof value === 'string') {
95
- if (value && !supportedColorSchemes.includes(value)) {
100
+ if (value && !joinedColorSchemes.includes(value)) {
96
101
  console.error(`\`${value}\` does not exist in \`theme.colorSchemes\`.`);
97
102
  } else {
98
103
  setState(currentState => {
@@ -119,7 +124,7 @@ export default function useCurrentColorScheme(options) {
119
124
  return newState;
120
125
  });
121
126
  }
122
- } else if (value.light && !supportedColorSchemes.includes(value.light) || value.dark && !supportedColorSchemes.includes(value.dark)) {
127
+ } else if (value.light && !joinedColorSchemes.includes(value.light) || value.dark && !joinedColorSchemes.includes(value.dark)) {
123
128
  console.error(`\`${value}\` does not exist in \`theme.colorSchemes\`.`);
124
129
  } else {
125
130
  setState(currentState => {
@@ -144,7 +149,7 @@ export default function useCurrentColorScheme(options) {
144
149
  localStorage.setItem(`${colorSchemeStorageKey}-dark`, value.dark);
145
150
  }
146
151
  }
147
- }, [colorSchemeStorageKey, supportedColorSchemes, defaultLightColorScheme, defaultDarkColorScheme]);
152
+ }, [joinedColorSchemes, colorSchemeStorageKey, defaultLightColorScheme, defaultDarkColorScheme]);
148
153
  const handleMediaQuery = React.useCallback(e => {
149
154
  if (state.mode === 'system') {
150
155
  setState(currentState => _extends({}, currentState, {
@@ -206,9 +211,14 @@ export default function useCurrentColorScheme(options) {
206
211
  }
207
212
  };
208
213
 
209
- window.addEventListener('storage', handleStorage);
210
- return () => window.removeEventListener('storage', handleStorage);
211
- }, [setColorScheme, setMode, modeStorageKey, colorSchemeStorageKey, joinedColorSchemes, defaultMode]);
214
+ if (storageWindow) {
215
+ // For syncing color-scheme changes between iframes
216
+ storageWindow.addEventListener('storage', handleStorage);
217
+ return () => storageWindow.removeEventListener('storage', handleStorage);
218
+ }
219
+
220
+ return undefined;
221
+ }, [setColorScheme, setMode, modeStorageKey, colorSchemeStorageKey, joinedColorSchemes, defaultMode, storageWindow]);
212
222
  return _extends({}, state, {
213
223
  colorScheme,
214
224
  setMode,
package/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /** @license MUI v5.6.4
1
+ /** @license MUI v5.7.0
2
2
  *
3
3
  * This source code is licensed under the MIT license found in the
4
4
  * LICENSE file in the root directory of this source tree.
package/index.spec.d.ts CHANGED
@@ -1 +1 @@
1
- export {};
1
+ export {};
@@ -1,3 +1,4 @@
1
+ import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
1
2
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
2
3
  import _extends from "@babel/runtime/helpers/esm/extends";
3
4
  import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
@@ -9,7 +10,7 @@ import { deepmerge, unstable_useEnhancedEffect as useEnhancedEffect } from '@mui
9
10
  import { GlobalStyles } from '@mui/styled-engine';
10
11
  import cssVarsParser from './cssVarsParser';
11
12
  import ThemeProvider from '../ThemeProvider';
12
- import getInitColorSchemeScript, { DEFAULT_ATTRIBUTE, DEFAULT_MODE_STORAGE_KEY } from './getInitColorSchemeScript';
13
+ import getInitColorSchemeScript, { DEFAULT_ATTRIBUTE, DEFAULT_COLOR_SCHEME_STORAGE_KEY, DEFAULT_MODE_STORAGE_KEY } from './getInitColorSchemeScript';
13
14
  import useCurrentColorScheme from './useCurrentColorScheme';
14
15
  import createGetCssVar from './createGetCssVar';
15
16
  import { jsx as _jsx } from "react/jsx-runtime";
@@ -54,6 +55,8 @@ export default function createCssVarsProvider(options) {
54
55
  prefix = _ref$prefix === void 0 ? designSystemPrefix : _ref$prefix,
55
56
  _ref$modeStorageKey = _ref.modeStorageKey,
56
57
  modeStorageKey = _ref$modeStorageKey === void 0 ? DEFAULT_MODE_STORAGE_KEY : _ref$modeStorageKey,
58
+ _ref$colorSchemeStora = _ref.colorSchemeStorageKey,
59
+ colorSchemeStorageKey = _ref$colorSchemeStora === void 0 ? DEFAULT_COLOR_SCHEME_STORAGE_KEY : _ref$colorSchemeStora,
57
60
  _ref$attribute = _ref.attribute,
58
61
  attribute = _ref$attribute === void 0 ? DEFAULT_ATTRIBUTE : _ref$attribute,
59
62
  _ref$defaultMode = _ref.defaultMode,
@@ -63,7 +66,15 @@ export default function createCssVarsProvider(options) {
63
66
  _ref$disableTransitio = _ref.disableTransitionOnChange,
64
67
  disableTransitionOnChange = _ref$disableTransitio === void 0 ? designSystemTransitionOnChange : _ref$disableTransitio,
65
68
  _ref$enableColorSchem = _ref.enableColorScheme,
66
- enableColorScheme = _ref$enableColorSchem === void 0 ? designSystemEnableColorScheme : _ref$enableColorSchem;
69
+ enableColorScheme = _ref$enableColorSchem === void 0 ? designSystemEnableColorScheme : _ref$enableColorSchem,
70
+ _ref$storageWindow = _ref.storageWindow,
71
+ storageWindow = _ref$storageWindow === void 0 ? typeof window === 'undefined' ? undefined : window : _ref$storageWindow,
72
+ _ref$documentNode = _ref.documentNode,
73
+ documentNode = _ref$documentNode === void 0 ? typeof document === 'undefined' ? undefined : document : _ref$documentNode,
74
+ _ref$colorSchemeNode = _ref.colorSchemeNode,
75
+ colorSchemeNode = _ref$colorSchemeNode === void 0 ? typeof document === 'undefined' ? undefined : document.documentElement : _ref$colorSchemeNode,
76
+ _ref$colorSchemeSelec = _ref.colorSchemeSelector,
77
+ colorSchemeSelector = _ref$colorSchemeSelec === void 0 ? ':root' : _ref$colorSchemeSelec;
67
78
  var hasMounted = React.useRef(false);
68
79
 
69
80
  var _themeProp$colorSchem = themeProp.colorSchemes,
@@ -81,7 +92,9 @@ export default function createCssVarsProvider(options) {
81
92
  defaultLightColorScheme: defaultLightColorScheme,
82
93
  defaultDarkColorScheme: defaultDarkColorScheme,
83
94
  modeStorageKey: modeStorageKey,
84
- defaultMode: defaultMode
95
+ colorSchemeStorageKey: colorSchemeStorageKey,
96
+ defaultMode: defaultMode,
97
+ storageWindow: storageWindow
85
98
  }),
86
99
  mode = _useCurrentColorSchem.mode,
87
100
  setMode = _useCurrentColorSchem.setMode,
@@ -163,56 +176,56 @@ export default function createCssVarsProvider(options) {
163
176
  }();
164
177
 
165
178
  if (key === resolvedDefaultColorScheme) {
166
- styleSheet[':root'] = css;
179
+ styleSheet[colorSchemeSelector] = css;
167
180
  } else {
168
- styleSheet["[".concat(attribute, "=\"").concat(key, "\"]")] = css;
181
+ styleSheet["".concat(colorSchemeSelector === ':root' ? '' : colorSchemeSelector, "[").concat(attribute, "=\"").concat(key, "\"]")] = css;
169
182
  }
170
183
  });
171
184
  React.useEffect(function () {
172
- if (colorScheme) {
185
+ if (colorScheme && colorSchemeNode) {
173
186
  // attaches attribute to <html> because the css variables are attached to :root (html)
174
- document.documentElement.setAttribute(attribute, colorScheme);
187
+ colorSchemeNode.setAttribute(attribute, colorScheme);
175
188
  }
176
- }, [colorScheme, attribute]);
189
+ }, [colorScheme, attribute, colorSchemeNode]);
177
190
  useEnhancedEffect(function () {
178
- if (!mode || !enableColorScheme) {
191
+ if (!mode || !enableColorScheme || !colorSchemeNode) {
179
192
  return undefined;
180
193
  }
181
194
 
182
- var priorColorScheme = document.documentElement.style.getPropertyValue('color-scheme'); // `color-scheme` tells browser to render built-in elements according to its value: `light` or `dark`
195
+ var priorColorScheme = colorSchemeNode.style.getPropertyValue('color-scheme'); // `color-scheme` tells browser to render built-in elements according to its value: `light` or `dark`
183
196
 
184
197
  if (mode === 'system') {
185
- document.documentElement.style.setProperty('color-scheme', systemMode);
198
+ colorSchemeNode.style.setProperty('color-scheme', systemMode);
186
199
  } else {
187
- document.documentElement.style.setProperty('color-scheme', mode);
200
+ colorSchemeNode.style.setProperty('color-scheme', mode);
188
201
  }
189
202
 
190
203
  return function () {
191
- document.documentElement.style.setProperty('color-scheme', priorColorScheme);
204
+ colorSchemeNode.style.setProperty('color-scheme', priorColorScheme);
192
205
  };
193
- }, [mode, systemMode, enableColorScheme]);
206
+ }, [mode, systemMode, enableColorScheme, colorSchemeNode]);
194
207
  React.useEffect(function () {
195
208
  var timer;
196
209
 
197
- if (disableTransitionOnChange && hasMounted.current) {
210
+ if (disableTransitionOnChange && hasMounted.current && documentNode) {
198
211
  // credit: https://github.com/pacocoursey/next-themes/blob/b5c2bad50de2d61ad7b52a9c5cdc801a78507d7a/index.tsx#L313
199
- var css = document.createElement('style');
200
- css.appendChild(document.createTextNode(DISABLE_CSS_TRANSITION));
201
- document.head.appendChild(css); // Force browser repaint
212
+ var css = documentNode.createElement('style');
213
+ css.appendChild(documentNode.createTextNode(DISABLE_CSS_TRANSITION));
214
+ documentNode.head.appendChild(css); // Force browser repaint
202
215
 
203
216
  (function () {
204
- return window.getComputedStyle(document.body);
217
+ return window.getComputedStyle(documentNode.body);
205
218
  })();
206
219
 
207
220
  timer = setTimeout(function () {
208
- document.head.removeChild(css);
221
+ documentNode.head.removeChild(css);
209
222
  }, 1);
210
223
  }
211
224
 
212
225
  return function () {
213
226
  clearTimeout(timer);
214
227
  };
215
- }, [colorScheme, disableTransitionOnChange]);
228
+ }, [colorScheme, disableTransitionOnChange, documentNode]);
216
229
  React.useEffect(function () {
217
230
  hasMounted.current = true;
218
231
  return function () {
@@ -230,9 +243,7 @@ export default function createCssVarsProvider(options) {
230
243
  allColorSchemes: allColorSchemes
231
244
  },
232
245
  children: [/*#__PURE__*/_jsx(GlobalStyles, {
233
- styles: {
234
- ':root': rootCss
235
- }
246
+ styles: _defineProperty({}, colorSchemeSelector, rootCss)
236
247
  }), /*#__PURE__*/_jsx(GlobalStyles, {
237
248
  styles: styleSheet
238
249
  }), /*#__PURE__*/_jsx(ThemeProvider, {
@@ -253,6 +264,21 @@ export default function createCssVarsProvider(options) {
253
264
  */
254
265
  children: PropTypes.node,
255
266
 
267
+ /**
268
+ * The node used to attach the color-scheme attribute
269
+ */
270
+ colorSchemeNode: PropTypes.any,
271
+
272
+ /**
273
+ * The CSS selector for attaching the generated custom properties
274
+ */
275
+ colorSchemeSelector: PropTypes.string,
276
+
277
+ /**
278
+ * localStorage key used to store `colorScheme`
279
+ */
280
+ colorSchemeStorageKey: PropTypes.string,
281
+
256
282
  /**
257
283
  * The initial color scheme used.
258
284
  */
@@ -268,6 +294,11 @@ export default function createCssVarsProvider(options) {
268
294
  */
269
295
  disableTransitionOnChange: PropTypes.bool,
270
296
 
297
+ /**
298
+ * The document to attach the attribute to
299
+ */
300
+ documentNode: PropTypes.any,
301
+
271
302
  /**
272
303
  * Indicate to the browser which color scheme is used (light or dark) for rendering built-in UI
273
304
  */
@@ -283,6 +314,12 @@ export default function createCssVarsProvider(options) {
283
314
  */
284
315
  prefix: PropTypes.string,
285
316
 
317
+ /**
318
+ * The window that attaches the 'storage' event listener
319
+ * @default window
320
+ */
321
+ storageWindow: PropTypes.any,
322
+
286
323
  /**
287
324
  * The calculated theme object that will be passed through context.
288
325
  */
@@ -5,7 +5,8 @@ export var DEFAULT_COLOR_SCHEME_STORAGE_KEY = 'mui-color-scheme';
5
5
  export var DEFAULT_ATTRIBUTE = 'data-mui-color-scheme';
6
6
  export default function getInitColorSchemeScript(options) {
7
7
  var _ref = options || {},
8
- enableSystem = _ref.enableSystem,
8
+ _ref$enableSystem = _ref.enableSystem,
9
+ enableSystem = _ref$enableSystem === void 0 ? false : _ref$enableSystem,
9
10
  _ref$defaultLightColo = _ref.defaultLightColorScheme,
10
11
  defaultLightColorScheme = _ref$defaultLightColo === void 0 ? 'light' : _ref$defaultLightColo,
11
12
  _ref$defaultDarkColor = _ref.defaultDarkColorScheme,
@@ -15,12 +16,14 @@ export default function getInitColorSchemeScript(options) {
15
16
  _ref$colorSchemeStora = _ref.colorSchemeStorageKey,
16
17
  colorSchemeStorageKey = _ref$colorSchemeStora === void 0 ? DEFAULT_COLOR_SCHEME_STORAGE_KEY : _ref$colorSchemeStora,
17
18
  _ref$attribute = _ref.attribute,
18
- attribute = _ref$attribute === void 0 ? DEFAULT_ATTRIBUTE : _ref$attribute;
19
+ attribute = _ref$attribute === void 0 ? DEFAULT_ATTRIBUTE : _ref$attribute,
20
+ _ref$colorSchemeNode = _ref.colorSchemeNode,
21
+ colorSchemeNode = _ref$colorSchemeNode === void 0 ? 'document.documentElement' : _ref$colorSchemeNode;
19
22
 
20
23
  return /*#__PURE__*/_jsx("script", {
21
24
  // eslint-disable-next-line react/no-danger
22
25
  dangerouslySetInnerHTML: {
23
- __html: "(function() { try {\n var mode = localStorage.getItem('".concat(modeStorageKey, "');\n var colorScheme = '';\n if (mode === 'system' || (!mode && !!").concat(enableSystem, ")) {\n // handle system mode\n var mql = window.matchMedia('(prefers-color-scheme: dark)');\n if (mql.matches) {\n colorScheme = localStorage.getItem('").concat(colorSchemeStorageKey, "-dark') || '").concat(defaultDarkColorScheme, "';\n } else {\n colorScheme = localStorage.getItem('").concat(colorSchemeStorageKey, "-light') || '").concat(defaultLightColorScheme, "';\n }\n }\n if (mode === 'light') {\n colorScheme = localStorage.getItem('").concat(colorSchemeStorageKey, "-light') || '").concat(defaultLightColorScheme, "';\n }\n if (mode === 'dark') {\n colorScheme = localStorage.getItem('").concat(colorSchemeStorageKey, "-dark') || '").concat(defaultDarkColorScheme, "';\n }\n if (colorScheme) {\n document.documentElement.setAttribute('").concat(attribute, "', colorScheme);\n }\n } catch (e) {} })();")
26
+ __html: "(function() { try {\n var mode = localStorage.getItem('".concat(modeStorageKey, "');\n var colorScheme = '';\n if (mode === 'system' || (!mode && !!").concat(enableSystem, ")) {\n // handle system mode\n var mql = window.matchMedia('(prefers-color-scheme: dark)');\n if (mql.matches) {\n colorScheme = localStorage.getItem('").concat(colorSchemeStorageKey, "-dark') || '").concat(defaultDarkColorScheme, "';\n } else {\n colorScheme = localStorage.getItem('").concat(colorSchemeStorageKey, "-light') || '").concat(defaultLightColorScheme, "';\n }\n }\n if (mode === 'light') {\n colorScheme = localStorage.getItem('").concat(colorSchemeStorageKey, "-light') || '").concat(defaultLightColorScheme, "';\n }\n if (mode === 'dark') {\n colorScheme = localStorage.getItem('").concat(colorSchemeStorageKey, "-dark') || '").concat(defaultDarkColorScheme, "';\n }\n if (colorScheme) {\n ").concat(colorSchemeNode, ".setAttribute('").concat(attribute, "', colorScheme);\n }\n } catch (e) {} })();")
24
27
  }
25
28
  });
26
29
  }