Forms
File upload
A dropzone over a real `<input type="file">`.
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.
<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.
<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.
| Prop | Type | Default | Description |
|---|---|---|---|
accept | string | — | Same syntax as the native attribute: `".pdf,image/*"`. Enforced here too. |
multiple | boolean | — | — |
maxSize | number | — | Per-file limit, in bytes. |
maxFiles | number | — | Cap on the accepted list. Extra files are rejected with reason `'count'`. |
value | File[] | — | Controlled list. |
defaultValue | File[] | — | Uncontrolled initial list. Default `[]`. |
onFilesChange | (files: File[]) => void | — | Called with the whole accepted list on every change, in both modes. |
onReject | (rejections: FileRejection[]) => void | — | Called with everything refused by one drop or pick, and why. |
disabled | boolean | — | — |
invalid | boolean | — | Sets `aria-invalid` on the input. Injected by `Field`. |
required | boolean | — | Injected by `Field`. |
name | string | — | Submits with the form. |
label | ReactNode | — | Main dropzone text. Also the input's accessible name, unless `aria-label` is set. |
hint | ReactNode | — | Secondary line — the place for "PNG or JPG, up to 5 MB". |
size | 'sm' | 'md' | — | — |
removeLabel | (fileName: string) => string | — | Accessible 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
FileUploadformatBytesmatchesAcceptRendering
FileUpload declares 'use client' because it needs state, effects or event handlers. Importing it into a Server Component creates a client boundary at this component — everything above it stays on the server.