2022-03-24 18:44:42 +08:00
import useMemo from 'rc-util/lib/hooks/useMemo' ;
2022-12-27 15:46:51 +08:00
import isEqual from 'rc-util/lib/isEqual' ;
2024-04-01 15:49:45 +08:00
import { devUseWarning } from '../../_util/warning' ;
2022-06-27 14:25:59 +08:00
import type { OverrideToken } from '../../theme/interface' ;
2022-11-23 20:22:38 +08:00
import { defaultConfig } from '../../theme/internal' ;
2024-04-01 15:49:45 +08:00
import type { ThemeConfig } from '../context' ;
2023-11-06 10:31:51 +08:00
import useThemeKey from './useThemeKey' ;
2022-03-24 18:44:42 +08:00
export default function useTheme (
theme? : ThemeConfig ,
parentTheme? : ThemeConfig ,
2024-02-20 09:47:21 +08:00
config ? : {
prefixCls? : string ;
} ,
2022-03-24 18:44:42 +08:00
) : ThemeConfig | undefined {
2023-11-06 10:31:51 +08:00
const warning = devUseWarning ( 'ConfigProvider' ) ;
2022-03-24 18:44:42 +08:00
const themeConfig = theme || { } ;
2022-11-17 00:22:15 +08:00
const parentThemeConfig : ThemeConfig =
2024-02-06 17:38:03 +08:00
themeConfig . inherit === false || ! parentTheme
? {
. . . defaultConfig ,
hashed : parentTheme?.hashed ? ? defaultConfig . hashed ,
cssVar : parentTheme?.cssVar ,
}
: parentTheme ;
2022-03-24 18:44:42 +08:00
2023-11-06 10:31:51 +08:00
const themeKey = useThemeKey ( ) ;
if ( process . env . NODE_ENV !== 'production' ) {
const cssVarEnabled = themeConfig . cssVar || parentThemeConfig . cssVar ;
2023-11-10 10:02:46 +08:00
const validKey = ! ! (
( typeof themeConfig . cssVar === 'object' && themeConfig . cssVar ? . key ) ||
themeKey
) ;
2023-11-06 10:31:51 +08:00
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.' ,
) ;
}
2023-07-27 11:31:38 +08:00
return useMemo < ThemeConfig | undefined > (
2022-03-24 18:44:42 +08:00
( ) = > {
if ( ! theme ) {
return parentTheme ;
}
// Override
2022-10-18 23:18:11 +08:00
const mergedComponents = {
2022-09-15 21:26:04 +08:00
. . . parentThemeConfig . components ,
2022-03-24 18:44:42 +08:00
} ;
2024-04-01 15:49:45 +08:00
( Object . keys ( theme . components || { } ) as ( keyof OverrideToken ) [ ] ) . forEach ( ( componentName ) = > {
2022-10-18 23:18:11 +08:00
mergedComponents [ componentName ] = {
. . . mergedComponents [ componentName ] ,
2022-09-15 21:26:04 +08:00
. . . theme . components ! [ componentName ] ,
2022-03-24 18:44:42 +08:00
} as any ;
} ) ;
2023-11-06 10:31:51 +08:00
const cssVarKey = ` css-var- ${ themeKey . replace ( /:/g , '' ) } ` ;
2023-11-22 09:46:18 +08:00
const mergedCssVar = ( themeConfig . cssVar ? ? parentThemeConfig . cssVar ) && {
2024-02-20 09:47:21 +08:00
prefix : config?.prefixCls , // Same as prefixCls by default
2023-11-10 10:02:46 +08:00
. . . ( typeof parentThemeConfig . cssVar === 'object' ? parentThemeConfig . cssVar : { } ) ,
. . . ( typeof themeConfig . cssVar === 'object' ? themeConfig . cssVar : { } ) ,
key : ( typeof themeConfig . cssVar === 'object' && themeConfig . cssVar ? . key ) || cssVarKey ,
2023-11-06 10:31:51 +08:00
} ;
2022-03-24 18:44:42 +08:00
// Base token
2022-10-18 23:18:11 +08:00
return {
2022-03-24 18:44:42 +08:00
. . . parentThemeConfig ,
. . . themeConfig ,
token : {
. . . parentThemeConfig . token ,
. . . themeConfig . token ,
} ,
2022-10-18 23:18:11 +08:00
components : mergedComponents ,
2023-11-06 10:31:51 +08:00
cssVar : mergedCssVar ,
2022-03-24 18:44:42 +08:00
} ;
} ,
[ themeConfig , parentThemeConfig ] ,
( prev , next ) = >
prev . some ( ( prevTheme , index ) = > {
const nextTheme = next [ index ] ;
2022-12-27 15:46:51 +08:00
return ! isEqual ( prevTheme , nextTheme , true ) ;
2022-03-24 18:44:42 +08:00
} ) ,
) ;
}