ant-design/components/_util/theme/util/genComponentStyleHook.ts

91 lines
3.2 KiB
TypeScript
Raw Normal View History

/* eslint-disable no-redeclare */
2022-05-09 22:20:07 +08:00
import type { CSSInterpolation } from '@ant-design/cssinjs';
import { useStyleRegister } from '@ant-design/cssinjs';
import { useContext } from 'react';
2022-05-09 22:20:07 +08:00
import type { GlobalToken, OverrideToken } from '../interface';
import type { UseComponentStyleResult } from '../index';
import { mergeToken, statisticToken, useToken } from '../index';
import { ConfigContext } from '../../../config-provider';
export type OverrideTokenWithoutDerivative = Omit<OverrideToken, 'derivative'>;
export type OverrideComponent = keyof OverrideTokenWithoutDerivative;
export type GlobalTokenWithComponent<ComponentName extends OverrideComponent> = GlobalToken &
OverrideToken[ComponentName];
export interface StyleInfo {
hashId: string;
prefixCls: string;
rootPrefixCls: string;
iconPrefixCls: string;
}
2022-04-07 00:19:37 +08:00
export type TokenWithCommonCls<T> = 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 */
2022-04-07 00:19:37 +08:00
antCls: string;
};
2022-04-07 00:19:37 +08:00
export type FullToken<ComponentName extends OverrideComponent> = TokenWithCommonCls<
GlobalTokenWithComponent<ComponentName>
>;
function genComponentStyleHook<ComponentName extends OverrideComponent>(
component: ComponentName,
styleFn: (token: FullToken<ComponentName>, info: StyleInfo) => CSSInterpolation,
getDefaultToken?:
| OverrideTokenWithoutDerivative[ComponentName]
| ((token: GlobalToken) => OverrideTokenWithoutDerivative[ComponentName]),
) {
return (prefixCls: string): UseComponentStyleResult => {
const [theme, token, hashId] = useToken();
const { getPrefixCls, iconPrefixCls } = useContext(ConfigContext);
2022-04-07 00:19:37 +08:00
const rootPrefixCls = getPrefixCls();
return [
2022-04-28 18:32:33 +08:00
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<
2022-04-07 00:19:37 +08:00
TokenWithCommonCls<GlobalTokenWithComponent<OverrideComponent>>
>(
proxyToken,
2022-04-07 00:19:37 +08:00
{
componentCls: `.${prefixCls}`,
prefixCls,
iconCls: `.${iconPrefixCls}`,
antCls: `.${rootPrefixCls}`,
},
mergedComponentToken,
);
const styleInterpolation = styleFn(mergedToken as unknown as FullToken<ComponentName>, {
hashId,
prefixCls,
2022-04-07 00:19:37 +08:00
rootPrefixCls,
iconPrefixCls,
});
flush(component);
return styleInterpolation;
}),
hashId,
];
};
}
export default genComponentStyleHook;