ant-design/components/_util/theme/index.tsx
2022-02-27 22:17:17 +08:00

112 lines
3.0 KiB
TypeScript

import React from 'react';
import { generate } from '@ant-design/colors';
import { CSSObject, Theme, useCacheToken, useStyleRegister } from '@ant-design/cssinjs';
import defaultDesignToken from './default';
import version from '../../version';
import { ConfigContext } from '../../config-provider';
export interface DesignToken {
primaryColor: string;
errorColor: string;
lineHeight: number;
borderWidth: number;
borderStyle: string;
borderRadius: number;
borderColor: string;
easeInOut: string;
fontSize: number;
textColor: string;
textColorDisabled: string;
height: number;
padding: number;
margin: number;
componentBackground: string;
componentBackgroundDisabled: string;
duration: string;
}
/** This is temporary token definition since final token definition is not ready yet. */
export interface DerivativeToken extends DesignToken {
primaryHoverColor: string;
primaryActiveColor: string;
errorHoverColor: string;
errorActiveColor: string;
linkColor: string;
fontSizeSM: number;
fontSizeLG: number;
heightSM: number;
heightLG: number;
paddingXS: number;
marginXS: number;
}
export { useStyleRegister };
// =============================== Derivative ===============================
function derivative(designToken: DesignToken): DerivativeToken {
const primaryColors = generate(designToken.primaryColor);
const errorColors = generate(designToken.errorColor);
return {
...designToken,
primaryHoverColor: primaryColors[4],
primaryActiveColor: primaryColors[6],
errorHoverColor: errorColors[4],
errorActiveColor: errorColors[6],
linkColor: designToken.primaryColor,
fontSizeSM: designToken.fontSize - 2,
fontSizeLG: designToken.fontSize + 2,
heightSM: designToken.height * 0.75,
heightLG: designToken.height * 1.25,
paddingXS: designToken.padding * 0.5,
marginXS: designToken.margin * 0.5,
};
}
// ================================ Context =================================
export const ThemeContext = React.createContext(
new Theme<DesignToken, DerivativeToken>(derivative),
);
export const DesignTokenContext = React.createContext<{
token: Partial<DesignToken>;
hashed?: string | boolean;
}>({
token: defaultDesignToken,
});
// ================================== Hook ==================================
export function useToken() {
const { token: rootDesignToken, hashed } = React.useContext(DesignTokenContext);
const theme = React.useContext(ThemeContext);
const salt = `${version}-${hashed || ''}`;
const [token, hashId] = useCacheToken(theme, [defaultDesignToken, rootDesignToken], {
salt,
});
return [theme, token, hashed ? hashId : ''];
}
// ================================== Util ==================================
export function withPrefix(
style: CSSObject,
prefixCls: string,
additionalClsList: string[] = [],
): CSSObject {
const fullClsList = [prefixCls, ...additionalClsList].filter(cls => cls).map(cls => `.${cls}`);
return {
[fullClsList.join('')]: style,
};
}