diff --git a/components/avatar/__tests__/Avatar.test.js b/components/avatar/__tests__/Avatar.test.js
index 906ed81917..6380a7bd90 100644
--- a/components/avatar/__tests__/Avatar.test.js
+++ b/components/avatar/__tests__/Avatar.test.js
@@ -133,4 +133,15 @@ describe('Avatar Render', () => {
wrapper.setProps({ children: 'xx' });
expect(wrapper.state().scale).toBe(0.32);
});
+
+ it('should warning when pass a string as icon props', () => {
+ const warnSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
+ mount();
+ expect(warnSpy).not.toHaveBeenCalled();
+ mount();
+ expect(warnSpy).toHaveBeenCalledWith(
+ `Warning: [antd: Avatar] \`icon\` is using ReactNode instead of string naming in v4. Please check \`user\` at https://ant.design/components/icon`,
+ );
+ warnSpy.mockRestore();
+ });
});
diff --git a/components/avatar/index.tsx b/components/avatar/index.tsx
index 3c395ed9f5..a911413b25 100644
--- a/components/avatar/index.tsx
+++ b/components/avatar/index.tsx
@@ -2,6 +2,7 @@ import * as React from 'react';
import classNames from 'classnames';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
+import warning from '../_util/warning';
export interface AvatarProps {
/** Shape of avatar, options:`circle`, `square` */
@@ -108,6 +109,12 @@ export default class Avatar extends React.Component {
...others
} = this.props;
+ warning(
+ !(typeof icon === 'string' && icon.length > 2),
+ 'Avatar',
+ `\`icon\` is using ReactNode instead of string naming in v4. Please check \`${icon}\` at https://ant.design/components/icon`,
+ );
+
const { isImgExist, scale, mounted } = this.state;
const prefixCls = getPrefixCls('avatar', customizePrefixCls);
diff --git a/components/button/__tests__/index.test.js b/components/button/__tests__/index.test.js
index 9baf70cde9..0d9dc2840d 100644
--- a/components/button/__tests__/index.test.js
+++ b/components/button/__tests__/index.test.js
@@ -233,4 +233,15 @@ describe('Button', () => {
wrapper.unmount();
}).not.toThrow();
});
+
+ it('should warning when pass a string as icon props', () => {
+ const warnSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
+ mount();
+ expect(warnSpy).not.toHaveBeenCalled();
+ mount();
+ expect(warnSpy).toHaveBeenCalledWith(
+ `Warning: [antd: Button] \`icon\` is using ReactNode instead of string naming in v4. Please check \`search\` at https://ant.design/components/icon`,
+ );
+ warnSpy.mockRestore();
+ });
});
diff --git a/components/button/button.tsx b/components/button/button.tsx
index b90df35740..74d9ce7b9e 100644
--- a/components/button/button.tsx
+++ b/components/button/button.tsx
@@ -10,6 +10,7 @@ import Group from './button-group';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import Wave from '../_util/wave';
import { Omit, tuple } from '../_util/type';
+import warning from '../_util/warning';
const rxTwoCNChar = /^[\u4e00-\u9fa5]{2}$/;
const isTwoCNChar = rxTwoCNChar.test.bind(rxTwoCNChar);
@@ -231,6 +232,12 @@ class Button extends React.Component {
} = this.props;
const { loading, hasTwoCNChar } = this.state;
+ warning(
+ !(typeof icon === 'string' && icon.length > 2),
+ 'Button',
+ `\`icon\` is using ReactNode instead of string naming in v4. Please check \`${icon}\` at https://ant.design/components/icon`,
+ );
+
const prefixCls = getPrefixCls('btn', customizePrefixCls);
const autoInsertSpace = autoInsertSpaceInButton !== false;
diff --git a/components/modal/__tests__/confirm.test.js b/components/modal/__tests__/confirm.test.js
index e22c4f3519..17e4d08971 100644
--- a/components/modal/__tests__/confirm.test.js
+++ b/components/modal/__tests__/confirm.test.js
@@ -214,4 +214,21 @@ describe('Modal.confirm triggers callbacks correctly', () => {
});
jest.useRealTimers();
});
+
+ it('should warning when pass a string as icon props', () => {
+ const warnSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
+ confirm({
+ content: 'some descriptions',
+ icon: 'ab',
+ });
+ expect(warnSpy).not.toHaveBeenCalled();
+ confirm({
+ content: 'some descriptions',
+ icon: 'question',
+ });
+ expect(warnSpy).toHaveBeenCalledWith(
+ `Warning: [antd: Modal] \`icon\` is using ReactNode instead of string naming in v4. Please check \`question\` at https://ant.design/components/icon`,
+ );
+ warnSpy.mockRestore();
+ });
});
diff --git a/components/modal/confirm.tsx b/components/modal/confirm.tsx
index 2e598ca8d2..e81f48060e 100644
--- a/components/modal/confirm.tsx
+++ b/components/modal/confirm.tsx
@@ -5,6 +5,7 @@ import classNames from 'classnames';
import Dialog, { ModalFuncProps, destroyFns } from './Modal';
import ActionButton from './ActionButton';
import { getConfirmLocale } from './locale';
+import warning from '../_util/warning';
interface ConfirmDialogProps extends ModalFuncProps {
afterClose?: () => void;
@@ -31,6 +32,12 @@ const ConfirmDialog = (props: ConfirmDialogProps) => {
cancelButtonProps,
} = props;
+ warning(
+ !(typeof icon === 'string' && icon.length > 2),
+ 'Modal',
+ `\`icon\` is using ReactNode instead of string naming in v4. Please check \`${icon}\` at https://ant.design/components/icon`,
+ );
+
// 支持传入{ icon: null }来隐藏`Modal.confirm`默认的Icon
const okType = props.okType || 'primary';
const prefixCls = props.prefixCls || 'ant-modal';
diff --git a/components/result/__tests__/index.test.js b/components/result/__tests__/index.test.js
index f01a4c4577..85b3f61001 100644
--- a/components/result/__tests__/index.test.js
+++ b/components/result/__tests__/index.test.js
@@ -55,4 +55,15 @@ describe('Result', () => {
const wrapper = mount();
expect(wrapper.find('.ant-result.my-result')).toHaveLength(1);
});
+
+ it('should warning when pass a string as icon props', () => {
+ const warnSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
+ mount();
+ expect(warnSpy).not.toHaveBeenCalled();
+ mount();
+ expect(warnSpy).toHaveBeenCalledWith(
+ `Warning: [antd: Result] \`icon\` is using ReactNode instead of string naming in v4. Please check \`smile\` at https://ant.design/components/icon`,
+ );
+ warnSpy.mockRestore();
+ });
});
diff --git a/components/result/index.tsx b/components/result/index.tsx
index de26295fbc..568a6c7cbc 100644
--- a/components/result/index.tsx
+++ b/components/result/index.tsx
@@ -8,6 +8,7 @@ import {
} from '@ant-design/icons';
import { ConfigConsumerProps, ConfigConsumer } from '../config-provider';
+import warning from '../_util/warning';
import noFound from './noFound';
import serverError from './serverError';
@@ -53,6 +54,12 @@ const ExceptionStatus = Object.keys(ExceptionMap);
const renderIcon = (prefixCls: string, { status, icon }: ResultProps) => {
const className = classnames(`${prefixCls}-icon`);
+ warning(
+ !(typeof icon === 'string' && icon.length > 2),
+ 'Result',
+ `\`icon\` is using ReactNode instead of string naming in v4. Please check \`${icon}\` at https://ant.design/components/icon`,
+ );
+
if (ExceptionStatus.includes(status as ResultStatusType)) {
const SVGComponent = ExceptionMap[status as ExceptionStatusType];
return (