CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-rc-upload

React component for file upload with AJAX, drag-and-drop, and directory support

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

index.mddocs/

rc-upload

React Upload component with support for AJAX uploads, drag-and-drop, directory uploads, and multiple upload methods. Provides comprehensive file upload functionality with extensive customization options and backward compatibility.

Package Information

  • Package Name: rc-upload
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install rc-upload

Core Imports

import Upload, { UploadProps } from "rc-upload";

For CommonJS:

const Upload = require("rc-upload");
const { UploadProps } = require("rc-upload"); // Type only available in TypeScript

Basic Usage

import Upload from "rc-upload";

// Basic file upload
<Upload
  action="https://jsonplaceholder.typicode.com/posts/"
  accept=".jpg,.png,.gif"
  multiple
  onStart={(file) => {
    console.log('Upload started:', file.name);
  }}
  onSuccess={(response, file) => {
    console.log('Upload successful:', file.name, response);
  }}
  onError={(error, response, file) => {
    console.log('Upload failed:', error);
  }}
>
  <button>Click to Upload</button>
</Upload>

// Advanced usage with custom request
<Upload
  customRequest={({ file, onSuccess, onError, onProgress }) => {
    const formData = new FormData();
    formData.append('file', file);
    
    fetch('/api/upload', {
      method: 'POST',
      body: formData
    })
    .then(response => response.json())
    .then(data => onSuccess(data, file))
    .catch(error => onError(error));
  }}
  directory
  onStart={(file) => console.log('Started:', file.name)}
>
  <div>Drag files or folders here</div>
</Upload>

Capabilities

Upload Component

The main React component that provides file upload functionality with drag-and-drop support, AJAX uploads, and extensive customization options.

/**
 * Main Upload component providing comprehensive file upload functionality
 */
class Upload extends React.Component<UploadProps> {
  /**
   * Abort upload for a specific file
   * @param file - The file to abort upload for
   */
  abort(file: RcFile): void;
}

export default Upload;

Upload Configuration

Core configuration properties for controlling upload behavior, validation, and customization.

interface UploadProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'onError' | 'onProgress'> {
  /** Upload URL - can be string or function returning URL/Promise<URL> */
  action?: Action;
  /** HTTP method for upload request */
  method?: UploadRequestMethod;
  /** Additional form data to include with upload */
  data?: Record<string, unknown> | ((file: RcFile | string | Blob) => Record<string, unknown>);
  /** Custom HTTP headers */
  headers?: UploadRequestHeader;
  /** Include credentials in CORS requests */
  withCredentials?: boolean;
  /** Custom upload implementation */
  customRequest?: (option: UploadRequestOption) => void | { abort: () => void };
  
  /** File type restrictions (MIME types or extensions) */
  accept?: string;
  /** Allow multiple file selection */
  multiple?: boolean;
  /** Enable directory upload (deprecated, use folder instead) */
  directory?: boolean;
  /** Enable directory/folder upload */
  folder?: boolean;
  /** Enable paste-to-upload functionality */
  pastable?: boolean;
  
  /** Wrapper component type */
  component?: React.ComponentType<any> | string;
  /** CSS class name */
  className?: string;
  /** Inline styles */
  style?: React.CSSProperties;
  /** CSS class prefix */
  prefixCls?: string;
  /** Element ID */
  id?: string;
  /** Disable upload functionality */
  disabled?: boolean;
  /** Open file dialog on click */
  openFileDialogOnClick?: boolean;
  /** Whether control elements are inside component */
  hasControlInside?: boolean;
  
  /** Nested class names */
  classNames?: {
    input?: string;
  };
  /** Nested styles */
  styles?: {
    input?: React.CSSProperties;
  };
  
  /** Pre-upload validation/transformation hook */
  beforeUpload?: (file: RcFile, FileList: RcFile[]) => BeforeUploadFileType | Promise<void | BeforeUploadFileType> | void;
  
  /** Called when file upload starts */
  onStart?: (file: RcFile) => void;
  /** Called during upload progress */
  onProgress?: (event: UploadProgressEvent, file: RcFile) => void;
  /** Called on successful upload */
  onSuccess?: (response: Record<string, unknown>, file: RcFile, xhr: XMLHttpRequest) => void;
  /** Called on upload error */
  onError?: (error: Error, ret: Record<string, unknown>, file: RcFile) => void;
  /** Called when batch upload starts */
  onBatchStart?: (fileList: Array<{ file: RcFile; parsedFile: Exclude<BeforeUploadFileType, boolean> }>) => void;
  
  /** Custom click handler */
  onClick?: (e: React.MouseEvent<HTMLDivElement> | React.KeyboardEvent<HTMLDivElement>) => void;
  /** Mouse enter handler */
  onMouseEnter?: (e: React.MouseEvent<HTMLDivElement>) => void;
  /** Mouse leave handler */
  onMouseLeave?: (e: React.MouseEvent<HTMLDivElement>) => void;
}

File Types and Interfaces

Core type definitions for files, upload requests, and configuration options.

/**
 * Enhanced File interface with unique identifier
 */
interface RcFile extends File {
  /** Unique identifier for the file */
  uid: string;
}

/**
 * Upload request configuration and callbacks
 */
interface UploadRequestOption<T = any> {
  /** Upload progress callback */
  onProgress?: (event: UploadProgressEvent, file?: UploadRequestFile) => void;
  /** Upload error callback */
  onError?: (event: UploadRequestError | ProgressEvent, body?: T) => void;
  /** Upload success callback */
  onSuccess?: (body: T, fileOrXhr?: UploadRequestFile | XMLHttpRequest) => void;
  /** Additional form data */
  data?: Record<string, unknown>;
  /** Target filename */
  filename?: string;
  /** File to upload */
  file: UploadRequestFile;
  /** Include credentials */
  withCredentials?: boolean;
  /** Upload URL */
  action: string;
  /** HTTP headers */
  headers?: UploadRequestHeader;
  /** HTTP method */
  method: UploadRequestMethod;
}

/**
 * Upload progress event with percentage
 */
interface UploadProgressEvent extends Partial<ProgressEvent> {
  /** Upload progress percentage (0-100) */
  percent?: number;
}

/**
 * Enhanced error interface for upload failures
 */
interface UploadRequestError extends Error {
  /** HTTP response status */
  status?: number;
  /** HTTP method used */
  method?: UploadRequestMethod;
  /** Request URL */
  url?: string;
}

Type Aliases

Utility type definitions used throughout the upload component.

/** Upload URL - string or function returning URL */
type Action = string | ((file: RcFile) => string | PromiseLike<string>);

/** HTTP methods supported for upload */
type UploadRequestMethod = 'POST' | 'PUT' | 'PATCH' | 'post' | 'put' | 'patch';

/** HTTP headers object */
type UploadRequestHeader = Record<string, string>;

/** Return type for beforeUpload hook */
type BeforeUploadFileType = File | Blob | boolean | string;

/** File type for upload requests */
type UploadRequestFile = Exclude<BeforeUploadFileType, File | boolean> | RcFile;

Usage Examples

Directory Upload

import Upload from "rc-upload";

<Upload
  directory
  action="/api/upload"
  onStart={(file) => {
    console.log('Starting upload:', file.name);
    console.log('File path:', file.webkitRelativePath); // Available for directory uploads
  }}
  onSuccess={(response, file) => {
    console.log('Upload completed:', file.name);
  }}
>
  <div style={{ padding: '20px', border: '2px dashed #ccc' }}>
    Click or drag folders here
  </div>
</Upload>

Custom Request Handler

import Upload from "rc-upload";

const customUpload = ({ file, onSuccess, onError, onProgress }) => {
  const formData = new FormData();
  formData.append('file', file);
  formData.append('userId', '123');

  const xhr = new XMLHttpRequest();
  
  xhr.upload.addEventListener('progress', (e) => {
    if (e.lengthComputable) {
      onProgress({ percent: (e.loaded / e.total) * 100 });
    }
  });

  xhr.addEventListener('load', () => {
    if (xhr.status === 200) {
      onSuccess(JSON.parse(xhr.responseText), file);
    } else {
      onError(new Error(`Upload failed: ${xhr.status}`));
    }
  });

  xhr.addEventListener('error', () => {
    onError(new Error('Network error'));
  });

  xhr.open('POST', '/api/upload');
  xhr.send(formData);
};

<Upload customRequest={customUpload}>
  <button>Upload with Custom Handler</button>
</Upload>

File Validation

import Upload from "rc-upload";

const validateFile = (file, fileList) => {
  // Check file size (max 5MB)
  if (file.size > 5 * 1024 * 1024) {
    console.error('File too large');
    return false; // Reject file
  }
  
  // Check file type
  const allowedTypes = ['image/jpeg', 'image/png', 'image/gif'];
  if (!allowedTypes.includes(file.type)) {
    console.error('Invalid file type');
    return false;
  }
  
  // Transform file name
  const newFile = new File([file], `prefix_${file.name}`, {
    type: file.type,
    lastModified: file.lastModified,
  });
  
  return newFile; // Return transformed file
};

<Upload
  action="/api/upload"
  accept=".jpg,.png,.gif"
  beforeUpload={validateFile}
  onError={(error, response, file) => {
    console.error('Upload error:', error.message);
  }}
>
  <button>Upload Images Only</button>
</Upload>

Drag and Drop with Visual Feedback

import Upload from "rc-upload";
import { useState } from "react";

const DragUpload = () => {
  const [dragOver, setDragOver] = useState(false);

  return (
    <Upload
      action="/api/upload"
      multiple
      onStart={() => setDragOver(false)}
      onMouseEnter={() => setDragOver(true)}
      onMouseLeave={() => setDragOver(false)}
      style={{
        display: 'block',
        width: '300px',
        height: '200px',
        border: `2px dashed ${dragOver ? '#007acc' : '#ccc'}`,
        borderRadius: '8px',
        padding: '20px',
        textAlign: 'center',
        cursor: 'pointer',
        backgroundColor: dragOver ? '#f0f8ff' : '#fafafa'
      }}
    >
      <div>
        <p>📁 Drop files here or click to upload</p>
        <p style={{ fontSize: '12px', color: '#666' }}>
          Supports multiple files and drag & drop
        </p>
      </div>
    </Upload>
  );
};

docs

index.md

tile.json