CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-dropzone

Lightweight JavaScript library that transforms HTML elements into drag-and-drop file upload zones with thumbnail previews, progress tracking, and extensive customization options.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

static-utilities.mddocs/

Static Methods and Utilities

Static utility methods, global configuration, and instance management functionality for Dropzone.js.

Capabilities

Instance Management

Static methods for managing and accessing Dropzone instances globally.

/**
 * Find existing Dropzone instance for an element
 * @param element - CSS selector string or HTMLElement
 * @returns Dropzone instance attached to the element
 * @throws Error if no Dropzone found for element
 */
static forElement(element: string | HTMLElement): Dropzone;

/**
 * Automatically discover and initialize all .dropzone elements
 */
static discover(): void;

/**
 * Global array of all Dropzone instances
 */
static instances: Dropzone[];

/**
 * Current version of Dropzone library
 */
static version: string;

Usage Examples:

// Create dropzones
const dropzone1 = new Dropzone("#upload1", { url: "/upload" });
const dropzone2 = new Dropzone("#upload2", { url: "/upload" });

// Access existing dropzone instance
const existingDropzone = Dropzone.forElement("#upload1");
console.log("Found dropzone:", existingDropzone === dropzone1); // true

// Access by DOM element
const element = document.getElementById("upload2");
const dropzoneByElement = Dropzone.forElement(element);

// List all instances
console.log("Total dropzones:", Dropzone.instances.length);
Dropzone.instances.forEach((dz, index) => {
  console.log(`Dropzone ${index}:`, dz.element.id);
});

// Get library version
console.log("Dropzone version:", Dropzone.version); // "4.3.0"

// Auto-discover dropzones
Dropzone.discover(); // Initializes all .dropzone elements

// Error handling
try {
  const nonExistent = Dropzone.forElement("#not-found");
} catch (error) {
  console.error("Dropzone not found:", error.message);
}

Auto-Discovery Configuration

Global configuration system for automatic Dropzone initialization.

/**
 * Whether to automatically discover and initialize .dropzone elements
 */
static autoDiscover: boolean;

/**
 * Global options object for configuring dropzones by element ID
 * Key: camelCase version of element ID
 * Value: DropzoneOptions object or false to disable
 */
static options: { [elementId: string]: DropzoneOptions | false };

/**
 * Get options for a specific element
 * @param element - HTMLElement to get options for
 * @returns Options object or undefined
 */
static optionsForElement(element: HTMLElement): DropzoneOptions | false | undefined;

Usage Examples:

<!-- HTML elements -->
<form id="my-awesome-dropzone" action="/upload" class="dropzone"></form>
<div id="simple-upload" class="dropzone"></div>
<div id="disabled-dropzone" class="dropzone"></div>
// Configure dropzones before auto-discovery
Dropzone.options.myAwesomeDropzone = {
  maxFilesize: 2,
  acceptedFiles: "image/*",
  dictDefaultMessage: "Drop images here"
};

Dropzone.options.simpleUpload = {
  url: "/api/files",
  maxFiles: 5,
  addRemoveLinks: true
};

// Disable auto-discovery for specific element
Dropzone.options.disabledDropzone = false;

// Check configuration
const element = document.getElementById("my-awesome-dropzone");
const config = Dropzone.optionsForElement(element);
console.log("Configuration:", config);

// Disable auto-discovery globally
Dropzone.autoDiscover = false;

// Manual discovery after configuration
Dropzone.discover();

// Re-enable auto-discovery
Dropzone.autoDiscover = true;

DOM Utility Methods

Static utility methods for DOM manipulation and element handling.

/**
 * Create DOM element from HTML string
 * @param string - HTML string to convert to element
 * @returns HTMLElement created from string
 */
static createElement(string: string): HTMLElement;

/**
 * Test if element is inside (or is) the container
 * @param element - Element to test
 * @param container - Container element
 * @returns true if element is inside container
 */
static elementInside(element: HTMLElement, container: HTMLElement): boolean;

/**
 * Get single element from selector or element
 * @param el - CSS selector string or HTMLElement
 * @param name - Name for error messages
 * @returns HTMLElement
 * @throws Error if element not found or invalid
 */
static getElement(el: string | HTMLElement, name: string): HTMLElement;

/**
 * Get multiple elements from various input types
 * @param els - CSS selector, HTMLElement, or array of elements
 * @param name - Name for error messages
 * @returns Array of HTMLElements
 * @throws Error if no valid elements found
 */
static getElements(els: string | HTMLElement | HTMLElement[], name: string): HTMLElement[];

Usage Examples:

// Create elements from HTML strings
const previewElement = Dropzone.createElement(`
  <div class="file-preview">
    <img class="thumbnail" />
    <span class="filename"></span>
  </div>
`);
document.body.appendChild(previewElement);

// Test element containment
const dropzoneEl = document.getElementById("my-dropzone");
const fileInput = dropzoneEl.querySelector("input[type=file]");
const isInside = Dropzone.elementInside(fileInput, dropzoneEl);
console.log("Input is inside dropzone:", isInside); // true

// Get single element
const uploadArea = Dropzone.getElement("#upload-area", "upload area");
const formElement = Dropzone.getElement(document.forms[0], "form");

// Get multiple elements
const clickableElements = Dropzone.getElements([
  "#upload-button",
  "#drop-area",
  document.querySelector(".upload-zone")
], "clickable elements");

console.log("Found", clickableElements.length, "clickable elements");

// Error handling
try {
  const invalidElement = Dropzone.getElement("#nonexistent", "test element");
} catch (error) {
  console.error("Element not found:", error.message);
}

try {
  const noElements = Dropzone.getElements("", "empty selector");
} catch (error) {
  console.error("No elements found:", error.message);
}

File Validation Utilities

Static methods for file validation and browser capability detection.

/**
 * Validate file against accepted file types
 * @param file - File object to validate
 * @param acceptedFiles - Comma-separated string of accepted MIME types/extensions
 * @returns true if file is valid
 */
static isValidFile(file: File, acceptedFiles: string): boolean;

/**
 * Check if current browser supports drag and drop file uploads
 * @returns true if browser is supported
 */
static isBrowserSupported(): boolean;

/**
 * Array of regex patterns for blacklisted browsers
 */
static blacklistedBrowsers: RegExp[];

Usage Examples:

// File validation
const file = new File(["content"], "document.pdf", { type: "application/pdf" });

// Test against various accepted types
console.log("PDF accepted (application/pdf):", 
  Dropzone.isValidFile(file, "application/pdf")); // true

console.log("PDF accepted (pdf extension):", 
  Dropzone.isValidFile(file, ".pdf")); // true

console.log("PDF accepted (documents):", 
  Dropzone.isValidFile(file, "application/*")); // true

console.log("PDF accepted (images only):", 
  Dropzone.isValidFile(file, "image/*")); // false

// Multiple accepted types
const acceptedTypes = "image/*,application/pdf,.doc,.docx";
console.log("PDF in mixed types:", 
  Dropzone.isValidFile(file, acceptedTypes)); // true

// Image file validation
const imageFile = new File([""], "photo.jpg", { type: "image/jpeg" });
console.log("JPEG accepted:", 
  Dropzone.isValidFile(imageFile, "image/*")); // true

// Browser support detection
if (Dropzone.isBrowserSupported()) {
  console.log("Browser supports drag and drop uploads");
  new Dropzone("#my-dropzone", { url: "/upload" });
} else {
  console.log("Browser not supported, showing fallback");
  document.getElementById("fallback-form").style.display = "block";
}

// Check blacklisted browsers
console.log("Blacklisted browsers:", Dropzone.blacklistedBrowsers);
// Example: [/opera.*Macintosh.*version\/12/i]

// Custom browser detection
function isModernBrowser() {
  const supported = Dropzone.isBrowserSupported();
  const isBlacklisted = Dropzone.blacklistedBrowsers.some(regex => 
    regex.test(navigator.userAgent)
  );
  return supported && !isBlacklisted;
}

User Interaction Utilities

Static methods for user interaction and confirmation dialogs.

/**
 * Show confirmation dialog to user
 * @param question - Question to ask user
 * @param accepted - Callback if user accepts
 * @param rejected - Optional callback if user rejects
 */
static confirm(question: string, accepted: () => void, rejected?: () => void): void;

Usage Examples:

// Basic confirmation
Dropzone.confirm(
  "Are you sure you want to remove this file?",
  function() {
    console.log("User confirmed removal");
    // Proceed with removal
  },
  function() {
    console.log("User canceled removal");
    // Handle cancellation
  }
);

// Custom confirmation with dropzone integration
const dropzone = new Dropzone("#my-dropzone", {
  url: "/upload",
  addRemoveLinks: true,
  
  init: function() {
    this.on("removedfile", function(file) {
      // This uses Dropzone.confirm internally for dictRemoveFileConfirmation
      console.log("File removed:", file.name);
    });
  },
  
  // Enable confirmation for file removal
  dictRemoveFileConfirmation: "Are you sure you want to delete this file?"
});

// Override default confirm function
const originalConfirm = Dropzone.confirm;
Dropzone.confirm = function(question, accepted, rejected) {
  // Use custom modal instead of window.confirm
  showCustomModal({
    title: "Confirm Action",
    message: question,
    onConfirm: accepted,
    onCancel: rejected
  });
};

function showCustomModal(options) {
  const modal = document.createElement("div");
  modal.className = "custom-modal";
  modal.innerHTML = `
    <div class="modal-content">
      <h3>${options.title}</h3>
      <p>${options.message}</p>
      <button class="confirm-btn">Confirm</button>
      <button class="cancel-btn">Cancel</button>
    </div>
  `;
  
  modal.querySelector(".confirm-btn").onclick = function() {
    modal.remove();
    options.onConfirm();
  };
  
  modal.querySelector(".cancel-btn").onclick = function() {
    modal.remove();
    if (options.onCancel) options.onCancel();
  };
  
  document.body.appendChild(modal);
}

// Restore original confirm function
// Dropzone.confirm = originalConfirm;

Internal Utility Functions

Internal utility functions exposed for advanced usage.

// Internal helper functions (available but not part of public API)

/**
 * Remove item from array
 * @param list - Array to filter
 * @param rejectedItem - Item to remove
 * @returns New array without rejected item
 */
function without<T>(list: T[], rejectedItem: T): T[];

/**
 * Convert kebab-case or snake_case to camelCase
 * @param str - String to convert
 * @returns Camelized string
 */
function camelize(str: string): string;

Usage Examples:

// These are internal functions, but can be useful for custom implementations

// Array filtering (similar to lodash without)
const files = [file1, file2, file3];
const filteredFiles = without(files, file2);
console.log("Filtered files:", filteredFiles); // [file1, file3]

// String camelization for element IDs
const elementId = "my-awesome-dropzone";
const camelized = camelize(elementId);
console.log("Camelized:", camelized); // "myAwesomeDropzone"

// This is how Dropzone internally converts element IDs to option keys
const element = document.getElementById("upload-form-area");
const optionKey = camelize(element.getAttribute("id"));
console.log("Option key:", optionKey); // "uploadFormArea"

// Access options using camelized key
const options = Dropzone.options[optionKey];

Global Configuration Patterns

Common patterns for global Dropzone configuration and management.

Usage Examples:

// Centralized dropzone configuration
const DropzoneManager = {
  defaultOptions: {
    maxFilesize: 5,
    acceptedFiles: "image/*,application/pdf",
    addRemoveLinks: true,
    dictDefaultMessage: "Drop files here to upload"
  },
  
  instances: [],
  
  create: function(selector, customOptions = {}) {
    const options = Object.assign({}, this.defaultOptions, customOptions);
    const dropzone = new Dropzone(selector, options);
    this.instances.push(dropzone);
    return dropzone;
  },
  
  destroyAll: function() {
    this.instances.forEach(dz => dz.destroy());
    this.instances = [];
  },
  
  getByElement: function(element) {
    return this.instances.find(dz => dz.element === element);
  }
};

// Use centralized manager
const uploadDropzone = DropzoneManager.create("#upload-area", {
  url: "/api/upload",
  maxFiles: 10
});

const avatarDropzone = DropzoneManager.create("#avatar-upload", {
  url: "/api/avatar",
  maxFiles: 1,
  acceptedFiles: "image/*"
});

// Global event handling
function setupGlobalDropzoneEvents() {
  Dropzone.instances.forEach(dropzone => {
    dropzone.on("success", function(file, response) {
      console.log(`Upload successful in ${this.element.id}:`, file.name);
    });
    
    dropzone.on("error", function(file, message) {
      console.error(`Upload failed in ${this.element.id}:`, message);
    });
  });
}

// Setup global events after auto-discovery
document.addEventListener("DOMContentLoaded", function() {
  // Wait for auto-discovery to complete
  setTimeout(setupGlobalDropzoneEvents, 100);
});

Install with Tessl CLI

npx tessl i tessl/npm-dropzone

docs

constructor-config.md

event-system.md

file-management.md

index.md

static-utilities.md

thumbnails.md

upload-processing.md

tile.json