Skip to content

wmik/use-file-input

Repository files navigation

use-file-input

React based hooks for html file type inputs with drag and drop support.

Features

  • 👀 Familiar API - Extends the Map API with minimal abstraction making it easy to use.
  • 🖱️ Drag n Drop - Supports HTML Drag and Drop API.
  • 🎛️ Configurable - Adjust settings to match your requirements.
  • 💅 Headless - Build your own custom user interface to fit your style.

Installation

npm install @wmik/use-file-input

Example

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,
      padding: 8,
      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}
        onClick={() => fileInputRef?.current?.click()}
      >
        <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>
  );
}

API

useFileInput

Creates a custom file input object.

Parameters (FileInputProps)

Property Type Description
id function Custom ID generator
ref object Custom React reference object

NOTE: * means it is required

Returns (FileInputHookObject)

Property Type Description
files object Map-like object for file cache I/O operations
{files}.get function(key: string) Method to get a file from the cache
{files}.set function(file: File) Method to add a file to the cache
{files}.delete function(key: string) Method to remove a file from the cache
{files}.has function(key: string) Method to check if an identifier exists in the cache
{files}.clear function Method to remove all files from the cache
{files}.keys function Method to list identifiers in the cache
{files}.values function Method to list files in the cache
{files}.entries function Method to list identifier-file pairs in the cache
fileInputRef object React referencing object for HTMLInputElement
isDraggingOver boolean Dragging state
onFileInputChange function(event) HTML change event handler
onFileInputDragStart function(event) HTML dragstart event handler
onFileInputDragLeave function(event) HTML dragleave event handler
onFileInputDragOver function(event) HTML dragover event handler
onFileInputDrop function(event) HTML drop event handler

License

MIT ©2025

About

React based hooks for html file type inputs.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published