mirror of
https://github.com/ant-design/ant-design.git
synced 2025-01-18 06:03:38 +08:00
refactor(Alert): refactor closeIcon (#42962)
* refactor: refactor closeIcon * feat: update test case * feat: optimize code * feat: remove demo about closeText * feat: remove demo about closeText * feat: optimize code * feat: optimize code * feat: optimize code * feat: optimize code * feat: optimize code * feat: optimize code * feat: optimize code * feat: optimize code
This commit is contained in:
parent
d8f06c4779
commit
827ada2da6
@ -576,35 +576,6 @@ exports[`renders components/alert/demo/closable.tsx extend context correctly 1`]
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders components/alert/demo/close-text.tsx extend context correctly 1`] = `
|
||||
<div
|
||||
class="ant-alert ant-alert-info ant-alert-no-icon"
|
||||
data-show="true"
|
||||
role="alert"
|
||||
>
|
||||
<div
|
||||
class="ant-alert-content"
|
||||
>
|
||||
<div
|
||||
class="ant-alert-message"
|
||||
>
|
||||
Info Text
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
class="ant-alert-close-icon"
|
||||
tabindex="0"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="ant-alert-close-text"
|
||||
>
|
||||
Close Now
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders components/alert/demo/custom-icon.tsx extend context correctly 1`] = `
|
||||
<div
|
||||
class="ant-space ant-space-vertical"
|
||||
|
@ -576,35 +576,6 @@ exports[`renders components/alert/demo/closable.tsx correctly 1`] = `
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders components/alert/demo/close-text.tsx correctly 1`] = `
|
||||
<div
|
||||
class="ant-alert ant-alert-info ant-alert-no-icon"
|
||||
data-show="true"
|
||||
role="alert"
|
||||
>
|
||||
<div
|
||||
class="ant-alert-content"
|
||||
>
|
||||
<div
|
||||
class="ant-alert-message"
|
||||
>
|
||||
Info Text
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
class="ant-alert-close-icon"
|
||||
tabindex="0"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="ant-alert-close-text"
|
||||
>
|
||||
Close Now
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders components/alert/demo/custom-icon.tsx correctly 1`] = `
|
||||
<div
|
||||
class="ant-space ant-space-vertical"
|
||||
|
@ -1,4 +1,5 @@
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { resetWarned } from 'rc-util/lib/warning';
|
||||
import React from 'react';
|
||||
import Alert from '..';
|
||||
import accessibilityTest from '../../../tests/shared/accessibilityTest';
|
||||
@ -141,4 +142,30 @@ describe('Alert', () => {
|
||||
const { container } = render(<Alert description="description" />);
|
||||
expect(!!container.querySelector('.ant-alert-message')).toBe(false);
|
||||
});
|
||||
|
||||
it('close button should be hidden when closeIcon setting to null or false', () => {
|
||||
const { container, rerender } = render(<Alert closeIcon={null} />);
|
||||
expect(container.querySelector('.ant-alert-close-icon')).toBeFalsy();
|
||||
rerender(<Alert closeIcon={false} />);
|
||||
expect(container.querySelector('.ant-alert-close-icon')).toBeFalsy();
|
||||
rerender(<Alert closeIcon />);
|
||||
expect(container.querySelector('.ant-alert-close-icon')).toBeTruthy();
|
||||
rerender(<Alert />);
|
||||
expect(container.querySelector('.ant-alert-close-icon')).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should warning when using closeText', () => {
|
||||
resetWarned();
|
||||
const warnSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
|
||||
const { container } = render(<Alert closeText="close" />);
|
||||
|
||||
expect(warnSpy).toHaveBeenCalledWith(
|
||||
`Warning: [antd: Alert] \`closeText\` is deprecated. Please use \`closeIcon\` instead.`,
|
||||
);
|
||||
|
||||
expect(container.querySelector('.ant-alert-close-icon')?.textContent).toBe('close');
|
||||
|
||||
warnSpy.mockRestore();
|
||||
});
|
||||
});
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { Alert, Space } from 'antd';
|
||||
import React from 'react';
|
||||
|
||||
const onClose = (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
|
||||
console.log(e, 'I was closed.');
|
||||
@ -10,14 +10,14 @@ const App: React.FC = () => (
|
||||
<Alert
|
||||
message="Warning Text Warning Text Warning TextW arning Text Warning Text Warning TextWarning Text"
|
||||
type="warning"
|
||||
closable
|
||||
closeIcon
|
||||
onClose={onClose}
|
||||
/>
|
||||
<Alert
|
||||
message="Error Text"
|
||||
description="Error Description Error Description Error Description Error Description Error Description Error Description"
|
||||
type="error"
|
||||
closable
|
||||
closeIcon
|
||||
onClose={onClose}
|
||||
/>
|
||||
</Space>
|
||||
|
@ -1,7 +0,0 @@
|
||||
## zh-CN
|
||||
|
||||
可以自定义关闭,自定义的文字会替换原先的关闭 `Icon`。
|
||||
|
||||
## en-US
|
||||
|
||||
Replace the default icon with customized text.
|
@ -1,6 +0,0 @@
|
||||
import React from 'react';
|
||||
import { Alert } from 'antd';
|
||||
|
||||
const App: React.FC = () => <Alert message="Info Text" type="info" closeText="Close Now" />;
|
||||
|
||||
export default App;
|
@ -25,7 +25,6 @@ Alert component for feedback.
|
||||
<code src="./demo/closable.tsx">Closable</code>
|
||||
<code src="./demo/description.tsx">Description</code>
|
||||
<code src="./demo/icon.tsx">Icon</code>
|
||||
<code src="./demo/close-text.tsx">Customized Close Text</code>
|
||||
<code src="./demo/banner.tsx" iframe="250">Banner</code>
|
||||
<code src="./demo/loop-banner.tsx">Loop Banner</code>
|
||||
<code src="./demo/smooth-closed.tsx">Smoothly Unmount</code>
|
||||
@ -40,9 +39,7 @@ Alert component for feedback.
|
||||
| action | The action of Alert | ReactNode | - | 4.9.0 |
|
||||
| afterClose | Called when close animation is finished | () => void | - | |
|
||||
| banner | Whether to show as banner | boolean | false | |
|
||||
| closable | Whether Alert can be closed | boolean | - | |
|
||||
| closeText | Close text to show | ReactNode | - | |
|
||||
| closeIcon | Custom close icon | ReactNode | `<CloseOutlined />` | 4.18.0 |
|
||||
| closeIcon | Custom close icon, >=5.7.0: close button will be hidden when setting to `null` or `false` | boolean \| ReactNode | `<CloseOutlined />` | |
|
||||
| description | Additional content of Alert | ReactNode | - | |
|
||||
| icon | Custom icon, effective when `showIcon` is true | ReactNode | - | |
|
||||
| message | Content of Alert | ReactNode | - | |
|
||||
|
@ -9,6 +9,7 @@ import pickAttrs from 'rc-util/lib/pickAttrs';
|
||||
import type { ReactElement } from 'react';
|
||||
import * as React from 'react';
|
||||
import { replaceElement } from '../_util/reactNode';
|
||||
import warning from '../_util/warning';
|
||||
import { ConfigContext } from '../config-provider';
|
||||
import ErrorBoundary from './ErrorBoundary';
|
||||
|
||||
@ -20,7 +21,10 @@ export interface AlertProps {
|
||||
type?: 'success' | 'info' | 'warning' | 'error';
|
||||
/** Whether Alert can be closed */
|
||||
closable?: boolean;
|
||||
/** Close text to show */
|
||||
/**
|
||||
* @deprecated please use `closeIcon` instead.
|
||||
* Close text to show
|
||||
*/
|
||||
closeText?: React.ReactNode;
|
||||
/** Content of Alert */
|
||||
message?: React.ReactNode;
|
||||
@ -41,7 +45,7 @@ export interface AlertProps {
|
||||
banner?: boolean;
|
||||
icon?: React.ReactNode;
|
||||
/** Custom closeIcon */
|
||||
closeIcon?: React.ReactNode;
|
||||
closeIcon?: boolean | React.ReactNode;
|
||||
action?: React.ReactNode;
|
||||
onMouseEnter?: React.MouseEventHandler<HTMLDivElement>;
|
||||
onMouseLeave?: React.MouseEventHandler<HTMLDivElement>;
|
||||
@ -78,16 +82,17 @@ const IconNode: React.FC<IconNodeProps> = (props) => {
|
||||
interface CloseIconProps {
|
||||
isClosable: boolean;
|
||||
prefixCls: AlertProps['prefixCls'];
|
||||
closeText: AlertProps['closeText'];
|
||||
closeIcon: AlertProps['closeIcon'];
|
||||
handleClose: AlertProps['onClose'];
|
||||
}
|
||||
|
||||
const CloseIcon: React.FC<CloseIconProps> = (props) => {
|
||||
const { isClosable, closeText, prefixCls, closeIcon, handleClose } = props;
|
||||
const { isClosable, prefixCls, closeIcon, handleClose } = props;
|
||||
const mergedCloseIcon =
|
||||
closeIcon === true || closeIcon === undefined ? <CloseOutlined /> : closeIcon;
|
||||
return isClosable ? (
|
||||
<button type="button" onClick={handleClose} className={`${prefixCls}-close-icon`} tabIndex={0}>
|
||||
{closeText ? <span className={`${prefixCls}-close-text`}>{closeText}</span> : closeIcon}
|
||||
{mergedCloseIcon}
|
||||
</button>
|
||||
) : null;
|
||||
};
|
||||
@ -111,12 +116,14 @@ const Alert: CompoundedComponent = ({
|
||||
showIcon,
|
||||
closable,
|
||||
closeText,
|
||||
closeIcon = <CloseOutlined />,
|
||||
closeIcon,
|
||||
action,
|
||||
...props
|
||||
}) => {
|
||||
const [closed, setClosed] = React.useState(false);
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
warning(!closeText, 'Alert', '`closeText` is deprecated. Please use `closeIcon` instead.');
|
||||
}
|
||||
const ref = React.useRef<HTMLDivElement>(null);
|
||||
const { getPrefixCls, direction } = React.useContext(ConfigContext);
|
||||
const prefixCls = getPrefixCls('alert', customizePrefixCls);
|
||||
@ -136,8 +143,18 @@ const Alert: CompoundedComponent = ({
|
||||
return banner ? 'warning' : 'info';
|
||||
};
|
||||
|
||||
// closeable when closeText is assigned
|
||||
const isClosable = closeText ? true : closable;
|
||||
// closeable when closeText or closeIcon is assigned
|
||||
const isClosable = React.useMemo(() => {
|
||||
if (closeText) {
|
||||
return true;
|
||||
}
|
||||
if (typeof closable === 'boolean') {
|
||||
return closable;
|
||||
}
|
||||
// should be true when closeIcon is 0 or ''
|
||||
return closeIcon !== false && closeIcon !== null && closeIcon !== undefined;
|
||||
}, [closeText, closeIcon, closable]);
|
||||
|
||||
const type = getType();
|
||||
|
||||
// banner mode defaults to Icon
|
||||
@ -199,10 +216,9 @@ const Alert: CompoundedComponent = ({
|
||||
</div>
|
||||
{action ? <div className={`${prefixCls}-action`}>{action}</div> : null}
|
||||
<CloseIcon
|
||||
isClosable={!!isClosable}
|
||||
closeText={closeText}
|
||||
isClosable={isClosable}
|
||||
prefixCls={prefixCls}
|
||||
closeIcon={closeIcon}
|
||||
closeIcon={closeText || closeIcon}
|
||||
handleClose={handleClose}
|
||||
/>
|
||||
</div>
|
||||
|
@ -26,7 +26,6 @@ group:
|
||||
<code src="./demo/closable.tsx">可关闭的警告提示</code>
|
||||
<code src="./demo/description.tsx">含有辅助性文字介绍</code>
|
||||
<code src="./demo/icon.tsx">图标</code>
|
||||
<code src="./demo/close-text.tsx">自定义关闭</code>
|
||||
<code src="./demo/banner.tsx" iframe="250">顶部公告</code>
|
||||
<code src="./demo/loop-banner.tsx">轮播的公告</code>
|
||||
<code src="./demo/smooth-closed.tsx">平滑地卸载</code>
|
||||
@ -41,9 +40,7 @@ group:
|
||||
| action | 自定义操作项 | ReactNode | - | 4.9.0 |
|
||||
| afterClose | 关闭动画结束后触发的回调函数 | () => void | - | |
|
||||
| banner | 是否用作顶部公告 | boolean | false | |
|
||||
| closable | 默认不显示关闭按钮 | boolean | - | |
|
||||
| closeText | 自定义关闭按钮 | ReactNode | - | |
|
||||
| closeIcon | 自定义关闭 Icon | ReactNode | `<CloseOutlined />` | 4.18.0 |
|
||||
| closeIcon | 自定义关闭 Icon,>=5.7.0: 设置为 `null` 或 `false` 时隐藏关闭按钮 | boolean \| ReactNode | `<CloseOutlined />` | |
|
||||
| description | 警告提示的辅助性文字介绍 | ReactNode | - | |
|
||||
| icon | 自定义图标,`showIcon` 为 true 时有效 | ReactNode | - | |
|
||||
| message | 警告提示内容 | ReactNode | - | |
|
||||
|
Loading…
Reference in New Issue
Block a user