FileUpload
Drop, paste or browse for files; see them listed with previews, sizes, errors and progress.
One file
maxFiles is 1 by default: a new pick replaces the file.
Drag and drop files here
PNG, JPG or GIF
Code
<FileUpload files={state.avatar} accept="image/*" hint="PNG or JPG" />Usage
import { FileUpload } from "@elements/ui/file-upload";
<FileUpload files={form.photos} accept="image/*" maxFiles={5} maxFileSize={5_000_000} />
<FileUpload files={form.resume} accept={[".pdf", ".docx"]} name="resume" required />Examples
Several images
Thumbnails, sizes, delete and clear. Drop files, paste them, or browse.
Drag and drop files here
Up to 4 images
Code
<FileUpload files={state.photos} rejected={state.rejected} accept="image/*" maxFiles={4}
onFileAccept={() => state.accepts++} onFileReject={() => state.rejects++} />Types and sizes
accept takes MIME types, type/* and extensions. maxFileSize and minFileSize are bytes.
Drag and drop files here
PDF, TXT or CSV
Drag and drop files here
Between 10 bytes and 2 KB
Code
<FileUpload files={state.docs} accept={[".pdf", ".txt", "text/csv"]} maxFiles={5} />
<FileUpload files={state.sized} maxFiles={5} minFileSize={10} maxFileSize={2000} />Custom validation
validate returns error codes; translations turn them into messages.
Drag and drop files here
Code
<FileUpload files={state.files} maxFiles={5}
validate={(file) => file.name.includes(" ") ? ["NO_SPACES"] : null}
translations={{ error: (code) => code === "NO_SPACES" ? "No spaces in names" : code }} />Transform
transformFiles runs before files are read: here it lowercases names.
Drag and drop files here
Code
<FileUpload files={state.files} maxFiles={5}
transformFiles={async (files) => files.map((f) => new File([f], f.name.toLowerCase(), { type: f.type }))} />Upload progress
progress maps a file name to a percent: a bar on the row, announced when it reaches 100.
Drag and drop files here
Code
<FileUpload files={state.uploads} maxFiles={5} progress={state.progress}
onFileAccept={({ files }) => upload(files, state.progress)} />In a form
The input holds the files, so required, FormData and reset work as for any input.
Code
<form onsubmit={(e) => apply(e)}>
<Field label="Resume" description="PDF, up to 5 MB.">
<FileUpload files={state.resume} accept=".pdf" maxFileSize={5_000_000} name="resume" required />
</Field>
<Button type="submit" variant="primary">Apply</Button>
</form>Initial files
Files set before any pick are listed, carried in the input for a form submit, and deletable. Bind files to an array that already holds them.
Code
<FileUpload files={state.attachments} maxFiles={3} name="attachments" />
// state.attachments starts with files the user saved earlier:
attachments: [new File({ name: "notes.txt", contentType: "text/plain", size, data, lastModified })]Locale and translations
locale formats file sizes; translations replace every label and message.
Dateien hierher ziehen
- notes.txt 33 Byte
Code
<FileUpload files={state.files} maxFiles={3} locale="de-DE"
translations={{ dropzoneTitle: "Dateien hierher ziehen", trigger: "Dateien wählen", clear: "Alle entfernen", deleteFile: (n) => `${n} entfernen` }} />Dropzone as the button
trigger={false} makes the dropzone the button; the dropzone slot replaces its content.
Code
<FileUpload files={state.files} trigger={false} maxFiles={3}>
<div slot="dropzone">...</div>
</FileUpload>Folders and camera
directory picks a whole folder; capture opens the camera on a phone.
Drag and drop files here
Drag and drop files here
Code
<FileUpload files={state.folder} directory maxFiles={50} />
<FileUpload files={state.photo} accept="image/*" capture="environment" />Disabled and read-only
Neither takes files nor removes the ones it has.
Drag and drop files here
- notes.txt 33 bytes
Drag and drop files here
- notes.txt 33 bytes
Code
<FileUpload files={state.files} disabled />
<FileUpload files={state.files} readonly />Without drop
allowDrop={false} turns drag and drop off: a drop is refused and the dropzone never shows the drag state. Browsing still works.
Code
<FileUpload files={state.files} allowDrop={false} />Only the button opens the picker
disableClick keeps a press on the dropzone from opening the picker, so a button inside it opens it once, not twice.
Drag and drop files here
Code
<FileUpload files={state.files} disableClick />