2023-09-17 23:32:14 +08:00
|
|
|
import React, { useContext } from 'react';
|
|
|
|
import { theme as antdTheme, ConfigProvider } from 'antd';
|
|
|
|
import type { ThemeConfig } from 'antd';
|
2023-04-20 10:47:06 +08:00
|
|
|
import type { ThemeProviderProps } from 'antd-style';
|
2023-04-18 15:29:34 +08:00
|
|
|
import { ThemeProvider } from 'antd-style';
|
2023-09-25 16:08:42 +08:00
|
|
|
import SiteContext from './slots/SiteContext';
|
2023-04-18 15:29:34 +08:00
|
|
|
|
2023-07-20 19:27:33 +08:00
|
|
|
interface NewToken {
|
2023-09-17 23:32:14 +08:00
|
|
|
bannerHeight: number;
|
2023-07-20 19:27:33 +08:00
|
|
|
headerHeight: number;
|
|
|
|
menuItemBorder: number;
|
|
|
|
mobileMaxWidth: number;
|
|
|
|
siteMarkdownCodeBg: string;
|
|
|
|
antCls: string;
|
|
|
|
iconCls: string;
|
|
|
|
marginFarXS: number;
|
|
|
|
marginFarSM: number;
|
|
|
|
marginFar: number;
|
|
|
|
codeFamily: string;
|
2023-08-08 19:48:41 +08:00
|
|
|
contentMarginTop: number;
|
2023-09-25 16:08:42 +08:00
|
|
|
anchorTop: number;
|
2023-07-20 19:27:33 +08:00
|
|
|
}
|
|
|
|
|
2023-10-08 13:44:02 +08:00
|
|
|
// 通过给 antd-style 扩展 CustomToken 对象类型定义,可以为 useTheme 中增加相应的 token 对象
|
|
|
|
declare module 'antd-style' {
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
|
|
|
export interface CustomToken extends NewToken {}
|
|
|
|
}
|
|
|
|
|
2023-09-25 16:08:42 +08:00
|
|
|
const headerHeight = 64;
|
|
|
|
const bannerHeight = 38;
|
|
|
|
|
2023-09-17 23:32:14 +08:00
|
|
|
const SiteThemeProvider: React.FC<ThemeProviderProps<any>> = ({ children, theme, ...rest }) => {
|
2023-05-18 23:53:34 +08:00
|
|
|
const { getPrefixCls, iconPrefixCls } = useContext(ConfigProvider.ConfigContext);
|
2023-04-18 15:29:34 +08:00
|
|
|
const rootPrefixCls = getPrefixCls();
|
2023-05-18 23:53:34 +08:00
|
|
|
const { token } = antdTheme.useToken();
|
2023-09-25 16:08:42 +08:00
|
|
|
const { bannerVisible } = useContext(SiteContext);
|
2023-05-18 23:53:34 +08:00
|
|
|
React.useEffect(() => {
|
2023-09-17 23:32:14 +08:00
|
|
|
ConfigProvider.config({ theme: theme as ThemeConfig });
|
2023-05-18 23:53:34 +08:00
|
|
|
}, [theme]);
|
2023-04-18 15:29:34 +08:00
|
|
|
|
|
|
|
return (
|
2023-07-20 19:27:33 +08:00
|
|
|
<ThemeProvider<NewToken>
|
2023-04-20 10:47:06 +08:00
|
|
|
{...rest}
|
2023-05-18 23:53:34 +08:00
|
|
|
theme={theme}
|
2023-04-18 15:29:34 +08:00
|
|
|
customToken={{
|
2023-09-25 16:08:42 +08:00
|
|
|
headerHeight,
|
|
|
|
bannerHeight,
|
2023-04-18 15:29:34 +08:00
|
|
|
menuItemBorder: 2,
|
|
|
|
mobileMaxWidth: 767.99,
|
|
|
|
siteMarkdownCodeBg: token.colorFillTertiary,
|
|
|
|
antCls: `.${rootPrefixCls}`,
|
|
|
|
iconCls: `.${iconPrefixCls}`,
|
|
|
|
/** 56 */
|
|
|
|
marginFarXS: (token.marginXXL / 6) * 7,
|
|
|
|
/** 80 */
|
|
|
|
marginFarSM: (token.marginXXL / 3) * 5,
|
|
|
|
/** 96 */
|
|
|
|
marginFar: token.marginXXL * 2,
|
|
|
|
codeFamily: `'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace`,
|
2023-08-08 19:48:41 +08:00
|
|
|
contentMarginTop: 40,
|
2023-09-25 16:08:42 +08:00
|
|
|
anchorTop: headerHeight + token.margin + (bannerVisible ? bannerHeight : 0),
|
2023-04-18 15:29:34 +08:00
|
|
|
}}
|
|
|
|
>
|
|
|
|
{children}
|
|
|
|
</ThemeProvider>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
export default SiteThemeProvider;
|