/* eslint-disable no-redeclare */ import type { CSSInterpolation } from '@ant-design/cssinjs'; import { useStyleRegister } from '@ant-design/cssinjs'; import { useContext } from 'react'; import { ConfigContext } from '../../config-provider/context'; import type { UseComponentStyleResult } from '../index'; import { mergeToken, statisticToken, useToken } from '../index'; import type { ComponentTokenMap, GlobalToken } from '../interface'; export type OverrideTokenWithoutDerivative = ComponentTokenMap; export type OverrideComponent = keyof OverrideTokenWithoutDerivative; export type GlobalTokenWithComponent = GlobalToken & ComponentTokenMap[ComponentName]; export interface StyleInfo { hashId: string; prefixCls: string; rootPrefixCls: string; iconPrefixCls: string; } export type TokenWithCommonCls = T & { /** Wrap component class with `.` prefix */ componentCls: string; /** Origin prefix which do not have `.` prefix */ prefixCls: string; /** Wrap icon class with `.` prefix */ iconCls: string; /** Wrap ant prefixCls class with `.` prefix */ antCls: string; }; export type FullToken = TokenWithCommonCls< GlobalTokenWithComponent >; export default function genComponentStyleHook( component: ComponentName, styleFn: (token: FullToken, info: StyleInfo) => CSSInterpolation, getDefaultToken?: | OverrideTokenWithoutDerivative[ComponentName] | ((token: GlobalToken) => OverrideTokenWithoutDerivative[ComponentName]), ) { return (prefixCls: string): UseComponentStyleResult => { const [theme, token, hashId] = useToken(); const { getPrefixCls, iconPrefixCls } = useContext(ConfigContext); const rootPrefixCls = getPrefixCls(); return [ useStyleRegister({ theme, token, hashId, path: [component, prefixCls] }, () => { const { token: proxyToken, flush } = statisticToken(token); const defaultComponentToken = typeof getDefaultToken === 'function' ? getDefaultToken(proxyToken) : getDefaultToken; const overrideComponentToken = token[component] as any; // Only merge token specified in interface const mergedComponentToken = { ...defaultComponentToken } as any; if (overrideComponentToken) { Object.keys(mergedComponentToken).forEach(key => { mergedComponentToken[key] = overrideComponentToken[key] ?? mergedComponentToken[key]; }); } const mergedToken = mergeToken< TokenWithCommonCls> >( proxyToken, { componentCls: `.${prefixCls}`, prefixCls, iconCls: `.${iconPrefixCls}`, antCls: `.${rootPrefixCls}`, }, mergedComponentToken, ); const styleInterpolation = styleFn(mergedToken as unknown as FullToken, { hashId, prefixCls, rootPrefixCls, iconPrefixCls, }); flush(component, mergedComponentToken); return styleInterpolation; }), hashId, ]; }; }