React File Input Hooks

File uploads made elegant

A powerful, headless React hook for file inputs with drag-and-drop support. Build beautiful file upload experiences with complete control.

npm install @wmik/use-file-input

Everything you need, nothing you don't

Familiar API

Extends the Map API with minimal abstraction, making it incredibly easy to use and integrate.

Drag & Drop

Native HTML5 Drag and Drop API support built right in, no extra configuration needed.

Configurable

Flexible settings that adapt to your specific requirements and use cases.

Headless UI

Build your own custom interface that perfectly matches your design system.

Simple, intuitive API

          
import { useFileInput } from '@wmik/use-file-input';
  
function FileInputComponent() {
  const LABEL_TEXT_DEFAULT = 'Click or drag/drop files to upload';
  const LABEL_TEXT_HOVER = 'Drop files to upload';
  const PLACEHOLDER_TEXT = 'No files';

  let { 
    files,
    fileInputRef,
    isDraggingOver,
    onFileInputChange,
    onFileInputDragStart,
    onFileInputDragOver,
    onFileInputDragLeave,
    onFileInputDrop
   } = useFileInput();
  let hasFiles = Array.from(files?.values() ?? [])?.length > 0;

  let styles = {
    container: {
      width: 400,
      height: 400,
      border: '1px dashed #dddccc'
    },
    label: {},
    input: {
      display: 'none'
    },
    list: {
      display: hasFiles ? 'block' : 'none'
    },
    placeholder: {
      display: !hasFiles ? 'block' : 'none'
    }
  };

  return (
    <main>
      <div
        style={styles.container}
        onDragOver={onFileInputDragOver}
        onDragStart={onFileInputDragStart}
        onDragLeave={onFileInputDragLeave}
        onDrop={onFileInputDrop}
      >
        <label
          htmlFor="files"
          style={styles.label}
          children={isDraggingOver ? LABEL_TEXT_HOVER : LABEL_TEXT_DEFAULT}
        />
        <input
          multiple
          id="files"
          type="file"
          name="files"
          ref={fileInputRef}
          style={styles.input}
          onChange={onFileInputChange}
        />
      </div>

      <ul style={styles.list}>
        {Array.from(files.values())?.map(file => (
          <li key={file?.name}>
            <span children={file?.name} />
            <button
              type="button"
              aria-roledescription="delete"
              onClick={() => files.delete(file)}
            >
              DELETE
            </button>
          </li>
        ))}
      </ul>

      <p style={styles.placeholder} children={PLACEHOLDER_TEXT} />
    </main>
  );
}
      
    
~3KB
Minified + Gzipped
0
Dependencies
100%
TypeScript

Ready to get started?

Install the package and start building better file upload experiences today.

View on GitHub