import React, { HTMLAttributes, useCallback, useEffect, useRef, useState } from 'react' import cns from 'classnames' import { usePrefix } from '../ConfigProvider' import { concat } from '../utils' import { FileIcon, CloseThinIcon, TipFilledIcon } from '../icons' import Button from '../Button' import { useUpload } from './common' import Tooltip from '../Tooltip' import { getFontStyles, getMiddleEllipsisText } from '../utils/paragraph' import { UploadFunction, UploadStatus } from './types' import { WithRef } from '../utils/type' export interface FileItemProps { id: string name: string file?: File status: UploadStatus onUpload: UploadFunction onDelete: (id: string) => void handleFileStatusChange: (id: string, status: UploadStatus) => void fileHtmlProps?: WithRef, HTMLDivElement> } export function FileItem( { id, name, file, status, onUpload, onDelete, handleFileStatusChange, fileHtmlProps }: FileItemProps ) { const prefix = usePrefix('upload') const itemPrefix = concat(prefix, 'list', 'item') const uploadOperationPrefix = concat(itemPrefix, 'operation', 'button') const [ uploadFile, canStopUpload, stopUpload, uploadStatus, percent, errorInfo ] = useUpload(id, name, file, status, onUpload, handleFileStatusChange) useEffect(() => { uploadFile() return () => stopUpload(true) }, [name, stopUpload, uploadFile]) return (
{errorInfo && ( )} {!!file && ( <> {(uploadStatus === 'error' || uploadStatus === 'stopped') && ( )} {uploadStatus === 'uploading' && canStopUpload && ( )} )} onDelete(id)} />
) } export interface FileTitleProps { name: string uploadStatus: UploadStatus errorInfo: string } function FileTitle({ name, uploadStatus, errorInfo }: FileTitleProps) { const rootElementRef = useRef(null) const [text, setText] = useState(name) const [shouldGrow, setShouldGrow] = useState(false) const prefix = usePrefix('upload') const itemPrefix = concat(prefix, 'list', 'item') const contentPrefix = concat(itemPrefix, 'content') const setEllipsisText = useCallback(() => { if (rootElementRef.current) { const fontStyles = getFontStyles(rootElementRef.current) const maxWidth = rootElementRef.current.getBoundingClientRect().width const [textInfo, fullWidth] = getMiddleEllipsisText(name, fontStyles, maxWidth, 1) if (fullWidth > maxWidth) { setShouldGrow(true) } else { setShouldGrow(false) } setText(textInfo.text) } }, [name]) // 将 uploadStatus 和 errorInfo 加入 useEffect 的依赖项而不是通过 key 进行刷新是为了避免闪烁 useEffect(() => { setEllipsisText() }, [setEllipsisText, uploadStatus, errorInfo]) return ( {text} ) }