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}
)
}