import { useRef, useState, type DragEvent } from "react"; import { Upload } from "lucide-react"; import { ACCEPTED_DATA_EXTS, MAX_DATA_FILE_SIZE } from "../utils/data-files"; interface UploadZoneProps { onFiles: (files: FileList | File[]) => void | Promise; disabled?: boolean; compact?: boolean; } const ACCEPT_ATTR = ACCEPTED_DATA_EXTS.map((e) => `.${e}`).join(","); const MAX_MB = (MAX_DATA_FILE_SIZE / (1024 * 1024)).toFixed(0); export function UploadZone({ onFiles, disabled, compact }: UploadZoneProps) { const inputRef = useRef(null); const [isDragging, setIsDragging] = useState(false); const handleDrop = (e: DragEvent) => { e.preventDefault(); setIsDragging(false); if (disabled) return; if (e.dataTransfer.files?.length) void onFiles(e.dataTransfer.files); }; const handleDragOver = (e: DragEvent) => { e.preventDefault(); if (!disabled) setIsDragging(true); }; const handleDragLeave = () => setIsDragging(false); return (
!disabled && inputRef.current?.click()} role="button" tabIndex={disabled ? -1 : 0} aria-label="Upload data file" > { if (e.target.files?.length) void onFiles(e.target.files); e.target.value = ""; }} style={{ display: "none" }} /> {compact ? ( Add data file ) : (
Drop a data file CSV, TSV, JSON, NDJSON, TXT - up to {MAX_MB} MB
)}
); }