Dropzone Uploader
A drag-and-drop zone with visual feedback when files are dragged over.
Preview
Code
1import {2 UplofileRoot,3 UplofileDropzone,4 UplofileTrigger,5 UplofilePreview,6 type UploadFileItem,7} from "@/components/ui/uplofile";8import { IoCloudUploadOutline, IoDocumentOutline, IoCloseOutline, IoCheckmarkCircleOutline, IoReloadOutline } from "react-icons/io5";9import { mockUpload } from "@/lib/utils.ts";1011export default function DropzoneUploaderDemo() {12 return (13 <UplofileRoot upload={mockUpload} accept="*/*" multiple>14 <UplofileDropzone className="group relative border-2 border-dashed border-muted-foreground/25 rounded-xl p-12 text-center hover:border-primary/50 transition-all duration-200 data-[dragging=true]:border-primary data-[dragging=true]:bg-primary/5 data-[dragging=true]:scale-[1.01]">15 <UplofileTrigger>16 <div className="flex flex-col items-center gap-4 cursor-pointer">17 <div className="p-4 rounded-full bg-primary/10 text-primary group-hover:scale-110 transition-transform duration-200">18 <IoCloudUploadOutline className="h-8 w-8" />19 </div>20 <div className="grid gap-1">21 <p className="text-sm font-semibold">22 Click to upload or drag and drop23 </p>24 <p className="text-xs text-muted-foreground">25 Any file type26 </p>27 </div>28 </div>29 </UplofileTrigger>30 </UplofileDropzone>3132 <UplofilePreview33 render={({ items }) => (34 <div className="mt-8 space-y-3">35 {items.map((item) => (36 <DropzoneFileItem key={item.uid} item={item} />37 ))}38 </div>39 )}40 />41 </UplofileRoot>42 );43}4445function DropzoneFileItem({ item }: { item: UploadFileItem }) {46 return (47 <div className="flex items-center gap-4 p-3 rounded-xl border bg-card shadow-sm animate-in fade-in slide-in-from-bottom-2">48 <div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary">49 <IoDocumentOutline className="h-5 w-5" />50 </div>51 <div className="grid flex-1 gap-1 overflow-hidden">52 <div className="flex items-center justify-between gap-2">53 <span className="text-sm font-medium truncate">{item.name}</span>54 <span className="text-xs text-muted-foreground whitespace-nowrap">55 {item.status === "uploading" ? `${item.progress}%` : item.status}56 </span>57 </div>58 <div className="relative h-1.5 w-full overflow-hidden rounded-full bg-secondary">59 <div60 className="h-full bg-primary transition-all duration-300"61 style={{62 width: item.status === "done" ? "100%" : `${item.progress}%`,63 }}64 />65 </div>66 </div>67 <div className="flex items-center gap-2">68 {item.status === "uploading" && (69 <IoReloadOutline className="h-4 w-4 animate-spin text-muted-foreground" />70 )}71 {item.status === "done" && (72 <IoCheckmarkCircleOutline className="h-4 w-4 text-emerald-500" />73 )}74 {item.status === "error" && <IoCloseOutline className="h-4 w-4 text-destructive" />}75 </div>76 </div>77 );78}
Key Points
- → Uses
data-[dragging=true]for visual feedback on drag - → Combines dropzone with clickable trigger
- →
multipleprop enables multi-file selection