Before Upload Validation
Validate or enrich files before they are added to the state and uploaded.
Preview
Validation: Max 2MB, no "restricted" in filename.
No files selected
Code
1import {2 UplofileRoot,3 UplofileTrigger,4 UplofilePreview,5 type UploadFileItem,6} from "@/components/ui/uplofile";7import { IoDocumentOutline, IoCheckmarkCircleOutline, IoReloadOutline, IoAlertCircleOutline } from "react-icons/io5";8import { mockUpload } from "@/lib/utils.ts";9import { type BeforeUploadFn } from "uplofile";1011const beforeUpload: BeforeUploadFn = async (items: UploadFileItem[]) => {12 return items.map((item) => {13 // Example: Reject files larger than 2MB14 if (item.file && item.file.size > 2 * 1024 * 1024) {15 return {16 uid: item.uid,17 valid: false,18 reason: "File too large (max 2MB)",19 };20 }2122 // Example: Reject specific file names (e.g., restricted keywords)23 if (item.name.toLowerCase().includes("restricted")) {24 return {25 uid: item.uid,26 valid: false,27 reason: "File name contains restricted words",28 };29 }3031 return { uid: item.uid, valid: true };32 });33};3435export default function BeforeUploadValidationDemo() {36 return (37 <UplofileRoot upload={mockUpload} beforeUpload={beforeUpload}>38 <div className="space-y-4">39 <p className="text-sm text-muted-foreground">40 Validation: Max 2MB, no "restricted" in filename.41 </p>42 <UplofileTrigger asChild>43 <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">44 Select Files45 </button>46 </UplofileTrigger>4748 <UplofilePreview49 render={({ items }) => (50 <div className="mt-6 space-y-3">51 {items.length === 0 ? (52 <div className="text-center py-4 border-2 border-dashed rounded-lg bg-muted/5">53 <p className="text-muted-foreground text-sm">54 No files selected55 </p>56 </div>57 ) : (58 <div className="grid gap-2">59 {items.map((item) => (60 <ValidationFileItem key={item.uid} item={item} />61 ))}62 </div>63 )}64 </div>65 )}66 />67 </div>68 </UplofileRoot>69 );70}7172function ValidationFileItem({ item }: { item: UploadFileItem }) {73 return (74 <div75 className={`flex flex-col p-3 rounded-lg border bg-card text-card-foreground shadow-sm animate-in fade-in slide-in-from-top-1 ${item.status === "error" ? "border-destructive/50 bg-destructive/5" : ""}`}76 >77 <div className="flex items-center justify-between">78 <div className="flex items-center gap-3 overflow-hidden">79 <div80 className={`p-2 rounded-md ${item.status === "error" ? "bg-destructive/10 text-destructive" : "bg-primary/10 text-primary"}`}81 >82 <IoDocumentOutline className="h-4 w-4" />83 </div>84 <div className="grid gap-0.5 overflow-hidden">85 <span className="text-sm font-medium truncate max-w-[200px] sm:max-w-[400px]">86 {item.name}87 </span>88 </div>89 </div>90 <div className="flex items-center gap-2 ml-4">91 {item.status === "uploading" && (92 <IoReloadOutline className="h-4 w-4 animate-spin text-muted-foreground" />93 )}94 {item.status === "done" && (95 <IoCheckmarkCircleOutline className="h-4 w-4 text-emerald-500" />96 )}97 {item.status === "error" && (98 <IoAlertCircleOutline className="h-4 w-4 text-destructive" />99 )}100 </div>101 </div>102103 {item.status === "error" && item.error && (104 <p className="mt-2 text-xs text-destructive font-medium flex items-center gap-1">105 {item.error}106 </p>107 )}108109 {item.status === "uploading" && (110 <div className="mt-3 w-full bg-secondary rounded-full h-1.5 overflow-hidden">111 <div112 className="bg-primary h-full transition-all duration-300 ease-in-out"113 style={{ width: `${item.progress}%` }}114 />115 </div>116 )}117 </div>118 );119}
Key Points
- → Use the
beforeUploadprop onUplofileRoot - → Supports asynchronous validation (e.g., checking image dimensions)
- → Return
falseto reject the entire batch - → Return an array of objects to provide granular control and error reasons
- → Files rejected with a
reasonare added to state with "error" status