GitHubnpm

Accent theme

Base radius

GitHubnpm

Accent theme

Base radius

Colour scheme
Docs menu

Guides


Primitives
Forms
Layout
Feedback
Overlays
Navigation
Data Display
AI

File Upload

A real <input type="file">, wrapped entirely inside a real <label> that IS the drop zone — the whole padded area is natively clickable, no .click()forwarding needed. Drag-and-drop is a progressive enhancement on top of that: the native element has none, and accept only filters the OS dialog, never a drop, so both are reimplemented once and reused by whichever path a file actually arrives through. The real input stays authoritative either way — dropped files are re-assigned onto its own .files via a fresh DataTransfer, so it still participates correctly in a plain, non-JS <form> submission.

Playground

Toggle every adjustable prop and watch the component — and the code — update live.

multiple
max files
max size (MB)
invalid
disabled
hide label
label offset
Usage
<FileUpload label="Upload files" description="PNG or JPG, up to 5MB" accept="image/*" multiple maxFiles={3} maxSize={5242880} errorMessage="That file is too large." />

Props

Props for File Upload.
PropTypeDefault
labelReactNode (required)
hideLabelbooleanfalse
descriptionReactNode
filesFile[]
defaultFilesFile[][]
acceptstring
multiplebooleanfalse
maxFilesnumber
maxSizenumber (bytes)
onError(error) => void
errorMessageReactNode
invalidbooleanfalse
disabledbooleanfalse

Rejections (wrong type, over maxSize, or over maxFiles) reject the whole attempted batch and call onError rather than silently keeping only some of what was dropped. Dropping accumulates onto the existing selection; re-opening the OS picker still replaces it, the same as the native element's own behaviour — that inconsistency comes from the browser, not from this wrapper.

Accessibility

  • Drag-and-drop is a progressive enhancement only: Tab to the drop zone, Enter or Space opens the native OS dialog, fully usable with zero pointer/drag involvement.
  • Each file's remove button gets aria-label="Remove {filename}" since it's otherwise an icon-only control.
  • Rejected files go through the same role="alert" error region as every other Kernel form field's errorMessage.