Skip to content
Component

File Upload

Button-triggered file input and its drag-and-drop sibling, Dropzone. Both keep a removable file list once files are selected.

Button-triggered

Dropzone

Drag-and-drop target with a click-to-browse fallback.

Drag and drop files here, or click to browse

  • Dropzone falls back to a native file picker on click for keyboard and touch users

When to use

  • FileUpload: a compact, button-triggered picker inside a form (profile photo, attachment, document).
  • Dropzone: a larger, drag-and-drop-first target where the upload is the primary action on the page or panel.

When not to use

  • Very large file counts or resumable/chunked uploads - both components handle file selection and a local list, not upload transport; wire your own upload logic to onChange.

Keyboard

KeyAction
Enter / SpaceOpens the native file picker from the trigger button or Dropzone.
TabMoves to each file's remove button once files are selected.

Mobile behavior

  • Drag-and-drop has no equivalent on touch, so Dropzone always renders a real, tappable file input underneath - touch users tap to open the native file picker instead of dragging.
  • FileUpload is a standard button + native input on every viewport.

Accessibility notes

  • Both wrap a real <input type="file"> under the hood, so they inherit native file-picker accessibility (OS dialog, screen reader file-count announcements) rather than reimplementing it.
  • Each selected file's remove control has an accessible name identifying that specific file.

Common mistakes

  • Relying on drag-and-drop as the only way to add a file - Dropzone's click-to-browse fallback exists specifically so keyboard and touch users aren't blocked; don't hide or disable it.
  • Not validating accept/file size server-side - the accept attribute is a UI hint only, not a security boundary.

Known limitations

  • No built-in upload progress, chunking, or retry - these are local file-selection components, not an upload client.

Related components

FileUpload / Dropzone props

value / onChangeNone
File[] / (files: File[]) => void

Controlled selected files.

defaultValueNone
File[]

Uncontrolled initial files.

acceptNone
string

Native accept attribute, e.g. "image/*".

multiplefalse
boolean

Allows selecting more than one file.

disabledfalse
boolean

Disables the trigger/drop target.

CriterionStatusNote
Keyboard supportSupportedEnter/Space opens the native picker; Tab reaches each file's remove control.
Focus managementNot applicableNo modal/portal surface - just a native input and a local list.
Screen reader labelsSupportedNative file input semantics plus a labeled remove control per file.
Reduced motionSupportedNo motion beyond the shared Fuji transition tokens, which zero under prefers-reduced-motion.
Reduced transparencyNot applicableUses opaque surfaces in every theme.
Mobile touch behaviorSupportedDropzone always exposes a tappable native file input, not drag-only.

API reference

acceptNone
string

Accepted file types.

multiplefalse
boolean

Allows more than one file.

onFilesChangeNone
(files: File[]) => void

Receives chosen or dropped files.

classNameNone
string

Additional classes applied to the component root.