fix: upload button position flashes when it changes from hidden to displayed (#33820)

* fix: fix upload button position flashes when it changes from hidden to displayed (#33819)

* fix: typo in upload

Co-authored-by: chenqiufan <chenqiufan@shiqiao.com>
This commit is contained in:
Cole 2022-01-25 11:20:46 +08:00 committed by GitHub
parent 8217c544da
commit dc019dca56
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 34 additions and 6 deletions

View File

@ -322,7 +322,7 @@ const InternalUpload: React.ForwardRefRenderFunction<unknown, UploadProps> = (pr
delete rcUploadProps.id; delete rcUploadProps.id;
} }
const renderUploadList = (button?: React.ReactNode) => const renderUploadList = (button?: React.ReactNode, buttonVisible?: boolean) =>
showUploadList ? ( showUploadList ? (
<LocaleReceiver componentName="Upload" defaultLocale={defaultLocale.Upload}> <LocaleReceiver componentName="Upload" defaultLocale={defaultLocale.Upload}>
{(locale: UploadLocale) => { {(locale: UploadLocale) => {
@ -354,6 +354,7 @@ const InternalUpload: React.ForwardRefRenderFunction<unknown, UploadProps> = (pr
isImageUrl={isImageUrl} isImageUrl={isImageUrl}
progress={progress} progress={progress}
appendAction={button} appendAction={button}
appendActionVisible={buttonVisible}
itemRender={itemRender} itemRender={itemRender}
/> />
); );
@ -400,8 +401,8 @@ const InternalUpload: React.ForwardRefRenderFunction<unknown, UploadProps> = (pr
[`${prefixCls}-rtl`]: direction === 'rtl', [`${prefixCls}-rtl`]: direction === 'rtl',
}); });
const uploadButton = ( const renderUploadButton = (uploadButtonStyle?: React.CSSProperties) => (
<div className={uploadButtonCls} style={children ? undefined : { display: 'none' }}> <div className={uploadButtonCls} style={uploadButtonStyle}>
<RcUpload {...rcUploadProps} ref={upload} /> <RcUpload {...rcUploadProps} ref={upload} />
</div> </div>
); );
@ -409,14 +410,14 @@ const InternalUpload: React.ForwardRefRenderFunction<unknown, UploadProps> = (pr
if (listType === 'picture-card') { if (listType === 'picture-card') {
return ( return (
<span className={classNames(`${prefixCls}-picture-card-wrapper`, className)}> <span className={classNames(`${prefixCls}-picture-card-wrapper`, className)}>
{renderUploadList(uploadButton)} {renderUploadList(renderUploadButton(), !!children)}
</span> </span>
); );
} }
return ( return (
<span className={className}> <span className={className}>
{uploadButton} {renderUploadButton(children ? undefined : { display: 'none' })}
{renderUploadList()} {renderUploadList()}
</span> </span>
); );

View File

@ -42,6 +42,7 @@ const InternalUploadList: React.ForwardRefRenderFunction<unknown, UploadListProp
downloadIcon, downloadIcon,
progress, progress,
appendAction, appendAction,
appendActionVisible,
itemRender, itemRender,
}, },
ref, ref,
@ -225,12 +226,14 @@ const InternalUploadList: React.ForwardRefRenderFunction<unknown, UploadListProp
{/* Append action */} {/* Append action */}
{appendAction && ( {appendAction && (
<CSSMotion {...motionConfig}> <CSSMotion {...motionConfig} visible={appendActionVisible} forceRender>
{({ className: motionClassName, style: motionStyle }) => {({ className: motionClassName, style: motionStyle }) =>
cloneElement(appendAction, oriProps => ({ cloneElement(appendAction, oriProps => ({
className: classNames(oriProps.className, motionClassName), className: classNames(oriProps.className, motionClassName),
style: { style: {
...motionStyle, ...motionStyle,
// prevent the element has hover css pseudo-class that may cause animation to end prematurely.
pointerEvents: motionClassName ? 'none' : undefined,
...oriProps.style, ...oriProps.style,
}, },
})) }))
@ -254,6 +257,7 @@ UploadList.defaultProps = {
showRemoveIcon: true, showRemoveIcon: true,
showDownloadIcon: false, showDownloadIcon: false,
showPreviewIcon: true, showPreviewIcon: true,
appendActionVisible: true,
previewFile: previewImage, previewFile: previewImage,
isImageUrl, isImageUrl,
}; };

View File

@ -867,4 +867,26 @@ describe('Upload', () => {
expect(onChange.mock.calls[0][0].fileList).toHaveLength(1); expect(onChange.mock.calls[0][0].fileList).toHaveLength(1);
}); });
// https://github.com/ant-design/ant-design/issues/33819
it('should show the animation of the upload children leaving when the upload children becomes null', async () => {
const wrapper = mount(
<Upload listType="picture-card">
<button type="button">upload</button>
</Upload>,
);
wrapper.setProps({ children: null });
expect(wrapper.find('.ant-upload-select-picture-card').getDOMNode().style.display).not.toBe(
'none',
);
await act(async () => {
await sleep(100);
wrapper
.find('.ant-upload-select-picture-card')
.getDOMNode()
.dispatchEvent(new Event('animationend'));
await sleep(20);
});
expect(wrapper.find('.ant-upload-select-picture-card').getDOMNode().style.display).toBe('none');
});
}); });

View File

@ -155,5 +155,6 @@ export interface UploadListProps<T = any> {
iconRender?: (file: UploadFile<T>, listType?: UploadListType) => React.ReactNode; iconRender?: (file: UploadFile<T>, listType?: UploadListType) => React.ReactNode;
isImageUrl?: (file: UploadFile) => boolean; isImageUrl?: (file: UploadFile) => boolean;
appendAction?: React.ReactNode; appendAction?: React.ReactNode;
appendActionVisible?: boolean;
itemRender?: ItemRender<T>; itemRender?: ItemRender<T>;
} }