import { ArrowDownTray } from "@medusajs/icons" import { Text, clx } from "@medusajs/ui" import { ChangeEvent, DragEvent, useRef, useState } from "react" export interface FileType { id: string url: string file: File } export interface RejectedFile { file: File reason: "size" | "format" } export interface FileUploadProps { label: string multiple?: boolean hint?: string hasError?: boolean formats: string[] maxFileSize?: number // in bytes, defaults to 1MB. Set to Infinity to disable. onUploaded: (files: FileType[], rejectedFiles?: RejectedFile[]) => void } const DEFAULT_MAX_FILE_SIZE = __MAX_UPLOAD_FILE_SIZE__ ?? 1024 * 1024 // 1MB fallback export const FileUpload = ({ label, hint, multiple = true, hasError, formats, maxFileSize = DEFAULT_MAX_FILE_SIZE, onUploaded, }: FileUploadProps) => { const [isDragOver, setIsDragOver] = useState(false) const inputRef = useRef(null) const dropZoneRef = useRef(null) const handleOpenFileSelector = () => { inputRef.current?.click() } const handleDragEnter = (event: DragEvent) => { event.preventDefault() event.stopPropagation() const files = event.dataTransfer?.files if (!files) { return } setIsDragOver(true) } const handleDragLeave = (event: DragEvent) => { event.preventDefault() event.stopPropagation() if ( !dropZoneRef.current || dropZoneRef.current.contains(event.relatedTarget as Node) ) { return } setIsDragOver(false) } const handleUploaded = (files: FileList | null) => { if (!files) { return } const fileList = Array.from(files) const validFiles: FileType[] = [] const rejectedFiles: RejectedFile[] = [] const normalizedMaxFileSize = Math.min(maxFileSize, Infinity) fileList.forEach((file) => { if (file.size > normalizedMaxFileSize) { rejectedFiles.push({ file, reason: "size" }) return } const id = Math.random().toString(36).substring(7) const previewUrl = URL.createObjectURL(file) validFiles.push({ id: id, url: previewUrl, file, }) }) onUploaded(validFiles, rejectedFiles) } const handleDrop = (event: DragEvent) => { event.preventDefault() event.stopPropagation() setIsDragOver(false) handleUploaded(event.dataTransfer?.files) } const handleFileChange = async (event: ChangeEvent) => { handleUploaded(event.target.files) } return (
) }