dimah-s3v0.4.1

Upload

Upload hooks for single and multiple files.

HookUse case
useUploadControlsOne file — picker + drag-and-drop
useMultiUploadControlsMany files — picker + drop
useUpload / useMultiUploadYou already have a File

Enforce accept and maxFileSize on the server too (presignGuard).


useUploadControls

Same pattern as UploadButton and UploadDropzone.

"use client";

import { useUploadControls } from "@dimah-s3/react";

const {
  openFilePicker,
  inputProps,
  dropHandlers,
  phase,
  progress,
  isUploading,
  cancel,
} = useUploadControls({
  objectKey: (file) => `uploads/${Date.now()}-${file.name}`,
  accept: ["image/*"],
  maxFileSize: 10 * 1024 * 1024,
  onSuccess: (file, result) => console.log(result.key),
});

return (
  <div {...dropHandlers} onClick={openFilePicker}>
    <input {...inputProps} />
    {isUploading ? `${progress.percent}%` : "Click or drop to upload"}
  </div>
);

useMultiUploadControls

Same as above, for multiple files. Set maxFiles.

"use client";

import { useMultiUploadControls } from "@dimah-s3/react";

const {
  openFilePicker,
  inputProps,
  dropHandlers,
  files,
  totalProgress,
  isUploading,
  cancel,
} = useMultiUploadControls({
  objectKey: (file) => `uploads/${Date.now()}-${file.name}`,
  maxFiles: 5,
  concurrentFiles: 3,
  accept: ["image/*"],
  onSuccess: (results) => console.log(results.map((r) => r.key)),
});

return (
  <div {...dropHandlers} onClick={openFilePicker}>
    <input {...inputProps} />
    {isUploading
      ? `${totalProgress.percent}% — ${files.filter((f) => f.status === "success").length}/${files.length}`
      : "Click or drop files"}
  </div>
);

multipart splits one large file into parts — it is not multi-file upload.


Lower-level hooks

Skip the picker when you already have a File.

useUpload

const { phase, progress, upload, cancel, reset } = useUpload();

await upload(file, `uploads/${file.name}`, { metadata: { userId: "1" } });

useMultiUpload

const { files, totalProgress, upload, cancel, reset } = useMultiUpload({
  maxFiles: 10,
  concurrentFiles: 3,
});

await upload(fileArray, (file) => `uploads/${file.name}`);

Same options as the controls hooks (accept, maxFileSize, onSuccess, …).

On this page