Drop only .png files!
diff --git a/projects/app/src/app/app.module.ts b/projects/app/src/app/app.module.ts
deleted file mode 100644
index 6f41c97..0000000
--- a/projects/app/src/app/app.module.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import { NgModule } from '@angular/core';
-import { ReactiveFormsModule } from '@angular/forms';
-import { MatChipsModule } from '@angular/material/chips';
-import { MatFormFieldModule } from '@angular/material/form-field';
-import { MatIconModule } from '@angular/material/icon';
-import { MatInputModule } from '@angular/material/input';
-import { BrowserModule } from '@angular/platform-browser';
-import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
-import { DropzoneCdkModule } from '@ngx-dropzone/cdk';
-import { DropzoneMaterialModule } from '@ngx-dropzone/material';
-import { AppComponent } from './app.component';
-
-@NgModule({
- declarations: [AppComponent],
- imports: [
- BrowserModule,
- BrowserAnimationsModule,
- ReactiveFormsModule,
- MatFormFieldModule,
- MatInputModule,
- MatChipsModule,
- MatIconModule,
- DropzoneCdkModule,
- DropzoneMaterialModule,
- ],
- providers: [],
- bootstrap: [AppComponent],
-})
-export class AppModule {}
diff --git a/projects/app/src/main.ts b/projects/app/src/main.ts
index c58dc05..c67d684 100644
--- a/projects/app/src/main.ts
+++ b/projects/app/src/main.ts
@@ -1,7 +1,7 @@
-import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
+import { bootstrapApplication } from '@angular/platform-browser';
+import { provideAnimations } from '@angular/platform-browser/animations';
+import { AppComponent } from './app/app.component';
-import { AppModule } from './app/app.module';
-
-
-platformBrowserDynamic().bootstrapModule(AppModule)
- .catch(err => console.error(err));
+bootstrapApplication(AppComponent, {
+ providers: [provideAnimations()],
+}).catch((e) => console.error(e));
diff --git a/projects/cdk/package.json b/projects/cdk/package.json
index 7d86d05..7ec7e54 100644
--- a/projects/cdk/package.json
+++ b/projects/cdk/package.json
@@ -23,9 +23,9 @@
"cdk"
],
"peerDependencies": {
- "@angular/common": "^18.0.0",
- "@angular/core": "^18.0.0",
- "@angular/forms": "^18.0.0",
+ "@angular/common": "^19.0.0",
+ "@angular/core": "^19.0.0",
+ "@angular/forms": "^19.0.0",
"rxjs": "^7.4.0"
}
}
diff --git a/projects/cdk/src/lib/cdk.module.ts b/projects/cdk/src/lib/cdk.module.ts
deleted file mode 100644
index 4d5d24e..0000000
--- a/projects/cdk/src/lib/cdk.module.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { NgModule } from '@angular/core';
-import { DropzoneComponent } from './dropzone';
-import { FileInputDirective } from './file-input';
-
-@NgModule({
- declarations: [FileInputDirective, DropzoneComponent],
- exports: [FileInputDirective, DropzoneComponent],
-})
-export class DropzoneCdkModule {}
diff --git a/projects/cdk/src/lib/dropzone/dropzone.component.spec.ts b/projects/cdk/src/lib/dropzone/dropzone.component.spec.ts
index 0ceec36..8139af9 100644
--- a/projects/cdk/src/lib/dropzone/dropzone.component.spec.ts
+++ b/projects/cdk/src/lib/dropzone/dropzone.component.spec.ts
@@ -3,7 +3,6 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { FormControl, ReactiveFormsModule } from '@angular/forms';
import { By } from '@angular/platform-browser';
import { FileInputDirective, FileInputValidators, FileInputValue } from '../file-input';
-import { DropzoneCdkModule } from './../cdk.module';
import { DropzoneComponent } from './dropzone.component';
interface Selectors {
@@ -17,8 +16,7 @@ interface Selectors {
describe('DropzoneComponent', () => {
function configureDropzoneTestingModule(testComponent: Type): Selectors {
const fixture = TestBed.configureTestingModule({
- imports: [ReactiveFormsModule, DropzoneCdkModule],
- declarations: [testComponent],
+ imports: [testComponent],
}).createComponent(testComponent);
const element = fixture.debugElement.query(By.directive(DropzoneComponent));
@@ -148,6 +146,7 @@ describe('DropzoneComponent', () => {
@Component({
selector: 'basic-dropzone',
+ imports: [DropzoneComponent, FileInputDirective],
template: `
@@ -158,6 +157,7 @@ class DropzoneBasic {}
@Component({
selector: 'form-control-dropzone',
+ imports: [ReactiveFormsModule, DropzoneComponent, FileInputDirective],
template: `
diff --git a/projects/cdk/src/lib/dropzone/dropzone.component.ts b/projects/cdk/src/lib/dropzone/dropzone.component.ts
index 2c4e487..95eef11 100644
--- a/projects/cdk/src/lib/dropzone/dropzone.component.ts
+++ b/projects/cdk/src/lib/dropzone/dropzone.component.ts
@@ -20,6 +20,8 @@ import { DropzoneService } from './dropzone.service';
@Component({
selector: 'ngx-dropzone',
exportAs: 'dropzone',
+ imports: [FileInputDirective],
+ providers: [DropzoneService],
template: ``,
host: {
tabindex: '0',
diff --git a/projects/cdk/src/lib/dropzone/dropzone.service.ts b/projects/cdk/src/lib/dropzone/dropzone.service.ts
index 3d7cc2e..ead22ce 100644
--- a/projects/cdk/src/lib/dropzone/dropzone.service.ts
+++ b/projects/cdk/src/lib/dropzone/dropzone.service.ts
@@ -1,6 +1,6 @@
import { Injectable } from '@angular/core';
import { nonNullable } from '../coercion';
-import { File } from './../file-input';
+import { type File } from './../file-input';
@Injectable({
providedIn: 'root',
diff --git a/projects/cdk/src/lib/file-input/accept.service.spec.ts b/projects/cdk/src/lib/file-input/accept.service.spec.ts
index e209e17..46e412e 100644
--- a/projects/cdk/src/lib/file-input/accept.service.spec.ts
+++ b/projects/cdk/src/lib/file-input/accept.service.spec.ts
@@ -4,6 +4,11 @@ import { AcceptService } from './accept.service';
describe('AcceptService', () => {
let service: AcceptService;
+ beforeEach(() => {
+ TestBed.configureTestingModule({});
+ service = TestBed.inject(AcceptService);
+ });
+
/** Returns a simple fake file with given extension and optional type. */
const getFile = (ext: string, type?: string) => new File(['...'], `${Date.now()}.${ext}`, { type });
@@ -14,11 +19,6 @@ describe('AcceptService', () => {
getFile('pdf', 'application/octet-stream'),
];
- beforeEach(() => {
- TestBed.configureTestingModule({});
- service = TestBed.inject(AcceptService);
- });
-
it('should filter based on file extension', () => {
const files = getFileList();
const accepted = service.accepts(files, '.doc, txt , .pdf,random/MIME');
diff --git a/projects/cdk/src/lib/file-input/file-input.directive.spec.ts b/projects/cdk/src/lib/file-input/file-input.directive.spec.ts
index c8b4c2f..8c84bb1 100644
--- a/projects/cdk/src/lib/file-input/file-input.directive.spec.ts
+++ b/projects/cdk/src/lib/file-input/file-input.directive.spec.ts
@@ -1,6 +1,6 @@
import { Component, DebugElement, Type } from '@angular/core';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
-import { FormControl, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
+import { FormControl, ReactiveFormsModule, Validators } from '@angular/forms';
import { By } from '@angular/platform-browser';
import { getArrayValueError, getNonArrayValueError } from './file-input-errors';
import { FileInputValue } from './file-input-value';
@@ -24,8 +24,7 @@ const getFileList = (files: File[]): FileList => {
describe('FileInputDirective', () => {
function configureFileInputTestingModule(testComponent: Type): Selectors {
const fixture = TestBed.configureTestingModule({
- imports: [FormsModule, ReactiveFormsModule],
- declarations: [FileInputDirective, testComponent],
+ imports: [testComponent],
}).createComponent(testComponent);
const inputElement = fixture.debugElement.query(By.directive(FileInputDirective));
@@ -299,27 +298,32 @@ describe('FileInputDirective', () => {
});
@Component({
+ imports: [FileInputDirective],
template: ``,
})
class FileInputBasic {}
@Component({
+ imports: [FileInputDirective],
template: ``,
})
class FileInputMultiple {}
@Component({
+ imports: [FileInputDirective],
// This combination is not valid! "Append" should only be used together with "multiple".
template: ``,
})
class FileInputAppend {}
@Component({
+ imports: [FileInputDirective],
template: ``,
})
class FileInputMultipleAppend {}
@Component({
+ imports: [ReactiveFormsModule, FileInputDirective],
template: ``,
})
class FileInputWithFormControl {
@@ -327,6 +331,7 @@ class FileInputWithFormControl {
}
@Component({
+ imports: [ReactiveFormsModule, FileInputDirective],
template: ``,
})
class FileInputDisabled {}
diff --git a/projects/cdk/src/public-api.ts b/projects/cdk/src/public-api.ts
index 12f88a2..eecfc72 100644
--- a/projects/cdk/src/public-api.ts
+++ b/projects/cdk/src/public-api.ts
@@ -2,7 +2,6 @@
* Public API Surface of cdk
*/
-export * from './lib/cdk.module';
export * from './lib/coercion';
export * from './lib/dropzone';
export * from './lib/file-input';
diff --git a/projects/material/package.json b/projects/material/package.json
index b164607..20af854 100644
--- a/projects/material/package.json
+++ b/projects/material/package.json
@@ -23,10 +23,10 @@
"material"
],
"peerDependencies": {
- "@angular/common": "^18.0.0",
- "@angular/core": "^18.0.0",
- "@angular/forms": "^18.0.0",
- "@ngx-dropzone/cdk": "^18.0.0",
+ "@angular/common": "^19.0.0",
+ "@angular/core": "^19.0.0",
+ "@angular/forms": "^19.0.0",
+ "@ngx-dropzone/cdk": "^19.0.0",
"rxjs": "^7.4.0"
}
}
diff --git a/projects/material/src/lib/mat-dropzone/mat-dropzone.component.spec.ts b/projects/material/src/lib/mat-dropzone/mat-dropzone.component.spec.ts
index a6ba8f6..10b6688 100644
--- a/projects/material/src/lib/mat-dropzone/mat-dropzone.component.spec.ts
+++ b/projects/material/src/lib/mat-dropzone/mat-dropzone.component.spec.ts
@@ -1,3 +1,4 @@
+import { CommonModule } from '@angular/common';
import { Component, DebugElement, Type } from '@angular/core';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { FormControl, ReactiveFormsModule } from '@angular/forms';
@@ -6,8 +7,7 @@ import { MatError, MatFormFieldModule, MatLabel } from '@angular/material/form-f
import { MatIconModule } from '@angular/material/icon';
import { By } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
-import { DropzoneCdkModule, FileInputDirective, FileInputValidators, FileInputValue } from '@ngx-dropzone/cdk';
-import { DropzoneMaterialModule } from '../material.module';
+import { FileInputDirective, FileInputValidators, FileInputValue } from '@ngx-dropzone/cdk';
import { MatDropzone } from './mat-dropzone.component';
interface Selectors {
@@ -25,16 +25,7 @@ interface Selectors {
describe('MatDropzone', () => {
function configureDropzoneTestingModule(testComponent: Type): Selectors {
const fixture = TestBed.configureTestingModule({
- imports: [
- BrowserAnimationsModule,
- ReactiveFormsModule,
- MatFormFieldModule,
- MatIconModule,
- MatChipsModule,
- DropzoneCdkModule,
- DropzoneMaterialModule,
- ],
- declarations: [testComponent],
+ imports: [CommonModule, BrowserAnimationsModule, testComponent],
}).createComponent(testComponent);
const element = fixture.debugElement.query(By.directive(MatDropzone));
@@ -127,6 +118,7 @@ describe('MatDropzone', () => {
@Component({
selector: 'basic-dropzone',
+ imports: [MatFormFieldModule, MatDropzone, FileInputDirective],
template: `
Drop it basic!
@@ -140,6 +132,7 @@ class DropzoneBasic {}
@Component({
selector: 'form-control-dropzone',
+ imports: [ReactiveFormsModule, MatFormFieldModule, MatIconModule, MatChipsModule, MatDropzone, FileInputDirective],
template: `
diff --git a/projects/material/src/lib/mat-dropzone/mat-dropzone.component.ts b/projects/material/src/lib/mat-dropzone/mat-dropzone.component.ts
index d941ee5..5d11b4c 100644
--- a/projects/material/src/lib/mat-dropzone/mat-dropzone.component.ts
+++ b/projects/material/src/lib/mat-dropzone/mat-dropzone.component.ts
@@ -14,14 +14,31 @@ import {
import { Validators } from '@angular/forms';
import { MatChipRow } from '@angular/material/chips';
import { MatFormField, MatFormFieldControl } from '@angular/material/form-field';
-import { coerceBoolean, DropzoneComponent, FileInputValue } from '@ngx-dropzone/cdk';
+import {
+ AcceptService,
+ coerceBoolean,
+ DropzoneComponent,
+ DropzoneService,
+ FileInputDirective,
+ FileInputValue,
+} from '@ngx-dropzone/cdk';
import { merge, Observable, Subject, takeUntil, tap } from 'rxjs';
@Component({
selector: 'ngx-mat-dropzone',
exportAs: 'matDropzone',
+ imports: [MatFormField, MatChipRow, FileInputDirective, DropzoneComponent],
+ providers: [
+ DropzoneService,
+ AcceptService,
+ {
+ provide: MatFormFieldControl,
+ useExisting: MatDropzone,
+ },
+ ],
template: `
+
@@ -57,12 +74,6 @@ import { merge, Observable, Subject, takeUntil, tap } from 'rxjs';
],
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
- providers: [
- {
- provide: MatFormFieldControl,
- useExisting: MatDropzone,
- },
- ],
})
export class MatDropzone
extends DropzoneComponent
diff --git a/projects/material/src/lib/material.module.ts b/projects/material/src/lib/material.module.ts
deleted file mode 100644
index a407043..0000000
--- a/projects/material/src/lib/material.module.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { CommonModule } from '@angular/common';
-import { NgModule } from '@angular/core';
-import { ReactiveFormsModule } from '@angular/forms';
-import { MatChipsModule } from '@angular/material/chips';
-import { MatFormFieldModule } from '@angular/material/form-field';
-import { MatIconModule } from '@angular/material/icon';
-import { DropzoneCdkModule } from '@ngx-dropzone/cdk';
-import { MatDropzone } from './mat-dropzone/mat-dropzone.component';
-
-@NgModule({
- declarations: [MatDropzone],
- imports: [CommonModule, ReactiveFormsModule, MatFormFieldModule, MatChipsModule, MatIconModule, DropzoneCdkModule],
- exports: [MatDropzone],
-})
-export class DropzoneMaterialModule {}
diff --git a/projects/material/src/public-api.ts b/projects/material/src/public-api.ts
index b729c4c..46a7ac2 100644
--- a/projects/material/src/public-api.ts
+++ b/projects/material/src/public-api.ts
@@ -3,4 +3,3 @@
*/
export * from './lib/mat-dropzone';
-export * from './lib/material.module';
diff --git a/readme.md b/readme.md
index edf4314..e4b746f 100644
--- a/readme.md
+++ b/readme.md
@@ -38,7 +38,7 @@ npm install @ngx-dropzone/cdk @ngx-dropzone/material
## Versioning
For the versioning, we stay consistent with the major Angular releases.
-So Angular (components) 18 will be compatible with `@ngx-dropzone/cdk@18.x.x`.
+So Angular (components) 19 will be compatible with `@ngx-dropzone/cdk@19.x.x`.
Please note, that v16 is the first officially supported version.
For older Angular releases, use the libs at your own risk.
@@ -48,22 +48,24 @@ For older Angular releases, use the libs at your own risk.
This describes how to use the Material dropzone.
If you want to extend the CDK with your own styling, see below.
-```js
-// in app.module.ts
-import { MatFormFieldModule } from '@angular/material/form-field';
-import { DropzoneCdkModule } from '@ngx-dropzone/cdk';
-import { DropzoneMaterialModule } from '@ngx-dropzone/material';
+```ts
+// in app.component.ts
+import { MatFormField, MatLabel } from '@angular/material/form-field';
+import { MatIcon } from '@angular/material/icon';
+import { FileInputDirective } from '@ngx-dropzone/cdk';
+import { MatDropzone } from '@ngx-dropzone/material';
-@NgModule({
+@Component({
...
imports: [
- MatFormFieldModule,
- DropzoneCdkModule,
- DropzoneMaterialModule,
+ MatFormField,
+ MatLabel,
+ MatIcon,
+ MatDropzone,
+ FileInputDirective,
],
...
})
-export class AppModule { }
```
Now you can use it in your markup.
@@ -88,27 +90,19 @@ for `[(ngModel)]` and `[formControl]` directives, so you can seamlessly integrat
file upload into your form.
First, make sure to import the `ReactiveFormsModule`.
+Then, you're able to define your form control element (incl. validation).
-```js
-// in app.module.ts
+```ts
+// in app.component.ts
import { ReactiveFormsModule } from '@angular/forms';
-@NgModule({
- ...
+@Component({
+ selector: "form-control-dropzone",
imports: [
ReactiveFormsModule,
+ MatError,
...
],
- ...
-})
-export class AppModule { }
-```
-
-Then, you're able to define your form control element (incl. validation).
-
-```ts
-@Component({
- selector: "form-control-dropzone",
template: `
@@ -164,7 +158,7 @@ because people are way too opinionated about their styling and behaviour.
```
-```js
+```ts
export class AppComponent {
fileCtrl = new FormControl();
@@ -212,32 +206,18 @@ However, you might want to apply your own custom styling (or library).
In this case, you're able to build upon the dropzone CDK. See the [Material dropzone](/projects/material/src/lib/mat-dropzone/mat-dropzone.component.ts) as an example.
-The basic setup requires you to import the `DropzoneCdkModule` into your app.
-
-```js
-// in app.module.ts
-import { DropzoneCdkModule } from '@ngx-dropzone/cdk';
-
-@NgModule({
- ...
- imports: [
- DropzoneCdkModule,
- ],
- ...
-})
-export class AppModule { }
-```
-
-Next up, you extend the `DropzoneComponent` and apply your own styling and functionality.
+The basic setup requires you to extend the `DropzoneComponent` in your app to apply your own styling and functionality.
Use the following skeleton as a starting point. You may always have a look at the
Material reference implementation linked above.
```ts
import { Component } from "@angular/core";
-import { DropzoneComponent } from "@ngx-dropzone/cdk";
+import { AcceptService, DropzoneComponent, DropzoneService, FileInputDirective } from "@ngx-dropzone/cdk";
@Component({
selector: "my-dropzone",
+ imports: [FileInputDirective, DropzoneComponent],
+ providers: [DropzoneService, AcceptService],
template: `