Browse Source

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
pull/43011/head
kiner-tang(文辉) 1 year ago
committed by GitHub
parent
commit
827ada2da6
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 29
      components/alert/__tests__/__snapshots__/demo-extend.test.ts.snap
  2. 29
      components/alert/__tests__/__snapshots__/demo.test.ts.snap
  3. 27
      components/alert/__tests__/index.test.tsx
  4. 6
      components/alert/demo/closable.tsx
  5. 7
      components/alert/demo/close-text.md
  6. 6
      components/alert/demo/close-text.tsx
  7. 5
      components/alert/index.en-US.md
  8. 40
      components/alert/index.tsx
  9. 5
      components/alert/index.zh-CN.md

29
components/alert/__tests__/__snapshots__/demo-extend.test.ts.snap

@ -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"

29
components/alert/__tests__/__snapshots__/demo.test.ts.snap

@ -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"

27
components/alert/__tests__/index.test.tsx

@ -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();
});
});

6
components/alert/demo/closable.tsx

@ -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>

7
components/alert/demo/close-text.md

@ -1,7 +0,0 @@
## zh-CN
可以自定义关闭,自定义的文字会替换原先的关闭 `Icon`
## en-US
Replace the default icon with customized text.

6
components/alert/demo/close-text.tsx

@ -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;

5
components/alert/index.en-US.md

@ -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 | - | |

40
components/alert/index.tsx

@ -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>

5
components/alert/index.zh-CN.md

@ -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…
Cancel
Save