Skip to content
Merged
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
3 changes: 2 additions & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ insert_final_newline = false
[*.md]
max_line_length = off
trim_trailing_whitespace = false
indent_style = space

[*.{ts,js,html}]
indent_size = 4
indent_style = tab
indent_style = tab
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ This repo contains general usage libraries for shd Angular projects. Those libra
- images (`@studiohyperdrive/ngx-images`):
- progressive image loading

- forms (`@studiohyperdrive/ngx-forms`):
- custom validators

You can find detailed explanations in their respective README’s.

It is build with:
Expand Down
43 changes: 43 additions & 0 deletions angular.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"cli": {
"analytics": false
},
"version": 1,
"newProjectRoot": "projects",
"projects": {
Expand Down Expand Up @@ -82,6 +85,46 @@
}
}
}
},
"forms": {
"projectType": "library",
"root": "projects/forms",
"sourceRoot": "projects/forms/src",
"prefix": "lib",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:ng-packagr",
"options": {
"tsConfig": "projects/forms/tsconfig.lib.json",
"project": "projects/forms/ng-package.json"
},
"configurations": {
"production": {
"tsConfig": "projects/forms/tsconfig.lib.prod.json"
}
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "projects/forms/src/test.ts",
"tsConfig": "projects/forms/tsconfig.spec.json",
"karmaConfig": "projects/forms/karma.conf.js"
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"projects/forms/tsconfig.lib.json",
"projects/forms/tsconfig.spec.json"
],
"exclude": [
"**/node_modules/**"
]
}
}
}
}
},
"defaultProject": "utils"
Expand Down
36 changes: 34 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "ng test",
"test": "ng test --code-coverage --watch false",
"test:watch": "ng test",
"lint": "ng lint --fix"
},
"private": true,
Expand Down
14 changes: 14 additions & 0 deletions projects/forms/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Angular Tools: forms (`@studiohyperdrive/ngx-forms`)

Install the package first:
```shell
npm install @studiohyperdrive/ngx-forms
```

## 1. Validators

A set of extra custom validators compatible with the default Angular validators and reactive forms.

| Validator | Description |
|----------------|------------------------------------------------------------------------------------------------------|
| extendedEmail | Extends the default e-mail validator with a required period in the tld part of te email. |
44 changes: 44 additions & 0 deletions projects/forms/karma.conf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Karma configuration file, see link for more information
// https://karma-runner.github.io/1.0/config/configuration-file.html

module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '@angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage'),
require('@angular-devkit/build-angular/plugins/karma')
],
client: {
jasmine: {
// you can add configuration options for Jasmine here
// the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
// for example, you can disable the random execution with `random: false`
// or set a specific seed with `seed: 4321`
},
clearContext: false // leave Jasmine Spec Runner output visible in browser
},
jasmineHtmlReporter: {
suppressAll: true // removes the duplicated traces
},
coverageReporter: {
dir: require('path').join(__dirname, '../../coverage/forms'),
subdir: '.',
reporters: [
{ type: 'html' },
{ type: 'text-summary' }
]
},
reporters: ['progress', 'kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false,
restartOnFileChange: true
});
};
7 changes: 7 additions & 0 deletions projects/forms/ng-package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
"dest": "../../dist/forms",
"lib": {
"entryFile": "src/public-api.ts"
}
}
11 changes: 11 additions & 0 deletions projects/forms/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "@studiohyperdrive/ngx-utils",
"version": "0.0.1",
"peerDependencies": {
"@angular/common": "^11.2.1",
"@angular/core": "^11.2.1"
},
"dependencies": {
"tslib": "^2.0.0"
}
}
34 changes: 34 additions & 0 deletions projects/forms/src/lib/validators/extended-email.validator.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { FormControl, FormGroup } from '@angular/forms';

import { Validators } from './validators';

describe('Extended Email Validator', () => {
it('should throw an error if e-mail is not valid', () => {
const control1 = new FormControl('test');
const control2 = new FormControl('test@test');

expect(Validators.extendedEmail(control1)).toEqual({ extendedEmail: true });
expect(Validators.extendedEmail(control2)).toEqual({ extendedEmail: true });
});

it('should not throw an error if e-mail is valid', () => {
const control1 = new FormControl(''); // Should be valid, use Validators.required for this
const control2 = new FormControl('test@test.be');

expect(Validators.extendedEmail(control1)).toBeNull();
expect(Validators.extendedEmail(control2)).toBeNull();
});

it('should work as validator in a reactive form', () => {
const form = new FormGroup({
email1: new FormControl('', [Validators.extendedEmail]),
email2: new FormControl('', [Validators.extendedEmail]),
});

form.get('email1').setValue('test@test');
form.get('email2').setValue('test@test.be');

expect(form.get('email1').errors).toEqual({ extendedEmail: true });
expect(form.get('email2').errors).toBeNull();
});
});
34 changes: 34 additions & 0 deletions projects/forms/src/lib/validators/validators.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { AbstractControl, ValidationErrors } from '@angular/forms';

/**
* Helpers
*
* Don't add to class because we don't want them to be exposed as static prop
*/

function isEmptyInputValue(value: any): boolean {
// we don't check for string here so it also works with arrays
return value == null || value.length === 0;
}

export function extendedEmailValidator(control: AbstractControl): ValidationErrors|null {
if (isEmptyInputValue(control.value)) {
return null; // don't validate empty values to allow optional controls
}

// Validates more strictly than the default email validator. Requires a period in the tld part.
return /^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$/.test(control.value) ? null : { extendedEmail : true};
}


/**
* Exported Class
*/

export class Validators {
static extendedEmail(control: AbstractControl): ValidationErrors|null {
return extendedEmailValidator(control);
}

// Add other custom validators :-)
}
5 changes: 5 additions & 0 deletions projects/forms/src/public-api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/*
* Public API Surface of forms
*/

export { Validators } from '../../forms/src/lib/validators/validators';
26 changes: 26 additions & 0 deletions projects/forms/src/test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// This file is required by karma.conf.js and loads recursively all the .spec and framework files

import { getTestBed } from '@angular/core/testing';
import {
BrowserDynamicTestingModule,
platformBrowserDynamicTesting,
} from '@angular/platform-browser-dynamic/testing';
import 'zone.js/dist/zone';
import 'zone.js/dist/zone-testing';

declare const require: {
context(path: string, deep?: boolean, filter?: RegExp): {
keys(): string[];
<T>(id: string): T;
};
};

// First, initialize the Angular testing environment.
getTestBed().initTestEnvironment(
BrowserDynamicTestingModule,
platformBrowserDynamicTesting()
);
// Then we find all the tests.
const context = require.context('./', true, /\.spec\.ts$/);
// And load the modules.
context.keys().map(context);
25 changes: 25 additions & 0 deletions projects/forms/tsconfig.lib.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "../../out-tsc/lib",
"target": "es2015",
"declaration": true,
"declarationMap": true,
"inlineSources": true,
"types": [],
"lib": [
"dom",
"es2018"
]
},
"angularCompilerOptions": {
"skipTemplateCodegen": true,
"strictMetadataEmit": true,
"enableResourceInlining": true
},
"exclude": [
"src/test.ts",
"**/*.spec.ts"
]
}
10 changes: 10 additions & 0 deletions projects/forms/tsconfig.lib.prod.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"extends": "./tsconfig.lib.json",
"compilerOptions": {
"declarationMap": false
},
"angularCompilerOptions": {
"enableIvy": false
}
}
17 changes: 17 additions & 0 deletions projects/forms/tsconfig.spec.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "../../out-tsc/spec",
"types": [
"jasmine"
]
},
"files": [
"src/test.ts"
],
"include": [
"**/*.spec.ts",
"**/*.d.ts"
]
}
Loading