image-upload-wc
v3.0.1
Published
A lightweight, accessible image upload web component with drag-and-drop support and preview functionality
Maintainers
Readme
Image Upload Web Component
A lightweight, accessible image upload web component with drag-and-drop support and preview functionality. Built with TypeScript and vanilla JavaScript as a custom element.
Features
- Web Component / Custom Element architecture
- Image preview with thumbnails
- Drag and drop support
- Delete individual images
- Accessible with ARIA labels
- Memory leak prevention with automatic URL cleanup
- Zero dependencies
- Clean, modern UI
- Single or multiple file upload support
- Works seamlessly with HTML forms
Installation
npm install image-upload-wcUsage
Basic Setup
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Image Upload Demo</title>
</head>
<body>
<script type="module">
import { defineImageUpload } from "image-upload-wc";
defineImageUpload("image-upload-wc");
</script>
<!-- Single file upload -->
<image-upload-wc></image-upload-wc>
</body>
</html>Multiple File Upload
Add the multiple attribute to enable multiple file selection:
<script type="module">
import { defineImageUpload } from "image-upload-wc";
defineImageUpload("image-upload-wc");
</script>
<image-upload-wc multiple></image-upload-wc>Form Integration
The component works seamlessly with HTML forms:
<script type="module">
import { defineImageUpload } from "image-upload-wc";
defineImageUpload("image-upload-wc");
</script>
<form id="uploadForm" action="/upload" method="post" enctype="multipart/form-data">
<label for="user-images">Upload your images:</label>
<image-upload-wc multiple name="images"></image-upload-wc>
<button type="submit">Submit</button>
</form>Custom Tag Name
You can register the component with a custom tag name:
<script type="module">
import { defineImageUpload } from "image-upload-wc";
// Register with a custom tag name
defineImageUpload("my-image-uploader");
</script>
<my-image-uploader multiple></my-image-uploader>API
defineImageUpload(tagName?: string): void
Registers the image upload web component with the custom elements registry.
Parameters:
tagName(optional): The custom element tag name to register. Defaults to"image-upload-wc".
Example:
import { defineImageUpload } from 'image-upload-wc';
// Register with default tag name
defineImageUpload();
// Register with custom tag name
defineImageUpload('custom-upload');Component Properties
The <image-upload-wc> element exposes the following properties:
files
Returns the current FileList from the component.
const uploader = document.querySelector('image-upload-wc');
console.log(uploader.files); // FileListname
Gets or sets the name attribute for form submission.
const uploader = document.querySelector('image-upload-wc');
uploader.name = 'myFiles';Attributes
| Attribute | Type | Description |
|-----------|------|-------------|
| multiple | boolean | Enables multiple file selection |
| name | string | Name attribute for form submission |
Examples
Single File Upload
<image-upload-wc></image-upload-wc>Multiple File Upload with Custom Name
<image-upload-wc multiple name="photos"></image-upload-wc>Using with JavaScript
import { defineImageUpload } from 'image-upload-wc';
// Define the component
defineImageUpload();
// Access the component
const uploader = document.querySelector('image-upload-wc');
// Get selected files
console.log(uploader.files);
// Set name for form submission
uploader.name = 'userImages';Styling
The component uses CSS custom properties (CSS variables) for easy customization. You can override any of these variables to match your design system.
Available CSS Variables
| Variable | Default Value | Description |
|----------|--------------|-------------|
| --image-upload-width | 100% | Component width |
| --image-upload-max-width | 500px | Maximum upload container width |
| --image-upload-margin | 0 auto | Upload container margin |
| --image-upload-padding | 20px | Upload container padding |
| --image-upload-bg-color | #f5f7fa | Upload area background color |
| --image-upload-bg-color-hover | #eef1f5 | Upload area hover background |
| --image-upload-border | 1px solid #e1e4e8 | Upload area border |
| --image-upload-border-radius | 8px | Upload area border radius |
| --image-upload-font-family | Arial, sans-serif | Font family |
| --image-upload-text-size | 16px | Regular text size |
| --image-upload-text-color | #586069 | Regular text color |
| --image-upload-title-size | 18px | Title text size |
| --image-upload-title-color | #586069 | Title text color |
| --image-upload-title-weight | 500 | Title font weight |
| --image-upload-preview-justify | center | Preview container alignment |
| --image-upload-preview-gap | 10px | Gap between previews |
| --image-upload-preview-margin-top | 20px | Preview container top margin |
| --image-upload-preview-width | 240px | Preview thumbnail width |
| --image-upload-preview-border-radius | 8px | Preview border radius |
| --image-upload-preview-shadow | 0 2px 8px rgba(0,0,0,0.1) | Preview box shadow |
| --image-upload-preview-hover-transform | scale(1.02) | Preview hover effect |
| --image-upload-preview-object-fit | cover | Image object-fit property |
| --image-upload-delete-top | 10px | Delete button top position |
| --image-upload-delete-right | 10px | Delete button right position |
| --image-upload-delete-size | 25px | Delete button size |
| --image-upload-delete-bg | white | Delete button background |
| --image-upload-delete-bg-hover | #fee | Delete button hover background |
| --image-upload-delete-shadow | 0 2px 4px rgba(0,0,0,0.2) | Delete button shadow |
| --image-upload-delete-hover-transform | scale(1.1) | Delete button hover effect |
Custom Styling Examples
Example 1: Dark Theme
<style>
image-upload-wc {
--image-upload-bg-color: #2d333b;
--image-upload-bg-color-hover: #373e47;
--image-upload-border: 1px solid #444c56;
--image-upload-text-color: #adbac7;
--image-upload-title-color: #cdd9e5;
}
</style>
<image-upload-wc multiple></image-upload-wc>Example 2: Custom Brand Colors
<style>
image-upload-wc {
--image-upload-bg-color: #e3f2fd;
--image-upload-bg-color-hover: #bbdefb;
--image-upload-border: 2px dashed #2196f3;
--image-upload-border-radius: 12px;
--image-upload-text-color: #1976d2;
--image-upload-title-color: #0d47a1;
--image-upload-preview-border-radius: 12px;
--image-upload-delete-bg: #f44336;
--image-upload-delete-bg-hover: #d32f2f;
}
</style>
<image-upload-wc multiple></image-upload-wc>Example 3: Minimal Style
<style>
image-upload-wc {
--image-upload-bg-color: transparent;
--image-upload-bg-color-hover: #f9f9f9;
--image-upload-border: 2px dashed #ccc;
--image-upload-border-radius: 0;
--image-upload-preview-border-radius: 0;
--image-upload-preview-shadow: none;
}
</style>
<image-upload-wc multiple></image-upload-wc>Example 4: Scoped Styling
You can also scope styles to specific instances:
<style>
.custom-uploader {
--image-upload-max-width: 800px;
--image-upload-preview-width: 180px;
--image-upload-preview-justify: flex-start;
}
.compact-uploader {
--image-upload-padding: 10px;
--image-upload-preview-width: 120px;
--image-upload-preview-gap: 5px;
}
</style>
<image-upload-wc class="custom-uploader" multiple></image-upload-wc>
<image-upload-wc class="compact-uploader" multiple></image-upload-wc>Advanced Styling
For more complex customization, you can target the component's internal elements directly:
/* Override specific elements */
image-upload-wc #upload-container {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
}
image-upload-wc .image-upload-preview {
border: 3px solid #667eea;
}Component Behavior
Drag and Drop
Users can drag image files directly onto the upload area. The component handles all drag events and updates the file input accordingly.
Image Previews
Uploaded images are automatically displayed as thumbnails. Each preview includes:
- Image thumbnail with the original aspect ratio
- Delete button for removing individual images
- Hover effects for better user experience
Memory Management
The component automatically revokes object URLs when images are deleted, preventing memory leaks during long sessions.
Accessibility
- ARIA labels for screen readers
- Keyboard navigation support
- Semantic HTML structure
- Proper role attributes
Browser Support
This component works in all modern browsers that support:
- ES6 modules
- FileList API
- DataTransfer API
- URL.createObjectURL
Supported browsers include:
- Chrome 61+
- Firefox 60+
- Safari 11+
- Edge 79+
Development
Building from Source
# Install dependencies
npm install
# Build the project
npm run build
# Clean build artifacts
npm run cleanProject Structure
src/
├── index.ts # Main entry point and exports
├── createElements/
│ ├── createInput.ts # File input element creation
│ ├── createPreviews.ts # Image preview components
│ ├── createStyles.ts # Component styles injection
│ └── createUploadContainer.ts # Main upload container
└── utils/
├── handleDragAndDrop.ts # Drag and drop event handlers
└── handleFiles.ts # File manipulation utilitiesLicense
ISC
