elements
Demos UI Feed Discuss Install
Style System
  • Style
  • Themes
  • Behaviors
Forms
  • Button
  • ButtonGroup
  • Checkbox
  • ColorPicker
  • Combobox
  • Field
  • FileUpload
  • Input
  • InputGroup
  • InputOTP
  • Label
  • NativeSelect
  • NumberInput
  • PasswordInput
  • RadioGroup
  • Select
  • Slider
  • Switch
  • TagsInput
  • Textarea
  • Toggle
  • ToggleGroup
Overlays
  • AlertDialog
  • Command
  • ContextMenu
  • Dialog
  • Drawer
  • DropdownMenu
  • HoverCard
  • Menubar
  • NavigationMenu
  • Popover
  • Sheet
  • Toast
  • Tooltip
Display
  • Accordion
  • Alert
  • AspectRatio
  • Avatar
  • Badge
  • Breadcrumb
  • Card
  • Collapsible
  • Empty
  • Item
  • Kbd
  • Pagination
  • Progress
  • Separator
  • Skeleton
  • Spinner
  • Table
  • Tabs
  • Tree
Layout
  • Carousel
  • Resizable
  • ScrollArea
  • Sidebar
Dates
  • Calendar
  • DatePicker
  • DateRangePicker
  • TimePicker
Data
  • AreaChart
  • BarChart
  • Chart
  • DataTable
  • Kanban
  • LineChart
  • PieChart
  • RadarChart
  • RadialChart
  • VirtualList
Chat
  • Attachment
  • Message
  • MessageList
  • PromptInput
Elements UI / Forms / FileUpload

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

files: ; rejected: ; accepts: 0; rejects: 0; changes: 0
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.

Drag and drop files here

PDF, up to 5 MB.

not submitted
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.

Drag and drop files here

Up to three files

1 / 3
  • notes.txt 33 bytes
not submitted
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

1 / 3
  • 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.

Attach up to 3 files
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

1 / 1
  • notes.txt 33 bytes

Drag and drop files here

1 / 1
  • 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.

Choose up to 3 files
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 />
Reference FileUpload in the manual Every part, attribute, slot, key and data attribute.
Prev FieldNext Input
Product
Manual Pricing Compare
Company
History Contact
Legal
Privacy Policy Acceptable Use Terms License Agreement
© Elements Dev Corporation 2026