Mischief

11 / Forms

File Upload

A file picker and dropzone with clear validation and a visible queue. Connect your upload function when you need progress, cancel, and retry.

Live previewSource

Drop files here

Images or PDF ยท Up to 10 MB each

Installation

Copy the source into your project, or keep it behind a package.

Copy the component into your project and make it yours.

Usage

async function uploadFile(file, { signal, onProgress }) {
  await uploadToYourStorage(file, { signal, onProgress })
}

export function Attachments() {
  return (
    <FileUpload
      accept="image/*,.pdf"
      maxFiles={5}
      maxSize={10 * 1024 * 1024}
      uploadFile={uploadFile}
    />
  )
}

API

acceptstringMIME types and extensions accepted by the picker.
multiplebooleanAllows more than one file. Defaults to true.
maxFilesnumberMaximum files in the queue. Defaults to 5.
maxSizenumberMaximum bytes per file. Defaults to 10 MB.
uploadFileFileUploadAdapterYour async upload function with progress and cancellation hooks.
autoUploadbooleanStarts the adapter when files are accepted. Defaults to true.
onFilesAccepted(files: File[]) => voidRuns with files that pass validation.
onFilesRejected(rejections) => voidReports type, size, count, and duplicate failures.
onFilesChange(entries) => voidRuns when the queue or an upload state changes.
disabledbooleanDisables both picking and dropping.
classNamestringClasses for the root element.

Accessibility

The picker is a named native button backed by a file input. Drag and drop is an additional path, not the only one. Validation and upload changes are announced politely. Every queue action and the primary picker keep a 44px target. Progress uses native progressbar semantics.

Dependencies

lucide-react, clsx, tailwind-merge