Skip to content

Forms

IFileUpload

A drag-and-drop file field, with a browse button and a list of what has been picked.

The model is always a File[], even without multiple — in that case an array holding at most one file, and picking again replaces it.

Multiple files

Image files get a thumbnail and everything else a placeholder of the same size. The object URLs behind the thumbnails are revoked when a file leaves the list or the component unmounts.

Accepted types and sizes

accept uses the native syntax — image/*, .pdf, image/png — and is enforced on dragged-in files as well as on the browse dialog.

Put the accepted types in hint: label is the instruction, hint is the fine print.

Capping the count

Rejections

Refused files raise @reject once per drop, with an array of { file, reason }, where reason is 'type', 'size' or 'count'. The messages shown on the rows come from tooLargeText, wrongTypeText and tooManyText.

Invalid and disabled

Inside an IFormField the field passes its own validity down, so invalid rarely needs setting by hand.

Props

PropTypeDefaultDescription
multiplebooleanAccept more than one file. The model is an array either way
acceptstringNative syntax: image/*, .pdf, image/png
maxSizenumberLargest accepted size, in bytes
maxFilesnumberCap on how many files may be held at once
disabledbooleanZone and browse button are inert
invalidbooleanRed border; inherited from IFormField when unset
idstringId for the input; IFormField supplies one
labelstring'Drag and drop a file here'Prompt inside the zone
hintstringFine print under the prompt
browseLabelstring'Browse files'Text on the browse button
removeLabelstring'Remove'Accessible name for a row's remove action
tooLargeTextstring'is too large'Message for a size rejection
wrongTypeTextstring'is not an accepted type'Message for a type rejection
tooManyTextstring'exceeds the file limit'Message for a count rejection
unstyledbooleanDrop built-in classes
classstringApplied to the wrapper stacking the zone above the list
ui{ root?, dropzone?, input?, icon?, label?, browse?, hint?, list?, item?, thumbnail?, placeholder?, details?, name?, meta?, remove?, error? }Per-slot class overrides

Events

EventPayloadWhen
rejectFileRejection[]One or more files were refused, once per drop or pick
ts
interface FileRejection {
  file: File
  reason: 'type' | 'size' | 'count'
}

Model

ts
const files = ref<File[]>([])

The component never uploads anything: it hands you File objects, and posting them, showing progress and retrying are yours.