fix: drawer close speed (#35339)

* fix: drawer close speed

* chroe: snap

* chroe: test

* chroe: test

* feat: remove file

* feat: 重新整理

* feat: forceRender

* feat: snap

* chroe: test

* chroe: test

* chroe: test

* feat: create event

* feat: diff code

* feat: forceRender

* chore: test (#35364)

* Update components/drawer/index.tsx

Co-authored-by: afc163 <afc163@gmail.com>

* feat: remove load state

* feat: test

* fix: destroyOnClose

* feat: add load

* fix: update snap

* fix: update snap

* feat: reset test

* feat: docs

* feat: test

* feat: test

Co-authored-by: afc163 <afc163@gmail.com>
This commit is contained in:
叶枫 2022-05-16 10:14:26 +08:00 committed by GitHub
parent 47d40325fe
commit 644e4bfc6a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 53 additions and 39 deletions

View File

@ -50,7 +50,9 @@ describe('Drawer', () => {
const { container, rerender } = render(getDrawer({ destroyOnClose: true }));
rerender(getDrawer({ destroyOnClose: true, visible: false }));
fireEvent.transitionEnd(container.querySelector('.ant-drawer-wrapper-body'));
const ev = new TransitionEvent('transitionend', { bubbles: true });
ev.propertyName = 'transform';
fireEvent(document.querySelector('.ant-drawer-content-wrapper'), ev);
expect(container.querySelector('.ant-drawer-wrapper-body')).toBeFalsy();
});
@ -60,8 +62,19 @@ describe('Drawer', () => {
expect(container.querySelector('.ant-drawer-wrapper-body')).toBeTruthy();
rerender(getDrawer({ visible: false }));
fireEvent.transitionEnd(container.querySelector('.ant-drawer-wrapper-body'));
const ev = new TransitionEvent('transitionend', { bubbles: true });
ev.propertyName = 'transform';
fireEvent(document.querySelector('.ant-drawer-content-wrapper'), ev);
expect(container.querySelector('.ant-drawer-wrapper-body')).toBeTruthy();
});
it('test afterVisibleChange', async () => {
const afterVisibleChange = jest.fn();
const { rerender } = render(getDrawer({ afterVisibleChange, visible: true }));
rerender(getDrawer({ afterVisibleChange, visible: false }));
const ev = new TransitionEvent('transitionend', { bubbles: true });
ev.propertyName = 'transform';
fireEvent(document.querySelector('.ant-drawer-content-wrapper'), ev);
expect(afterVisibleChange).toBeCalledTimes(1);
});
});

View File

@ -20,7 +20,6 @@ exports[`Drawer className is test_drawer 1`] = `
>
<div
class="ant-drawer-wrapper-body"
style="opacity: 0; transition: opacity .3s;"
>
<div
class="ant-drawer-header ant-drawer-header-close-only"
@ -120,7 +119,6 @@ exports[`Drawer destroyOnClose is true 1`] = `
>
<div
class="ant-drawer-wrapper-body"
style="opacity: 0; transition: opacity .3s;"
>
<div
class="ant-drawer-header ant-drawer-header-close-only"

View File

@ -4,7 +4,6 @@ import CloseOutlined from '@ant-design/icons/CloseOutlined';
import classNames from 'classnames';
import { ConfigContext } from '../config-provider';
import { tuple } from '../_util/type';
import useForceUpdate from '../_util/hooks/useForceUpdate';
type DrawerRef = {
push(): void;
@ -87,7 +86,8 @@ const Drawer = React.forwardRef<DrawerRef, DrawerProps>(
bodyStyle,
drawerStyle,
className,
visible,
visible: propsVisible,
forceRender,
children,
zIndex,
destroyOnClose,
@ -100,14 +100,31 @@ const Drawer = React.forwardRef<DrawerRef, DrawerProps>(
prefixCls: customizePrefixCls,
getContainer: customizeGetContainer,
extra,
afterVisibleChange,
...rest
},
ref,
) => {
const forceUpdate = useForceUpdate();
const [internalPush, setPush] = React.useState(false);
const parentDrawer = React.useContext(DrawerContext);
const destroyClose = React.useRef<boolean>(false);
const destroyCloseRef = React.useRef<boolean>(false);
const [load, setLoad] = React.useState(false);
const [visible, setVisible] = React.useState(false);
React.useEffect(() => {
if (propsVisible) {
setLoad(true);
} else {
setVisible(false);
}
}, [propsVisible]);
React.useEffect(() => {
if (load && propsVisible) {
setVisible(true);
}
}, [load, propsVisible]);
const { getPopupContainer, getPrefixCls, direction } = React.useContext(ConfigContext);
const prefixCls = getPrefixCls('drawer', customizePrefixCls);
@ -120,7 +137,7 @@ const Drawer = React.forwardRef<DrawerRef, DrawerProps>(
React.useEffect(() => {
// fix: delete drawer in child and re-render, no push started.
// <Drawer>{show && <Drawer />}</Drawer>
if (visible && parentDrawer) {
if (propsVisible && parentDrawer) {
parentDrawer.push();
}
@ -160,18 +177,6 @@ const Drawer = React.forwardRef<DrawerRef, DrawerProps>(
React.useImperativeHandle(ref, () => operations, [operations]);
const isDestroyOnClose = destroyOnClose && !visible;
const onDestroyTransitionEnd = () => {
if (!isDestroyOnClose) {
return;
}
if (!visible) {
destroyClose.current = true;
forceUpdate();
}
};
const getOffsetStyle = () => {
// https://github.com/ant-design/ant-design/issues/24287
if (!visible && !mask) {
@ -260,28 +265,13 @@ const Drawer = React.forwardRef<DrawerRef, DrawerProps>(
// render drawer body dom
const renderBody = () => {
if (destroyClose.current && !visible) {
// destroyCloseRef.current =false Load the body only once by default
if (destroyCloseRef.current && !forceRender && !load) {
return null;
}
destroyClose.current = false;
const containerStyle: React.CSSProperties = {};
if (isDestroyOnClose) {
// Increase the opacity transition, delete children after closing.
containerStyle.opacity = 0;
containerStyle.transition = 'opacity .3s';
}
return (
<div
className={`${prefixCls}-wrapper-body`}
style={{
...containerStyle,
...drawerStyle,
}}
onTransitionEnd={onDestroyTransitionEnd}
>
<div className={`${prefixCls}-wrapper-body`} style={{ ...drawerStyle }}>
{renderHeader()}
<div className={`${prefixCls}-body`} style={bodyStyle}>
{children}
@ -312,6 +302,7 @@ const Drawer = React.forwardRef<DrawerRef, DrawerProps>(
keyboard,
children,
onClose,
forceRender,
...rest,
}}
{...offsetStyle}
@ -320,6 +311,18 @@ const Drawer = React.forwardRef<DrawerRef, DrawerProps>(
style={getRcDrawerStyle()}
className={drawerClassName}
getContainer={getContainer}
afterVisibleChange={open => {
if (!open) {
if (destroyCloseRef.current === false) {
// set true only once
destroyCloseRef.current = true;
}
if (destroyOnClose) {
setLoad(false);
}
}
afterVisibleChange?.(open);
}}
>
{renderBody()}
</RcDrawer>