or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-react-dropzone

Simple HTML5 drag-drop zone with React.js

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/react-dropzone@14.3.x

To install, run

npx @tessl/cli install tessl/npm-react-dropzone@14.3.0

index.mddocs/

React Dropzone

React Dropzone is a React library that provides simple HTML5-compliant drag-and-drop zones for file uploads. It offers a powerful useDropzone hook and convenient Dropzone component wrapper with extensive customization options, file validation, and comprehensive event handling.

Package Information

  • Package Name: react-dropzone
  • Package Type: npm
  • Language: JavaScript/TypeScript
  • Installation: npm install react-dropzone or yarn add react-dropzone

Core Imports

import Dropzone, { useDropzone, ErrorCode, FileWithPath } from "react-dropzone";

For CommonJS:

const Dropzone = require("react-dropzone").default;
const { useDropzone, ErrorCode, FileWithPath } = require("react-dropzone");

Basic Usage

import React, { useCallback } from "react";
import { useDropzone } from "react-dropzone";

function MyDropzone() {
  const onDrop = useCallback((acceptedFiles: File[]) => {
    // Process the dropped files
    console.log(acceptedFiles);
  }, []);

  const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop });

  return (
    <div {...getRootProps()}>
      <input {...getInputProps()} />
      {isDragActive ? (
        <p>Drop the files here...</p>
      ) : (
        <p>Drag 'n' drop files here, or click to select files</p>
      )}
    </div>
  );
}

Architecture

React Dropzone is built around modern React patterns:

  • Hook-based API: Primary interface through useDropzone hook (React 16.8+)
  • Component Wrapper: Optional Dropzone component for render prop pattern
  • Event-driven Architecture: Comprehensive drag and drop event handling
  • File Validation System: Built-in validation for file types, sizes, and custom rules
  • Zero Dependencies: Core functionality has no external dependencies beyond React
  • TypeScript Support: Complete type definitions included

Capabilities

useDropzone Hook

The primary interface for creating drag-and-drop zones with full customization options.

/**
 * Creates a drag 'n' drop area with comprehensive configuration options
 * @param options - Configuration options for the dropzone
 * @returns State object with drag states, file arrays, and prop getter functions
 */
function useDropzone(options?: DropzoneOptions): DropzoneState;

interface DropzoneOptions {
  /** Accepted file types as MIME type object (default: undefined - all files) */
  accept?: Accept;
  /** Allow multiple file selection (default: true) */
  multiple?: boolean;
  /** Prevent drops on document (default: true) */
  preventDropOnDocument?: boolean;
  /** Disable click to open file dialog (default: false) */
  noClick?: boolean;
  /** Disable keyboard file dialog triggers (default: false) */
  noKeyboard?: boolean;
  /** Disable drag and drop (default: false) */
  noDrag?: boolean;
  /** Stop drag event bubbling (default: false) */
  noDragEventsBubbling?: boolean;
  /** Minimum file size in bytes (default: 0) */
  minSize?: number;
  /** Maximum file size in bytes (default: Infinity) */
  maxSize?: number;
  /** Maximum number of files (default: 0 - unlimited) */
  maxFiles?: number;
  /** Disable the dropzone (default: false) */
  disabled?: boolean;
  /** Use File System Access API (default: false) */
  useFsAccessApi?: boolean;
  /** Auto focus the dropzone (default: false) */
  autoFocus?: boolean;
  /** Custom file aggregator function (default: fromEvent from file-selector) */
  getFilesFromEvent?: (event: DropEvent) => Promise<Array<File | DataTransferItem>>;
  /** Custom file validator (default: null) */
  validator?: <T extends File>(file: T) => FileError | readonly FileError[] | null;
  /** Callback when files are dropped */
  onDrop?: <T extends File>(
    acceptedFiles: T[],
    fileRejections: FileRejection[],
    event: DropEvent
  ) => void;
  /** Callback when files are accepted */
  onDropAccepted?: <T extends File>(files: T[], event: DropEvent) => void;
  /** Callback when files are rejected */
  onDropRejected?: (fileRejections: FileRejection[], event: DropEvent) => void;
  /** Callback when drag enters */
  onDragEnter?: (event: React.DragEvent<HTMLElement>) => void;
  /** Callback when drag leaves */
  onDragLeave?: (event: React.DragEvent<HTMLElement>) => void;
  /** Callback when dragging over */
  onDragOver?: (event: React.DragEvent<HTMLElement>) => void;
  /** Callback when file dialog opens */
  onFileDialogOpen?: () => void;
  /** Callback when file dialog is cancelled */
  onFileDialogCancel?: () => void;
  /** Error handler */
  onError?: (error: Error) => void;
}

interface DropzoneState {
  /** Dropzone is focused */
  isFocused: boolean;
  /** Active drag is in progress */
  isDragActive: boolean;
  /** Dragged files are accepted */
  isDragAccept: boolean;
  /** Some dragged files are rejected */
  isDragReject: boolean;
  /** File dialog is open */
  isFileDialogActive: boolean;
  /** Array of accepted files */
  acceptedFiles: readonly FileWithPath[];
  /** Array of rejected files with errors */
  fileRejections: readonly FileRejection[];
  /** Reference to root element */
  rootRef: React.RefObject<HTMLElement>;
  /** Reference to input element */
  inputRef: React.RefObject<HTMLInputElement>;
  /** Get props for root container */
  getRootProps: <T extends DropzoneRootProps>(props?: T) => T;
  /** Get props for hidden file input */
  getInputProps: <T extends DropzoneInputProps>(props?: T) => T;
  /** Programmatically open file dialog */
  open: () => void;
}

Usage Examples:

import { useDropzone } from "react-dropzone";

// Basic file upload
const basic = useDropzone({
  onDrop: (files) => console.log("Dropped files:", files),
});

// With file type restrictions
const imageOnly = useDropzone({
  accept: {
    "image/*": [".jpeg", ".jpg", ".png", ".gif"],
  },
  onDrop: (files) => uploadImages(files),
});

// With size limits and multiple files
const documents = useDropzone({
  accept: {
    "application/pdf": [".pdf"],
    "application/msword": [".doc", ".docx"],
  },
  minSize: 1024, // 1KB minimum
  maxSize: 5242880, // 5MB maximum
  maxFiles: 3,
  onDropAccepted: (files) => handleAccepted(files),
  onDropRejected: (rejections) => handleRejected(rejections),
});

Dropzone Component

Convenience wrapper component using render prop pattern for the useDropzone hook.

/**
 * Convenience wrapper component for the useDropzone hook
 * @param props - Dropzone options plus children render function
 */
function Dropzone(
  props: DropzoneProps & React.RefAttributes<DropzoneRef>
): React.ReactElement;

interface DropzoneProps extends DropzoneOptions {
  /** Render function that receives dropzone state */
  children?(state: DropzoneState): React.ReactElement;
}

interface DropzoneRef {
  /** Programmatically open file dialog */
  open: () => void;
}

Usage Examples:

import Dropzone from "react-dropzone";

// Basic usage with render prop
<Dropzone onDrop={(files) => console.log(files)}>
  {({ getRootProps, getInputProps, isDragActive }) => (
    <div {...getRootProps()}>
      <input {...getInputProps()} />
      {isDragActive ? (
        <p>Drop files here...</p>
      ) : (
        <p>Drag files here or click to browse</p>
      )}
    </div>
  )}
</Dropzone>

// With imperative access via ref
const dropzoneRef = useRef<DropzoneRef>(null);

<Dropzone ref={dropzoneRef} onDrop={handleDrop}>
  {({ getRootProps, getInputProps }) => (
    <div {...getRootProps()}>
      <input {...getInputProps()} />
      <button onClick={() => dropzoneRef.current?.open()}>
        Browse Files
      </button>
    </div>
  )}
</Dropzone>

File Validation and Error Handling

Built-in validation system with detailed error reporting for rejected files.

/** Error codes for file validation failures */
enum ErrorCode {
  FileInvalidType = "file-invalid-type",
  FileTooLarge = "file-too-large",
  FileTooSmall = "file-too-small",
  TooManyFiles = "too-many-files",
}

interface FileError {
  /** Human-readable error message */
  message: string;
  /** Error code for programmatic handling */
  code: ErrorCode | string;
}

interface FileRejection {
  /** The rejected file */
  file: FileWithPath;
  /** Array of validation errors */
  errors: readonly FileError[];
}

interface FileWithPath extends File {
  /** File path (when available) */
  path?: string;
}

Usage Examples:

import { useDropzone, ErrorCode } from "react-dropzone";

const { getRootProps, getInputProps, fileRejections } = useDropzone({
  accept: { "image/*": [] },
  maxSize: 1048576, // 1MB
  onDropRejected: (rejections) => {
    rejections.forEach(({ file, errors }) => {
      console.log(`File ${file.name} rejected:`);
      errors.forEach((error) => {
        switch (error.code) {
          case ErrorCode.FileInvalidType:
            console.log("Invalid file type");
            break;
          case ErrorCode.FileTooLarge:
            console.log("File too large");
            break;
          default:
            console.log(error.message);
        }
      });
    });
  },
});

// Custom validator
const customValidation = useDropzone({
  validator: (file) => {
    if (file.name.includes("temp")) {
      return {
        code: "name-not-allowed",
        message: "Temporary files are not allowed",
      };
    }
    return null;
  },
});

Advanced Configuration

Advanced features for specialized use cases and enhanced user experience.

interface DropzoneRootProps extends React.HTMLAttributes<HTMLElement> {
  /** Reference key for root element (default: "ref") */
  refKey?: string;
  [key: string]: any;
}

interface DropzoneInputProps extends React.InputHTMLAttributes<HTMLInputElement> {
  /** Reference key for input element (default: "ref") */
  refKey?: string;
}

interface Accept {
  /** MIME type keys with array of file extensions */
  [mimeType: string]: readonly string[];
}

type DropEvent =
  | React.DragEvent<HTMLElement>
  | React.ChangeEvent<HTMLInputElement>
  | DragEvent
  | Event
  | Array<FileSystemFileHandle>;

Usage Examples:

// File System Access API (modern browsers)
const modernFileAccess = useDropzone({
  useFsAccessApi: true,
  onDrop: (files) => console.log("Files selected:", files),
});

// Custom file processing
const customProcessor = useDropzone({
  getFilesFromEvent: async (event) => {
    // Custom file extraction logic
    const items = Array.from(event.dataTransfer?.items || []);
    return items
      .filter((item) => item.kind === "file")
      .map((item) => item.getAsFile())
      .filter(Boolean);
  },
});

// Preventing document drops globally
const secureDropzone = useDropzone({
  preventDropOnDocument: true,
  noDragEventsBubbling: true,
  onDrop: (files) => secureUpload(files),
});

// Accessibility and keyboard support
const accessibleDropzone = useDropzone({
  autoFocus: true,
  noKeyboard: false, // Allow SPACE/ENTER to open dialog
  onDrop: (files) => handleFiles(files),
});

Types

/** File with optional path information */
interface FileWithPath extends File {
  path?: string;
}

/** Configuration for accepted file types */
interface Accept {
  [mimeType: string]: readonly string[];
}

/** Union type for various drop events */
type DropEvent =
  | React.DragEvent<HTMLElement>
  | React.ChangeEvent<HTMLInputElement>
  | DragEvent
  | Event
  | Array<FileSystemFileHandle>;

/** Error codes for file validation */
enum ErrorCode {
  FileInvalidType = "file-invalid-type",
  FileTooLarge = "file-too-large",
  FileTooSmall = "file-too-small",
  TooManyFiles = "too-many-files",
}

/** File validation error */
interface FileError {
  message: string;
  code: ErrorCode | string;
}

/** Rejected file with associated errors */
interface FileRejection {
  file: FileWithPath;
  errors: readonly FileError[];
}