File uploads with preview, progress, and drag-and-drop.
Basic file input:
1function FileUpload() {2 const [file, setFile] = useState<File | null>(null);3 const [preview, setPreview] = useState<string | null>(null);45 const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {6 const selected = e.target.files?.[0];7 if (selected) {8 setFile(selected);9 const reader = new FileReader();10 reader.onloadend = () => setPreview(reader.result as string);11 reader.readAsDataURL(selected);12 }13 };1415 const handleUpload = async () => {16 if (!file) return;17 const formData = new FormData();18 formData.append("file", file);19 await fetch("/api/upload", { method: "POST", body: formData });20 };2122 return (23 <div>24 <input type="file" onChange={handleFileChange} accept="image/*" />25 {preview && <img src={preview} alt="Preview" style={{ maxWidth: 200 }} />}26 <button onClick={handleUpload}>Upload</button>27 </div>28 );29}
With progress:
1function UploadWithProgress() {2 const [progress, setProgress] = useState(0);34 const handleUpload = async (file: File) => {5 const formData = new FormData();6 formData.append("file", file);78 const xhr = new XMLHttpRequest();9 xhr.upload.onprogress = (e) => {10 setProgress(Math.round((e.loaded / e.total) * 100));11 };12 xhr.open("POST", "/api/upload");13 xhr.send(formData);14 };1516 return (17 <div>18 <input type="file" onChange={e => e.target.files?.[0] && handleUpload(e.target.files[0])} />19 <progress value={progress} max={100} />20 <span>{progress}%</span>21 </div>22 );23}
Drag and drop:
1function DragDropUpload() {2 const [isDragging, setIsDragging] = useState(false);34 const handleDrag = (e: React.DragEvent) => {5 e.preventDefault();6 setIsDragging(e.type === "dragenter" || e.type === "dragover");7 };89 const handleDrop = (e: React.DragEvent) => {10 e.preventDefault();11 setIsDragging(false);12 const file = e.dataTransfer.files[0];13 if (file) handleUpload(file);14 };1516 return (17 <div18 className={`dropzone ${isDragging ? "active" : ""}`}19 onDragEnter={handleDrag}20 onDragLeave={handleDrag}21 onDragOver={handleDrag}22 onDrop={handleDrop}23 >24 Drag & drop files here25 </div>26 );27}