Skip to content

Update to Angular 19 #128

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules/
3 changes: 0 additions & 3 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
{
"root": true,
"ignorePatterns": [
"projects/**/*"
],
"overrides": [
{
"files": [
Expand Down
106 changes: 70 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,16 @@ Or run locally:
# Usage

## Installation

```shell
npm install angular-cc-library --save
```

## Version Compatibility

| Angular | Library |
|---------|---------|
| ------- | ------- |
| 19.x | 3.5.x |
| 18.x | 3.4.x |
| 17.x | 3.3.x |
| 16.x | 3.2.x |
Expand All @@ -40,92 +42,121 @@ npm install angular-cc-library --save
| 13.x | 3.0.0 |
| 12.x | 2.1.3 |


## Formatting Directive

On the input fields, add the specific directive to format inputs.
All fields must be `type='tel'` in order to support spacing and additional characters.

Since `angular-cc-library@3.3.0` all directives declared as standalone,
Since `angular-cc-library@3.3.0` all directives declared as standalone,
so you can import them directly into your component:

```typescript
import { Component } from '@angular/core';
import { CreditCardFormatDirective } from 'angular-cc-library';
import { Component } from "@angular/core";
import { CreditCardFormatDirective } from "angular-cc-library";

@Component({
selector: 'credit-card-number-input',
selector: "credit-card-number-input",
standalone: true,
deps: [CreditCardFormatDirective],
template: `<input id="cc-number" type="tel" autocomplete="cc-number" ccNumber>`
template: `<input
id="cc-number"
type="tel"
autocomplete="cc-number"
ccNumber
/>`,
})
export class CreditCardNumberInputComponent {}
```

But you can still import them all at once using `CreditCardDirectivesModule`:

```typescript
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { CreditCardDirectivesModule } from 'angular-cc-library';
import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";
import { FormsModule } from "@angular/forms";
import { CreditCardDirectivesModule } from "angular-cc-library";

import { AppComponent } from './app.component';
import { AppComponent } from "./app.component";

@NgModule({
imports: [BrowserModule, FormsModule, CreditCardDirectivesModule],
declarations: [AppComponent],
bootstrap: [AppComponent]
imports: [BrowserModule, FormsModule, CreditCardDirectivesModule],
declarations: [AppComponent],
bootstrap: [AppComponent],
})
export class AppModule {
}
export class AppModule {}
```

**Credit Card Formatter**
* add `ccNumber` directive:

- add `ccNumber` directive:

```html
<input id="cc-number" type="tel" autocomplete="cc-number" ccNumber>
<input id="cc-number" type="tel" autocomplete="cc-number" ccNumber />
```
* this will also apply a class name based off the card `.visa`, `.amex`, etc. See the array of card types in `credit-card.ts` for all available types

* You can get parsed card type by using export api:
- this will also apply a class name based off the card `.visa`, `.amex`, etc. See the array of card types in `credit-card.ts` for all available types

- You can get parsed card type by using export api:

```html
<input type="tel" ccNumber #ccNumber="ccNumber">
<input type="tel" ccNumber #ccNumber="ccNumber" />
<span class="scheme">{{ccNumber.resolvedScheme$ | async}}</span>
```

`resolvedScheme$` will be populated with `visa`, `amex`, etc.


**Expiration Date Formatter**
Will support format of MM/YY or MM/YYYY
* add `ccExp` directive:

- add `ccExp` directive:

```html
<input id="cc-exp-date" type="tel" autocomplete="cc-exp" ccExp>
<input id="cc-exp-date" type="tel" autocomplete="cc-exp" ccExp />
```

**CVC Formater**
* add `ccCvc` directive:

- add `ccCvc` directive:

```html
<input id="cc-cvc" type="tel" autocomplete="off" ccCVC>
<input id="cc-cvc" type="tel" autocomplete="off" ccCVC />
```

### Validation

Current only Model Validation is supported.
To implement, import the validator library and apply the specific validator on each form control

```typescript
import { CreditCardValidators } from 'angular-cc-library';
import { CreditCardValidators } from "angular-cc-library";

@Component({
selector: 'app',
selector: "app",
template: `
<form #demoForm="ngForm" (ngSubmit)="onSubmit(demoForm)" novalidate>
<input id="cc-number" formControlName="creditCard" type="tel" autocomplete="cc-number" ccNumber>
<input id="cc-exp-date" formControlName="expirationDate" type="tel" autocomplete="cc-exp" ccExp>
<input id="cc-cvc" formControlName="cvc" type="tel" autocomplete="off" ccCvc>
<input
id="cc-number"
formControlName="creditCard"
type="tel"
autocomplete="cc-number"
ccNumber
/>
<input
id="cc-exp-date"
formControlName="expirationDate"
type="tel"
autocomplete="cc-exp"
ccExp
/>
<input
id="cc-cvc"
formControlName="cvc"
type="tel"
autocomplete="off"
ccCvc
/>
</form>
`
`,
})
export class AppComponent implements OnInit {
form: FormGroup;
Expand All @@ -135,9 +166,12 @@ export class AppComponent implements OnInit {

ngOnInit() {
this.form = this._fb.group({
creditCard: ['', [CreditCardValidators.validateCCNumber]],
expirationDate: ['', [CreditCardValidators.validateExpDate]],
cvc: ['', [Validators.required, Validators.minLength(3), Validators.maxLength(4)]]
creditCard: ["", [CreditCardValidators.validateCCNumber]],
expirationDate: ["", [CreditCardValidators.validateExpDate]],
cvc: [
"",
[Validators.required, Validators.minLength(3), Validators.maxLength(4)],
],
});
}

Expand Down
58 changes: 29 additions & 29 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,41 +13,41 @@
"prepare": "husky"
},
"dependencies": {
"@angular/common": "^18.2.2",
"@angular/compiler": "^18.2.2",
"@angular/core": "^18.2.2",
"@angular/forms": "^18.2.2",
"@angular/platform-browser": "^18.2.2",
"@angular/platform-browser-dynamic": "^18.2.2",
"@angular/common": "^19.1.5",
"@angular/compiler": "^19.1.5",
"@angular/core": "^19.1.5",
"@angular/forms": "^19.1.5",
"@angular/platform-browser": "^19.1.5",
"@angular/platform-browser-dynamic": "^19.1.5",
"rxjs": "~7.8.1",
"tslib": "^2.7.0",
"zone.js": "~0.14.10"
"tslib": "^2.8.1",
"zone.js": "~0.15.0"
},
"devDependencies": {
"@angular-builders/jest": "18.0.0",
"@angular-devkit/build-angular": "^18.2.2",
"@angular-eslint/builder": "18.3.0",
"@angular-eslint/eslint-plugin": "18.3.0",
"@angular-eslint/eslint-plugin-template": "18.3.0",
"@angular-eslint/schematics": "18.3.0",
"@angular-eslint/template-parser": "18.3.0",
"@angular/cli": "^18.2.2",
"@angular/compiler-cli": "^18.2.2",
"@angular/language-service": "^18.2.2",
"@angular-builders/jest": "19.0.0",
"@angular-devkit/build-angular": "^19.1.6",
"@angular-eslint/builder": "19.0.2",
"@angular-eslint/eslint-plugin": "19.0.2",
"@angular-eslint/eslint-plugin-template": "19.0.2",
"@angular-eslint/schematics": "19.0.2",
"@angular-eslint/template-parser": "19.0.2",
"@angular/cli": "^19.1.6",
"@angular/compiler-cli": "^19.1.5",
"@angular/language-service": "^19.1.5",
"@release-it/bumper": "^6.0.1",
"@release-it/conventional-changelog": "^8.0.1",
"@types/jest": "^29.5.12",
"@types/node": "^22.5.3",
"@typescript-eslint/eslint-plugin": "8.4.0",
"@typescript-eslint/parser": "8.4.0",
"eslint": "^8.56.0",
"husky": "^9.1.5",
"@release-it/conventional-changelog": "^8.0.2",
"@types/jest": "^29.5.14",
"@types/node": "^22.13.1",
"@typescript-eslint/eslint-plugin": "8.23.0",
"@typescript-eslint/parser": "8.23.0",
"eslint": "^8.57.1",
"husky": "^9.1.7",
"jest": "29.7.0",
"lint-staged": "^15.2.10",
"ng-packagr": "^18.2.1",
"release-it": "^17.6.0",
"lint-staged": "^15.4.3",
"ng-packagr": "^19.1.2",
"release-it": "^17.11.0",
"ts-node": "~10.9.2",
"typescript": "~5.5.4"
"typescript": "~5.7.3"
},
"lint-staged": {
"*.{ts,component.html}": [
Expand Down
6 changes: 3 additions & 3 deletions projects/angular-cc-library/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@
"url": "git+https://github.com/timofei-iatsenko/angular-cc-library.git"
},
"dependencies": {
"tslib": "^2.4.1"
"tslib": "^2.8.1"
},
"peerDependencies": {
"@angular/common": "^18.0.0",
"@angular/core": "^18.0.0"
"@angular/common": "^19.1.4",
"@angular/core": "^19.1.4"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testin
import { CreditCardFormatDirective } from './credit-card-format.directive';
import { Component, DebugElement } from '@angular/core';
import { By } from '@angular/platform-browser';
import { CommonModule } from '@angular/common';

const KEY_MAP = {
ONE: 49, // input `1`
Expand All @@ -22,15 +23,15 @@ describe('Directive: CreditCardFormat', () => {
describe('general cases', () => {
@Component({
template: `<input type="tel" ccNumber>`,
imports: [CreditCardFormatDirective],
})
class TestCreditCardFormatComponent {}

let fixture: ComponentFixture<TestCreditCardFormatComponent>;
let inputEl: DebugElement;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [TestCreditCardFormatComponent],
imports: [CreditCardFormatDirective]
imports: [TestCreditCardFormatComponent]
});
fixture = TestBed.createComponent(TestCreditCardFormatComponent);
inputEl = fixture.debugElement.query(By.css('input'));
Expand Down Expand Up @@ -144,7 +145,8 @@ describe('Directive: CreditCardFormat', () => {
describe('exportAs cases', () => {
@Component({
template: `<input type="tel" ccNumber #ccNumber="ccNumber">
<span class="scheme">{{ccNumber.resolvedScheme$ | async}}</span>`,
<span class="scheme">{{ ccNumber.resolvedScheme$ | async }}</span>`,
imports: [CreditCardFormatDirective, CommonModule],
})
class TestCreditCardFormatComponent {}

Expand All @@ -153,8 +155,7 @@ describe('Directive: CreditCardFormat', () => {

beforeEach(() => {
TestBed.configureTestingModule({
declarations: [TestCreditCardFormatComponent],
imports: [CreditCardFormatDirective],
imports: [TestCreditCardFormatComponent],
});
fixture = TestBed.createComponent(TestCreditCardFormatComponent);
inputEl = fixture.debugElement.query(By.css('input'));
Expand Down
7 changes: 3 additions & 4 deletions projects/example/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@ import { defer } from 'rxjs';
import { map } from 'rxjs/operators';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
standalone: true,
imports: [FormsModule, ReactiveFormsModule, AsyncPipe, CreditCardDirectivesModule]
selector: 'app-root',
templateUrl: './app.component.html',
imports: [FormsModule, ReactiveFormsModule, AsyncPipe, CreditCardDirectivesModule]
})
export class AppComponent {
public demoForm = this.fb.group({
Expand Down
Loading