import { Component, ElementRef, EventEmitter, Input, Output, ViewChild } from '@angular/core'; @Component({ selector: 'vsp-file-dropzone', template: `
Drop files or browse
{{ hint }}
`, }) export class VspFileDropzone { @Input() hint = 'PNG, JPG or PDF up to 10MB'; @Input() accept?: string; @Input() multiple = true; @Input() maxSize?: number; @Input() maxFiles?: number; @Input() disabled = false; @Output() files = new EventEmitter(); @Output() reject = new EventEmitter(); @ViewChild('input') input?: ElementRef; drag = false; private take(list: FileList | null): void { if (!list || !list.length) return; let files = Array.from(list); const rejected: File[] = []; if (this.maxSize != null) files = files.filter((f) => { if (f.size > this.maxSize!) { rejected.push(f); return false; } return true; }); if (this.maxFiles != null && files.length > this.maxFiles) { rejected.push(...files.slice(this.maxFiles)); files = files.slice(0, this.maxFiles); } if (rejected.length) this.reject.emit(rejected); if (files.length) this.files.emit(files); } onDragOver(e: DragEvent): void { if (this.disabled) return; e.preventDefault(); this.drag = true; } onDrop(e: DragEvent): void { if (this.disabled) return; e.preventDefault(); this.drag = false; this.take(e.dataTransfer?.files ?? null); } onChange(e: Event): void { this.take((e.target as HTMLInputElement).files); } }