Skip to content

Commit

Permalink
[system] Remove unnecessary parsed theme (mui#35239)
Browse files Browse the repository at this point in the history
  • Loading branch information
siriwatknp authored and felipe.richter committed Dec 6, 2022
1 parent 9d085eb commit f33d632
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 101 deletions.
19 changes: 12 additions & 7 deletions packages/mui-system/src/cssVars/createCssVarsProvider.d.ts
Expand Up @@ -89,7 +89,7 @@ export default function createCssVarsProvider<ColorScheme extends string>(
/**
* Design system default theme
*
* The structure inside `theme.colorSchemes[colorScheme]` should be exactly the same in all color schemes because
* - The structure inside `theme.colorSchemes[colorScheme]` should be exactly the same in all color schemes because
* those object of the color scheme will be used when the color scheme is active.
*
* {
Expand All @@ -99,16 +99,21 @@ export default function createCssVarsProvider<ColorScheme extends string>(
* }
* }
*
* If colorScheme is 'light', the `lightColorSchemeValues` will be merged to theme as `{ ...theme, ...lightColorSchemeValues }`
* likewise, if colorScheme is 'dark', the `darkColorSchemeValues` will be merged to theme as `{ ...theme, ...darkColorSchemeValues }`
* - If colorScheme is 'light', the `lightColorSchemeValues` will be merged to theme as `{ ...theme, ...lightColorSchemeValues }`
* likewise, if colorScheme is 'dark', the `darkColorSchemeValues` will be merged to theme as `{ ...theme, ...darkColorSchemeValues }`
*
* !!! Don't provided the same keys as in colorSchemes to theme because they will be replaced internally when the selected colorScheme is calculated.
* - If the theme contains the same keys as the color scheme, their values will be merged.
* Ex. {
* colorSchemes: {
* light: { palette: { ... } },
* dark: { palette: { ... } }
* light: { palette: { primary: { ... } } },
* dark: { palette: { primary: { ...} } }
* },
* palette: { ... }, // This values will be replaced by the `palette` from the light | dark color scheme at runtime.
* palette: { shared: { ... } }
* }
*
* becomes: {
* colorSchemes: { ... },
* palette: { shared: { ... }, primary: { ... } }
* }
*/
theme: any;
Expand Down
25 changes: 10 additions & 15 deletions packages/mui-system/src/cssVars/createCssVarsProvider.js
Expand Up @@ -116,15 +116,14 @@ export default function createCssVarsProvider(options) {
})();

// 2. Create CSS variables and store them in objects (to be generated in stylesheets in the final step)
const {
css: rootCss,
vars: rootVars,
parsedTheme,
} = cssVarsParser(restThemeProp, { prefix: cssVarPrefix, shouldSkipGeneratingVar });
const { css: rootCss, vars: rootVars } = cssVarsParser(restThemeProp, {
prefix: cssVarPrefix,
shouldSkipGeneratingVar,
});

// 3. Start composing the theme object
const theme = {
...parsedTheme,
...restThemeProp,
components,
colorSchemes,
cssVarPrefix,
Expand All @@ -138,26 +137,22 @@ export default function createCssVarsProvider(options) {
const defaultColorSchemeStyleSheet = {};
const otherColorSchemesStyleSheet = {};
Object.entries(colorSchemes).forEach(([key, scheme]) => {
const {
css,
vars,
parsedTheme: parsedScheme,
} = cssVarsParser(scheme, {
const { css, vars } = cssVarsParser(scheme, {
prefix: cssVarPrefix,
shouldSkipGeneratingVar,
});
theme.vars = deepmerge(theme.vars, vars);
if (key === calculatedColorScheme) {
// 4.1 Merge the selected color scheme to the theme
Object.keys(parsedScheme).forEach((schemeKey) => {
if (parsedScheme[schemeKey] && typeof parsedScheme[schemeKey] === 'object') {
Object.keys(scheme).forEach((schemeKey) => {
if (scheme[schemeKey] && typeof scheme[schemeKey] === 'object') {
// shallow merge the 1st level structure of the theme.
theme[schemeKey] = {
...theme[schemeKey],
...parsedScheme[schemeKey],
...scheme[schemeKey],
};
} else {
theme[schemeKey] = parsedScheme[schemeKey];
theme[schemeKey] = scheme[schemeKey];
}
});
if (theme.palette) {
Expand Down
73 changes: 0 additions & 73 deletions packages/mui-system/src/cssVars/cssVarsParser.test.ts
Expand Up @@ -359,79 +359,6 @@ describe('cssVarsParser', () => {
});
});

describe('parsedObject', () => {
it('creates a new object on every call', () => {
const theme = {
primary: {
500: '#ffffff',
main: 'var(--palette-500)',
},
};
const { parsedTheme } = cssVarsParser(theme, { prefix: 'foo' });
const { parsedTheme: parsedTheme2 } = cssVarsParser(theme, { prefix: 'bar' });
expect(theme).not.to.equal(parsedTheme);
expect(parsedTheme).to.deep.equal({
primary: {
500: '#ffffff',
main: 'var(--palette-500)',
},
});
expect(parsedTheme2).to.deep.equal({
primary: {
500: '#ffffff',
main: 'var(--palette-500)',
},
});
expect(parsedTheme).not.to.equal(parsedTheme2);
});

it('preserve array even if the key is listed in `shouldSkipGeneratingVar`', () => {
const theme = {
breakpoints: {
keys: ['xs', 'sm', 'md', 'lg', 'xl'],
},
};
const { parsedTheme } = cssVarsParser(theme, {
shouldSkipGeneratingVar: (keys) => keys[0] === 'breakpoints',
});
expect(parsedTheme.breakpoints.keys).to.deep.equal(['xs', 'sm', 'md', 'lg', 'xl']);
});

it('preserve function value', () => {
const theme = {
palette: {
getContrastText: () => 'foo',
},
pxToRem: (px: number) => `${px / 16}rem`,
};
const { parsedTheme } = cssVarsParser(theme);
expect(parsedTheme.palette.getContrastText()).to.equal('foo');
expect(parsedTheme.pxToRem(16)).to.equal('1rem');
});

it('all key,values remains in parsedTheme even shouldSkipGeneratingVar is provided', () => {
const { parsedTheme } = cssVarsParser(
{
pxToRem: (px: number) => `${px / 16}rem`,
typography: {
body: {
fontSize: 'var(--fontSize-md)',
fontFamily: 'Roboto, var(--fontFamily-fallback)',
},
},
},
{ prefix: 'foo', shouldSkipGeneratingVar: (keys) => keys[0] === 'typgoraphy' },
);
expect(parsedTheme.pxToRem(14)).to.equal('0.875rem');
expect(parsedTheme.typography).to.deep.equal({
body: {
fontSize: 'var(--fontSize-md)',
fontFamily: 'Roboto, var(--fontFamily-fallback)',
},
});
});
});

it('does nothing if deep value is not string or number', () => {
const { css, vars } = cssVarsParser({
fooBar: () => '',
Expand Down
9 changes: 3 additions & 6 deletions packages/mui-system/src/cssVars/cssVarsParser.ts
Expand Up @@ -107,18 +107,17 @@ const getCssValue = (keys: string[], value: string | number) => {
* }} options.
* `prefix`: The prefix of the generated CSS variables. This function does not change the value.
*
* @returns {{ css: Object, vars: Object, parsedTheme: typeof theme }} `css` is the stylesheet, `vars` is an object to get css variable (same structure as theme), and `parsedTheme` is the cloned version of theme.
* @returns {{ css: Object, vars: Object }} `css` is the stylesheet, `vars` is an object to get css variable (same structure as theme).
*
* @example
* const { css, vars, parsedTheme } = parser({
* const { css, vars } = parser({
* fontSize: 12,
* lineHeight: 1.2,
* palette: { primary: { 500: 'var(--color)' } }
* }, { prefix: 'foo' })
*
* console.log(css) // { '--foo-fontSize': '12px', '--foo-lineHeight': 1.2, '--foo-palette-primary-500': 'var(--color)' }
* console.log(vars) // { fontSize: 'var(--foo-fontSize)', lineHeight: 'var(--foo-lineHeight)', palette: { primary: { 500: 'var(--foo-palette-primary-500)' } } }
* console.log(parsedTheme) // { fontSize: 12, lineHeight: 1.2, palette: { primary: { 500: 'var(--color)' } } }
*/
export default function cssVarsParser<T extends Record<string, any>>(
theme: T,
Expand All @@ -130,7 +129,6 @@ export default function cssVarsParser<T extends Record<string, any>>(
const { prefix, shouldSkipGeneratingVar } = options || {};
const css = {} as Record<string, string | number>;
const vars = {} as NestedRecord<string>;
const parsedTheme = {} as T;

walkObjectDeep(
theme,
Expand All @@ -144,10 +142,9 @@ export default function cssVarsParser<T extends Record<string, any>>(
assignNestedKeys(vars, keys, `var(${cssVar})`, arrayKeys);
}
}
assignNestedKeys(parsedTheme, keys, value, arrayKeys);
},
(keys) => keys[0] === 'vars', // skip 'vars/*' paths
);

return { css, vars, parsedTheme };
return { css, vars };
}

0 comments on commit f33d632

Please sign in to comment.