Skip to main content

FileUploader

FileUploader is a flexible file upload component that supports drag-and-drop, click-to-upload, keyboard interaction, file previews, and file removal. It works for both single and multiple file uploads with optional file type filtering.


Usage

Basic usage

import { FileUploader } from '@nofinite/nui';

<FileUploader onChange={(files) => console.log(files)} />;

With accept filter

<FileUploader accept="image/*" />

Variants

This component does not have visual variants. Styling is handled via CSS and the optional className prop.


Sizes

FileUploader does not provide explicit size variants. Size can be controlled using CSS (padding, font size, container width).


States

Drag over (active)

Triggered when files are dragged over the dropzone:

  • Dashed border changes color
  • Background and text color update
  • Visual feedback for drop readiness

File list visible

When one or more files are selected:

  • A file list is rendered below the dropzone
  • Each file shows its name and a remove button

Native Props / Composition

The component internally uses a hidden <input type="file" /> and forwards behavior through the dropzone.

<FileUploader
className="my-custom-uploader"
accept=".pdf,.docx"
multiple
onChange={handleFiles}
/>

You can fully control layout and spacing via className.


Props

PropTypeDefaultDescription
multiplebooleanfalseAllows selecting or dropping multiple files
acceptstringFile type filter passed to the native input
onChange(files: File[]) => voidCallback fired whenever the file list changes
classNamestring""Additional class names for custom styling
placeholderstring"Drag files here or click to upload"Text displayed inside the dropzone

Behavior Notes

  • If multiple is false, only the first selected or dropped file is kept.
  • If multiple is true, new files are appended to the existing list.
  • Removing a file updates internal state and triggers onChange.
  • The dropzone is keyboard-accessible and behaves like a button.
<FileUploader multiple onChange={(files) => console.log(files)} />

Accessibility

  • Dropzone renders as a <div role="button">

  • Keyboard support:

    • Enter and Space trigger file selection
  • Focus-visible outline is shown for keyboard users

  • Remove buttons include aria-label="Remove file"

Example:

<FileUploader aria-label="Upload documents" />

Layout

  • The component is block-level by default
  • Stacks vertically: dropzone → file list
  • Width is controlled by its container
<div style={{ maxWidth: 400 }}>
<FileUploader />
</div>

Best Practices

Do

  • Use accept to limit selectable file types
  • Enable multiple only when users genuinely need multi-file uploads
  • Handle onChange to sync files with form or state

Don’t

  • Use it without visual spacing in dense layouts
  • Rely on it for validation only — always validate files on submit
  • Hide the file list if users need confirmation of selected files