Uploading
Drop Upload can drive the actual file upload for you, not just the picking
and previewing. Pass an uploadAdapter and the component takes care of the
rest: per-file progress, error/retry, and (optionally) starting the upload
automatically.
import { DropUpload, createSupabaseAdapter } from "../components/DropUpload"
const adapter = createSupabaseAdapter({
url: "https://your-project.supabase.co",
bucket: "uploads",
getToken: () => yourSupabaseAnonKey,
})
<DropUpload uploadAdapter={adapter} />Built-in adapters:
- Custom Endpoint —
multipart/form-dataPOST to your own backend - S3 — single PUT to a presigned URL
- S3 Multipart — chunked upload for large files
- Supabase
- Cloudinary
Every adapter implements the same small interface, so they're interchangeable:
interface UploadAdapter {
upload(
file: File,
ctx: { onProgress: (percent: number) => void; signal?: AbortSignal },
): Promise<{ url?: string }>
}Write your own adapter for any other provider by implementing this interface.
Automatic vs. manual upload
By default (autoUpload: true), a file starts uploading as soon as it passes
validation. Set autoUpload={false} and each attached file waits with an
upload button of its own in the list, so the user decides what goes up and
when. The same trigger is available programmatically — get a ref to the
component and call startUpload():
const ref = useRef<DropUploadHandle>(null)
<DropUpload ref={ref} autoUpload={false} uploadAdapter={adapter} />
<button onClick={() => ref.current?.startUpload()}>Upload</button>startUpload(fileName) uploads a single file by name; call it with no
arguments to upload every pending file. The same method is used internally
for the "Retry" button shown on a failed upload.
Progress and status
Each attached file carries status ("idle" | "uploading" | "done" | "error")
and uploadProgress (0-100). The list renders the whole run: a progress bar
with its percentage while the file is going up, a green check once it lands,
and a red frame with a "Retry" button if it fails. React to completion or
failure with callbacks:
<DropUpload
uploadAdapter={adapter}
onUploadComplete={(file) => console.log("uploaded", file.name)}
onUploadError={(file, error) => console.error("failed", file.name, error)}
/>Without an uploadAdapter, Drop Upload behaves exactly as before — it only
picks, validates, and previews files, and leaves the actual upload to you
via onFilesChanged.