Uplofile is open sourceStar on GitHub

Basic File Uploader

A minimal file uploader with a button trigger and file preview list.

Preview

No files selected

Code

1import {
2 UplofileRoot,
3 UplofileTrigger,
4 UplofilePreview,
5 type UploadFileItem,
6} from "@/components/ui/uplofile";
7import { IoDocumentOutline, IoCheckmarkCircleOutline, IoReloadOutline, IoCloseOutline } from "react-icons/io5";
8import { mockUpload } from "@/lib/utils.ts";
9
10export default function BasicUploaderDemo() {
11 return (
12 <UplofileRoot upload={mockUpload}>
13 <UplofileTrigger asChild>
14 <button className="inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-primary text-primary-foreground hover:bg-primary/90 h-10 px-4 py-2 shadow">
15 Select Files
16 </button>
17 </UplofileTrigger>
18
19 <UplofilePreview
20 render={({ items }) => (
21 <div className="mt-6 space-y-3">
22 {items.length === 0 ? (
23 <div className="text-center py-4 border-2 border-dashed rounded-lg bg-muted/5">
24 <p className="text-muted-foreground text-sm">
25 No files selected
26 </p>
27 </div>
28 ) : (
29 <div className="grid gap-2">
30 {items.map((item) => (
31 <BasicFileItem key={item.uid} item={item} />
32 ))}
33 </div>
34 )}
35 </div>
36 )}
37 />
38 </UplofileRoot>
39 );
40}
41
42function BasicFileItem({ item }: { item: UploadFileItem }) {
43 return (
44 <div className="flex items-center justify-between p-3 rounded-lg border bg-card text-card-foreground shadow-sm animate-in fade-in slide-in-from-top-1">
45 <div className="flex items-center gap-3 overflow-hidden">
46 <div className="p-2 rounded-md bg-primary/10 text-primary">
47 <IoDocumentOutline className="h-4 w-4" />
48 </div>
49 <div className="grid gap-0.5 overflow-hidden">
50 <span className="text-sm font-medium truncate max-w-[200px] sm:max-w-[400px]">
51 {item.name}
52 </span>
53 {item.status === "uploading" && (
54 <div className="w-full bg-secondary rounded-full h-1.5 overflow-hidden">
55 <div
56 className="bg-primary h-full transition-all duration-300 ease-in-out"
57 style={{ width: `${item.progress}%` }}
58 />
59 </div>
60 )}
61 </div>
62 </div>
63 <div className="flex items-center gap-2 ml-4">
64 {item.status === "uploading" && (
65 <IoReloadOutline className="h-4 w-4 animate-spin text-muted-foreground" />
66 )}
67 {item.status === "done" && (
68 <IoCheckmarkCircleOutline className="h-4 w-4 text-emerald-500" />
69 )}
70 {item.status === "error" && <IoCloseOutline className="h-4 w-4 text-destructive" />}
71 </div>
72 </div>
73 );
74}

Key Points

  • Uses UplofileTrigger with a custom button
  • Simple file list display with UplofilePreview
  • Requires an upload function that returns { url, id }