refactor(Drawer): refactor drawer closeIcon (#42993)

* feat: optimize closeIcon

* refactor: refactor closeIcon

* docs: update docs

* feat: optimize code

* feat: update test case

* feat: optimize code

* feat: optimize code

* feat: optimize code

* feat: optimize code

* feat: optimize code

* feat: optimize code

* docs: update docs
This commit is contained in:
kiner-tang(文辉) 2023-06-14 22:37:00 +08:00 committed by GitHub
parent 5d62e636a1
commit cf961b2c8c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 102 additions and 13 deletions

View File

@ -9,9 +9,15 @@ export interface DrawerPanelProps {
title?: React.ReactNode;
footer?: React.ReactNode;
extra?: React.ReactNode;
/**
* advised to use closeIcon instead
*
* e.g.
*
* `<Drawer closeIcon={false} />`
*/
closable?: boolean;
closeIcon?: React.ReactNode;
closeIcon?: boolean | React.ReactNode;
onClose?: RCDrawerProps['onClose'];
/** Wrapper dom node style of header and body */
@ -28,8 +34,8 @@ const DrawerPanel: React.FC<DrawerPanelProps> = (props) => {
title,
footer,
extra,
closable = true,
closeIcon = <CloseOutlined />,
closeIcon,
closable,
onClose,
headerStyle,
drawerStyle,
@ -38,21 +44,39 @@ const DrawerPanel: React.FC<DrawerPanelProps> = (props) => {
children,
} = props;
const closeIconNode = closable && (
const mergedClosable = React.useMemo(() => {
if (typeof closable === 'boolean') {
return closable;
}
return closeIcon !== null && closeIcon !== false;
}, [closable, closeIcon]);
const mergedCloseIcon = React.useMemo(() => {
if (!mergedClosable) {
return null;
}
if (closeIcon === undefined || closeIcon === true) {
return <CloseOutlined />;
}
return closeIcon;
}, [closeIcon, mergedClosable]);
const closeIconNode = mergedClosable && (
<button type="button" onClick={onClose} aria-label="Close" className={`${prefixCls}-close`}>
{closeIcon}
{mergedCloseIcon}
</button>
);
const headerNode = React.useMemo<React.ReactNode>(() => {
if (!title && !closable) {
if (!title && !mergedClosable) {
return null;
}
return (
<div
style={headerStyle}
className={classNames(`${prefixCls}-header`, {
[`${prefixCls}-header-close-only`]: closable && !title && !extra,
[`${prefixCls}-header-close-only`]: mergedClosable && !title && !extra,
})}
>
<div className={`${prefixCls}-header-title`}>
@ -62,7 +86,7 @@ const DrawerPanel: React.FC<DrawerPanelProps> = (props) => {
{extra && <div className={`${prefixCls}-extra`}>{extra}</div>}
</div>
);
}, [closable, closeIconNode, extra, headerStyle, prefixCls, title]);
}, [mergedClosable, closeIconNode, extra, headerStyle, prefixCls, title]);
const footerNode = React.useMemo<React.ReactNode>(() => {
if (!footer) {

View File

@ -242,5 +242,72 @@ describe('Drawer', () => {
errorSpy.mockRestore();
});
it('should hide close button when closeIcon is null or false', async () => {
const { baseElement, rerender } = render(
<Drawer open closeIcon={null}>
Here is content of Drawer
</Drawer>,
);
expect(baseElement.querySelector('.ant-drawer-close')).toBeNull();
rerender(
<Drawer open closeIcon={false}>
Here is content of Drawer
</Drawer>,
);
expect(baseElement.querySelector('.ant-drawer-close')).toBeNull();
rerender(
<Drawer open closeIcon={<span className="custom-close">Close</span>}>
Here is content of Drawer
</Drawer>,
);
expect(baseElement.querySelector('.custom-close')).not.toBeNull();
rerender(
<Drawer open closable={false} closeIcon={<span className="custom-close2">Close</span>}>
Here is content of Drawer
</Drawer>,
);
expect(baseElement.querySelector('.custom-close2')).toBeNull();
rerender(
<Drawer open closable closeIcon={<span className="custom-close3">Close</span>}>
Here is content of Drawer
</Drawer>,
);
expect(baseElement.querySelector('.custom-close3')).not.toBeNull();
rerender(
<Drawer open closeIcon={0} className="custom-drawer1">
Here is content of Drawer
</Drawer>,
);
expect(baseElement.querySelector('.custom-drawer1 .ant-drawer-close')).not.toBeNull();
expect(baseElement.querySelector('.custom-drawer1 .anticon-close')).toBeNull();
rerender(
<Drawer open closeIcon="" className="custom-drawer2">
Here is content of Drawer
</Drawer>,
);
expect(baseElement.querySelector('.custom-drawer2 .ant-drawer-close')).not.toBeNull();
expect(baseElement.querySelector('.custom-drawer2 .anticon-close')).toBeNull();
rerender(
<Drawer open closeIcon className="custom-drawer3">
Here is content of Drawer
</Drawer>,
);
expect(baseElement.querySelector('.custom-drawer3 .anticon-close')).not.toBeNull();
rerender(
<Drawer open closable>
Here is content of Drawer
</Drawer>,
);
expect(baseElement.querySelector('.anticon-close')).not.toBeNull();
});
});
});

View File

@ -46,8 +46,7 @@ A Drawer is a panel that is typically overlaid on top of a page and slides in fr
| afterOpenChange | Callback after the animation ends when switching drawers | function(open) | - | |
| bodyStyle | Style of the drawer content part | CSSProperties | - | |
| className | Config Drawer Panel className. Use `rootClassName` if want to config top dom style | string | - | |
| closable | Whether a close (x) button is visible on top left of the Drawer dialog or not | boolean | true | |
| closeIcon | Custom close icon | ReactNode | &lt;CloseOutlined /> | |
| closeIcon | Custom close icon. 5.7.0: close button will be hidden when setting to `null` or `false` | boolean \| ReactNode | &lt;CloseOutlined /> | |
| contentWrapperStyle | Style of the drawer wrapper of content part | CSSProperties | - | |
| destroyOnClose | Whether to unmount child components on closing drawer or not | boolean | false | |
| extra | Extra actions area at corner | ReactNode | - | 4.17.0 |

View File

@ -45,8 +45,7 @@ demo:
| afterOpenChange | 切换抽屉时动画结束后的回调 | function(open) | - | |
| bodyStyle | 可用于设置 Drawer 内容部分的样式 | CSSProperties | - | |
| className | Drawer 容器外层 className 设置,如果需要设置最外层,请使用 rootClassName | string | - | |
| closable | 是否显示左上角的关闭按钮 | boolean | true | |
| closeIcon | 自定义关闭图标 | ReactNode | &lt;CloseOutlined /> | |
| closeIcon | 自定义关闭图标。5.7.0:设置为 `null``false` 时隐藏关闭按钮 | boolean \| ReactNode | &lt;CloseOutlined /> | |
| contentWrapperStyle | 可用于设置 Drawer 包裹内容部分的样式 | CSSProperties | - | |
| destroyOnClose | 关闭时销毁 Drawer 里的子元素 | boolean | false | |
| extra | 抽屉右上角的操作区域 | ReactNode | - | 4.17.0 |