VUI File Uploader
A powerful, feature-rich file upload component with drag & drop, progress tracking, file validation, and multiple upload options.
Angular 20+
Drag & Drop
Progress Tracking
File Validation
Multiple Files
✨ Key Features
🗂️
Drag & Drop
Intuitive drag and drop interface with visual feedback and hover states.
📊
Progress Tracking
Real-time upload progress with detailed status information and error handling.
🛡️
File Validation
Comprehensive file validation including size limits, type restrictions, and custom rules.
📦 Installation
Install via npm
npm install @vui/file-uploader
Import in your module
import { VuiUploaderComponent } from '@vui/file-uploader';
@Component({
standalone: true,
imports: [VuiUploaderComponent],
// ...
})
🚀 Basic Usage
Simple File Upload
Live Demo
Click to upload or drag and drop files here
PNG, JPG, GIF up to 10MB
Implementation
@Component({
standalone: true,
imports: [VuiUploaderComponent],
template: `
<ng-vui-file-uploader
[multiple]="true"
[maxSize]="10485760"
[acceptedTypes]="acceptedTypes"
[uploadUrl]="'/api/upload'"
(filesSelected)="onFilesSelected($event)"
(uploadProgress)="onUploadProgress($event)"
(uploadComplete)="onUploadComplete($event)"
(uploadError)="onUploadError($event)">
</ng-vui-file-uploader>
`
})
export class MyComponent {
acceptedTypes = ['image/*', '.pdf', '.doc', '.docx'];
onFilesSelected(files: FileUploadMetadata[]): void {
console.log('Files selected:', files);
}
onUploadProgress(event: UploadProgressEvent): void {
console.log(`Upload progress: ${event.progress}%`);
}
onUploadComplete(response: any): void {
console.log('Upload completed:', response);
}
onUploadError(error: any): void {
console.error('Upload error:', error);
}
}
⚡ Advanced Examples
Custom Upload Configuration
export class CustomUploaderComponent {
uploadConfig: UploadConfig = {
uploadUrl: '/api/files/upload',
maxFileSize: 5 * 1024 * 1024, // 5MB
allowedTypes: [
'image/jpeg', 'image/png', 'image/gif',
'application/pdf',
'application/msword',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
],
maxFiles: 5,
autoUpload: false, // Manual upload control
headers: {
'Authorization': 'Bearer ' + this.authToken,
'X-Custom-Header': 'custom-value'
},
additionalData: {
userId: this.currentUser.id,
category: 'documents'
}
};
// Custom validation rules
customValidation = (file: File): ValidationResult => {
// Custom file name validation
if (file.name.includes(' ')) {
return {
valid: false,
error: 'File names cannot contain spaces'
};
}
// Custom content validation
if (file.type === 'image/jpeg' && file.size > 2 * 1024 * 1024) {
return {
valid: false,
error: 'JPEG images must be under 2MB'
};
}
return { valid: true };
};
onFileValidation(file: File): boolean {
const result = this.customValidation(file);
if (!result.valid) {
this.showError(result.error);
return false;
}
return true;
}
// Manual upload control
startUpload(): void {
this.uploaderComponent.startUpload();
}
pauseUpload(): void {
this.uploaderComponent.pauseUpload();
}
cancelUpload(): void {
this.uploaderComponent.cancelUpload();
}
}
Image Preview & Thumbnail Generation
Image Upload with Preview
Add Image
export class ImageUploaderComponent {
selectedImages: FileWithPreview[] = [];
imageConfig: UploadConfig = {
acceptedTypes: ['image/jpeg', 'image/png', 'image/gif', 'image/webp'],
maxFileSize: 5 * 1024 * 1024,
generateThumbnails: true,
thumbnailSize: { width: 200, height: 200 },
compressionQuality: 0.8
};
onImagesSelected(files: FileUploadMetadata[]): void {
files.forEach(fileData => {
if (fileData.file.type.startsWith('image/')) {
this.generatePreview(fileData);
}
});
}
private generatePreview(fileData: FileUploadMetadata): void {
const reader = new FileReader();
reader.onload = (e) => {
const preview: FileWithPreview = {
...fileData,
preview: e.target?.result as string,
thumbnail: this.generateThumbnail(e.target?.result as string)
};
this.selectedImages.push(preview);
};
reader.readAsDataURL(fileData.file);
}
private generateThumbnail(imageSrc: string): string {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const img = new Image();
img.onload = () => {
canvas.width = 200;
canvas.height = 200;
ctx?.drawImage(img, 0, 0, 200, 200);
};
img.src = imageSrc;
return canvas.toDataURL('image/jpeg', 0.8);
}
removeImage(index: number): void {
this.selectedImages.splice(index, 1);
}
}
interface FileWithPreview extends FileUploadMetadata {
preview: string;
thumbnail: string;
}
📚 API Reference
Component Inputs
| Property | Type | Default | Description |
|---|---|---|---|
| multiple | boolean | false | Allow multiple file selection |
| maxSize | number | -1 | Maximum file size in bytes |
| acceptedTypes | string[] | [] | Array of accepted file types |
| uploadUrl | string | '' | Upload endpoint URL |
| autoUpload | boolean | true | Automatically start upload on file selection |
Component Events
| Event | Type | Description |
|---|---|---|
| filesSelected | FileUploadMetadata[] | Emitted when files are selected |
| uploadProgress | UploadProgressEvent | Emitted during upload progress |
| uploadComplete | any | Emitted when upload completes successfully |
| uploadError | any | Emitted when upload fails |