import { FileImage, Upload } from "lucide-react"; import { type DragEvent, useCallback, useState } from "react"; import { cn } from "@/lib/utils"; interface DropzoneProps { onFiles?: (files: File[]) => void; accept?: string; multiple?: boolean; /** Files that have already been dropped (for showing count & list). */ currentFiles?: File[]; } // Browsers may not map certain formats (HEIC, JXL, RAW, etc.) to image/* in file pickers. // Append explicit extensions so they are selectable. function expandAccept(accept?: string): string | undefined { if (!accept?.includes("image/*")) return accept; return `${accept},.heic,.heif,.hif,.jxl,.ico,.dng,.cr2,.nef,.arw,.orf,.rw2,.tga,.psd,.exr,.hdr`; } export function Dropzone({ onFiles, accept, multiple = true, currentFiles = [] }: DropzoneProps) { const resolvedAccept = expandAccept(accept); const [isDragging, setIsDragging] = useState(false); const handleDrag = useCallback((e: DragEvent) => { e.preventDefault(); e.stopPropagation(); if (e.type === "dragenter" || e.type === "dragover") setIsDragging(true); else if (e.type === "dragleave") setIsDragging(false); }, []); const handleDrop = useCallback( (e: DragEvent) => { e.preventDefault(); e.stopPropagation(); setIsDragging(false); const files = Array.from(e.dataTransfer.files); if (files.length > 0) onFiles?.(files); }, [onFiles], ); const handleClick = () => { const input = document.createElement("input"); input.type = "file"; input.multiple = multiple; if (resolvedAccept) input.accept = resolvedAccept; input.onchange = (e) => { const files = Array.from((e.target as HTMLInputElement).files || []); if (files.length > 0) onFiles?.(files); }; input.click(); }; const hasMultipleFiles = currentFiles.length > 1; return (
ashim

Drop files here or click the upload button

{/* Show file count badge and list when multiple files are dropped */} {hasMultipleFiles && (
{currentFiles.length} files selected
{currentFiles.map((f) => (
{f.name} {(f.size / 1024).toFixed(0)} KB
))}
)}
); }