import { useId, useRef, useState } from 'react'; const MAX_FILES = 20; const MAX_SIZE_MB = 250; const MAX_SIZE_BYTES = MAX_SIZE_MB * 1024 * 1024; const formatSize = (bytes) => { if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB'; return (bytes / (1024 * 1024)).toFixed(1) + ' MB'; }; export default function FileAttachment({ files, onChange }) { const inputId = useId(); const [errors, setErrors] = useState([]); const [dragging, setDragging] = useState(false); const dragCounter = useRef(0); const processFiles = (incoming) => { const combined = [...files, ...incoming]; const errs = []; if (combined.length > MAX_FILES) errs.push(`Maximum ${MAX_FILES} files allowed.`); incoming.filter(f => f.size > MAX_SIZE_BYTES).forEach(f => errs.push(`"${f.name}" exceeds ${MAX_SIZE_MB} MB limit.`)); if (errs.length > 0) { setErrors(errs); return; } setErrors([]); onChange(combined); }; const handleChange = (e) => { processFiles(Array.from(e.target.files)); e.target.value = ''; }; const handleDragEnter = (e) => { e.preventDefault(); dragCounter.current++; setDragging(true); }; const handleDragLeave = (e) => { e.preventDefault(); dragCounter.current--; if (dragCounter.current === 0) setDragging(false); }; const handleDragOver = (e) => { e.preventDefault(); }; const handleDrop = (e) => { e.preventDefault(); dragCounter.current = 0; setDragging(false); const dropped = Array.from(e.dataTransfer.files); if (dropped.length > 0) processFiles(dropped); }; const remove = (index) => { setErrors([]); onChange(files.filter((_, i) => i !== index)); }; return (
Attach Files Up to {MAX_FILES} files ยท Max {MAX_SIZE_MB} MB each ยท Any file type
0 ? 'var(--accent)' : 'var(--border)'}`, borderRadius: 8, padding: '16px', textAlign: 'center', background: dragging ? 'color-mix(in srgb, var(--accent) 8%, var(--bg))' : 'transparent', transition: 'all 160ms', cursor: 'pointer', }} >
{errors.length > 0 && errors.map((err, i) => (
โš  {err}
))} {files.length > 0 && (
{files.map((file, i) => (
๐Ÿ“„
{file.name}
{formatSize(file.size)}
))}
{files.length}/{MAX_FILES} files
)}
); }