Forms

File upload

A dropzone over a real `<input type="file">`.

Client component3 exportsSource

Import

import { FileUpload, formatBytes, matchesAccept } from '@the_viveksingh/vivek-ui'

A drop zone

It is a real file input behind a labelled drop zone, so click, drag-and-drop, keyboard activation and the OS file picker all work. Selected files are listed with a remove button each.

No files selected
<FileUpload
  multiple
  label="Attachments"
  hint="Drop files here, or click to browse."
  onFilesChange={setFiles}
/>

Constraints

Rejections are reported through onReject with a reason, rather than being dropped silently - the user needs to know their 12 MB file was refused.

No files selected
<FileUpload
  accept="image/png,image/jpeg"
  maxSize={2 * 1024 * 1024}
  maxFiles={3}
  multiple
  size="sm"
  label="Screenshots"
  hint="PNG or JPEG, up to 2 MB each, 3 files maximum."
  onReject={(rejections) => console.warn(rejections)}
/>

Props

Generated from the package's own type declarations, so this table cannot drift from the code.

Props for FileUpload
PropTypeDefaultDescription
acceptstringSame syntax as the native attribute: `".pdf,image/*"`. Enforced here too.
multipleboolean
maxSizenumberPer-file limit, in bytes.
maxFilesnumberCap on the accepted list. Extra files are rejected with reason `'count'`.
valueFile[]Controlled list.
defaultValueFile[]Uncontrolled initial list. Default `[]`.
onFilesChange(files: File[]) => voidCalled with the whole accepted list on every change, in both modes.
onReject(rejections: FileRejection[]) => voidCalled with everything refused by one drop or pick, and why.
disabledboolean
invalidbooleanSets `aria-invalid` on the input. Injected by `Field`.
requiredbooleanInjected by `Field`.
namestringSubmits with the form.
labelReactNodeMain dropzone text. Also the input's accessible name, unless `aria-label` is set.
hintReactNodeSecondary line — the place for "PNG or JPG, up to 5 MB".
size'sm' | 'md'
removeLabel(fileName: string) => stringAccessible name for a row's remove button. Default `` `Remove ${name}` ``.

Every remaining prop is spread onto the root element, so all standard HTML and ARIA attributes work. className and style are merged with the library's own, never replaced, and the ref forwards to the root DOM node.

Exports

FileUploadformatBytesmatchesAccept

Rendering