ant-design/components/config-provider/hooks/useTheme.ts
MadCcc 5f1dd427df
feat: css var (#45589)
* feat: css variables theme

* chore: temp

* chore temp

* chore: temp

* chore: temp

* chore: tmp

* chore: temp

* feat: full css variables

* feat: css var

* chore: code clean

* chore: code clean

* chore: bump cssinjs

* test: fix lint

* feat: better key logic

* feat: useStyle add param rootCls for cssVar scope

* chore: fix lint

* chore: code clean

* chore: fix lint

* perf: minimize component token size

* chore: make useId compatible

* chore: code clean

* chore: fix lint

* chore: code clean

* chore: update test case

* feat: genCSSVarRegister

* feat: RPN Calculator

* chore: add test for css var

* chore: code clean

* test: add test for calc

* feat: better calc type

* chore: code clean

* chore: update size limit

* feat: better useCSSVar

* chore: better useCSSVar

* test: add cov

* feat: better calc logic

* test: add test case

* chore: code clean

---------

Signed-off-by: MadCcc <madccc@foxmail.com>
2023-11-06 10:31:51 +08:00

79 lines
2.3 KiB
TypeScript

import useMemo from 'rc-util/lib/hooks/useMemo';
import isEqual from 'rc-util/lib/isEqual';
import type { OverrideToken } from '../../theme/interface';
import type { ThemeConfig } from '../context';
import { defaultConfig } from '../../theme/internal';
import useThemeKey from './useThemeKey';
import { devUseWarning } from '../../_util/warning';
export default function useTheme(
theme?: ThemeConfig,
parentTheme?: ThemeConfig,
): ThemeConfig | undefined {
const warning = devUseWarning('ConfigProvider');
const themeConfig = theme || {};
const parentThemeConfig: ThemeConfig =
themeConfig.inherit === false || !parentTheme ? defaultConfig : parentTheme;
const themeKey = useThemeKey();
if (process.env.NODE_ENV !== 'production') {
const cssVarEnabled = themeConfig.cssVar || parentThemeConfig.cssVar;
const validKey = !!(themeConfig.cssVar?.key || themeKey);
warning(
!cssVarEnabled || validKey,
'breaking',
'Missing key in `cssVar` config. Please upgrade to React 18 or set `cssVar.key` manually in each ConfigProvider inside `cssVar` enabled ConfigProvider.',
);
}
return useMemo<ThemeConfig | undefined>(
() => {
if (!theme) {
return parentTheme;
}
// Override
const mergedComponents = {
...parentThemeConfig.components,
};
Object.keys(theme.components || {}).forEach((componentName: keyof OverrideToken) => {
mergedComponents[componentName] = {
...mergedComponents[componentName],
...theme.components![componentName],
} as any;
});
const cssVarKey = `css-var-${themeKey.replace(/:/g, '')}`;
const mergedCssVar = (themeConfig.cssVar || parentThemeConfig.cssVar) && {
prefix: 'antd', // Default to antd
...parentThemeConfig.cssVar,
...themeConfig.cssVar,
key: themeConfig.cssVar?.key || cssVarKey,
};
// Base token
return {
...parentThemeConfig,
...themeConfig,
token: {
...parentThemeConfig.token,
...themeConfig.token,
},
components: mergedComponents,
cssVar: mergedCssVar,
};
},
[themeConfig, parentThemeConfig],
(prev, next) =>
prev.some((prevTheme, index) => {
const nextTheme = next[index];
return !isEqual(prevTheme, nextTheme, true);
}),
);
}