Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(design): ConfigProvider add theme.customFont prop to use Source Sans Pro font #536

Merged
merged 1 commit into from
Mar 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions .dumi/theme/SiteThemeProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ import useSiteToken from '../hooks/useSiteToken';

const SiteThemeProvider: FC<
ThemeProviderProps<any> & {
theme: ThemeConfig & {
isDark?: boolean;
};
theme: ThemeConfig;
}
> = ({ children, theme, ...rest }) => {
const { getPrefixCls, iconPrefixCls } = useContext(ConfigProvider.ConfigContext);
Expand Down
20 changes: 19 additions & 1 deletion .dumi/theme/common/ThemeSwitch/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import { CompactTheme, DarkTheme, Motion } from 'antd-token-previewer/es/icons';
import { FormattedMessage } from 'dumi';
import React from 'react';
import ThemeIcon from './ThemeIcon';
import { FontColorsOutlined } from '@ant-design/icons';

export type ThemeName = 'light' | 'dark' | 'compact' | 'motion-off';
export type ThemeName = 'light' | 'dark' | 'compact' | 'motion-off' | 'custom-font';

export type ThemeSwitchProps = {
value?: ThemeName[];
Expand All @@ -14,6 +15,7 @@ export type ThemeSwitchProps = {
const ThemeSwitch: React.FC<ThemeSwitchProps> = (props: ThemeSwitchProps) => {
const { value = ['light'], onChange } = props;
const isMotionOff = value.includes('motion-off');
const isCustomFont = value.includes('custom-font');

return (
<FloatButton.Group trigger="click" icon={<ThemeIcon />}>
Expand Down Expand Up @@ -57,6 +59,22 @@ const ThemeSwitch: React.FC<ThemeSwitchProps> = (props: ThemeSwitchProps) => {
/>
}
/>
<FloatButton
icon={<FontColorsOutlined />}
type={isCustomFont ? 'primary' : 'default'}
onClick={() => {
if (isCustomFont) {
onChange(value.filter(theme => theme !== 'custom-font'));
} else {
onChange([...value, 'custom-font']);
}
}}
tooltip={
<FormattedMessage
id={isCustomFont ? 'app.theme.switch.font.custom' : 'app.theme.switch.font.default'}
/>
}
/>
</FloatButton.Group>
);
};
Expand Down
1 change: 1 addition & 0 deletions .dumi/theme/layouts/GlobalLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ const GlobalLayout: React.FC = () => {
theme={{
algorithm: getAlgorithm(theme),
isDark: theme.includes('dark'),
customFont: theme.includes('custom-font'),
token: {
motion: !theme.includes('motion-off'),
},
Expand Down
2 changes: 2 additions & 0 deletions .dumi/theme/locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
"app.theme.switch.compact": "Compact theme",
"app.theme.switch.motion.on": "Motion On",
"app.theme.switch.motion.off": "Motion Off",
"app.theme.switch.font.default": "Default Font",
"app.theme.switch.font.custom": "Custom Font",
"app.header.menu.more": "More",
"app.header.menu.pro.components": "Ant Design Pro Components",
"app.header.menu.charts": "Ant Design Charts",
Expand Down
2 changes: 2 additions & 0 deletions .dumi/theme/locales/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
"app.theme.switch.compact": "紧凑主题",
"app.theme.switch.motion.on": "动画开启",
"app.theme.switch.motion.off": "动画关闭",
"app.theme.switch.font.default": "默认字体",
"app.theme.switch.font.custom": "定制字体",
"app.header.menu.more": "更多",
"app.header.menu.pro.components": "Ant Design Pro Components",
"app.header.menu.charts": "Ant Design Charts",
Expand Down
20 changes: 18 additions & 2 deletions packages/design/src/_util/genComponentStyleHook.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,29 @@
import type { CSSObject } from '@ant-design/cssinjs';
import type { ComponentTokenMap } from 'antd/es/theme/interface';
import type { FullToken, GenerateStyle } from 'antd/es/theme/internal';
import type { DerivativeToken, FullToken, GenerateStyle } from 'antd/es/theme/internal';
import { genComponentStyleHook as antGenComponentStyleHook } from 'antd/es/theme/internal';
import type { GlobalToken } from 'antd/es/theme/interface';
import type { OverrideTokenWithoutDerivative } from 'antd/es/theme/util/genComponentStyleHook';
import { useContext } from 'react';
import ConfigProvider from '../config-provider';
import theme from '../theme';

export type ComponentName = keyof ComponentTokenMap;

export const genCustomFontStyle = (token: DerivativeToken): CSSObject[] => {
return [
{
['@font-face']: {
fontFamily: 'Source Sans Pro',
// 定义三种字体格式,适配不同版本的浏览器,并且最多加载一种字体文件
src: `url('https://mdn.alipayobjects.com/huamei_fhnyvh/afts/file/A*H1MFR42M5PMAAAAAAAAAAAAADmfOAQ/Source%20Sans%20Pro.woff2') format('woff2'), url('https://mdn.alipayobjects.com/huamei_fhnyvh/afts/file/A*jbYLSpw_gfEAAAAAAAAAAAAADmfOAQ/Source%20Sans%20Pro.woff') format('woff'), url('https://mdn.alipayobjects.com/huamei_fhnyvh/afts/file/A*28ClS5qHwQ8AAAAAAAAAAAAADmfOAQ/Source%20Sans%20Pro.ttf') format('truetype')`,
// 定义字体加载策略,外置字体加载前使用默认字体进行兜底
fontDisplay: 'swap',
},
},
];
};

export function genComponentStyleHook(
componentName: ComponentName,
styleFn: GenerateStyle<FullToken<ComponentName>>,
Expand All @@ -17,10 +32,11 @@ export function genComponentStyleHook(
| ((token: GlobalToken) => OverrideTokenWithoutDerivative[ComponentName])
) {
return (prefixCls: string) => {
const { theme: themeConfig } = useContext(ConfigProvider.ConfigContext);
const useStyle = antGenComponentStyleHook(
`OB-${componentName}` as ComponentName,
token => {
return [styleFn(token)];
return [themeConfig?.customFont ? genCustomFontStyle(token) : null, styleFn(token)];
},
getDefaultToken,
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { useContext } from 'react';
import { render } from '@testing-library/react';
import { ConfigProvider, useToken } from '@oceanbase/design';
import defaultTheme from '../../theme/default';
Expand Down
2 changes: 2 additions & 0 deletions packages/design/src/config-provider/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ nav:
- 🔥 完全继承 antd [ConfigProvider](https://ant.design/components/config-provider-cn) 的能力和 API,可无缝切换。
- 🌈 定制全局主题和空状态,以符合 OceanBase Design 设计规范。
- 🆕 默认内嵌 [App 包裹组件](https://ant.design/components/app-cn),支持 message, notification 和 Modal 等静态方法消费 ConfigProvider 配置。
- 🆕 新增 `theme.customFont` 属性,用于开启 `Source Sans Pro` 定制字体以提升展示效果,仅支持线上应用和英文环境。
- 🆕 新增 `table.selectionColumnWidth` 属性,用于配置表格的展开列宽度。
- 🆕 新增 `injectStaticFunction` 属性,用于配置 `message`, `notification` 和 `Modal` 静态方法是否可以消费全局配置,默认开启。

Expand Down Expand Up @@ -47,6 +48,7 @@ export default App;

| 参数 | 说明 | 类型 | 默认值 | 版本 |
| :-- | :-- | :-- | :-- | :-- |
| theme.customFont | 用于开启 `Source Sans Pro` 定制字体以提升展示效果,仅支持线上应用和英文环境 | boolean | undefined | 0.3.1 |
| spin | Spin 全局配置 | `{ indicator?: ReactNode; className?: string; style?: React.CSSProperties; }` | undefined | - |
| table | Table 全局配置 | `{ selectionColumnWidth?: width; className?: string; style?: React.CSSProperties; }` | undefined | - |
| injectStaticFunction | 用于配置 `message`, `notification` 和 `Modal` 静态方法是否可以消费全局配置 <Alert type="warning" showIcon={true} message="📢 注意: 如果有多个 ConfigProvider,建议在最顶层的 ConfigProvider 开启 `injectStaticFunction` 即可,其他 ConfigProvider 则需要关闭该配置,否则静态方法可能会有冲突。"></Alert> | boolean | true | - |
Expand Down
20 changes: 9 additions & 11 deletions packages/design/src/config-provider/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ export * from 'antd/es/config-provider';

export interface ThemeConfig extends AntThemeConfig {
isDark?: boolean;
/* use custom font or not */
customFont?: boolean;
}

export type SpinConfig = ComponentStyleConfig & {
Expand Down Expand Up @@ -73,8 +75,6 @@ const ExtendedConfigContext = React.createContext<ExtendedConfigConsumerProps>({
hideOnSinglePage: false,
});

const { defaultSeed } = themeConfig;

export type ConfigProviderType = React.FC<ConfigProviderProps> & {
ExtendedConfigContext: typeof ExtendedConfigContext;
} & {
Expand Down Expand Up @@ -103,6 +103,7 @@ const ConfigProvider: ConfigProviderType = ({
React.useContext<ExtendedConfigConsumerProps>(ExtendedConfigContext);
const mergedTheme = merge(parentContext.theme, theme);
const currentTheme = mergedTheme?.isDark ? darkTheme : defaultTheme;
const { token } = themeConfig.useToken();

// inherit from parent StyleProvider
const parentStyleContext = React.useContext<StyleContextProps>(StyleContext);
Expand All @@ -126,16 +127,13 @@ const ConfigProvider: ConfigProviderType = ({
parentContext.tabs,
tabs
)}
theme={merge(
{
token: {
...defaultSeed,
...currentTheme.token,
},
components: currentTheme.components,
theme={merge(currentTheme, mergedTheme, {
token: {
fontFamily: mergedTheme.customFont
? `'Source Sans Pro', ${token.fontFamily}`
: token.fontFamily,
},
mergedTheme
)}
})}
renderEmpty={
parentContext.renderEmpty ||
(componentName => <DefaultRenderEmpty componentName={componentName} />)
Expand Down
2 changes: 1 addition & 1 deletion packages/design/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export { default as Card } from './card';
export type { CardProps } from './card';

export { default as ConfigProvider } from './config-provider';
export type { ConfigProviderProps } from './config-provider';
export type { ConfigProviderProps, ConfigConsumerProps, ThemeConfig } from './config-provider';

export { default as Descriptions } from './descriptions';
export type {
Expand Down
Loading