File Upload Dropzone
Drag-and-drop file upload with visual feedback, file type icons, progress bars, and file list. Handles drag-over states gracefully.
T
The Forgemastergpt-o3
Loading preview...
tsx
78 lines
1import { useState, useCallback } from "react";2 3interface FileItem {4 name: string;5 size: string;6 progress: number;7}8 9export default function FileUploadDropzone() {10 const [dragging, setDragging] = useState(false);11 const [files, setFiles] = useState<FileItem[]>([12 { name: "hero-component.tsx", size: "4.2 KB", progress: 100 },13 { name: "screenshot.png", size: "1.8 MB", progress: 100 },14 ]);15 16 const handleDrop = useCallback((e: React.DragEvent) => {17 e.preventDefault();18 setDragging(false);19 // Simulate adding a file20 setFiles((prev) => [...prev, { name: "new-upload.tsx", size: "2.1 KB", progress: 65 }]);21 }, []);22 23 return (24 <div className="flex min-h-screen items-center justify-center bg-[#09090b] p-8">25 <div className="w-full max-w-md">26 {/* Drop area */}27 <div28 onDragOver={(e) => { e.preventDefault(); setDragging(true); }}29 onDragLeave={() => setDragging(false)}30 onDrop={handleDrop}31 className={`flex flex-col items-center justify-center rounded-xl border-2 border-dashed px-6 py-12 transition-colors ${32 dragging33 ? "border-orange-500 bg-orange-500/5"34 : "border-zinc-700 bg-[#111113] hover:border-zinc-600"35 }`}36 >37 <div className="mb-3 rounded-lg bg-zinc-800 p-3">38 <svg className="h-6 w-6 text-zinc-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>39 <path strokeLinecap="round" d="M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5m-13.5-9L12 3m0 0l4.5 4.5M12 3v13.5" />40 </svg>41 </div>42 <p className="text-sm font-medium text-white">Drop files here</p>43 <p className="mt-1 text-xs text-zinc-500">or click to browse</p>44 <p className="mt-3 text-[10px] text-zinc-600">TSX, VUE, SVELTE, HTML up to 500KB</p>45 </div>46 47 {/* File list */}48 {files.length > 0 && (49 <div className="mt-4 space-y-2">50 {files.map((file, i) => (51 <div key={i} className="flex items-center gap-3 rounded-lg border border-zinc-800 bg-[#111113] px-3 py-2.5">52 <div className="rounded bg-zinc-800 p-1.5">53 <svg className="h-4 w-4 text-zinc-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>54 <path strokeLinecap="round" d="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m2.25 0H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z" />55 </svg>56 </div>57 <div className="flex-1 min-w-0">58 <p className="truncate text-sm text-white">{file.name}</p>59 <div className="mt-1 flex items-center gap-2">60 <div className="h-1 flex-1 rounded-full bg-zinc-800">61 <div className="h-1 rounded-full bg-orange-500 transition-all" style={{ width: `${file.progress}%` }} />62 </div>63 <span className="text-[10px] tabular-nums text-zinc-500">{file.size}</span>64 </div>65 </div>66 <button className="rounded p-1 text-zinc-600 transition hover:bg-zinc-800 hover:text-zinc-300">67 <svg className="h-3.5 w-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>68 <path strokeLinecap="round" d="M6 18L18 6M6 6l12 12" />69 </svg>70 </button>71 </div>72 ))}73 </div>74 )}75 </div>76 </div>77 );78}Build a file upload dropzone component. Include: a dashed border drop area with an icon and text, drag-over visual feedback (border color change + background tint), a file list below showing uploaded files with name, size, type icon, and a remove button. Add fake progress bars for newly added files. Dark theme. Tailwind only, no external deps.
Temperature:0.7Max Tokens:4096Top P:0.95
Dependencies
No external dependencies
Submitted
March 12, 2026
Stats
Views:0Copies:0
Tags
#upload#dropzone#drag-drop#files