Skip to content

Commit 422b983

Browse files
authored
feat!: update to angular 19 (#106)
- updates to angular 19 - **BREAKING CHANGE** removes the use of `NgModule` and makes the components / directives `standalone: true`
1 parent 0b47988 commit 422b983

17 files changed

+4028
-4079
lines changed

.github/workflows/ci.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
runs-on: ubuntu-latest
1818
strategy:
1919
matrix:
20-
node-version: [20.x]
20+
node-version: [22.x]
2121
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
2222

2323
steps:

.nvmrc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
20.13.1
1+
22.12.0

CHANGES.md

+10
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
# 19.0.0 - 2025-01-05
2+
- Support Angular 19 (#106)
3+
4+
*BREAKING CHANGES:*
5+
- `QrCodeComponent` and `QrCodeDirective` are now `standalone` components
6+
- `QrCodeModule` has been removed
7+
8+
See the [readme](https://github.com/mnahkies/ng-qrcode#importing) for instructions on how to import the
9+
components correctly after these changes, but **tldr; replace imports of `QrCodeModule` with `QrCodeComponent`**
10+
111
# 18.0.0 - 2024-05-25
212
- Support Angular 18 (#98)
313
- Add new inputs `style` / `styleClass` (#88)

README.md

+35-5
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
Easy to use QR code generator for Angular projects.
77

88
**Features:**
9-
* Compatible with Angular 18
9+
* Compatible with Angular 19, uses `standalone` components
1010
* Leverages the widely used [qrcode](https://www.npmjs.com/package/qrcode)
1111
package to do the heavy lifting
1212
* Renders to HTML Canvas
@@ -16,6 +16,9 @@ Easy to use QR code generator for Angular projects.
1616
<!-- toc -->
1717

1818
- [Installation](#installation)
19+
- [Importing](#importing)
20+
- [Standalone Component](#standalone-component)
21+
- [NgModule](#ngmodule)
1922
- [Usage](#usage)
2023
- [Component](#component)
2124
- [value: string (required)](#value-string-required)
@@ -42,19 +45,45 @@ Add as a dependency to your angular application:
4245

4346
npm install ng-qrcode --save
4447

45-
## Usage
46-
Import into your consuming module (Eg: AppModule):
48+
### Importing
49+
This library ships with [standalone components](https://angular.dev/reference/migrations/standalone)
50+
51+
How you consume it depends on whether you have migrated to standalone components (the default since Angular v19)
52+
53+
#### Standalone Component
54+
55+
Add the `QrCodeComponent` or `QrCodeDirective` to your `@Component` declarations `imports` array. Eg:
56+
```typescript
57+
import { QrCodeComponent } from 'ng-qrcode';
58+
59+
@Component({
60+
selector: "app-root",
61+
templateUrl: "./app.component.html",
62+
styleUrls: ["./app.component.scss"],
63+
standalone: true,
64+
imports: [
65+
QrCodeComponent,
66+
]
67+
})
68+
export class AppComponent {
69+
// ...
70+
}
71+
```
72+
#### NgModule
4773

74+
If you're still using `NgModule` / non-standalone components, then you can add `QrCodeComponent` or `QrCodeDirective` to your `@NgModule` declarations `imports` array. Eg:
4875
```typescript
49-
import { QrCodeModule } from 'ng-qrcode';
76+
import { QrCodeComponent } from 'ng-qrcode';
5077

5178
@NgModule({
5279
imports: [
53-
QrCodeModule
80+
QrCodeComponent
5481
]
5582
})
5683
```
5784

85+
## Usage
86+
5887
### Component
5988
```angular17html
6089
<qr-code value="Hello world!"
@@ -135,6 +164,7 @@ major version.
135164

136165
| Angular Version | ng-qrcode Versions |
137166
|-----------------|--------------------|
167+
| ^19 | ^19 |
138168
| ^18 | ^18 |
139169
| ^17 | ^17 |
140170
| ^16 | ^16 |

package.json

+33-33
Original file line numberDiff line numberDiff line change
@@ -33,48 +33,48 @@
3333
"ci-lint": "ng lint"
3434
},
3535
"dependencies": {
36-
"@angular/animations": "^18.0.0",
37-
"@angular/common": "^18.0.0",
38-
"@angular/compiler": "^18.0.0",
39-
"@angular/core": "^18.0.0",
40-
"@angular/forms": "^18.0.0",
41-
"@angular/platform-browser": "^18.0.0",
42-
"@angular/platform-browser-dynamic": "^18.0.0",
43-
"@angular/router": "^18.0.0",
44-
"qrcode": "^1.5.3",
36+
"@angular/animations": "^19.0.5",
37+
"@angular/common": "^19.0.5",
38+
"@angular/compiler": "^19.0.5",
39+
"@angular/core": "^19.0.5",
40+
"@angular/forms": "^19.0.5",
41+
"@angular/platform-browser": "^19.0.5",
42+
"@angular/platform-browser-dynamic": "^19.0.5",
43+
"@angular/router": "^19.0.5",
44+
"qrcode": "^1.5.4",
4545
"rxjs": "^7.8.1",
46-
"tslib": "^2.6.2",
47-
"zone.js": "~0.14.2"
46+
"tslib": "^2.8.1",
47+
"zone.js": "~0.15.0"
4848
},
4949
"devDependencies": {
50-
"@angular-devkit/build-angular": "^18.0.1",
51-
"@angular-eslint/builder": "18.0.0-alpha.1",
52-
"@angular-eslint/eslint-plugin": "18.0.0-alpha.1",
53-
"@angular-eslint/eslint-plugin-template": "18.0.0-alpha.1",
54-
"@angular-eslint/schematics": "18.0.0-alpha.1",
55-
"@angular-eslint/template-parser": "18.0.0-alpha.1",
56-
"@angular/cli": "^18.0.1",
57-
"@angular/compiler-cli": "^18.0.0",
58-
"@angular/language-service": "^18.0.0",
59-
"@types/jasmine": "~5.1.2",
60-
"@types/node": "^20.9.2",
50+
"@angular-devkit/build-angular": "^19.0.6",
51+
"@angular-eslint/builder": "19.0.2",
52+
"@angular-eslint/eslint-plugin": "19.0.2",
53+
"@angular-eslint/eslint-plugin-template": "19.0.2",
54+
"@angular-eslint/schematics": "19.0.2",
55+
"@angular-eslint/template-parser": "19.0.2",
56+
"@angular/cli": "^19.0.6",
57+
"@angular/compiler-cli": "^19.0.5",
58+
"@angular/language-service": "^19.0.5",
59+
"@types/jasmine": "~5.1.5",
60+
"@types/node": "^20.17.11",
6161
"@types/qrcode": "^1.5.5",
62-
"@typescript-eslint/eslint-plugin": "7.10.0",
63-
"@typescript-eslint/parser": "7.10.0",
64-
"eslint": "^8.54.0",
65-
"gh-pages": "^6.1.1",
66-
"husky": "^9.0.11",
67-
"jasmine-core": "~5.1.1",
62+
"@typescript-eslint/eslint-plugin": "8.19.0",
63+
"@typescript-eslint/parser": "8.19.0",
64+
"eslint": "^9.17.0",
65+
"gh-pages": "^6.3.0",
66+
"husky": "^9.1.7",
67+
"jasmine-core": "~5.5.0",
6868
"jasmine-spec-reporter": "~7.0.0",
69-
"karma": "^6.4.2",
69+
"karma": "^6.4.4",
7070
"karma-chrome-launcher": "~3.2.0",
7171
"karma-coverage": "^2.2.1",
7272
"karma-jasmine": "~5.1.0",
7373
"karma-jasmine-html-reporter": "^2.1.0",
74-
"lint-staged": "^15.2.5",
74+
"lint-staged": "^15.3.0",
7575
"markdown-toc": "^1.2.0",
76-
"ng-packagr": "^18.0.0",
77-
"typescript": "~5.4.5"
76+
"ng-packagr": "^19.0.1",
77+
"typescript": "~5.6.3"
7878
},
7979
"lint-staged": {
8080
"*.md": [
@@ -84,5 +84,5 @@
8484
"engines": {
8585
"node": ">=20 <23"
8686
},
87-
"packageManager": "yarn@4.2.2"
87+
"packageManager": "yarn@4.6.0"
8888
}

projects/ng-qrcode-demo/src/app/app.component.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ <h3>Result:</h3>
6767
[lightColor]="lightColor"
6868
[errorCorrectionLevel]="errorCorrectionLevel"
6969
[centerImageSrc]="centerImageSrc"
70-
[centerImageSize]="centerImageSize ? this.centerImageSize : undefined"
70+
[centerImageSize]="centerImageSize"
7171
[margin]="margin" />
7272
</div>
7373
</div>

projects/ng-qrcode-demo/src/app/app.component.spec.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
import { TestBed } from "@angular/core/testing"
22
import { AppComponent } from "./app.component"
3-
import { AppModule } from "./app.module"
43

54
describe("AppComponent", () => {
65
beforeEach(async () => {
76
await TestBed.configureTestingModule({
87
imports: [
9-
AppModule,
8+
AppComponent,
109
],
1110
}).compileComponents()
1211
})

projects/ng-qrcode-demo/src/app/app.component.ts

+11-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
import { Component } from "@angular/core"
2-
import { QrCodeErrorCorrectionLevel, RGBAColor } from "ng-qrcode"
2+
import { FormsModule } from "@angular/forms"
3+
import { QrCodeComponent, QrCodeErrorCorrectionLevel, RGBAColor } from "ng-qrcode"
34

45
@Component({
56
selector: "app-root",
67
templateUrl: "./app.component.html",
78
styleUrls: ["./app.component.scss"],
9+
standalone: true,
10+
imports: [
11+
QrCodeComponent,
12+
FormsModule,
13+
]
814
})
915
export class AppComponent {
1016

@@ -25,13 +31,13 @@ export class AppComponent {
2531
get example() {
2632
return `
2733
<qr-code value="${ this.value }"
28-
size="${ this.size }"${this.darkColor ? `
29-
darkColor="${this.darkColor}"` : ""}${this.lightColor ? `
30-
lightColor="${this.lightColor}"` : ""}
34+
size="${ this.size }"${ this.darkColor ? `
35+
darkColor="${ this.darkColor }"` : "" }${ this.lightColor ? `
36+
lightColor="${ this.lightColor }"` : "" }
3137
errorCorrectionLevel="${ this.errorCorrectionLevel }"
3238
centerImageSrc="${ this.centerImageSrc }"
3339
centerImageSize="${ this.centerImageSize ? parseInt(this.centerImageSize, 10) : undefined }"
34-
margin="${ this.margin }">
40+
[margin]="${ this.margin }">
3541
</qr-code>`
3642
}
3743

projects/ng-qrcode-demo/src/app/app.module.ts

-20
This file was deleted.

projects/ng-qrcode-demo/src/main.ts

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
import { enableProdMode } from "@angular/core"
2-
import { platformBrowserDynamic } from "@angular/platform-browser-dynamic"
3-
4-
import { AppModule } from "./app/app.module"
2+
import { bootstrapApplication } from "@angular/platform-browser"
3+
import { AppComponent } from "./app/app.component"
54
import { environment } from "./environments/environment"
65

76
if (environment.production) {
87
enableProdMode()
98
}
109

11-
platformBrowserDynamic().bootstrapModule(AppModule)
12-
.catch((err) => console.error(err))
10+
bootstrapApplication(AppComponent)
11+
.catch(e => console.error(e))

projects/ng-qrcode/package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "ng-qrcode",
33
"description": "Simple AOT compatible QR code generator for your Angular project.",
4-
"version": "18.0.0",
4+
"version": "19.0.0",
55
"license": "MIT",
66
"author": {
77
"name": "Michael Nahkies",
@@ -19,8 +19,8 @@
1919
"tslib": "^2.6.2"
2020
},
2121
"peerDependencies": {
22-
"@angular/common": ">=18 <19",
23-
"@angular/core": ">=18 <19"
22+
"@angular/common": ">=19 <20",
23+
"@angular/core": ">=19 <20"
2424
},
2525
"keywords": [
2626
"qr",

projects/ng-qrcode/src/lib/qr-code.component.spec.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
11
import { ComponentFixture, TestBed } from "@angular/core/testing"
22

33
import { QrCodeComponent } from "./qr-code.component"
4-
import { QrCodeDirective } from "./qr-code.directive"
54

65
describe("QrCodeComponent", () => {
76
let component: QrCodeComponent
87
let fixture: ComponentFixture<QrCodeComponent>
98

109
beforeEach(async () => {
1110
await TestBed.configureTestingModule({
12-
declarations: [
11+
imports: [
1312
QrCodeComponent,
14-
QrCodeDirective,
1513
],
1614
})
1715
.compileComponents()

projects/ng-qrcode/src/lib/qr-code.component.ts

+8-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
import { CommonModule } from "@angular/common"
12
import { Component, Input } from "@angular/core"
3+
import { QrCodeDirective } from "./qr-code.directive"
24
import { QrCodeErrorCorrectionLevel, RGBAColor } from "./types"
35

46
@Component({
@@ -23,6 +25,8 @@ import { QrCodeErrorCorrectionLevel, RGBAColor } from "./types"
2325
}
2426
`,
2527
styles: [],
28+
standalone: true,
29+
imports: [QrCodeDirective, CommonModule]
2630
})
2731
export class QrCodeComponent {
2832

@@ -33,14 +37,14 @@ export class QrCodeComponent {
3337
size?: string | number
3438

3539
@Input()
36-
style?: {
40+
style?: {
3741
// matches type of ngStyle https://angular.io/api/common/NgStyle
3842
// eslint-disable-next-line @typescript-eslint/no-explicit-any
39-
[klass: string]: any
40-
} | null;
43+
[klass: string]: any
44+
} | null
4145

4246
@Input()
43-
styleClass?: string;
47+
styleClass?: string
4448

4549
@Input()
4650
darkColor?: RGBAColor

projects/ng-qrcode/src/lib/qr-code.directive.ts

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const validColorRegex = /^#(?:[0-9a-fA-F]{3,4}){1,2}$/
77
@Directive({
88
// eslint-disable-next-line @angular-eslint/directive-selector
99
selector: `canvas[qrCode]`,
10+
standalone: true,
1011
})
1112
export class QrCodeDirective implements OnChanges {
1213

projects/ng-qrcode/src/lib/qr-code.module.ts

-20
This file was deleted.

projects/ng-qrcode/src/public-api.ts

-1
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,4 @@
44

55
export * from "./lib/qr-code.component"
66
export * from "./lib/qr-code.directive"
7-
export * from "./lib/qr-code.module"
87
export * from "./lib/types"

0 commit comments

Comments
 (0)