# MultipleUpload

A standalone JavaScript file upload component that works with **any backend**. Zero dependencies.

## Project Layout

- `src/` contains the canonical source files.
- `dist/` contains the publishable build output.
- `npm run build` refreshes `dist/` and syncs `D:\Projects\site\multipleupload.com.Core\wwwroot\lib\multipleupload`.

## Features

- Multiple file selection
- Drag-and-drop with visual feedback
- Chunked uploads for large files
- Image thumbnails with progress overlays
- Clipboard paste support
- Custom headers & CORS support
- Progress tracking with speed & ETA
- Queue management (cancel, remove, retry)
- Attachment mode for compact UIs
- Dark mode support
- Fully customizable via CSS variables
- UMD module (script tag, CommonJS, AMD)
- TypeScript declarations included

## Quick Start

### CDN

```html
<link rel="stylesheet" href="https://unpkg.com/multipleupload/multipleupload.css">
<script src="https://unpkg.com/multipleupload/multipleupload.js"></script>
```

Licensed deployments can place a sibling `multipleupload.lic` next to `multipleupload.js`. The runtime auto-loads that file by default.

### npm

```bash
npm install multipleupload
npm run build
```

### Usage

```html
<div id="uploader" class="mu-uploader">
    <button type="button" class="mu-select-btn">Select Files</button>
    <input type="file" class="mu-file-input" multiple style="display:none" />
    <div class="mu-dropzone">
        <div class="mu-dropzone-text">Drag & drop files here</div>
    </div>
    <div class="mu-preview-area"></div>
    <div class="mu-progress" style="display:none">
        <div class="mu-progress-bar"><div class="mu-progress-fill"></div></div>
        <div class="mu-progress-text"></div>
    </div>
    <div class="mu-queue"></div>
</div>

<script>
var uploader = new MultipleUpload('#uploader', {
    uploadUrl: '/api/upload',
    multiple: true,
    maxFileSize: 100 * 1024 * 1024,
    onComplete: function(files) {
        console.log('All uploads complete:', files);
    }
});
</script>
```

### Licensed File Deployment

Licensed customers can replace `dist/multipleupload.lic` with the `multipleupload.lic` downloaded from Client Center. `multipleupload.js` auto-loads a sibling `multipleupload.lic`, or you can point to a custom location with `licenseUrl`.

```html
<script src="/assets/multipleupload.js"></script>
<script>
var uploader = new MultipleUpload('#uploader', {
    uploadUrl: '/api/upload',
    licenseUrl: '/licenses/multipleupload.lic'
});
</script>
```

## Development

```bash
npm install
npm run build
```

Use `npm run build:package` when you only want to refresh `dist/`.
`npm pack` also rebuilds `dist/` automatically via `prepack`.
Use `npm run build:download-package` to regenerate the downloadable starter ZIP and the site preview under `D:\Projects\site\multipleupload.com.Core\wwwroot\downloads`.

## Backend-Agnostic Options

```javascript
new MultipleUpload('#uploader', {
    headers: function(task) {
        return {
            'Authorization': 'Bearer YOUR_TOKEN',
            'X-Upload-Id': task.id
        };
    },
    withCredentials: true,
    fieldName: 'attachment',
    chunkUrl: '/api/upload/chunk',
    chunkCompleteUrl: '/api/upload/chunk/complete',
    deleteUrl: '/api/files/delete',
    responseParser: function(responseText, task) {
        var data = JSON.parse(responseText);
        return {
            success: true,
            fileGuid: data.id,
            fileName: data.name || task.fileName,
            fileSize: data.size
        };
    },
    transformPipeline: [
        function(file) {
            return file;
        }
    ],
    allowedMimeTypes: 'image/*,application/pdf',
    validateMimeByMagic: true,
    customValidation: function(file, uploader) {
        if (uploader.getTasksByStatus('completed').length > 25) {
            return 'Too many completed files in the queue.';
        }
    }
});
```

## License

Commercial license. See [multipleupload.com](https://multipleupload.com) for details.
