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(plugins): support to configure token algorithm for antd 5 #11461

Merged
merged 1 commit into from
Aug 17, 2023
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
2 changes: 2 additions & 0 deletions examples/with-antd-5/.umirc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ export default {
colorPrimary: '#1DA57A',
},
},
// dark: true,
compact: true,
/**
* antd@5.1.0 ~ 5.2.3 仅支持 appConfig: {}, 来启用 <App /> 组件;
* antd@5.3.0 及以上才支持 appConfig: { // ... } 来添加更多 App 配置项;
Expand Down
31 changes: 19 additions & 12 deletions examples/with-antd-5/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { App, Button, Space, version } from 'antd';
import { App, Button, Space, theme, version } from 'antd';
import React, { useState } from 'react';
import { getLocale, setLocale, useIntl } from 'umi';

Expand All @@ -7,6 +7,8 @@ export default function Page() {
// 若要使用 useApp hook,须先在 antd 插件中配置 appConfig
const { message, modal } = App.useApp();
const locale = getLocale();
const { token } = theme.useToken();

const showModal = () => {
modal.confirm({
title: 'Hai',
Expand All @@ -25,23 +27,28 @@ export default function Page() {
};

return (
<>
<div
style={{
backgroundColor: token.colorBgContainer,
height: '100vh',
}}
>
<h1>with antd@{version}</h1>
<Space>
<Button onClick={sayHai}>Say Hai</Button>
<Button type="primary" onClick={showModal}>
Open Modal
</Button>
locale:{locale}
<Button
onClick={() => {
setIsZh(!isZh);
setLocale(isZh ? 'en-US' : 'zh-CN', false);
}}
>
{msg}
</Button>
</Space>
locale:{locale}
<Button
onClick={() => {
setIsZh(!isZh);
setLocale(isZh ? 'en-US' : 'zh-CN', false);
}}
>
{msg}
</Button>
</>
</div>
);
}
76 changes: 39 additions & 37 deletions packages/plugins/src/antd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export default (api: IApi) => {
} catch (e) {}

const isV5 = antdVersion.startsWith('5');
const isV4 = antdVersion.startsWith('4');
// App components exist only from 5.1.0 onwards
const appComponentAvailable = semver.gte(antdVersion, '5.1.0');
const appConfigAvailable = semver.gte(antdVersion, '5.3.0');
Expand Down Expand Up @@ -97,7 +98,7 @@ export default (api: IApi) => {
memo.alias.antd = pkgPath;

// antd 5 里面没有变量了,less 跑不起来。注入一份变量至少能跑起来
if (antdVersion.startsWith('5')) {
if (isV5) {
const theme = require('@ant-design/antd-theme-variable');
memo.theme = {
...theme,
Expand All @@ -114,27 +115,25 @@ export default (api: IApi) => {
}
}

// dark mode & compact mode
if (antd.dark || antd.compact) {
const { getThemeVariables } = require('antd/dist/theme');
// 只有 antd@4 才需要将 compact 和 dark 传入 less 变量
if (isV4) {
if (antd.dark || antd.compact) {
const { getThemeVariables } = require('antd/dist/theme');
memo.theme = {
...getThemeVariables(antd),
...memo.theme,
};
}

memo.theme = {
...getThemeVariables(antd),
'root-entry-name': 'default',
...memo.theme,
};
}

// antd theme
memo.theme = {
'root-entry-name': 'default',
...memo.theme,
};

// allow use `antd.theme` as the shortcut of `antd.configProvider.theme`
if (antd.theme) {
assert(
antdVersion.startsWith('5'),
`antd.theme is only valid when antd is 5`,
);
assert(isV5, `antd.theme is only valid when antd is 5`);
antd.configProvider ??= {};
// priority: antd.theme > antd.configProvider.theme
antd.configProvider.theme = deepmerge(
Expand Down Expand Up @@ -178,33 +177,32 @@ export default (api: IApi) => {

// babel-plugin-import
api.addExtraBabelPlugins(() => {
// only enable style for non-antd@5
const style = isV5 ? false : api.config.antd.style || 'less';

return api.config.antd.import && !api.appData.vite
? [
[
require.resolve('babel-plugin-import'),
{
libraryName: 'antd',
libraryDirectory: 'es',
...(style
? {
style: style === 'less' || 'css',
}
: {}),
},
'antd',
],
]
: [];
const style = api.config.antd.style || 'less';

if (api.config.antd.import && !api.appData.vite) {
return [
[
require.resolve('babel-plugin-import'),
{
libraryName: 'antd',
libraryDirectory: 'es',
...(isV5 ? {} : { style: style === 'less' || 'css' }),
},
'antd',
],
];
}

return [];
});

// antd config provider & app component
api.onGenerateFiles(() => {
const withConfigProvider = !!api.config.antd.configProvider;
const withAppConfig = appConfigAvailable && !!api.config.antd.appConfig;
const styleProvider = api.config.antd.styleProvider;
const userInputCompact = api.config.antd.compact;
const userInputDark = api.config.antd.dark;

// Hack StyleProvider

Expand Down Expand Up @@ -246,6 +244,11 @@ export default (api: IApi) => {
appConfig:
appComponentAvailable && JSON.stringify(api.config.antd.appConfig),
styleProvider: styleProviderConfig,
// 是否启用了 v5 的 theme algorithm
enableV5ThemeAlgorithm:
isV5 && (userInputCompact || userInputDark)
? { compact: userInputCompact, dark: userInputDark }
: false,
},
tplPath: winPath(join(ANTD_TEMPLATES_DIR, 'runtime.ts.tpl')),
});
Expand Down Expand Up @@ -301,13 +304,12 @@ export type IRuntimeConfig = {
});

api.addEntryImportsAhead(() => {
const isAntd5 = antdVersion.startsWith('5');
const style = api.config.antd.style || 'less';
const imports: Awaited<
ReturnType<Parameters<IApi['addEntryImportsAhead']>[0]['fn']>
> = [];

if (isAntd5) {
if (isV5) {
// import antd@5 reset style
imports.push({ source: 'antd/dist/reset.css' });
} else if (!api.config.antd.import || api.appData.vite) {
Expand Down
26 changes: 24 additions & 2 deletions packages/plugins/templates/antd/runtime.ts.tpl
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import React from 'react';
import {
Modal,
{{#configProvider}}
ConfigProvider,
{{/configProvider}}
{{#appConfig}}
App,
{{/appConfig}}
message,
notification,
{{#enableV5ThemeAlgorithm}}
theme,
{{/enableV5ThemeAlgorithm}}
} from 'antd';
import { ApplyPluginsType } from 'umi';
{{#styleProvider}}
Expand Down Expand Up @@ -47,6 +48,7 @@ export function rootContainer(rawContainer) {
...finalConfigProvider
} = getAntdConfig();
let container = rawContainer;

{{#configProvider}}
if (finalConfigProvider.prefixCls) {
Modal.config({
Expand Down Expand Up @@ -77,6 +79,26 @@ export function rootContainer(rawContainer) {
container = <ConfigProvider {...finalConfigProvider}>{container}</ConfigProvider>;
{{/configProvider}}

{{#enableV5ThemeAlgorithm}}
// Add token algorithm for antd5 only
container = (
<ConfigProvider
theme={({
algorithm: [
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

上面已经包了 ConfigProvider 了,改下 theme 列表应该就行了吧。

时机应该在用户修改之前,感觉要放到 getAntdConfig 里。

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

另外我理解目前 appConfig 要强依赖 configProvider ,这个 configProvider 选项应该在 compact / dark / appConfig 时都自动打开。

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

目前 appConfig 要强依赖 configProvider

貌似不是强依赖, AppConfig 只是帮助开发者将 message 这类弹窗的 contextHolder 节点放在上下文中, 不仅仅消费 CP 的 theme token 包括其他多语言可能都有...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里可以包两层 ConfigProvider 吗?当用户配置了 configProvider 的时候就有两层了。

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我尝试看看能不能调整一下

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里如果是响应 theme 外的 darkcompact 的话,保证这里的 ConfigProvider 是在 theme 的 ConfigProvider 外面的就行,这样 themealgorithm 配置会覆盖 antd.compactantd.dark

对于 antd@5 来说 darkcompacttheme 的一部分,保证 theme 的优先级更高就可以

{{#enableV5ThemeAlgorithm.compact}}
theme.compactAlgorithm,
{{/enableV5ThemeAlgorithm.compact}}
{{#enableV5ThemeAlgorithm.dark}}
theme.darkAlgorithm,
{{/enableV5ThemeAlgorithm.dark}}
],
})}
>
{container}
</ConfigProvider>
);
{{/enableV5ThemeAlgorithm}}

{{#styleProvider}}
container = (
<StyleProvider
Expand Down
Loading