import React from 'react'; import classNames from 'classnames'; import type { SafeExtract } from '../../../types'; import type { Size } from '../../../types'; import { IconButton } from '../../IconButton/IconButton'; import { Image } from '../../Image/Image'; import type { LabelAfterProps } from '../../LabelAfter/LabelAfter'; import { LabelAfter } from '../../LabelAfter/LabelAfter'; import { Tooltip } from '../../Tooltip/Tooltip'; import { getTextInputClassName } from '../TextInput/TextInput'; import type { FileInputItem } from './hooks'; import { getFileExtension, getFileName, getImagePreviewSource, IMAGE_FILE_EXTENSION_REGEX } from './utils'; export interface FileItemProps { file: FileInputItem; onRemove: () => void; onReplace: () => void; tooltip?: React.ReactNode; width?: SafeExtract; error?: boolean; warning?: boolean; labelAfter?: LabelAfterProps['label']; disabled?: boolean; /** * Whether to show an image preview for image files. * @default false */ showImagePreview?: boolean; /** * Explicit image URL to use as the preview source. * Useful for already-uploaded files (StoredFile) where the URL is known. * It is used for non-File items. A newly selected local File always uses its own preview. */ previewSrc?: string; } export const FileItem = React.forwardRef( ( { file, onRemove, onReplace, tooltip, width, error, warning, labelAfter, disabled, showImagePreview = false, previewSrc, ...rest }, ref ) => { const [fileImagePreviewSource, setFileImagePreviewSource] = React.useState(); const imagePreviewSource = React.useMemo(() => { if (!showImagePreview) { return undefined; } if (file instanceof File) { return fileImagePreviewSource; } if (previewSrc) { return previewSrc; } return getImagePreviewSource(file); }, [file, fileImagePreviewSource, previewSrc, showImagePreview]); React.useLayoutEffect(() => { if (!(file instanceof File)) { setFileImagePreviewSource(undefined); return; } const isImageFileByExtension = IMAGE_FILE_EXTENSION_REGEX.test(getFileExtension(file)); const isImageFile = file.type ? file.type.startsWith('image/') : isImageFileByExtension; if (!isImageFile || !showImagePreview) { setFileImagePreviewSource(undefined); return; } const objectUrl = URL.createObjectURL(file); setFileImagePreviewSource(objectUrl); return () => { URL.revokeObjectURL(objectUrl); }; }, [file, showImagePreview]); return (
{imagePreviewSource ? ( ) : ( )}
{ e.preventDefault(); onRemove(); }} ghost disabled={disabled} /> {tooltip && ( )} {labelAfter && }
); } ); FileItem.displayName = 'FileItem';