import * as React from 'react'; import Animate from 'rc-animate'; import classNames from 'classnames'; import { UploadListProps, UploadFile, UploadListType } from './interface'; import { previewImage, isImageUrl } from './utils'; import Icon from '../icon'; import Tooltip from '../tooltip'; import Progress from '../progress'; import { ConfigConsumer, ConfigConsumerProps } from '../config-provider'; export default class UploadList extends React.Component { static defaultProps = { listType: 'text' as UploadListType, // or picture progressAttr: { strokeWidth: 2, showInfo: false, }, showRemoveIcon: true, showPreviewIcon: true, previewFile: previewImage, }; handleClose = (file: UploadFile) => { const { onRemove } = this.props; if (onRemove) { onRemove(file); } }; handlePreview = (file: UploadFile, e: React.SyntheticEvent) => { const { onPreview } = this.props; if (!onPreview) { return; } e.preventDefault(); return onPreview(file); }; componentDidUpdate() { const { listType, items, previewFile } = this.props; if (listType !== 'picture' && listType !== 'picture-card') { return; } (items || []).forEach(file => { if ( typeof document === 'undefined' || typeof window === 'undefined' || !(window as any).FileReader || !(window as any).File || !(file.originFileObj instanceof File) || file.thumbUrl !== undefined ) { return; } file.thumbUrl = ''; if (previewFile) { previewFile(file.originFileObj).then((previewDataUrl: string) => { // Need append '' to avoid dead loop file.thumbUrl = previewDataUrl || ''; this.forceUpdate(); }); } }); } renderUploadList = ({ getPrefixCls }: ConfigConsumerProps) => { const { prefixCls: customizePrefixCls, items = [], listType, showPreviewIcon, showRemoveIcon, locale, } = this.props; const prefixCls = getPrefixCls('upload', customizePrefixCls); const list = items.map(file => { let progress; let icon = ; if (listType === 'picture' || listType === 'picture-card') { if (listType === 'picture-card' && file.status === 'uploading') { icon =
{locale.uploading}
; } else if (!file.thumbUrl && !file.url) { icon = ( ); } else { const thumbnail = isImageUrl(file) ? ( {file.name} ) : ( ); icon = ( this.handlePreview(file, e)} href={file.url || file.thumbUrl} target="_blank" rel="noopener noreferrer" > {thumbnail} ); } } if (file.status === 'uploading') { // show loading icon if upload progress listener is disabled const loadingProgress = 'percent' in file ? ( ) : null; progress = (
{loadingProgress}
); } const infoUploadingClass = classNames({ [`${prefixCls}-list-item`]: true, [`${prefixCls}-list-item-${file.status}`]: true, }); const linkProps = typeof file.linkProps === 'string' ? JSON.parse(file.linkProps) : file.linkProps; const preview = file.url ? ( this.handlePreview(file, e)} > {file.name} ) : ( this.handlePreview(file, e)} title={file.name} > {file.name} ); const style: React.CSSProperties = { pointerEvents: 'none', opacity: 0.5, }; const previewIcon = showPreviewIcon ? ( this.handlePreview(file, e)} title={locale.previewFile} > ) : null; const removeIcon = showRemoveIcon ? ( this.handleClose(file)} /> ) : null; const removeIconClose = showRemoveIcon ? ( this.handleClose(file)} /> ) : null; const actions = listType === 'picture-card' && file.status !== 'uploading' ? ( {previewIcon} {removeIcon} ) : ( removeIconClose ); let message; if (file.response && typeof file.response === 'string') { message = file.response; } else { message = (file.error && file.error.statusText) || locale.uploadError; } const iconAndPreview = file.status === 'error' ? ( {icon} {preview} ) : ( {icon} {preview} ); return (
{iconAndPreview}
{actions} {progress}
); }); const listClassNames = classNames({ [`${prefixCls}-list`]: true, [`${prefixCls}-list-${listType}`]: true, }); const animationDirection = listType === 'picture-card' ? 'animate-inline' : 'animate'; return ( {list} ); }; render() { return {this.renderUploadList}; } }