From 43d7b9ca92038379ed3c4f3a0ccdc103093ea1b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=8C=E8=B4=A7=E7=88=B1=E5=90=83=E7=99=BD=E8=90=9D?= =?UTF-8?q?=E5=8D=9C?= Date: Thu, 18 May 2023 23:53:34 +0800 Subject: [PATCH] feat: ConfigProvider.config support theme config (#42473) * chore: static config of theme * chore: static all method * test: add test case * docs: comment * docs: more info * test: update snapshot * test: fix test logic --- .dumi/theme/SiteThemeProvider.tsx | 20 ++++++++++------ .../config-provider/__tests__/static.test.ts | 23 +++++++++++++++++++ .../config-provider/__tests__/theme.test.tsx | 4 +++- components/config-provider/index.en-US.md | 12 ++++++---- components/config-provider/index.tsx | 19 +++++++++++++-- components/config-provider/index.zh-CN.md | 12 ++++++---- .../__snapshots__/demo-extend.test.ts.snap | 2 +- .../__tests__/__snapshots__/demo.test.ts.snap | 2 +- components/message/demo/info.md | 4 ++-- components/message/demo/info.tsx | 4 ++-- components/message/index.en-US.md | 2 +- components/message/index.tsx | 5 ++-- components/message/index.zh-CN.md | 2 +- components/modal/ConfirmDialog.tsx | 14 ++++++++--- components/modal/confirm.tsx | 8 ++++--- components/notification/demo/basic.md | 4 ++-- components/notification/index.en-US.md | 2 +- components/notification/index.tsx | 3 ++- components/notification/index.zh-CN.md | 2 +- 19 files changed, 105 insertions(+), 39 deletions(-) diff --git a/.dumi/theme/SiteThemeProvider.tsx b/.dumi/theme/SiteThemeProvider.tsx index f342aaab10..da43b7aac4 100644 --- a/.dumi/theme/SiteThemeProvider.tsx +++ b/.dumi/theme/SiteThemeProvider.tsx @@ -1,18 +1,24 @@ -import type { FC } from 'react'; -import React, { useContext } from 'react'; -import { ConfigContext } from 'antd/es/config-provider'; +import { ConfigProvider, theme as antdTheme } from 'antd'; import type { ThemeProviderProps } from 'antd-style'; import { ThemeProvider } from 'antd-style'; -import { theme } from 'antd'; +import type { FC } from 'react'; +import React, { useContext } from 'react'; -const SiteThemeProvider: FC = ({ children, ...rest }) => { - const { getPrefixCls, iconPrefixCls } = useContext(ConfigContext); +const SiteThemeProvider: FC = ({ children, theme, ...rest }) => { + const { getPrefixCls, iconPrefixCls } = useContext(ConfigProvider.ConfigContext); const rootPrefixCls = getPrefixCls(); - const { token } = theme.useToken(); + const { token } = antdTheme.useToken(); + + React.useEffect(() => { + ConfigProvider.config({ + theme, + }); + }, [theme]); return ( { }); expect(globalConfig().getRootPrefixCls()).toEqual('light'); }); + + it('theme', () => { + const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {}); + expect(globalConfig().getTheme()).toBeFalsy(); + + ConfigProvider.config({ + theme: { + infoColor: 'red', + }, + }); + + expect(errSpy).toHaveBeenCalledWith( + 'Warning: [antd: ConfigProvider] `config` of css variable theme is not work in v5. Please use new `theme` config instead.', + ); + + ConfigProvider.config({ + theme: { + token: {}, + }, + }); + + expect(globalConfig().getTheme()).toEqual({ token: {} }); + }); }); diff --git a/components/config-provider/__tests__/theme.test.tsx b/components/config-provider/__tests__/theme.test.tsx index 4d733896f3..d3c14df61c 100644 --- a/components/config-provider/__tests__/theme.test.tsx +++ b/components/config-provider/__tests__/theme.test.tsx @@ -49,7 +49,9 @@ describe('ConfigProvider.Theme', () => { expect(canUseDom()).toBeFalsy(); ConfigProvider.config({ - theme: {}, + theme: { + infoColor: 'red', + }, }); expect(errorSpy).toHaveBeenCalledWith( diff --git a/components/config-provider/index.en-US.md b/components/config-provider/index.en-US.md index b21f009ec0..c6b4764ed1 100644 --- a/components/config-provider/index.en-US.md +++ b/components/config-provider/index.en-US.md @@ -70,14 +70,18 @@ Some components use dynamic style to support wave effect. You can config `csp` p | theme | Set theme, ref [Customize Theme](/docs/react/customize-theme) | - | - | 5.0.0 | | virtual | Disable virtual scroll when set to `false` | boolean | - | 4.3.0 | -### ConfigProvider.config() `4.13.0+` +### ConfigProvider.config() -Setting `Modal`、`Message`、`Notification` rootPrefixCls. +Setting `Modal`、`Message`、`Notification` static config. Not work on hooks. ```ts ConfigProvider.config({ - prefixCls: 'ant', // 4.13.0+ - iconPrefixCls: 'anticon', // 4.17.0+ + prefixCls: 'ant', + iconPrefixCls: 'anticon', + + // 5.6.0+ + // Please use hooks version first + theme: { token: { colorPrimary: 'red' } }, }); ``` diff --git a/components/config-provider/index.tsx b/components/config-provider/index.tsx index 32cdd11f59..027af450b9 100644 --- a/components/config-provider/index.tsx +++ b/components/config-provider/index.tsx @@ -138,6 +138,7 @@ interface ProviderChildrenProps extends ConfigProviderProps { export const defaultPrefixCls = 'ant'; let globalPrefixCls: string; let globalIconPrefixCls: string; +let globalTheme: ThemeConfig; function getGlobalPrefixCls() { return globalPrefixCls || defaultPrefixCls; @@ -147,11 +148,15 @@ function getGlobalIconPrefixCls() { return globalIconPrefixCls || defaultIconPrefixCls; } +function isLegacyTheme(theme: Theme | ThemeConfig): theme is Theme { + return Object.keys(theme).some((key) => key.endsWith('Color')); +} + const setGlobalConfig = ({ prefixCls, iconPrefixCls, theme, -}: Pick & { theme?: Theme }) => { +}: Pick & { theme?: Theme | ThemeConfig }) => { if (prefixCls !== undefined) { globalPrefixCls = prefixCls; } @@ -160,7 +165,16 @@ const setGlobalConfig = ({ } if (theme) { - registerTheme(getGlobalPrefixCls(), theme); + if (isLegacyTheme(theme)) { + warning( + false, + 'ConfigProvider', + '`config` of css variable theme is not work in v5. Please use new `theme` config instead.', + ); + registerTheme(getGlobalPrefixCls(), theme); + } else { + globalTheme = theme; + } } }; @@ -179,6 +193,7 @@ export const globalConfig = () => ({ // Fallback to default prefixCls return getGlobalPrefixCls(); }, + getTheme: () => globalTheme, }); const ProviderChildren: React.FC = (props) => { diff --git a/components/config-provider/index.zh-CN.md b/components/config-provider/index.zh-CN.md index 574081685d..400596aa23 100644 --- a/components/config-provider/index.zh-CN.md +++ b/components/config-provider/index.zh-CN.md @@ -71,14 +71,18 @@ export default Demo; | theme | 设置主题,参考 [定制主题](/docs/react/customize-theme-cn) | - | - | 5.0.0 | | virtual | 设置 `false` 时关闭虚拟滚动 | boolean | - | 4.3.0 | -### ConfigProvider.config() `4.13.0+` +### ConfigProvider.config() -设置 `Modal`、`Message`、`Notification` rootPrefixCls。 +设置 `Modal`、`Message`、`Notification` 静态方法配置,只会对非 hooks 的静态方法调用生效。 ```ts ConfigProvider.config({ - prefixCls: 'ant', // 4.13.0+ - iconPrefixCls: 'anticon', // 4.17.0+ + prefixCls: 'ant', + iconPrefixCls: 'anticon', + + // 5.6.0+ + // 请优先考虑使用 hooks 版本 + theme: { token: { colorPrimary: 'red' } }, }); ``` diff --git a/components/message/__tests__/__snapshots__/demo-extend.test.ts.snap b/components/message/__tests__/__snapshots__/demo-extend.test.ts.snap index 9531a5c88f..6495338c90 100644 --- a/components/message/__tests__/__snapshots__/demo-extend.test.ts.snap +++ b/components/message/__tests__/__snapshots__/demo-extend.test.ts.snap @@ -76,7 +76,7 @@ exports[`renders components/message/demo/info.tsx extend context correctly 1`] = type="button" > - Display normal message + Static Method `; diff --git a/components/message/__tests__/__snapshots__/demo.test.ts.snap b/components/message/__tests__/__snapshots__/demo.test.ts.snap index af0b392f4f..bc9beff6d2 100644 --- a/components/message/__tests__/__snapshots__/demo.test.ts.snap +++ b/components/message/__tests__/__snapshots__/demo.test.ts.snap @@ -76,7 +76,7 @@ exports[`renders components/message/demo/info.tsx correctly 1`] = ` type="button" > - Display normal message + Static Method `; diff --git a/components/message/demo/info.md b/components/message/demo/info.md index e9f6dd0182..b913751f60 100644 --- a/components/message/demo/info.md +++ b/components/message/demo/info.md @@ -1,7 +1,7 @@ ## zh-CN -信息提醒反馈。 +静态方法无法消费 Context,推荐优先使用 Hooks 版本。 ## en-US -Normal message for information. +Static methods cannot consume Context. Please use hooks first. diff --git a/components/message/demo/info.tsx b/components/message/demo/info.tsx index b559e9d8f8..b2b598503d 100644 --- a/components/message/demo/info.tsx +++ b/components/message/demo/info.tsx @@ -1,5 +1,5 @@ -import React from 'react'; import { Button, message } from 'antd'; +import React from 'react'; const info = () => { message.info('This is a normal message'); @@ -7,7 +7,7 @@ const info = () => { const App: React.FC = () => ( ); diff --git a/components/message/index.en-US.md b/components/message/index.en-US.md index c62beea676..b1051b0ed8 100644 --- a/components/message/index.en-US.md +++ b/components/message/index.en-US.md @@ -26,7 +26,7 @@ Display global messages as feedback in response to user operations. Promise interface Customized style Update Message Content -Normal prompt +Static method (deprecated) _InternalPanelDoNotUseOrYouWillBeFired Component Token diff --git a/components/message/index.tsx b/components/message/index.tsx index c005728462..c0fc527c88 100755 --- a/components/message/index.tsx +++ b/components/message/index.tsx @@ -1,6 +1,7 @@ import { render } from 'rc-util/lib/React/render'; import * as React from 'react'; import ConfigProvider, { globalConfig, warnContext } from '../config-provider'; +import PurePanel from './PurePanel'; import type { ArgsProps, ConfigOptions, @@ -9,7 +10,6 @@ import type { NoticeType, TypeOpen, } from './interface'; -import PurePanel from './PurePanel'; import useMessage, { useInternalMessage } from './useMessage'; import { wrapPromiseFn } from './util'; @@ -102,6 +102,7 @@ const GlobalHolder = React.forwardRef((_, ref) => { const global = globalConfig(); const rootPrefixCls = global.getRootPrefixCls(); const rootIconPrefixCls = global.getIconPrefixCls(); + const theme = global.getTheme(); const sync = () => { setMessageConfig(initializeMessageConfig); @@ -126,7 +127,7 @@ const GlobalHolder = React.forwardRef((_, ref) => { }); return ( - + {holder} ); diff --git a/components/message/index.zh-CN.md b/components/message/index.zh-CN.md index 824b1fd0f4..fe608a94c5 100644 --- a/components/message/index.zh-CN.md +++ b/components/message/index.zh-CN.md @@ -27,7 +27,7 @@ demo: Promise 接口 自定义样式 更新消息内容 -普通提示 +静态方法(不推荐) _InternalPanelDoNotUseOrYouWillBeFired 组件 Token diff --git a/components/modal/ConfirmDialog.tsx b/components/modal/ConfirmDialog.tsx index 84f36b22d2..127a71f15a 100644 --- a/components/modal/ConfirmDialog.tsx +++ b/components/modal/ConfirmDialog.tsx @@ -4,11 +4,12 @@ import ExclamationCircleFilled from '@ant-design/icons/ExclamationCircleFilled'; import InfoCircleFilled from '@ant-design/icons/InfoCircleFilled'; import classNames from 'classnames'; import * as React from 'react'; -import ConfigProvider from '../config-provider'; -import { useLocale } from '../locale'; import ActionButton from '../_util/ActionButton'; import { getTransitionName } from '../_util/motion'; import warning from '../_util/warning'; +import type { ThemeConfig } from '../config-provider'; +import ConfigProvider from '../config-provider'; +import { useLocale } from '../locale'; import type { ModalFuncProps, ModalLocale } from './Modal'; import Dialog from './Modal'; @@ -18,6 +19,7 @@ interface ConfirmDialogProps extends ModalFuncProps { autoFocusButton?: null | 'ok' | 'cancel'; rootPrefixCls: string; iconPrefixCls?: string; + theme?: ThemeConfig; /** @private Internal Usage. Do not override this */ locale?: ModalLocale; @@ -143,6 +145,7 @@ const ConfirmDialog: React.FC = (props) => { wrapClassName, rootPrefixCls, iconPrefixCls, + theme, bodyStyle, closable = false, closeIcon, @@ -174,7 +177,12 @@ const ConfirmDialog: React.FC = (props) => { ); return ( - + { const runtimeLocale = getConfirmLocale(); - const { getPrefixCls, getIconPrefixCls } = globalConfig(); + const { getPrefixCls, getIconPrefixCls, getTheme } = globalConfig(); // because Modal.config  set rootPrefixCls, which is different from other components const rootPrefixCls = getPrefixCls(undefined, getRootPrefixCls()); const prefixCls = customizePrefixCls || `${rootPrefixCls}-modal`; const iconPrefixCls = getIconPrefixCls(); + const theme = getTheme(); reactRender( , container, diff --git a/components/notification/demo/basic.md b/components/notification/demo/basic.md index e84d29e329..b913751f60 100644 --- a/components/notification/demo/basic.md +++ b/components/notification/demo/basic.md @@ -1,7 +1,7 @@ ## zh-CN -最简单的用法,4.5 秒后自动关闭。 +静态方法无法消费 Context,推荐优先使用 Hooks 版本。 ## en-US -The simplest usage that close the notification box after 4.5s. +Static methods cannot consume Context. Please use hooks first. diff --git a/components/notification/index.en-US.md b/components/notification/index.en-US.md index 2493fbd557..2c75b72a27 100644 --- a/components/notification/index.en-US.md +++ b/components/notification/index.en-US.md @@ -23,7 +23,6 @@ To display a notification message at any of the four corners of the viewport. Ty Hooks usage (recommended) -Basic Duration after which the notification box is closed Notification with icon Custom close button @@ -31,6 +30,7 @@ To display a notification message at any of the four corners of the viewport. Ty Placement Customized style Update Message Content +Static Method (deprecated) _InternalPanelDoNotUseOrYouWillBeFired ## API diff --git a/components/notification/index.tsx b/components/notification/index.tsx index f1f696cd56..41f4bf71f7 100755 --- a/components/notification/index.tsx +++ b/components/notification/index.tsx @@ -76,6 +76,7 @@ const GlobalHolder = React.forwardRef((_, ref) => { const global = globalConfig(); const rootPrefixCls = global.getRootPrefixCls(); const rootIconPrefixCls = global.getIconPrefixCls(); + const theme = global.getTheme(); const sync = () => { const { @@ -114,7 +115,7 @@ const GlobalHolder = React.forwardRef((_, ref) => { }); return ( - + {holder} ); diff --git a/components/notification/index.zh-CN.md b/components/notification/index.zh-CN.md index a777dd7910..ccfa26af49 100644 --- a/components/notification/index.zh-CN.md +++ b/components/notification/index.zh-CN.md @@ -24,7 +24,6 @@ demo: Hooks 调用(推荐) -基本 自动关闭的延时 带有图标的通知提醒框 自定义按钮 @@ -32,6 +31,7 @@ demo: 位置 自定义样式 更新消息内容 +静态方法(不推荐) _InternalPanelDoNotUseOrYouWillBeFired ## API