import { ComponentFactoryResolver, ComponentRef, Directive, ElementRef, EventEmitter, HostListener, Inject, Output, ViewContainerRef, } from '@angular/core'; import { DropZoneComponent, } from './../../../elements/drop-zone/drop-zone.component'; @Directive({ selector: '[drop-zone-on-drag-over]', }) export class DropZoneOnDragOverDirective { public beingDraggedOver = false; public dropZoneComponent: ComponentRef; @Output() public onDropFiles = new EventEmitter(); constructor( private _viewContainerRef: ViewContainerRef, private _componentFactoryResolver: ComponentFactoryResolver, ) {} @HostListener('dragover') public dragover() { if (!this.beingDraggedOver) { this.beingDraggedOver = true; this.addDropZoneToPage(); } } public addDropZoneToPage() { const componentFactory = this._componentFactoryResolver.resolveComponentFactory( DropZoneComponent, ); this.dropZoneComponent = this._viewContainerRef.createComponent( componentFactory, ); const renderedElement = this.dropZoneComponent.location.nativeElement; renderedElement.style.position = 'absolute'; renderedElement.style.top = 0; renderedElement.style.left = 0; renderedElement.style.width = '100%'; renderedElement.style.height = '100%'; this._viewContainerRef.element.nativeElement.appendChild( renderedElement, ); this.dropZoneComponent.instance.onDragLeave.emit = () => { this.onDragLeave(); }; this.dropZoneComponent.instance.onDropFiles.emit = (files) => { this.onDropFiles.emit(files); this.onDragLeave(); }; } public onDragLeave() { if (this.beingDraggedOver) { this.beingDraggedOver = false; this.removeDropZoneFromPage(); } } public removeDropZoneFromPage() { this.dropZoneComponent.location.nativeElement.remove(); } }