From bbc5f6cd6bd0150610d12b25a4d54edbed8558be Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sun, 1 Jan 2023 17:52:24 +0100 Subject: [PATCH] theme: add component style transform for v5 state to v4 Signed-off-by: Patrik Oldsberg --- packages/theme/src/unified/overrides.test.ts | 29 ++++++++++ packages/theme/src/unified/overrides.ts | 58 ++++++++++++++++--- .../theme/src/v5/defaultComponentThemes.ts | 10 ++-- 3 files changed, 84 insertions(+), 13 deletions(-) diff --git a/packages/theme/src/unified/overrides.test.ts b/packages/theme/src/unified/overrides.test.ts index 68fd883168..4cf2fdedf5 100644 --- a/packages/theme/src/unified/overrides.test.ts +++ b/packages/theme/src/unified/overrides.test.ts @@ -135,4 +135,33 @@ describe('transformV5ComponentThemesToV4', () => { }, }); }); + + it('transform state styles', () => { + expect( + transformV5ComponentThemesToV4(mockTheme, { + MuiButton: { + styleOverrides: { + root: { + color: 'green', + '&.Mui-disabled': { + color: 'red', + }, + }, + }, + }, + }), + ).toEqual({ + overrides: { + MuiButton: { + root: { + color: 'green', + }, + disabled: { + color: 'red', + }, + }, + }, + props: {}, + }); + }); }); diff --git a/packages/theme/src/unified/overrides.ts b/packages/theme/src/unified/overrides.ts index a9e080af36..5c5990c65d 100644 --- a/packages/theme/src/unified/overrides.ts +++ b/packages/theme/src/unified/overrides.ts @@ -17,18 +17,26 @@ import { Overrides } from '@material-ui/core/styles/overrides'; import { ComponentsProps } from '@material-ui/core/styles/props'; import { ComponentsOverrides, Theme, ThemeOptions } from '@mui/material/styles'; +import { CSSProperties } from 'react'; type V5Override = ComponentsOverrides[keyof ComponentsOverrides]; type V4Override = Overrides[keyof Overrides]; +type StaticStyleRules = Record< + string, + CSSProperties | Record +>; // Converts callback-based overrides to static styles, e.g. // { root: theme => ({ color: theme.color }) } -> { root: { color: 'red' } } -function adaptV5Override(theme: Theme, overrides: V5Override): V4Override { - if (!overrides) { - return overrides as V4Override; +function adaptV5Override( + theme: Theme, + overrides: V5Override, +): StaticStyleRules | undefined { + if (!overrides || typeof overrides === 'string') { + return undefined; } if (typeof overrides === 'function') { - return overrides(theme) as V4Override; + return overrides(theme) as StaticStyleRules; } if (typeof overrides === 'object') { return Object.fromEntries( @@ -40,7 +48,42 @@ function adaptV5Override(theme: Theme, overrides: V5Override): V4Override { }), ); } - return overrides as V4Override; + return overrides as StaticStyleRules; +} + +const stateStyleKeyPattern = /^&.Mui-([\w-]+)$/; + +// Move state style overrides to the top level, e.g. +// { root: { '&.Mui-active': { color: 'red' } } } -> { active: { color: 'red' } } +function extractV5StateOverrides( + overrides: StaticStyleRules | undefined, +): StaticStyleRules | undefined { + let output = overrides; + if (!overrides || typeof overrides !== 'object') { + return output; + } + for (const className of Object.keys(overrides)) { + const styles = overrides[className]; + if (!styles || typeof styles !== 'object') { + continue; + } + for (const _styleKey of Object.keys(styles)) { + const styleKey = _styleKey as keyof typeof styles; + const match = styleKey.match(stateStyleKeyPattern); + if (match) { + const [, state] = match; + const { [styleKey]: stateStyles, ...restStyles } = styles; + if (stateStyles) { + output = { + ...output, + [className]: restStyles, + [state]: stateStyles, + }; + } + } + } + } + return output; } /** @@ -61,9 +104,8 @@ export function transformV5ComponentThemesToV4( continue; } if ('styleOverrides' in component) { - overrides[name] = adaptV5Override( - theme, - component.styleOverrides as V5Override, + overrides[name] = extractV5StateOverrides( + adaptV5Override(theme, component.styleOverrides as V5Override), ); } if ('defaultProps' in component) { diff --git a/packages/theme/src/v5/defaultComponentThemes.ts b/packages/theme/src/v5/defaultComponentThemes.ts index 288ba819bf..15cba7f6b6 100644 --- a/packages/theme/src/v5/defaultComponentThemes.ts +++ b/packages/theme/src/v5/defaultComponentThemes.ts @@ -139,11 +139,11 @@ export const defaultComponentThemes: ThemeOptions['components'] = { '&:focus': { color: 'inherit', }, - }, - // Bold font for highlighting selected column - active: { - fontWeight: 'bold', - color: 'inherit', + // Bold font for highlighting selected column + '&.Mui-active': { + fontWeight: 'bold', + color: 'inherit', + }, }, }, },