@mui/system 5.0.5 → 5.2.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 (57) hide show
  1. package/Box/Box.spec.d.ts +1 -1
  2. package/CHANGELOG.md +302 -9
  3. package/breakpoints.js +42 -9
  4. package/createBox.d.ts +5 -1
  5. package/createBox.js +5 -3
  6. package/createStyled.js +5 -1
  7. package/createTheme/createBreakpoints.js +2 -2
  8. package/createTheme/createSpacing.d.ts +10 -10
  9. package/cssVars/createCssVarsProvider.d.ts +88 -38
  10. package/cssVars/createCssVarsProvider.js +84 -64
  11. package/cssVars/createCssVarsProvider.spec.d.ts +1 -1
  12. package/cssVars/cssVarsParser.d.ts +68 -57
  13. package/cssVars/cssVarsParser.js +41 -11
  14. package/cssVars/getInitColorSchemeScript.d.ts +12 -7
  15. package/cssVars/getInitColorSchemeScript.js +27 -5
  16. package/cssVars/index.d.ts +2 -2
  17. package/cssVars/useCurrentColorScheme.d.ts +50 -0
  18. package/cssVars/useCurrentColorScheme.js +235 -0
  19. package/esm/breakpoints.js +40 -9
  20. package/esm/createBox.js +5 -3
  21. package/esm/createStyled.js +5 -1
  22. package/esm/createTheme/createBreakpoints.js +2 -2
  23. package/esm/cssVars/createCssVarsProvider.js +83 -66
  24. package/esm/cssVars/cssVarsParser.js +40 -11
  25. package/esm/cssVars/getInitColorSchemeScript.js +24 -3
  26. package/esm/cssVars/useCurrentColorScheme.js +217 -0
  27. package/esm/styleFunctionSx/extendSxProp.js +20 -1
  28. package/esm/styleFunctionSx/styleFunctionSx.js +47 -35
  29. package/index.js +1 -1
  30. package/index.spec.d.ts +1 -1
  31. package/legacy/breakpoints.js +40 -9
  32. package/legacy/createBox.js +6 -3
  33. package/legacy/createStyled.js +5 -1
  34. package/legacy/createTheme/createBreakpoints.js +2 -2
  35. package/legacy/cssVars/createCssVarsProvider.js +85 -73
  36. package/legacy/cssVars/cssVarsParser.js +37 -9
  37. package/legacy/cssVars/getInitColorSchemeScript.js +12 -4
  38. package/legacy/cssVars/useCurrentColorScheme.js +231 -0
  39. package/legacy/index.js +1 -1
  40. package/legacy/styleFunctionSx/extendSxProp.js +21 -1
  41. package/legacy/styleFunctionSx/styleFunctionSx.js +47 -35
  42. package/modern/breakpoints.js +40 -9
  43. package/modern/createBox.js +5 -3
  44. package/modern/createStyled.js +5 -1
  45. package/modern/createTheme/createBreakpoints.js +2 -2
  46. package/modern/cssVars/createCssVarsProvider.js +83 -66
  47. package/modern/cssVars/cssVarsParser.js +40 -11
  48. package/modern/cssVars/getInitColorSchemeScript.js +24 -3
  49. package/modern/cssVars/useCurrentColorScheme.js +217 -0
  50. package/modern/index.js +1 -1
  51. package/modern/styleFunctionSx/extendSxProp.js +20 -1
  52. package/modern/styleFunctionSx/styleFunctionSx.js +47 -35
  53. package/package.json +8 -8
  54. package/styleFunctionSx/extendSxProp.js +21 -1
  55. package/styleFunctionSx/styleFunctionSx.d.ts +2 -1
  56. package/styleFunctionSx/styleFunctionSx.js +49 -37
  57. package/styleFunctionSx/styleFunctionSx.spec.d.ts +1 -0
@@ -14,53 +14,65 @@ function callIfFn(maybeFn, arg) {
14
14
 
15
15
  function styleFunctionSx(props) {
16
16
  const {
17
- sx: styles,
17
+ sx,
18
18
  theme = {}
19
19
  } = props || {};
20
20
 
21
- if (!styles) {
22
- return null;
21
+ if (!sx) {
22
+ return null; // emotion & styled-components will neglect null
23
23
  }
24
+ /*
25
+ * Receive `sxInput` as object or callback
26
+ * and then recursively check keys & values to create media query object styles.
27
+ * (the result will be used in `styled`)
28
+ */
24
29
 
25
- let stylesObject = styles;
26
30
 
27
- if (typeof styles === 'function') {
28
- stylesObject = styles(theme);
29
- } else if (typeof styles !== 'object') {
30
- // value
31
- return styles;
32
- }
31
+ function traverse(sxInput) {
32
+ let sxObject = sxInput;
33
+
34
+ if (typeof sxInput === 'function') {
35
+ sxObject = sxInput(theme);
36
+ } else if (typeof sxInput !== 'object') {
37
+ // value
38
+ return sxInput;
39
+ }
33
40
 
34
- const emptyBreakpoints = createEmptyBreakpointObject(theme.breakpoints);
35
- const breakpointsKeys = Object.keys(emptyBreakpoints);
36
- let css = emptyBreakpoints;
37
- Object.keys(stylesObject).forEach(styleKey => {
38
- const value = callIfFn(stylesObject[styleKey], theme);
41
+ const emptyBreakpoints = createEmptyBreakpointObject(theme.breakpoints);
42
+ const breakpointsKeys = Object.keys(emptyBreakpoints);
43
+ let css = emptyBreakpoints;
44
+ Object.keys(sxObject).forEach(styleKey => {
45
+ const value = callIfFn(sxObject[styleKey], theme);
39
46
 
40
- if (typeof value === 'object') {
41
- if (propToStyleFunction[styleKey]) {
42
- css = merge(css, getThemeValue(styleKey, value, theme));
43
- } else {
44
- const breakpointsValues = handleBreakpoints({
45
- theme
46
- }, value, x => ({
47
- [styleKey]: x
48
- }));
47
+ if (value !== null && value !== undefined) {
48
+ if (typeof value === 'object') {
49
+ if (propToStyleFunction[styleKey]) {
50
+ css = merge(css, getThemeValue(styleKey, value, theme));
51
+ } else {
52
+ const breakpointsValues = handleBreakpoints({
53
+ theme
54
+ }, value, x => ({
55
+ [styleKey]: x
56
+ }));
49
57
 
50
- if (objectsHaveSameKeys(breakpointsValues, value)) {
51
- css[styleKey] = styleFunctionSx({
52
- sx: value,
53
- theme
54
- });
58
+ if (objectsHaveSameKeys(breakpointsValues, value)) {
59
+ css[styleKey] = styleFunctionSx({
60
+ sx: value,
61
+ theme
62
+ });
63
+ } else {
64
+ css = merge(css, breakpointsValues);
65
+ }
66
+ }
55
67
  } else {
56
- css = merge(css, breakpointsValues);
68
+ css = merge(css, getThemeValue(styleKey, value, theme));
57
69
  }
58
70
  }
59
- } else {
60
- css = merge(css, getThemeValue(styleKey, value, theme));
61
- }
62
- });
63
- return removeUnusedBreakpoints(breakpointsKeys, css);
71
+ });
72
+ return removeUnusedBreakpoints(breakpointsKeys, css);
73
+ }
74
+
75
+ return Array.isArray(sx) ? sx.map(traverse) : traverse(sx);
64
76
  }
65
77
 
66
78
  styleFunctionSx.filterProps = ['sx'];
package/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /** @license MUI v5.0.5
1
+ /** @license MUI v5.2.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 {};
@@ -10,12 +10,12 @@ export var values = {
10
10
  xs: 0,
11
11
  // phone
12
12
  sm: 600,
13
- // tablets
13
+ // tablet
14
14
  md: 900,
15
15
  // small laptop
16
16
  lg: 1200,
17
17
  // desktop
18
- xl: 1536 // large screens
18
+ xl: 1536 // large screen
19
19
 
20
20
  };
21
21
  var defaultBreakpoints = {
@@ -102,7 +102,7 @@ export function createEmptyBreakpointObject() {
102
102
  export function removeUnusedBreakpoints(breakpointKeys, style) {
103
103
  return breakpointKeys.reduce(function (acc, key) {
104
104
  var breakpointOutput = acc[key];
105
- var isBreakpointUnused = Object.keys(breakpointOutput).length === 0;
105
+ var isBreakpointUnused = !breakpointOutput || Object.keys(breakpointOutput).length === 0;
106
106
 
107
107
  if (isBreakpointUnused) {
108
108
  delete acc[key];
@@ -122,10 +122,40 @@ export function mergeBreakpointsInOrder(breakpointsInput) {
122
122
  return deepmerge(prev, next);
123
123
  }, {});
124
124
  return removeUnusedBreakpoints(Object.keys(emptyBreakpoints), mergedOutput);
125
+ } // compute base for responsive values; e.g.,
126
+ // [1,2,3] => {xs: true, sm: true, md: true}
127
+ // {xs: 1, sm: 2, md: 3} => {xs: true, sm: true, md: true}
128
+
129
+ export function computeBreakpointsBase(breakpointValues, themeBreakpoints) {
130
+ // fixed value
131
+ if (_typeof(breakpointValues) !== 'object') {
132
+ return {};
133
+ }
134
+
135
+ var base = {};
136
+ var breakpointsKeys = Object.keys(themeBreakpoints);
137
+
138
+ if (Array.isArray(breakpointValues)) {
139
+ breakpointsKeys.forEach(function (breakpoint, i) {
140
+ if (i < breakpointValues.length) {
141
+ base[breakpoint] = true;
142
+ }
143
+ });
144
+ } else {
145
+ breakpointsKeys.forEach(function (breakpoint) {
146
+ if (breakpointValues[breakpoint] != null) {
147
+ base[breakpoint] = true;
148
+ }
149
+ });
150
+ }
151
+
152
+ return base;
125
153
  }
126
154
  export function resolveBreakpointValues(_ref) {
127
155
  var breakpointValues = _ref.values,
128
- base = _ref.base;
156
+ themeBreakpoints = _ref.breakpoints,
157
+ customBase = _ref.base;
158
+ var base = customBase || computeBreakpointsBase(breakpointValues, themeBreakpoints);
129
159
  var keys = Object.keys(base);
130
160
 
131
161
  if (keys.length === 0) {
@@ -133,14 +163,15 @@ export function resolveBreakpointValues(_ref) {
133
163
  }
134
164
 
135
165
  var previous;
136
- return keys.reduce(function (acc, breakpoint) {
137
- if (_typeof(breakpointValues) === 'object') {
138
- acc[breakpoint] = breakpointValues[breakpoint] != null ? breakpointValues[breakpoint] : breakpointValues[previous];
166
+ return keys.reduce(function (acc, breakpoint, i) {
167
+ if (Array.isArray(breakpointValues)) {
168
+ acc[breakpoint] = breakpointValues[i] != null ? breakpointValues[i] : breakpointValues[previous];
169
+ previous = i;
139
170
  } else {
140
- acc[breakpoint] = breakpointValues;
171
+ acc[breakpoint] = breakpointValues[breakpoint] != null ? breakpointValues[breakpoint] : breakpointValues[previous] || breakpointValues;
172
+ previous = breakpoint;
141
173
  }
142
174
 
143
- previous = breakpoint;
144
175
  return acc;
145
176
  }, {});
146
177
  }
@@ -9,7 +9,10 @@ import useTheme from './useTheme';
9
9
  import { jsx as _jsx } from "react/jsx-runtime";
10
10
  export default function createBox() {
11
11
  var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
12
- var defaultTheme = options.defaultTheme;
12
+ var defaultTheme = options.defaultTheme,
13
+ _options$defaultClass = options.defaultClassName,
14
+ defaultClassName = _options$defaultClass === void 0 ? 'MuiBox-root' : _options$defaultClass,
15
+ generateClassName = options.generateClassName;
13
16
  var BoxRoot = styled('div')(styleFunctionSx);
14
17
  var Box = /*#__PURE__*/React.forwardRef(function Box(inProps, ref) {
15
18
  var theme = useTheme(defaultTheme);
@@ -23,7 +26,7 @@ export default function createBox() {
23
26
  return /*#__PURE__*/_jsx(BoxRoot, _extends({
24
27
  as: component,
25
28
  ref: ref,
26
- className: clsx(className, 'MuiBox-root'),
29
+ className: clsx(className, generateClassName ? generateClassName(defaultClassName) : defaultClassName),
27
30
  theme: theme
28
31
  }, other));
29
32
  });
@@ -49,7 +52,7 @@ export default function createBox() {
49
52
  /**
50
53
  * @ignore
51
54
  */
52
- sx: PropTypes.object
55
+ sx: PropTypes.oneOfType([PropTypes.object, PropTypes.array, PropTypes.func])
53
56
  } : void 0;
54
57
  return Box;
55
58
  }
@@ -118,7 +118,11 @@ export default function createStyled() {
118
118
  }
119
119
 
120
120
  var expressionsWithDefaultTheme = expressions ? expressions.map(function (stylesArg) {
121
- return typeof stylesArg === 'function' ? function (_ref) {
121
+ // On the server emotion doesn't use React.forwardRef for creating components, so the created
122
+ // component stays as a function. This condition makes sure that we do not interpolate functions
123
+ // which are basically components used as a selectors.
124
+ // eslint-disable-next-line no-underscore-dangle
125
+ return typeof stylesArg === 'function' && stylesArg.__emotion_real !== stylesArg ? function (_ref) {
122
126
  var themeInput = _ref.theme,
123
127
  other = _objectWithoutProperties(_ref, ["theme"]);
124
128
 
@@ -10,12 +10,12 @@ export default function createBreakpoints(breakpoints) {
10
10
  xs: 0,
11
11
  // phone
12
12
  sm: 600,
13
- // tablets
13
+ // tablet
14
14
  md: 900,
15
15
  // small laptop
16
16
  lg: 1200,
17
17
  // desktop
18
- xl: 1536 // large screens
18
+ xl: 1536 // large screen
19
19
 
20
20
  } : _breakpoints$values,
21
21
  _breakpoints$unit = breakpoints.unit,
@@ -1,43 +1,29 @@
1
1
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
2
2
  import _extends from "@babel/runtime/helpers/esm/extends";
3
3
  import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
4
+ import _typeof from "@babel/runtime/helpers/esm/typeof";
4
5
  import { formatMuiErrorMessage as _formatMuiErrorMessage } from "@mui/utils";
5
6
  import * as React from 'react';
6
7
  import PropTypes from 'prop-types';
7
8
  import { GlobalStyles } from '@mui/styled-engine';
8
9
  import { deepmerge } from '@mui/utils';
9
10
  import cssVarsParser from './cssVarsParser';
10
- import getInitColorSchemeScript, { DEFAULT_ATTRIBUTE, DEFAULT_STORAGE_KEY } from './getInitColorSchemeScript';
11
+ import ThemeProvider from '../ThemeProvider';
12
+ import getInitColorSchemeScript, { DEFAULT_ATTRIBUTE, DEFAULT_MODE_STORAGE_KEY } from './getInitColorSchemeScript';
13
+ import useCurrentColorScheme from './useCurrentColorScheme';
11
14
  import { jsx as _jsx } from "react/jsx-runtime";
12
15
  import { jsxs as _jsxs } from "react/jsx-runtime";
13
-
14
- var resolveMode = function resolveMode(key, fallback, supportedColorSchemes) {
15
- if (typeof window === 'undefined') {
16
- return undefined;
17
- }
18
-
19
- var value;
20
-
21
- try {
22
- value = localStorage.getItem(key) || undefined;
23
-
24
- if (!supportedColorSchemes.includes(value)) {
25
- value = undefined;
26
- }
27
- } catch (e) {// Unsupported
28
- }
29
-
30
- return value || fallback;
31
- };
32
-
33
- export default function createCssVarsProvider(ThemeContext, options) {
16
+ export default function createCssVarsProvider(options) {
34
17
  var _options$theme = options.theme,
35
18
  baseTheme = _options$theme === void 0 ? {} : _options$theme,
19
+ _options$defaultMode = options.defaultMode,
20
+ desisgnSystemMode = _options$defaultMode === void 0 ? 'light' : _options$defaultMode,
36
21
  designSystemColorScheme = options.defaultColorScheme,
37
22
  _options$prefix = options.prefix,
38
- designSystemPrefix = _options$prefix === void 0 ? '' : _options$prefix;
23
+ designSystemPrefix = _options$prefix === void 0 ? '' : _options$prefix,
24
+ shouldSkipGeneratingVar = options.shouldSkipGeneratingVar;
39
25
 
40
- if (!baseTheme.colorSchemes || !baseTheme.colorSchemes[designSystemColorScheme]) {
26
+ 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]) {
41
27
  console.error("MUI: `".concat(designSystemColorScheme, "` does not exist in `theme.colorSchemes`."));
42
28
  }
43
29
 
@@ -59,10 +45,12 @@ export default function createCssVarsProvider(ThemeContext, options) {
59
45
  themeProp = _ref$theme === void 0 ? {} : _ref$theme,
60
46
  _ref$prefix = _ref.prefix,
61
47
  prefix = _ref$prefix === void 0 ? designSystemPrefix : _ref$prefix,
62
- _ref$storageKey = _ref.storageKey,
63
- storageKey = _ref$storageKey === void 0 ? DEFAULT_STORAGE_KEY : _ref$storageKey,
48
+ _ref$modeStorageKey = _ref.modeStorageKey,
49
+ modeStorageKey = _ref$modeStorageKey === void 0 ? DEFAULT_MODE_STORAGE_KEY : _ref$modeStorageKey,
64
50
  _ref$attribute = _ref.attribute,
65
51
  attribute = _ref$attribute === void 0 ? DEFAULT_ATTRIBUTE : _ref$attribute,
52
+ _ref$defaultMode = _ref.defaultMode,
53
+ defaultMode = _ref$defaultMode === void 0 ? desisgnSystemMode : _ref$defaultMode,
66
54
  _ref$defaultColorSche = _ref.defaultColorScheme,
67
55
  defaultColorScheme = _ref$defaultColorSche === void 0 ? designSystemColorScheme : _ref$defaultColorSche;
68
56
 
@@ -77,23 +65,47 @@ export default function createCssVarsProvider(ThemeContext, options) {
77
65
  var mergedTheme = deepmerge(restBaseTheme, restThemeProp);
78
66
  var colorSchemes = deepmerge(baseColorSchemes, colorSchemesProp);
79
67
  var allColorSchemes = Object.keys(colorSchemes);
80
- var joinedColorSchemes = allColorSchemes.join(',');
81
-
82
- var _React$useState = React.useState(function () {
83
- return resolveMode(storageKey, defaultColorScheme, allColorSchemes);
68
+ var defaultLightColorScheme = typeof defaultColorScheme === 'string' ? defaultColorScheme : defaultColorScheme.light;
69
+ var defaultDarkColorScheme = typeof defaultColorScheme === 'string' ? defaultColorScheme : defaultColorScheme.dark;
70
+
71
+ var _useCurrentColorSchem = useCurrentColorScheme({
72
+ supportedColorSchemes: allColorSchemes,
73
+ defaultLightColorScheme: defaultLightColorScheme,
74
+ defaultDarkColorScheme: defaultDarkColorScheme,
75
+ modeStorageKey: modeStorageKey,
76
+ defaultMode: defaultMode
84
77
  }),
85
- colorScheme = _React$useState[0],
86
- setColorScheme = _React$useState[1];
78
+ mode = _useCurrentColorSchem.mode,
79
+ setMode = _useCurrentColorSchem.setMode,
80
+ lightColorScheme = _useCurrentColorSchem.lightColorScheme,
81
+ darkColorScheme = _useCurrentColorSchem.darkColorScheme,
82
+ colorScheme = _useCurrentColorSchem.colorScheme,
83
+ setColorScheme = _useCurrentColorSchem.setColorScheme;
84
+
85
+ var resolvedColorScheme = function () {
86
+ if (!colorScheme) {
87
+ // This scope occurs on the server
88
+ if (defaultMode === 'dark') {
89
+ return defaultDarkColorScheme;
90
+ } // use light color scheme, if default mode is 'light' | 'auto'
91
+
92
+
93
+ return defaultLightColorScheme;
94
+ }
87
95
 
88
- var resolvedColorScheme = colorScheme || defaultColorScheme;
96
+ return colorScheme;
97
+ }();
89
98
 
90
99
  var _cssVarsParser = cssVarsParser(mergedTheme, {
91
- prefix: prefix
100
+ prefix: prefix,
101
+ basePrefix: designSystemPrefix,
102
+ shouldSkipGeneratingVar: shouldSkipGeneratingVar
92
103
  }),
93
104
  rootCss = _cssVarsParser.css,
94
105
  rootVars = _cssVarsParser.vars;
95
106
 
96
107
  mergedTheme = _extends({}, mergedTheme, colorSchemes[resolvedColorScheme], {
108
+ colorSchemes: colorSchemes,
97
109
  vars: rootVars
98
110
  });
99
111
  var styleSheet = {};
@@ -103,17 +115,29 @@ export default function createCssVarsProvider(ThemeContext, options) {
103
115
  scheme = _ref3[1];
104
116
 
105
117
  var _cssVarsParser2 = cssVarsParser(scheme, {
106
- prefix: prefix
118
+ prefix: prefix,
119
+ basePrefix: designSystemPrefix,
120
+ shouldSkipGeneratingVar: shouldSkipGeneratingVar
107
121
  }),
108
122
  css = _cssVarsParser2.css,
109
123
  vars = _cssVarsParser2.vars;
110
124
 
111
- if (key === resolvedColorScheme) {
112
- mergedTheme.vars = _extends({}, mergedTheme.vars, vars);
113
- }
125
+ mergedTheme.vars = deepmerge(mergedTheme.vars, vars);
126
+
127
+ var resolvedDefaultColorScheme = function () {
128
+ if (typeof defaultColorScheme === 'string') {
129
+ return defaultColorScheme;
130
+ }
131
+
132
+ if (defaultMode === 'dark') {
133
+ return defaultColorScheme.dark;
134
+ }
114
135
 
115
- if (key === defaultColorScheme) {
116
- styleSheet[':root'] = deepmerge(rootCss, css);
136
+ return defaultColorScheme.light;
137
+ }();
138
+
139
+ if (key === resolvedDefaultColorScheme) {
140
+ styleSheet[':root'] = css;
117
141
  } else {
118
142
  styleSheet["[".concat(attribute, "=\"").concat(key, "\"]")] = css;
119
143
  }
@@ -121,43 +145,26 @@ export default function createCssVarsProvider(ThemeContext, options) {
121
145
  React.useEffect(function () {
122
146
  if (colorScheme) {
123
147
  document.body.setAttribute(attribute, colorScheme);
124
- localStorage.setItem(storageKey, colorScheme);
125
- }
126
- }, [colorScheme, attribute, storageKey]); // local storage modified in the context of another document
127
-
128
- React.useEffect(function () {
129
- var handleStorage = function handleStorage(event) {
130
- var storageColorScheme = event.newValue;
131
-
132
- if (event.key === storageKey && joinedColorSchemes.match(storageColorScheme)) {
133
- if (storageColorScheme) {
134
- setColorScheme(storageColorScheme);
135
- }
136
- }
137
- };
138
-
139
- window.addEventListener('storage', handleStorage);
140
- return function () {
141
- return window.removeEventListener('storage', handleStorage);
142
- };
143
- }, [setColorScheme, storageKey, joinedColorSchemes]);
144
- var wrappedSetColorScheme = React.useCallback(function (val) {
145
- if (typeof val === 'string' && !allColorSchemes.includes(val)) {
146
- console.error("`".concat(val, "` does not exist in `theme.colorSchemes`."));
147
- } else {
148
- setColorScheme(val);
149
148
  }
150
- }, [setColorScheme, allColorSchemes]);
149
+ }, [colorScheme, attribute]);
151
150
  return /*#__PURE__*/_jsxs(ColorSchemeContext.Provider, {
152
151
  value: {
152
+ mode: mode,
153
+ setMode: setMode,
154
+ lightColorScheme: lightColorScheme,
155
+ darkColorScheme: darkColorScheme,
153
156
  colorScheme: colorScheme,
154
- setColorScheme: wrappedSetColorScheme,
157
+ setColorScheme: setColorScheme,
155
158
  allColorSchemes: allColorSchemes
156
159
  },
157
160
  children: [/*#__PURE__*/_jsx(GlobalStyles, {
161
+ styles: {
162
+ ':root': rootCss
163
+ }
164
+ }), /*#__PURE__*/_jsx(GlobalStyles, {
158
165
  styles: styleSheet
159
- }), /*#__PURE__*/_jsx(ThemeContext.Provider, {
160
- value: mergedTheme,
166
+ }), /*#__PURE__*/_jsx(ThemeProvider, {
167
+ theme: mergedTheme,
161
168
  children: children
162
169
  })]
163
170
  });
@@ -177,17 +184,22 @@ export default function createCssVarsProvider(ThemeContext, options) {
177
184
  /**
178
185
  * The initial color scheme used.
179
186
  */
180
- defaultColorScheme: PropTypes.string,
187
+ defaultColorScheme: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
181
188
 
182
189
  /**
183
- * css variable prefix
190
+ * The initial mode used.
184
191
  */
185
- prefix: PropTypes.string,
192
+ defaultMode: PropTypes.string,
186
193
 
187
194
  /**
188
195
  * The key in the local storage used to store current color scheme.
189
196
  */
190
- storageKey: PropTypes.string,
197
+ modeStorageKey: PropTypes.string,
198
+
199
+ /**
200
+ * css variable prefix
201
+ */
202
+ prefix: PropTypes.string,
191
203
 
192
204
  /**
193
205
  * The calculated theme object that will be passed through context.
@@ -61,7 +61,7 @@ export var walkObjectDeep = function walkObjectDeep(obj, callback) {
61
61
  if (_typeof(value) === 'object' && Object.keys(value).length > 0) {
62
62
  recurse(value, [].concat(_toConsumableArray(parentKeys), [key]));
63
63
  } else {
64
- callback([].concat(_toConsumableArray(parentKeys), [key]), value);
64
+ callback([].concat(_toConsumableArray(parentKeys), [key]), value, object);
65
65
  }
66
66
  }
67
67
  });
@@ -88,7 +88,16 @@ var getCssValue = function getCssValue(keys, value) {
88
88
  * a function that parse theme and return { css, vars }
89
89
  *
90
90
  * @param {Object} theme
91
- * @param {{ prefix?: string }} options
91
+ * @param {{
92
+ * prefix?: string,
93
+ * basePrefix?: string,
94
+ * shouldSkipGeneratingVar?: (objectPathKeys: Array<string>, value: string | number) => boolean
95
+ * }} options.
96
+ * `basePrefix`: defined by design system.
97
+ * `prefix`: defined by application
98
+ *
99
+ * This function also mutate the string value of theme input by replacing `basePrefix` (if existed) with `prefix`
100
+ *
92
101
  * @returns {{ css: Object, vars: Object }} `css` is the stylesheet, `vars` is an object to get css variable (same structure as theme)
93
102
  *
94
103
  * @example
@@ -103,19 +112,38 @@ var getCssValue = function getCssValue(keys, value) {
103
112
  */
104
113
 
105
114
 
106
- export default function cssVarsParser(obj, options) {
115
+ export default function cssVarsParser(theme, options) {
116
+ var clonedTheme = _extends({}, theme);
117
+
118
+ delete clonedTheme.vars; // remove 'vars' from the structure
119
+
107
120
  var _ref3 = options || {},
108
- prefix = _ref3.prefix;
121
+ prefix = _ref3.prefix,
122
+ _ref3$basePrefix = _ref3.basePrefix,
123
+ basePrefix = _ref3$basePrefix === void 0 ? '' : _ref3$basePrefix,
124
+ shouldSkipGeneratingVar = _ref3.shouldSkipGeneratingVar;
109
125
 
110
126
  var css = {};
111
127
  var vars = {};
112
- walkObjectDeep(obj, function (keys, value) {
113
- if (typeof value === 'string' || typeof value === 'number') {
114
- var cssVar = "--".concat(prefix ? "".concat(prefix, "-") : '').concat(keys.join('-'));
128
+ walkObjectDeep(clonedTheme, function (keys, val, scope) {
129
+ if (typeof val === 'string' || typeof val === 'number') {
130
+ var _value = val;
115
131
 
116
- _extends(css, _defineProperty({}, cssVar, getCssValue(keys, value)));
132
+ if (typeof _value === 'string' && _value.startsWith('var')) {
133
+ // replace the value of the `scope` object with the prefix or remove basePrefix from the value
134
+ _value = prefix ? _value.replace(basePrefix, prefix) : _value.replace("".concat(basePrefix, "-"), ''); // scope is the deepest object in the tree, keys is the theme path keys
117
135
 
118
- assignNestedKeys(vars, keys, "var(".concat(cssVar, ")"));
136
+ scope[keys.slice(-1)[0]] = _value;
137
+ }
138
+
139
+ if (!shouldSkipGeneratingVar || shouldSkipGeneratingVar && !shouldSkipGeneratingVar(keys, _value)) {
140
+ // only create css & var if `shouldSkipGeneratingVar` return false
141
+ var cssVar = "--".concat(prefix ? "".concat(prefix, "-") : '').concat(keys.join('-'));
142
+
143
+ _extends(css, _defineProperty({}, cssVar, getCssValue(keys, _value)));
144
+
145
+ assignNestedKeys(vars, keys, "var(".concat(cssVar, ")"));
146
+ }
119
147
  }
120
148
  });
121
149
  return {
@@ -1,18 +1,26 @@
1
1
  import * as React from 'react';
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
- export var DEFAULT_STORAGE_KEY = 'mui-color-scheme';
3
+ export var DEFAULT_MODE_STORAGE_KEY = 'mui-mode';
4
+ export var DEFAULT_COLOR_SCHEME_STORAGE_KEY = 'mui-color-scheme';
4
5
  export var DEFAULT_ATTRIBUTE = 'data-mui-color-scheme';
5
6
  export default function getInitColorSchemeScript(options) {
6
7
  var _ref = options || {},
7
- _ref$storageKey = _ref.storageKey,
8
- storageKey = _ref$storageKey === void 0 ? DEFAULT_STORAGE_KEY : _ref$storageKey,
8
+ enableSystem = _ref.enableSystem,
9
+ _ref$defaultLightColo = _ref.defaultLightColorScheme,
10
+ defaultLightColorScheme = _ref$defaultLightColo === void 0 ? 'light' : _ref$defaultLightColo,
11
+ _ref$defaultDarkColor = _ref.defaultDarkColorScheme,
12
+ defaultDarkColorScheme = _ref$defaultDarkColor === void 0 ? 'dark' : _ref$defaultDarkColor,
13
+ _ref$modeStorageKey = _ref.modeStorageKey,
14
+ modeStorageKey = _ref$modeStorageKey === void 0 ? DEFAULT_MODE_STORAGE_KEY : _ref$modeStorageKey,
15
+ _ref$colorSchemeStora = _ref.colorSchemeStorageKey,
16
+ colorSchemeStorageKey = _ref$colorSchemeStora === void 0 ? DEFAULT_COLOR_SCHEME_STORAGE_KEY : _ref$colorSchemeStora,
9
17
  _ref$attribute = _ref.attribute,
10
18
  attribute = _ref$attribute === void 0 ? DEFAULT_ATTRIBUTE : _ref$attribute;
11
19
 
12
20
  return /*#__PURE__*/_jsx("script", {
13
21
  // eslint-disable-next-line react/no-danger
14
22
  dangerouslySetInnerHTML: {
15
- __html: "(function() { try {\n var colorScheme = localStorage.getItem('".concat(storageKey, "');\n if (colorScheme) {\n document.body.setAttribute('").concat(attribute, "', colorScheme);\n }\n } catch (e) {} })();")
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.body.setAttribute('").concat(attribute, "', colorScheme);\n }\n } catch (e) {} })();")
16
24
  }
17
25
  });
18
26
  }