Methods (ref)
Props and callbacks cover what the component does on its own. When your app needs to drive it — attach a file it picked up somewhere else, start an upload, take a file out of the list — put a ref on it and call the methods it exposes:
import { useRef } from "react"
import { DropUpload, type DropUploadHandle } from "@/components/DropUpload"
const ref = useRef<DropUploadHandle>(null)
<DropUpload ref={ref} />
<button onClick={() => ref.current?.clearFiles()}>Clear</button>The same handle is exposed by <AvatarUpload />, which is DropUpload
underneath.
| Method | Signature | What it does |
|---|---|---|
addFiles | (files: FileList | File[]) => void | Attaches files from outside the component |
removeFile | (fileRef: string) => void | Removes one file by id or name |
clearFiles | () => void | Empties the list |
startUpload | (fileRef?: string) => void | Uploads one file, or every pending file |
cancelUpload | (fileRef?: string) => void | Aborts one upload, or every one in flight |
Wherever a fileRef is taken, it matches either the file's id or its
name. Ids are stable and unique; names are what you have on hand if you
never looked at attachedFiles.
addFiles
addFiles: (files: FileList | File[]) => voidAttaches files the component never saw arrive — picked up by an <input> of
your own, dropped on a drop zone of your own, pulled off a clipboard event you
already handle, or built in code.
<input
type="file"
multiple
onChange={(e) => e.target.files && ref.current?.addFiles(e.target.files)}
/>
<DropUpload ref={ref} uploadAdapter={adapter} />The files take exactly the path a drop takes, so nothing is skipped along the
way: allowedFormats, minFileSize/maxFileSize and the spoofed-content
check still run, maxFiles still caps the list, duplicates are still dropped,
onFilesChanged and onFilesRejected still fire, the avatar variant still
offers its cropper, and autoUpload still starts the upload. A file that
fails validation lands in the list as status: "rejected" just as it would
have — addFiles is a way in, not a way around.
Building a File yourself works too — new File([blob], "photo.png", { type: "image/png" }) — which is how you re-attach something fetched from a URL or
produced by a canvas.
removeFile
removeFile: (fileRef: string) => voidTakes one file out of the list by id or name, the same as the user pressing
discard on it: an upload still in flight is aborted, the preview's object URL
is handed back, and onDiscardFile fires — so a list you mirror on your side
stays in step no matter who removed the file.
ref.current?.removeFile("invoice.pdf")clearFiles
clearFiles: () => voidEmpties the list in one call — after a form submits, say, or when the user switches to another record. Every upload in flight is aborted and every preview is released.
onDiscardFile does not fire here: this is a reset, not the user discarding
files one by one.
startUpload
startUpload: (fileRef?: string) => voidUploads a single file by id or name, or every file still waiting when called
with no arguments. Only needed with autoUpload={false}, where files sit in
the list until something asks for them to go up — see
Uploading. Requires an uploadAdapter.
cancelUpload
cancelUpload: (fileRef?: string) => voidAborts the upload of a single file by id or name, or every upload in flight
when called with no arguments. The file keeps its place in the list with
status: "canceled" and can be started again with startUpload.
onUploadCancel fires for each one.