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.

MethodSignatureWhat it does
addFiles(files: FileList | File[]) => voidAttaches files from outside the component
removeFile(fileRef: string) => voidRemoves one file by id or name
clearFiles() => voidEmpties the list
startUpload(fileRef?: string) => voidUploads one file, or every pending file
cancelUpload(fileRef?: string) => voidAborts 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[]) => void

Attaches 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) => void

Takes 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: () => void

Empties 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) => void

Uploads 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) => void

Aborts 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.