@mui/system 7.0.0-beta.1 → 7.0.0-beta.3

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,40 @@
1
1
  # [Versions](https://mui.com/versions/)
2
2
 
3
+ ## 7.0.0-beta.3
4
+
5
+ <!-- generated comparing v7.0.0-beta.2..master -->
6
+
7
+ _Mar 5, 2025_
8
+
9
+ A big thanks to the 3 contributors who made this release possible.
10
+
11
+ ### `@mui/material@7.0.0-beta.3`
12
+
13
+ - Fix moduleResolution:node for icons (#45444) @Janpot
14
+ - [ThemeProvider] Add `storageManager` prop to `ThemeProvider` (#45136) @siriwatknp
15
+ - [Radio] Fix `inputProps` not forwarded (#45471) @siriwatknp
16
+
17
+ ### `@mui/codemod@7.0.0-beta.3`
18
+
19
+ - [codemod] Fix codemods not found (#45473) @DiegoAndai
20
+
21
+ All contributors of this release in alphabetical order: @DiegoAndai, @Janpot, @siriwatknp
22
+
23
+ ## 7.0.0-beta.2
24
+
25
+ <!-- generated comparing v7.0.0-beta.1..master -->
26
+
27
+ _Feb 27, 2025_
28
+
29
+ A big thanks to the 2 contributors who made this release possible.
30
+
31
+ ### Core
32
+
33
+ - [code-infra] Add package.json export (#45433) @Janpot
34
+ - [blog] React 19 migration for MUI X (#45348) @arminmeh
35
+
36
+ All contributors of this release in alphabetical order: @arminmeh, @Janpot
37
+
3
38
  ## 7.0.0-beta.1
4
39
 
5
40
  <!-- generated comparing v7.0.0-beta.0..master -->
@@ -1,6 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import InitColorSchemeScript from "../InitColorSchemeScript/index.js";
3
3
  import { Result } from "./useCurrentColorScheme.js";
4
+ import type { StorageManager } from "./localStorageManager.js";
4
5
  export interface ColorSchemeContextValue<SupportedColorScheme extends string> extends Result<SupportedColorScheme> {
5
6
  allColorSchemes: SupportedColorScheme[];
6
7
  }
@@ -60,6 +61,11 @@ export interface CreateCssVarsProviderResult<ColorScheme extends string, Identif
60
61
  * @default document
61
62
  */
62
63
  colorSchemeNode?: Element | null;
64
+ /**
65
+ * The storage manager to be used for storing the mode and color scheme.
66
+ * @default using `window.localStorage`
67
+ */
68
+ storageManager?: StorageManager | null;
63
69
  /**
64
70
  * The window that attaches the 'storage' event listener
65
71
  * @default window
@@ -58,6 +58,7 @@ function createCssVarsProvider(options) {
58
58
  modeStorageKey = defaultModeStorageKey,
59
59
  colorSchemeStorageKey = defaultColorSchemeStorageKey,
60
60
  disableTransitionOnChange = designSystemTransitionOnChange,
61
+ storageManager,
61
62
  storageWindow = typeof window === 'undefined' ? undefined : window,
62
63
  documentNode = typeof document === 'undefined' ? undefined : document,
63
64
  colorSchemeNode = typeof document === 'undefined' ? undefined : document.documentElement,
@@ -105,6 +106,7 @@ function createCssVarsProvider(options) {
105
106
  modeStorageKey,
106
107
  colorSchemeStorageKey,
107
108
  defaultMode,
109
+ storageManager,
108
110
  storageWindow,
109
111
  noSsr
110
112
  });
@@ -299,6 +301,11 @@ function createCssVarsProvider(options) {
299
301
  * You should use this option in conjuction with `InitColorSchemeScript` component.
300
302
  */
301
303
  noSsr: _propTypes.default.bool,
304
+ /**
305
+ * The storage manager to be used for storing the mode and color scheme
306
+ * @default using `window.localStorage`
307
+ */
308
+ storageManager: _propTypes.default.func,
302
309
  /**
303
310
  * The window that attaches the 'storage' event listener.
304
311
  * @default window
@@ -4,4 +4,5 @@ export { default as prepareCssVars } from "./prepareCssVars.js";
4
4
  export { default as prepareTypographyVars } from "./prepareTypographyVars.js";
5
5
  export type { ExtractTypographyTokens } from "./prepareTypographyVars.js";
6
6
  export { default as createCssVarsTheme } from "./createCssVarsTheme.js";
7
- export { createGetColorSchemeSelector } from "./getColorSchemeSelector.js";
7
+ export { createGetColorSchemeSelector } from "./getColorSchemeSelector.js";
8
+ export type { StorageManager } from "./localStorageManager.js";
@@ -0,0 +1,34 @@
1
+ export interface StorageManager {
2
+ (options: {
3
+ key: string;
4
+ storageWindow?: Window | null;
5
+ }): {
6
+ /**
7
+ * Function to get the value from the storage
8
+ * @param defaultValue The default value to be returned if the key is not found
9
+ * @returns The value from the storage or the default value
10
+ */
11
+ get(defaultValue: any): any;
12
+ /**
13
+ * Function to set the value in the storage
14
+ * @param value The value to be set
15
+ * @returns void
16
+ */
17
+ set(value: any): void;
18
+ /**
19
+ * Function to subscribe to the value of the specified key triggered by external events
20
+ * @param handler The function to be called when the value changes
21
+ * @returns A function to unsubscribe the handler
22
+ * @example
23
+ * React.useEffect(() => {
24
+ * const unsubscribe = storageManager.subscribe((value) => {
25
+ * console.log(value);
26
+ * });
27
+ * return unsubscribe;
28
+ * }, []);
29
+ */
30
+ subscribe(handler: (value: any) => void): () => void;
31
+ };
32
+ }
33
+ declare const localStorageManager: StorageManager;
34
+ export default localStorageManager;
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ function noop() {}
8
+ const localStorageManager = ({
9
+ key,
10
+ storageWindow
11
+ }) => {
12
+ if (!storageWindow && typeof window !== 'undefined') {
13
+ storageWindow = window;
14
+ }
15
+ return {
16
+ get(defaultValue) {
17
+ if (typeof window === 'undefined') {
18
+ return undefined;
19
+ }
20
+ if (!storageWindow) {
21
+ return defaultValue;
22
+ }
23
+ let value;
24
+ try {
25
+ value = storageWindow.localStorage.getItem(key);
26
+ } catch {
27
+ // Unsupported
28
+ }
29
+ return value || defaultValue;
30
+ },
31
+ set: value => {
32
+ if (storageWindow) {
33
+ try {
34
+ storageWindow.localStorage.setItem(key, value);
35
+ } catch {
36
+ // Unsupported
37
+ }
38
+ }
39
+ },
40
+ subscribe: handler => {
41
+ if (!storageWindow) {
42
+ return noop;
43
+ }
44
+ const listener = event => {
45
+ const value = event.newValue;
46
+ if (event.key === key) {
47
+ handler(value);
48
+ }
49
+ };
50
+ storageWindow.addEventListener('storage', listener);
51
+ return () => {
52
+ storageWindow.removeEventListener('storage', listener);
53
+ };
54
+ }
55
+ };
56
+ };
57
+ var _default = exports.default = localStorageManager;
@@ -1,3 +1,4 @@
1
+ import type { StorageManager } from "./localStorageManager.js";
1
2
  export type Mode = 'light' | 'dark' | 'system';
2
3
  export type SystemMode = Exclude<Mode, 'system'>;
3
4
  export interface State<SupportedColorScheme extends string> {
@@ -48,6 +49,7 @@ interface UseCurrentColoSchemeOptions<SupportedColorScheme extends string> {
48
49
  modeStorageKey?: string;
49
50
  colorSchemeStorageKey?: string;
50
51
  storageWindow?: Window | null;
52
+ storageManager?: StorageManager | null;
51
53
  noSsr?: boolean;
52
54
  }
53
55
  export default function useCurrentColorScheme<SupportedColorScheme extends string>(options: UseCurrentColoSchemeOptions<SupportedColorScheme>): Result<SupportedColorScheme>;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  'use client';
3
3
 
4
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
4
5
  var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
5
6
  Object.defineProperty(exports, "__esModule", {
6
7
  value: true
@@ -10,6 +11,8 @@ exports.getColorScheme = getColorScheme;
10
11
  exports.getSystemMode = getSystemMode;
11
12
  var React = _interopRequireWildcard(require("react"));
12
13
  var _InitColorSchemeScript = require("../InitColorSchemeScript/InitColorSchemeScript");
14
+ var _localStorageManager = _interopRequireDefault(require("./localStorageManager"));
15
+ function noop() {}
13
16
  function getSystemMode(mode) {
14
17
  if (typeof window !== 'undefined' && typeof window.matchMedia === 'function' && mode === 'system') {
15
18
  const mql = window.matchMedia('(prefers-color-scheme: dark)');
@@ -40,22 +43,6 @@ function getColorScheme(state) {
40
43
  return undefined;
41
44
  });
42
45
  }
43
- function initializeValue(key, defaultValue) {
44
- if (typeof window === 'undefined') {
45
- return undefined;
46
- }
47
- let value;
48
- try {
49
- value = localStorage.getItem(key) || undefined;
50
- if (!value) {
51
- // the first time that user enters the site.
52
- localStorage.setItem(key, defaultValue);
53
- }
54
- } catch {
55
- // Unsupported
56
- }
57
- return value || defaultValue;
58
- }
59
46
  function useCurrentColorScheme(options) {
60
47
  const {
61
48
  defaultMode = 'light',
@@ -65,14 +52,27 @@ function useCurrentColorScheme(options) {
65
52
  modeStorageKey = _InitColorSchemeScript.DEFAULT_MODE_STORAGE_KEY,
66
53
  colorSchemeStorageKey = _InitColorSchemeScript.DEFAULT_COLOR_SCHEME_STORAGE_KEY,
67
54
  storageWindow = typeof window === 'undefined' ? undefined : window,
55
+ storageManager = _localStorageManager.default,
68
56
  noSsr = false
69
57
  } = options;
70
58
  const joinedColorSchemes = supportedColorSchemes.join(',');
71
59
  const isMultiSchemes = supportedColorSchemes.length > 1;
60
+ const modeStorage = React.useMemo(() => storageManager?.({
61
+ key: modeStorageKey,
62
+ storageWindow
63
+ }), [storageManager, modeStorageKey, storageWindow]);
64
+ const lightStorage = React.useMemo(() => storageManager?.({
65
+ key: `${colorSchemeStorageKey}-light`,
66
+ storageWindow
67
+ }), [storageManager, colorSchemeStorageKey, storageWindow]);
68
+ const darkStorage = React.useMemo(() => storageManager?.({
69
+ key: `${colorSchemeStorageKey}-dark`,
70
+ storageWindow
71
+ }), [storageManager, colorSchemeStorageKey, storageWindow]);
72
72
  const [state, setState] = React.useState(() => {
73
- const initialMode = initializeValue(modeStorageKey, defaultMode);
74
- const lightColorScheme = initializeValue(`${colorSchemeStorageKey}-light`, defaultLightColorScheme);
75
- const darkColorScheme = initializeValue(`${colorSchemeStorageKey}-dark`, defaultDarkColorScheme);
73
+ const initialMode = modeStorage?.get(defaultMode) || defaultMode;
74
+ const lightColorScheme = lightStorage?.get(defaultLightColorScheme) || defaultLightColorScheme;
75
+ const darkColorScheme = darkStorage?.get(defaultDarkColorScheme) || defaultDarkColorScheme;
76
76
  return {
77
77
  mode: initialMode,
78
78
  systemMode: getSystemMode(initialMode),
@@ -92,27 +92,19 @@ function useCurrentColorScheme(options) {
92
92
  return currentState;
93
93
  }
94
94
  const newMode = mode ?? defaultMode;
95
- try {
96
- localStorage.setItem(modeStorageKey, newMode);
97
- } catch {
98
- // Unsupported
99
- }
95
+ modeStorage?.set(newMode);
100
96
  return {
101
97
  ...currentState,
102
98
  mode: newMode,
103
99
  systemMode: getSystemMode(newMode)
104
100
  };
105
101
  });
106
- }, [modeStorageKey, defaultMode]);
102
+ }, [modeStorage, defaultMode]);
107
103
  const setColorScheme = React.useCallback(value => {
108
104
  if (!value) {
109
105
  setState(currentState => {
110
- try {
111
- localStorage.setItem(`${colorSchemeStorageKey}-light`, defaultLightColorScheme);
112
- localStorage.setItem(`${colorSchemeStorageKey}-dark`, defaultDarkColorScheme);
113
- } catch {
114
- // Unsupported
115
- }
106
+ lightStorage?.set(defaultLightColorScheme);
107
+ darkStorage?.set(defaultDarkColorScheme);
116
108
  return {
117
109
  ...currentState,
118
110
  lightColorScheme: defaultLightColorScheme,
@@ -128,15 +120,12 @@ function useCurrentColorScheme(options) {
128
120
  ...currentState
129
121
  };
130
122
  processState(currentState, mode => {
131
- try {
132
- localStorage.setItem(`${colorSchemeStorageKey}-${mode}`, value);
133
- } catch {
134
- // Unsupported
135
- }
136
123
  if (mode === 'light') {
124
+ lightStorage?.set(value);
137
125
  newState.lightColorScheme = value;
138
126
  }
139
127
  if (mode === 'dark') {
128
+ darkStorage?.set(value);
140
129
  newState.darkColorScheme = value;
141
130
  }
142
131
  });
@@ -155,11 +144,7 @@ function useCurrentColorScheme(options) {
155
144
  console.error(`\`${newLightColorScheme}\` does not exist in \`theme.colorSchemes\`.`);
156
145
  } else {
157
146
  newState.lightColorScheme = newLightColorScheme;
158
- try {
159
- localStorage.setItem(`${colorSchemeStorageKey}-light`, newLightColorScheme);
160
- } catch (error) {
161
- // Unsupported
162
- }
147
+ lightStorage?.set(newLightColorScheme);
163
148
  }
164
149
  }
165
150
  if (newDarkColorScheme) {
@@ -167,17 +152,13 @@ function useCurrentColorScheme(options) {
167
152
  console.error(`\`${newDarkColorScheme}\` does not exist in \`theme.colorSchemes\`.`);
168
153
  } else {
169
154
  newState.darkColorScheme = newDarkColorScheme;
170
- try {
171
- localStorage.setItem(`${colorSchemeStorageKey}-dark`, newDarkColorScheme);
172
- } catch (error) {
173
- // Unsupported
174
- }
155
+ darkStorage?.set(newDarkColorScheme);
175
156
  }
176
157
  }
177
158
  return newState;
178
159
  });
179
160
  }
180
- }, [joinedColorSchemes, colorSchemeStorageKey, defaultLightColorScheme, defaultDarkColorScheme]);
161
+ }, [joinedColorSchemes, lightStorage, darkStorage, defaultLightColorScheme, defaultDarkColorScheme]);
181
162
  const handleMediaQuery = React.useCallback(event => {
182
163
  if (state.mode === 'system') {
183
164
  setState(currentState => {
@@ -217,34 +198,34 @@ function useCurrentColorScheme(options) {
217
198
 
218
199
  // Handle when localStorage has changed
219
200
  React.useEffect(() => {
220
- if (storageWindow && isMultiSchemes) {
221
- const handleStorage = event => {
222
- const value = event.newValue;
223
- if (typeof event.key === 'string' && event.key.startsWith(colorSchemeStorageKey) && (!value || joinedColorSchemes.match(value))) {
224
- // If the key is deleted, value will be null then reset color scheme to the default one.
225
- if (event.key.endsWith('light')) {
226
- setColorScheme({
227
- light: value
228
- });
229
- }
230
- if (event.key.endsWith('dark')) {
231
- setColorScheme({
232
- dark: value
233
- });
234
- }
235
- }
236
- if (event.key === modeStorageKey && (!value || ['light', 'dark', 'system'].includes(value))) {
201
+ if (isMultiSchemes) {
202
+ const unsubscribeMode = modeStorage?.subscribe(value => {
203
+ if (!value || ['light', 'dark', 'system'].includes(value)) {
237
204
  setMode(value || defaultMode);
238
205
  }
239
- };
240
- // For syncing color-scheme changes between iframes
241
- storageWindow.addEventListener('storage', handleStorage);
206
+ }) || noop;
207
+ const unsubscribeLight = lightStorage?.subscribe(value => {
208
+ if (!value || joinedColorSchemes.match(value)) {
209
+ setColorScheme({
210
+ light: value
211
+ });
212
+ }
213
+ }) || noop;
214
+ const unsubscribeDark = darkStorage?.subscribe(value => {
215
+ if (!value || joinedColorSchemes.match(value)) {
216
+ setColorScheme({
217
+ dark: value
218
+ });
219
+ }
220
+ }) || noop;
242
221
  return () => {
243
- storageWindow.removeEventListener('storage', handleStorage);
222
+ unsubscribeMode();
223
+ unsubscribeLight();
224
+ unsubscribeDark();
244
225
  };
245
226
  }
246
227
  return undefined;
247
- }, [setColorScheme, setMode, modeStorageKey, colorSchemeStorageKey, joinedColorSchemes, defaultMode, storageWindow, isMultiSchemes]);
228
+ }, [setColorScheme, setMode, joinedColorSchemes, defaultMode, storageWindow, isMultiSchemes, modeStorage, lightStorage, darkStorage]);
248
229
  return {
249
230
  ...state,
250
231
  mode: isClient ? state.mode : undefined,
@@ -1,6 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import InitColorSchemeScript from "../InitColorSchemeScript/index.js";
3
3
  import { Result } from "./useCurrentColorScheme.js";
4
+ import type { StorageManager } from "./localStorageManager.js";
4
5
  export interface ColorSchemeContextValue<SupportedColorScheme extends string> extends Result<SupportedColorScheme> {
5
6
  allColorSchemes: SupportedColorScheme[];
6
7
  }
@@ -60,6 +61,11 @@ export interface CreateCssVarsProviderResult<ColorScheme extends string, Identif
60
61
  * @default document
61
62
  */
62
63
  colorSchemeNode?: Element | null;
64
+ /**
65
+ * The storage manager to be used for storing the mode and color scheme.
66
+ * @default using `window.localStorage`
67
+ */
68
+ storageManager?: StorageManager | null;
63
69
  /**
64
70
  * The window that attaches the 'storage' event listener
65
71
  * @default window
@@ -50,6 +50,7 @@ export default function createCssVarsProvider(options) {
50
50
  modeStorageKey = defaultModeStorageKey,
51
51
  colorSchemeStorageKey = defaultColorSchemeStorageKey,
52
52
  disableTransitionOnChange = designSystemTransitionOnChange,
53
+ storageManager,
53
54
  storageWindow = typeof window === 'undefined' ? undefined : window,
54
55
  documentNode = typeof document === 'undefined' ? undefined : document,
55
56
  colorSchemeNode = typeof document === 'undefined' ? undefined : document.documentElement,
@@ -97,6 +98,7 @@ export default function createCssVarsProvider(options) {
97
98
  modeStorageKey,
98
99
  colorSchemeStorageKey,
99
100
  defaultMode,
101
+ storageManager,
100
102
  storageWindow,
101
103
  noSsr
102
104
  });
@@ -291,6 +293,11 @@ export default function createCssVarsProvider(options) {
291
293
  * You should use this option in conjuction with `InitColorSchemeScript` component.
292
294
  */
293
295
  noSsr: PropTypes.bool,
296
+ /**
297
+ * The storage manager to be used for storing the mode and color scheme
298
+ * @default using `window.localStorage`
299
+ */
300
+ storageManager: PropTypes.func,
294
301
  /**
295
302
  * The window that attaches the 'storage' event listener.
296
303
  * @default window
@@ -4,4 +4,5 @@ export { default as prepareCssVars } from "./prepareCssVars.js";
4
4
  export { default as prepareTypographyVars } from "./prepareTypographyVars.js";
5
5
  export type { ExtractTypographyTokens } from "./prepareTypographyVars.js";
6
6
  export { default as createCssVarsTheme } from "./createCssVarsTheme.js";
7
- export { createGetColorSchemeSelector } from "./getColorSchemeSelector.js";
7
+ export { createGetColorSchemeSelector } from "./getColorSchemeSelector.js";
8
+ export type { StorageManager } from "./localStorageManager.js";
@@ -0,0 +1,34 @@
1
+ export interface StorageManager {
2
+ (options: {
3
+ key: string;
4
+ storageWindow?: Window | null;
5
+ }): {
6
+ /**
7
+ * Function to get the value from the storage
8
+ * @param defaultValue The default value to be returned if the key is not found
9
+ * @returns The value from the storage or the default value
10
+ */
11
+ get(defaultValue: any): any;
12
+ /**
13
+ * Function to set the value in the storage
14
+ * @param value The value to be set
15
+ * @returns void
16
+ */
17
+ set(value: any): void;
18
+ /**
19
+ * Function to subscribe to the value of the specified key triggered by external events
20
+ * @param handler The function to be called when the value changes
21
+ * @returns A function to unsubscribe the handler
22
+ * @example
23
+ * React.useEffect(() => {
24
+ * const unsubscribe = storageManager.subscribe((value) => {
25
+ * console.log(value);
26
+ * });
27
+ * return unsubscribe;
28
+ * }, []);
29
+ */
30
+ subscribe(handler: (value: any) => void): () => void;
31
+ };
32
+ }
33
+ declare const localStorageManager: StorageManager;
34
+ export default localStorageManager;
@@ -0,0 +1,51 @@
1
+ function noop() {}
2
+ const localStorageManager = ({
3
+ key,
4
+ storageWindow
5
+ }) => {
6
+ if (!storageWindow && typeof window !== 'undefined') {
7
+ storageWindow = window;
8
+ }
9
+ return {
10
+ get(defaultValue) {
11
+ if (typeof window === 'undefined') {
12
+ return undefined;
13
+ }
14
+ if (!storageWindow) {
15
+ return defaultValue;
16
+ }
17
+ let value;
18
+ try {
19
+ value = storageWindow.localStorage.getItem(key);
20
+ } catch {
21
+ // Unsupported
22
+ }
23
+ return value || defaultValue;
24
+ },
25
+ set: value => {
26
+ if (storageWindow) {
27
+ try {
28
+ storageWindow.localStorage.setItem(key, value);
29
+ } catch {
30
+ // Unsupported
31
+ }
32
+ }
33
+ },
34
+ subscribe: handler => {
35
+ if (!storageWindow) {
36
+ return noop;
37
+ }
38
+ const listener = event => {
39
+ const value = event.newValue;
40
+ if (event.key === key) {
41
+ handler(value);
42
+ }
43
+ };
44
+ storageWindow.addEventListener('storage', listener);
45
+ return () => {
46
+ storageWindow.removeEventListener('storage', listener);
47
+ };
48
+ }
49
+ };
50
+ };
51
+ export default localStorageManager;
@@ -1,3 +1,4 @@
1
+ import type { StorageManager } from "./localStorageManager.js";
1
2
  export type Mode = 'light' | 'dark' | 'system';
2
3
  export type SystemMode = Exclude<Mode, 'system'>;
3
4
  export interface State<SupportedColorScheme extends string> {
@@ -48,6 +49,7 @@ interface UseCurrentColoSchemeOptions<SupportedColorScheme extends string> {
48
49
  modeStorageKey?: string;
49
50
  colorSchemeStorageKey?: string;
50
51
  storageWindow?: Window | null;
52
+ storageManager?: StorageManager | null;
51
53
  noSsr?: boolean;
52
54
  }
53
55
  export default function useCurrentColorScheme<SupportedColorScheme extends string>(options: UseCurrentColoSchemeOptions<SupportedColorScheme>): Result<SupportedColorScheme>;