From 55d0239953a3841008fb36b0996bac45754f3b6b Mon Sep 17 00:00:00 2001 From: Pankaj Parkar Date: Sun, 13 Jul 2025 00:54:18 +0800 Subject: [PATCH 1/2] feat(package): update to use signal API --- .../file-upload/file-drop.directive.ts | 33 +++++++++---------- .../file-upload/file-select.directive.ts | 16 ++++----- .../testing/spec/file-drop.directive.spec.ts | 20 ++++++----- .../spec/file-select.directive.spec.ts | 16 +++++---- libs/ng2-file-upload/testing/test-setup.ts | 4 ++- 5 files changed, 44 insertions(+), 45 deletions(-) diff --git a/libs/ng2-file-upload/file-upload/file-drop.directive.ts b/libs/ng2-file-upload/file-upload/file-drop.directive.ts index e55c870e..ce7e8e5b 100644 --- a/libs/ng2-file-upload/file-upload/file-drop.directive.ts +++ b/libs/ng2-file-upload/file-upload/file-drop.directive.ts @@ -1,29 +1,25 @@ -import { Directive, EventEmitter, ElementRef, HostListener, Input, Output } from '@angular/core'; +import { Directive, ElementRef, HostListener, inject, input, output } from '@angular/core'; import { FileUploader, FileUploaderOptions } from './file-uploader.class'; @Directive({ selector: '[ng2FileDrop]', standalone: false }) export class FileDropDirective { - @Input() uploader?: FileUploader; - @Output() fileOver: EventEmitter = new EventEmitter(); + readonly uploader = input(); + readonly fileOver = output(); // eslint-disable-next-line @angular-eslint/no-output-on-prefix - @Output() onFileDrop: EventEmitter = new EventEmitter(); + readonly onFileDrop = output(); - protected element: ElementRef; - - constructor(element: ElementRef) { - this.element = element; - } + protected readonly element = inject(ElementRef); getOptions(): FileUploaderOptions | void { - return this.uploader?.options; + return this.uploader()?.options; } getFilters(): string { return ''; } - @HostListener('drop', [ '$event' ]) + @HostListener('drop', ['$event']) onDrop(event: MouseEvent): void { const transfer = this._getTransfer(event); if (!transfer) { @@ -34,13 +30,13 @@ export class FileDropDirective { const filters = this.getFilters(); this._preventAndStop(event); if (options) { - this.uploader?.addToQueue(transfer.files, options, filters); + this.uploader()?.addToQueue(transfer.files, options, filters); } this.fileOver.emit(false); this.onFileDrop.emit(transfer.files); } - @HostListener('dragover', [ '$event' ]) + @HostListener('dragover', ['$event']) onDragOver(event: MouseEvent): void { const transfer = this._getTransfer(event); if (!this._haveFiles(transfer.types)) { @@ -52,10 +48,10 @@ export class FileDropDirective { this.fileOver.emit(true); } - @HostListener('dragleave', [ '$event' ]) + @HostListener('dragleave', ['$event']) onDragLeave(event: MouseEvent): void { if ((this as any).element) { - if (event.currentTarget === (this as any).element[ 0 ]) { + if (event.currentTarget === (this as any).element[0]) { return; } } @@ -80,10 +76,11 @@ export class FileDropDirective { if (types.indexOf) { return types.indexOf('Files') !== -1; - } else if (types.contains) { + } + + if (types.contains) { return types.contains('Files'); - } else { - return false; } + return false; } } diff --git a/libs/ng2-file-upload/file-upload/file-select.directive.ts b/libs/ng2-file-upload/file-upload/file-select.directive.ts index fff97883..1472a878 100644 --- a/libs/ng2-file-upload/file-upload/file-select.directive.ts +++ b/libs/ng2-file-upload/file-upload/file-select.directive.ts @@ -1,21 +1,17 @@ -import { Directive, EventEmitter, ElementRef, Input, HostListener, Output } from '@angular/core'; +import { Directive, ElementRef, HostListener, inject, input, output } from '@angular/core'; import { FileUploader, FileUploaderOptions } from './file-uploader.class'; @Directive({ selector: '[ng2FileSelect]', standalone: false }) export class FileSelectDirective { - @Input() uploader?: FileUploader; + readonly uploader = input(); // eslint-disable-next-line @angular-eslint/no-output-on-prefix - @Output() onFileSelected: EventEmitter = new EventEmitter(); + readonly onFileSelected = output(); - protected element: ElementRef; - - constructor(element: ElementRef) { - this.element = element; - } + protected element = inject(ElementRef); getOptions(): FileUploaderOptions | undefined { - return this.uploader?.options; + return this.uploader()?.options; } getFilters(): string { @@ -31,7 +27,7 @@ export class FileSelectDirective { const files = this.element.nativeElement.files; const options = this.getOptions(); const filters = this.getFilters(); - this.uploader?.addToQueue(files, options, filters); + this.uploader()?.addToQueue(files, options, filters); this.onFileSelected.emit(files); if (this.isEmptyAfterSelection()) { diff --git a/libs/ng2-file-upload/testing/spec/file-drop.directive.spec.ts b/libs/ng2-file-upload/testing/spec/file-drop.directive.spec.ts index 0635f9a1..9eea0560 100644 --- a/libs/ng2-file-upload/testing/spec/file-drop.directive.spec.ts +++ b/libs/ng2-file-upload/testing/spec/file-drop.directive.spec.ts @@ -11,7 +11,8 @@ import { FileDropDirective } from '../../file-upload/file-drop.directive'; template: `
` + >`, + standalone: false }) export class ContainerComponent { public get url(): string { return 'localhost:3000'; } @@ -27,9 +28,9 @@ describe('Directive: FileDropDirective', () => { beforeEach(() => { TestBed.configureTestingModule({ - imports: [ FileUploadModule ], - declarations: [ ContainerComponent, FileDropDirective ], - providers: [ ContainerComponent ] + imports: [FileUploadModule], + declarations: [ContainerComponent, FileDropDirective], + providers: [ContainerComponent] }); }); @@ -50,7 +51,7 @@ describe('Directive: FileDropDirective', () => { }); it('can set file uploader', () => { - expect(fileDropDirective.uploader).toBe(hostComponent.uploader); + expect(fileDropDirective.uploader()).toBe(hostComponent.uploader); }); it('can get uploader options', () => { @@ -84,8 +85,9 @@ describe('Directive: FileDropDirective', () => { it('adds file to upload', () => { let addToQueue; - if (fileDropDirective.uploader?.addToQueue) { - addToQueue = jest.spyOn(fileDropDirective.uploader, 'addToQueue'); + const uploader = fileDropDirective.uploader(); + if (uploader?.addToQueue) { + addToQueue = jest.spyOn(uploader, 'addToQueue'); } let fileOverData; @@ -141,8 +143,8 @@ describe('Directive: FileDropDirective', () => { function getFakeEventData(): any { return { dataTransfer: { - files: [ 'foo.bar' ], - types: [ 'Files' ] + files: ['foo.bar'], + types: ['Files'] }, preventDefault: () => undefined, stopPropagation: () => undefined diff --git a/libs/ng2-file-upload/testing/spec/file-select.directive.spec.ts b/libs/ng2-file-upload/testing/spec/file-select.directive.spec.ts index 61df8f26..29b0829e 100644 --- a/libs/ng2-file-upload/testing/spec/file-select.directive.spec.ts +++ b/libs/ng2-file-upload/testing/spec/file-select.directive.spec.ts @@ -11,7 +11,8 @@ import { FileUploader } from '../../file-upload/file-uploader.class'; template: `` + />`, + standalone: false }) export class ContainerComponent { public get url(): string { return 'localhost:3000'; } @@ -26,9 +27,9 @@ describe('Directive: FileSelectDirective', () => { beforeEach(() => { TestBed.configureTestingModule({ - imports: [ FileUploadModule ], - declarations: [ ContainerComponent ], - providers: [ ContainerComponent ] + imports: [FileUploadModule], + declarations: [ContainerComponent], + providers: [ContainerComponent] }); }); @@ -49,7 +50,7 @@ describe('Directive: FileSelectDirective', () => { }); it('can set file uploader', () => { - expect(fileSelectDirective.uploader).toBe(hostComponent.uploader); + expect(fileSelectDirective.uploader()).toBe(hostComponent.uploader); }); it('can get uploader options', () => { @@ -91,8 +92,9 @@ describe('Directive: FileSelectDirective', () => { it('handles change event', () => { let addToQueue; - if (fileSelectDirective.uploader?.addToQueue) { - addToQueue = jest.spyOn(fileSelectDirective.uploader, 'addToQueue'); + const uploader = fileSelectDirective.uploader(); + if (uploader?.addToQueue) { + addToQueue = jest.spyOn(uploader, 'addToQueue'); } fileSelectDirective.onChange(); diff --git a/libs/ng2-file-upload/testing/test-setup.ts b/libs/ng2-file-upload/testing/test-setup.ts index 1100b3e8..30ed1bdd 100644 --- a/libs/ng2-file-upload/testing/test-setup.ts +++ b/libs/ng2-file-upload/testing/test-setup.ts @@ -1 +1,3 @@ -import 'jest-preset-angular/setup-jest'; +import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone/index.mjs'; + +setupZoneTestEnv(); \ No newline at end of file From 0ae73e919eda2b807e131c57f3f0677c97277b25 Mon Sep 17 00:00:00 2001 From: Pankaj Parkar Date: Sun, 13 Jul 2025 01:12:01 +0800 Subject: [PATCH 2/2] feat(package): update component to standalone: true --- apps/demo/src/doc.md | 4 ++-- .../file-upload/file-drop.directive.ts | 4 +++- .../file-upload/file-select.directive.ts | 2 +- .../file-upload/file-upload.module.ts | 14 +++++++++----- libs/ng2-file-upload/index.ts | 4 ++-- libs/ng2-file-upload/package.json | 3 +-- .../testing/spec/file-drop.directive.spec.ts | 10 +--------- .../testing/spec/file-select.directive.spec.ts | 10 +--------- package.json | 1 + 9 files changed, 21 insertions(+), 31 deletions(-) diff --git a/apps/demo/src/doc.md b/apps/demo/src/doc.md index afd7b8a5..0466b138 100644 --- a/apps/demo/src/doc.md +++ b/apps/demo/src/doc.md @@ -6,12 +6,12 @@ import { FileSelectDirective, FileDropDirective, FileUploader } from 'ng2-file-u ### Annotations ```typescript // class FileSelectDirective -@Directive({ selector: '[ng2FileSelect]', standalone: false }) +@Directive({ selector: '[ng2FileSelect]' }) ``` ```typescript // class FileDropDirective -@Directive({ selector: '[ng2FileDrop]', standalone: false }) +@Directive({ selector: '[ng2FileDrop]' }) ``` ## FileSelect API diff --git a/libs/ng2-file-upload/file-upload/file-drop.directive.ts b/libs/ng2-file-upload/file-upload/file-drop.directive.ts index ce7e8e5b..5a8a0378 100644 --- a/libs/ng2-file-upload/file-upload/file-drop.directive.ts +++ b/libs/ng2-file-upload/file-upload/file-drop.directive.ts @@ -2,7 +2,9 @@ import { Directive, ElementRef, HostListener, inject, input, output } from '@ang import { FileUploader, FileUploaderOptions } from './file-uploader.class'; -@Directive({ selector: '[ng2FileDrop]', standalone: false }) +@Directive({ + selector: '[ng2FileDrop]', +}) export class FileDropDirective { readonly uploader = input(); readonly fileOver = output(); diff --git a/libs/ng2-file-upload/file-upload/file-select.directive.ts b/libs/ng2-file-upload/file-upload/file-select.directive.ts index 1472a878..a8c9c185 100644 --- a/libs/ng2-file-upload/file-upload/file-select.directive.ts +++ b/libs/ng2-file-upload/file-upload/file-select.directive.ts @@ -2,7 +2,7 @@ import { Directive, ElementRef, HostListener, inject, input, output } from '@ang import { FileUploader, FileUploaderOptions } from './file-uploader.class'; -@Directive({ selector: '[ng2FileSelect]', standalone: false }) +@Directive({ selector: '[ng2FileSelect]' }) export class FileSelectDirective { readonly uploader = input(); // eslint-disable-next-line @angular-eslint/no-output-on-prefix diff --git a/libs/ng2-file-upload/file-upload/file-upload.module.ts b/libs/ng2-file-upload/file-upload/file-upload.module.ts index 62fdb14b..3c5fec8e 100644 --- a/libs/ng2-file-upload/file-upload/file-upload.module.ts +++ b/libs/ng2-file-upload/file-upload/file-upload.module.ts @@ -1,13 +1,17 @@ -import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; -import { FileDropDirective } from './file-drop.directive'; import { FileSelectDirective } from './file-select.directive'; +import { FileDropDirective } from './file-drop.directive'; @NgModule({ - imports: [ CommonModule ], - declarations: [ FileDropDirective, FileSelectDirective ], - exports: [ FileDropDirective, FileSelectDirective ] + imports: [ + FileSelectDirective, + FileDropDirective, + ], + exports: [ + FileSelectDirective, + FileDropDirective, + ], }) export class FileUploadModule { } diff --git a/libs/ng2-file-upload/index.ts b/libs/ng2-file-upload/index.ts index ec877e01..3326c0df 100644 --- a/libs/ng2-file-upload/index.ts +++ b/libs/ng2-file-upload/index.ts @@ -1,8 +1,8 @@ -export * from './file-upload/file-drop.directive'; -export * from './file-upload/file-uploader.class'; +export * from './file-upload/file-uploader.class'; export * from './file-upload/file-item.class'; export * from './file-upload/file-like-object.class'; export * from './file-upload/file-like-object.class'; export { FileUploadModule } from './file-upload/file-upload.module'; export { FileSelectDirective } from './file-upload/file-select.directive'; +export { FileDropDirective } from './file-upload/file-drop.directive'; diff --git a/libs/ng2-file-upload/package.json b/libs/ng2-file-upload/package.json index 9a5e1877..1d366944 100644 --- a/libs/ng2-file-upload/package.json +++ b/libs/ng2-file-upload/package.json @@ -5,8 +5,7 @@ "author": "Dmitriy Shekhovtsov ", "license": "MIT", "peerDependencies": { - "@angular/core": "^19.0.0", - "@angular/common": "^19.0.0" + "@angular/core": "^19.0.0" }, "sideEffects": false, "publishConfig": { diff --git a/libs/ng2-file-upload/testing/spec/file-drop.directive.spec.ts b/libs/ng2-file-upload/testing/spec/file-drop.directive.spec.ts index 9eea0560..6c104ba0 100644 --- a/libs/ng2-file-upload/testing/spec/file-drop.directive.spec.ts +++ b/libs/ng2-file-upload/testing/spec/file-drop.directive.spec.ts @@ -12,7 +12,7 @@ import { FileDropDirective } from '../../file-upload/file-drop.directive'; ng2FileDrop [uploader]="uploader" >`, - standalone: false + imports: [FileUploadModule], }) export class ContainerComponent { public get url(): string { return 'localhost:3000'; } @@ -26,14 +26,6 @@ describe('Directive: FileDropDirective', () => { let directiveElement: DebugElement; let fileDropDirective: FileDropDirective; - beforeEach(() => { - TestBed.configureTestingModule({ - imports: [FileUploadModule], - declarations: [ContainerComponent, FileDropDirective], - providers: [ContainerComponent] - }); - }); - beforeEach(() => { fixture = TestBed.createComponent(ContainerComponent); hostComponent = fixture.componentInstance; diff --git a/libs/ng2-file-upload/testing/spec/file-select.directive.spec.ts b/libs/ng2-file-upload/testing/spec/file-select.directive.spec.ts index 29b0829e..8bf30cee 100644 --- a/libs/ng2-file-upload/testing/spec/file-select.directive.spec.ts +++ b/libs/ng2-file-upload/testing/spec/file-select.directive.spec.ts @@ -12,7 +12,7 @@ import { FileUploader } from '../../file-upload/file-uploader.class'; ng2FileSelect [uploader]="uploader" />`, - standalone: false + imports: [FileUploadModule], }) export class ContainerComponent { public get url(): string { return 'localhost:3000'; } @@ -25,14 +25,6 @@ describe('Directive: FileSelectDirective', () => { let directiveElement: DebugElement; let fileSelectDirective: FileSelectDirective; - beforeEach(() => { - TestBed.configureTestingModule({ - imports: [FileUploadModule], - declarations: [ContainerComponent], - providers: [ContainerComponent] - }); - }); - beforeEach(() => { fixture = TestBed.createComponent(ContainerComponent); hostComponent = fixture.componentInstance; diff --git a/package.json b/package.json index d5b65882..73744d26 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "private": true, "description": "Angular file upload directives", "scripts": { + "nx": "nx", "start": "npx nx run ng2-file-upload-demo:serve", "demo.build": "ng build", "demo.build-prod": "ng build",