diff --git a/projects/angular/directives/ui-file-drop-zone/src/ui-file-drop-zone.directive.spec.ts b/projects/angular/directives/ui-file-drop-zone/src/ui-file-drop-zone.directive.spec.ts index c1c448ca..ca5e027e 100644 --- a/projects/angular/directives/ui-file-drop-zone/src/ui-file-drop-zone.directive.spec.ts +++ b/projects/angular/directives/ui-file-drop-zone/src/ui-file-drop-zone.directive.spec.ts @@ -72,15 +72,24 @@ describe('UiFileDropZoneDirective', () => { }); describe('dragging and dropping files', () => { - it('should add class to drop zone when dragging over', () => { + it('should not add class to drop zone when entering the drag zone', () => { + spectator.dispatchMouseEvent(byTestId('custom-drop-zone'), 'dragenter', 0, 0, getDragEventWithDataTransfer('dragover')); + spectator.detectChanges(); + + expect(spectator.query(byTestId('custom-drop-zone'))).not.toHaveClass('ui-file-drop-zone-highlight'); + }); + + it('should not add class to drop zone when entering the drag zone with data that does not include files', () => { spectator.dispatchMouseEvent(byTestId('custom-drop-zone'), 'dragenter'); + spectator.dispatchMouseEvent(byTestId('custom-drop-zone'), 'dragover', 0, 0, getDragEventWithDataTransfer('dragover', false)); spectator.detectChanges(); - expect(spectator.query(byTestId('custom-drop-zone'))).toHaveClass('ui-file-drop-zone-highlight'); + expect(spectator.query(byTestId('custom-drop-zone'))).not.toHaveClass('ui-file-drop-zone-highlight'); }); it('should not remove highlight class when dragging over an element inside the dropzone', () => { spectator.dispatchMouseEvent(byTestId('custom-drop-zone'), 'dragenter'); + spectator.dispatchMouseEvent(byTestId('custom-drop-zone'), 'dragover', 0, 0, getDragEventWithDataTransfer('dragover')); spectator.dispatchMouseEvent('button', 'dragenter'); spectator.dispatchMouseEvent(byTestId('custom-drop-zone'), 'dragleave'); spectator.detectChanges(); @@ -90,14 +99,17 @@ describe('UiFileDropZoneDirective', () => { it('should remove highlight when dropping files', () => { spectator.dispatchMouseEvent(byTestId('custom-drop-zone'), 'dragenter'); - spectator.dispatchMouseEvent(byTestId('custom-drop-zone'), 'drop'); + spectator.dispatchMouseEvent(byTestId('custom-drop-zone'), 'dragover', 0, 0, getDragEventWithDataTransfer('dragover')); + expect(spectator.query(byTestId('custom-drop-zone'))).toHaveClass('ui-file-drop-zone-highlight'); + + spectator.dispatchMouseEvent(byTestId('custom-drop-zone'), 'drop', 0, 0, getDragEventWithDataTransfer('drop')); spectator.detectChanges(); expect(spectator.query(byTestId('custom-drop-zone'))).not.toHaveClass('ui-file-drop-zone-highlight'); }); it('should call service with files that were dropped', () => { - const mouseEvent = createMouseEvent('drop'); + const mouseEvent = getDragEventWithDataTransfer('drop'); spectator.dispatchMouseEvent(byTestId('custom-drop-zone'), 'drop', undefined, undefined, mouseEvent); spectator.detectChanges(); @@ -155,3 +167,12 @@ describe('UiFileDropZoneDirective', () => { }); }); }); + +const getDragEventWithDataTransfer = (type: 'dragover' | 'drop', containsFiles = true) => { + const dataTransfer = new DataTransfer(); + if (containsFiles) { + const file = new File([''], 'file.jog'); + dataTransfer.items.add(file); + } + return new DragEvent(type, { dataTransfer }); +}; diff --git a/projects/angular/directives/ui-file-drop-zone/src/ui-file-drop-zone.directive.ts b/projects/angular/directives/ui-file-drop-zone/src/ui-file-drop-zone.directive.ts index 05f3c767..561ca2bc 100644 --- a/projects/angular/directives/ui-file-drop-zone/src/ui-file-drop-zone.directive.ts +++ b/projects/angular/directives/ui-file-drop-zone/src/ui-file-drop-zone.directive.ts @@ -63,22 +63,28 @@ export class UiFileDropZoneDirective implements OnInit, AfterViewInit, OnDestroy e.stopPropagation(); e.preventDefault(); this._dragCount -= 1; - this._clearDropZoneHighlight(); - this.filesLoading.next(true); - this._fileReaderService.processDroppedItems(e); + const dragDataContainsFiles = this._dragEventContainsFiles(e); + if (dragDataContainsFiles) { + this._clearDropZoneHighlight(); + this.filesLoading.next(true); + this._fileReaderService.processDroppedItems(e); + } } @HostListener('dragover', ['$event']) dragover(e: DragEvent) { // preventDefault is needed to enable drop event e.preventDefault(); + const dragDataContainsFiles = this._dragEventContainsFiles(e); + if (this._dragCount > 0 && dragDataContainsFiles) { + this._highlightDropZone(); + } } @HostListener('dragenter') dragenter() { if (!this.disabled) { this._dragCount += 1; - this._highlightDropZone(); } } @@ -136,4 +142,8 @@ export class UiFileDropZoneDirective implements OnInit, AfterViewInit, OnDestroy } this._dropZone.classList.remove(DROP_ZONE_HIGHLIGHT_CLASS); } + + private _dragEventContainsFiles(e: DragEvent) { + return e.dataTransfer?.types.includes('Files'); + } }