@gerandon/ngx-widgets 18.0.1 → 18.0.3
Sign up to get free protection for your applications and to get access to all the features.
- package/esm2022/gerandon-ngx-widgets.mjs +5 -0
- package/esm2022/lib/basic-chips/basic-chips.component.mjs +80 -0
- package/esm2022/lib/basic-input/basic-input.component.mjs +41 -0
- package/esm2022/lib/core/base-input.mjs +81 -0
- package/esm2022/lib/core/base-text-input.mjs +20 -0
- package/esm2022/lib/core/base-value-accessor.mjs +63 -0
- package/esm2022/lib/core/component-unsubscribe.mjs +54 -0
- package/esm2022/lib/select/select.component.mjs +61 -0
- package/esm2022/lib/textarea-input/textarea-input.component.mjs +39 -0
- package/esm2022/public-api.mjs +12 -0
- package/fesm2022/gerandon-ngx-widgets.mjs +409 -0
- package/fesm2022/gerandon-ngx-widgets.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/basic-chips/basic-chips.component.d.ts +17 -0
- package/lib/basic-input/basic-input.component.d.ts +9 -0
- package/lib/core/base-input.d.ts +38 -0
- package/lib/core/base-text-input.d.ts +8 -0
- package/lib/core/base-value-accessor.d.ts +28 -0
- package/lib/core/component-unsubscribe.d.ts +8 -0
- package/lib/select/select.component.d.ts +26 -0
- package/lib/textarea-input/textarea-input.component.d.ts +7 -0
- package/package.json +16 -6
- package/{src/public-api.ts → public-api.d.ts} +0 -5
- package/ng-package.json +0 -7
- package/src/lib/basic-chips/basic-chips.component.html +0 -42
- package/src/lib/basic-chips/basic-chips.component.scss +0 -31
- package/src/lib/basic-chips/basic-chips.component.ts +0 -83
- package/src/lib/basic-input/basic-input.component.html +0 -47
- package/src/lib/basic-input/basic-input.component.scss +0 -26
- package/src/lib/basic-input/basic-input.component.ts +0 -41
- package/src/lib/core/base-input.ts +0 -69
- package/src/lib/core/base-text-input.ts +0 -13
- package/src/lib/core/base-value-accessor.ts +0 -80
- package/src/lib/core/component-unsubscribe.ts +0 -58
- package/src/lib/select/select.component.html +0 -39
- package/src/lib/select/select.component.scss +0 -7
- package/src/lib/select/select.component.ts +0 -70
- package/src/lib/textarea-input/textarea-input.component.html +0 -48
- package/src/lib/textarea-input/textarea-input.component.scss +0 -27
- package/src/lib/textarea-input/textarea-input.component.ts +0 -30
- package/tsconfig.lib.json +0 -14
- package/tsconfig.lib.prod.json +0 -10
- package/tsconfig.spec.json +0 -14
@@ -0,0 +1,38 @@
|
|
1
|
+
import { AfterViewInit, InjectionToken, OnChanges, OnInit, SimpleChanges } from '@angular/core';
|
2
|
+
import { FloatLabelType, SubscriptSizing } from '@angular/material/form-field';
|
3
|
+
import { BaseValueAccessor } from './base-value-accessor';
|
4
|
+
import * as i0 from "@angular/core";
|
5
|
+
export interface NgxWidgetsValidationErrorTypes {
|
6
|
+
required?: string;
|
7
|
+
selectGlobalPlaceholder?: string;
|
8
|
+
}
|
9
|
+
export declare const NGX_WIDGETS_VALIDATION_TRANSLATIONS: InjectionToken<NgxWidgetsValidationErrorTypes>;
|
10
|
+
export declare class BaseInput<T> extends BaseValueAccessor<T> implements OnInit, AfterViewInit, OnChanges {
|
11
|
+
protected readonly validationTranslations: NgxWidgetsValidationErrorTypes;
|
12
|
+
id: string;
|
13
|
+
name: string;
|
14
|
+
label: string;
|
15
|
+
translateParams?: unknown;
|
16
|
+
placeholder: string;
|
17
|
+
isDisabled?: boolean | undefined;
|
18
|
+
floatLabel: FloatLabelType;
|
19
|
+
prefixIcon?: string;
|
20
|
+
suffixIcon?: string;
|
21
|
+
suffix?: string;
|
22
|
+
formControlName?: string;
|
23
|
+
validatorMessages?: {
|
24
|
+
[key: string]: string;
|
25
|
+
};
|
26
|
+
subscriptSizing: SubscriptSizing;
|
27
|
+
hintLabel: string;
|
28
|
+
validatorMessagesArray: {
|
29
|
+
key: string;
|
30
|
+
value: unknown;
|
31
|
+
}[];
|
32
|
+
constructor(validationTranslations: NgxWidgetsValidationErrorTypes);
|
33
|
+
ngOnInit(): void;
|
34
|
+
ngOnChanges(changes: SimpleChanges): void;
|
35
|
+
ngAfterViewInit(): void;
|
36
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<BaseInput<any>, [{ optional: true; }]>;
|
37
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<BaseInput<any>, never, never, { "id": { "alias": "id"; "required": false; }; "name": { "alias": "name"; "required": false; }; "label": { "alias": "label"; "required": false; }; "translateParams": { "alias": "translateParams"; "required": false; }; "placeholder": { "alias": "placeholder"; "required": false; }; "isDisabled": { "alias": "isDisabled"; "required": false; }; "floatLabel": { "alias": "floatLabel"; "required": false; }; "prefixIcon": { "alias": "prefixIcon"; "required": false; }; "suffixIcon": { "alias": "suffixIcon"; "required": false; }; "suffix": { "alias": "suffix"; "required": false; }; "formControlName": { "alias": "formControlName"; "required": false; }; "validatorMessages": { "alias": "validatorMessages"; "required": false; }; "subscriptSizing": { "alias": "subscriptSizing"; "required": false; }; "hintLabel": { "alias": "hintLabel"; "required": false; }; }, {}, never, never, false, never>;
|
38
|
+
}
|
@@ -0,0 +1,8 @@
|
|
1
|
+
import { BaseInput } from './base-input';
|
2
|
+
import * as i0 from "@angular/core";
|
3
|
+
export declare class BaseTextInput<T> extends BaseInput<T> {
|
4
|
+
type: ('text' | 'password' | 'number' | 'email' | 'tel');
|
5
|
+
maxLength?: number | undefined;
|
6
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<BaseTextInput<any>, never>;
|
7
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<BaseTextInput<any>, never, never, { "type": { "alias": "type"; "required": false; }; "maxLength": { "alias": "maxLength"; "required": false; }; }, {}, never, never, false, never>;
|
8
|
+
}
|
@@ -0,0 +1,28 @@
|
|
1
|
+
import { AfterViewInit, ChangeDetectorRef, ElementRef, OnDestroy } from '@angular/core';
|
2
|
+
import { AbstractControl, ControlValueAccessor, FormControl, NgControl, ValidationErrors, Validator, ValidatorFn } from '@angular/forms';
|
3
|
+
import { Observable, Subject } from 'rxjs';
|
4
|
+
import * as i0 from "@angular/core";
|
5
|
+
export declare class BaseValueAccessor<T> implements ControlValueAccessor, AfterViewInit, Validator, OnDestroy {
|
6
|
+
validator: Observable<ValidationErrors>;
|
7
|
+
inputElement: ElementRef;
|
8
|
+
input: NgControl;
|
9
|
+
control: FormControl;
|
10
|
+
private onChange;
|
11
|
+
private onTouched;
|
12
|
+
private readonly injector;
|
13
|
+
protected controlDir: NgControl;
|
14
|
+
protected readonly cdr: ChangeDetectorRef;
|
15
|
+
protected _validate: ValidatorFn;
|
16
|
+
protected readonly _defaultValidate: ValidatorFn;
|
17
|
+
protected readonly destroy$: Subject<void>;
|
18
|
+
constructor();
|
19
|
+
validate(control: AbstractControl): Observable<ValidationErrors>;
|
20
|
+
ngAfterViewInit(): void;
|
21
|
+
writeValue(obj: T): void;
|
22
|
+
registerOnChange(fn: (value: T) => unknown): void;
|
23
|
+
registerOnTouched(fn: () => unknown): void;
|
24
|
+
protected get valueAccessor(): ControlValueAccessor | null;
|
25
|
+
ngOnDestroy(): void;
|
26
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<BaseValueAccessor<any>, never>;
|
27
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<BaseValueAccessor<any>, never, never, { "validator": { "alias": "validator"; "required": false; }; }, {}, never, never, false, never>;
|
28
|
+
}
|
@@ -0,0 +1,8 @@
|
|
1
|
+
/**
|
2
|
+
* Automatically unsubscribe from an Observable when the view is destroyed
|
3
|
+
* Tested with checking the "complete" event of a subscribe method
|
4
|
+
* @description
|
5
|
+
* An Annotation that should be used with an Observable typed variable to handle its subscriptions
|
6
|
+
* @author gergo.asztalos
|
7
|
+
*/
|
8
|
+
export declare function UnsubscribeOnDestroy<ObservableType>(): PropertyDecorator;
|
@@ -0,0 +1,26 @@
|
|
1
|
+
import { ElementRef, OnInit, QueryList } from '@angular/core';
|
2
|
+
import { BaseInput } from '../core/base-input';
|
3
|
+
import { Observable } from 'rxjs';
|
4
|
+
import * as i0 from "@angular/core";
|
5
|
+
export interface SelectOptionType {
|
6
|
+
label: string;
|
7
|
+
value: string | number | null | unknown;
|
8
|
+
}
|
9
|
+
export declare class SelectComponent extends BaseInput<unknown> implements OnInit {
|
10
|
+
/**
|
11
|
+
* In this case, an empty option appears that resets the control, to an empty value state
|
12
|
+
*/
|
13
|
+
emptyOptionLabel?: string;
|
14
|
+
multiple?: boolean;
|
15
|
+
options: SelectOptionType[];
|
16
|
+
asyncOptions: Observable<SelectOptionType[]>;
|
17
|
+
optionElements: QueryList<ElementRef>;
|
18
|
+
/**
|
19
|
+
* Angular Material - Select component comparsion is only '===', does not work with Array values
|
20
|
+
* https://github.com/angular/components/blob/a07c0758a5ec2eb4de1bb822354be08178c66aa4/src/lib/select/select.ts#L242C48-L242C58
|
21
|
+
*/
|
22
|
+
readonly _isEqual: (value: any, other: any) => boolean;
|
23
|
+
ngOnInit(): void;
|
24
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<SelectComponent, never>;
|
25
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<SelectComponent, "gerandon-select", never, { "emptyOptionLabel": { "alias": "emptyOptionLabel"; "required": false; }; "multiple": { "alias": "multiple"; "required": false; }; "options": { "alias": "options"; "required": false; }; "asyncOptions": { "alias": "asyncOptions"; "required": false; }; }, {}, never, never, true, never>;
|
26
|
+
}
|
@@ -0,0 +1,7 @@
|
|
1
|
+
import { BaseTextInput } from "../core/base-text-input";
|
2
|
+
import * as i0 from "@angular/core";
|
3
|
+
export declare class TextareaInputComponent extends BaseTextInput<string> {
|
4
|
+
rows: number;
|
5
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<TextareaInputComponent, never>;
|
6
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<TextareaInputComponent, "gerandon-textarea-input", never, { "rows": { "alias": "rows"; "required": false; }; }, {}, never, never, true, never>;
|
7
|
+
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@gerandon/ngx-widgets",
|
3
|
-
"version": "18.0.
|
3
|
+
"version": "18.0.3",
|
4
4
|
"description": "Angular widget (components) collection using CVA (ControlValueAccessor)",
|
5
5
|
"keywords": [
|
6
6
|
"CVA",
|
@@ -36,11 +36,21 @@
|
|
36
36
|
"dependencies": {
|
37
37
|
"tslib": "^2.3.0"
|
38
38
|
},
|
39
|
-
"devDependencies": {
|
40
|
-
"@types/lodash-es": "^4.17.12"
|
41
|
-
},
|
42
39
|
"publishConfig": {
|
43
40
|
"access": "public"
|
44
41
|
},
|
45
|
-
"sideEffects": false
|
46
|
-
|
42
|
+
"sideEffects": false,
|
43
|
+
"module": "fesm2022/gerandon-ngx-widgets.mjs",
|
44
|
+
"typings": "index.d.ts",
|
45
|
+
"exports": {
|
46
|
+
"./package.json": {
|
47
|
+
"default": "./package.json"
|
48
|
+
},
|
49
|
+
".": {
|
50
|
+
"types": "./index.d.ts",
|
51
|
+
"esm2022": "./esm2022/gerandon-ngx-widgets.mjs",
|
52
|
+
"esm": "./esm2022/gerandon-ngx-widgets.mjs",
|
53
|
+
"default": "./fesm2022/gerandon-ngx-widgets.mjs"
|
54
|
+
}
|
55
|
+
}
|
56
|
+
}
|
@@ -1,12 +1,7 @@
|
|
1
|
-
/*
|
2
|
-
* Public API Surface of ngx-widgets
|
3
|
-
*/
|
4
|
-
|
5
1
|
export * from './lib/core/base-value-accessor';
|
6
2
|
export * from './lib/core/base-input';
|
7
3
|
export * from './lib/core/base-text-input';
|
8
4
|
export * from './lib/core/component-unsubscribe';
|
9
|
-
|
10
5
|
export * from './lib/basic-input/basic-input.component';
|
11
6
|
export * from './lib/select/select.component';
|
12
7
|
export * from './lib/textarea-input/textarea-input.component';
|
package/ng-package.json
DELETED
@@ -1,42 +0,0 @@
|
|
1
|
-
<mat-form-field appearance="outline" [subscriptSizing]="subscriptSizing" [floatLabel]="floatLabel">
|
2
|
-
@if (label) {
|
3
|
-
<mat-label [class.disabled]="isDisabled">{{ label }}</mat-label>
|
4
|
-
}
|
5
|
-
<mat-chip-grid #chipGrid class="w-100">
|
6
|
-
@for(item of control.value; track item) {
|
7
|
-
<mat-chip-row (removed)="remove(item)" color="primary" highlighted>
|
8
|
-
{{ labelProperty ? item[labelProperty] : item}}
|
9
|
-
<button matChipRemove [attr.aria-label]="(labelProperty ? item[labelProperty] : item) + ' eltávolítása'">
|
10
|
-
<mat-icon>cancel</mat-icon>
|
11
|
-
</button>
|
12
|
-
</mat-chip-row>
|
13
|
-
}
|
14
|
-
<input #inputElement
|
15
|
-
matInput
|
16
|
-
[placeholder]="placeholder || label"
|
17
|
-
[matAutocomplete]="auto"
|
18
|
-
[matChipInputFor]="chipGrid"
|
19
|
-
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
|
20
|
-
(matChipInputTokenEnd)="!labelProperty && add($event)"/>
|
21
|
-
<mat-autocomplete #auto="matAutocomplete"
|
22
|
-
(optionSelected)="selected($event)">
|
23
|
-
@for (filterItem of asyncOptions | async; track filterItem) {
|
24
|
-
<mat-option [value]="filterItem">
|
25
|
-
{{labelProperty ? filterItem[labelProperty] : filterItem}}
|
26
|
-
</mat-option>
|
27
|
-
}
|
28
|
-
</mat-autocomplete>
|
29
|
-
</mat-chip-grid>
|
30
|
-
<input #input="ngForm" [style.display]="'none'" [formControl]="control" />
|
31
|
-
@if (control.errors?.['server']) {
|
32
|
-
<mat-error>{{ control.errors?.['server'] }}</mat-error>
|
33
|
-
} @else if (control.errors?.['required']) {
|
34
|
-
@if (validationTranslations.required) {
|
35
|
-
<mat-error>{{ validationTranslations.required }}</mat-error>
|
36
|
-
} @else {
|
37
|
-
@for (error of validatorMessagesArray; track error) {
|
38
|
-
<mat-error>{{ error.value }}</mat-error>
|
39
|
-
}
|
40
|
-
}
|
41
|
-
}
|
42
|
-
</mat-form-field>
|
@@ -1,31 +0,0 @@
|
|
1
|
-
gerandon-basic-chips {
|
2
|
-
display: block;
|
3
|
-
.mat-mdc-standard-chip {
|
4
|
-
height: 28px !important;
|
5
|
-
}
|
6
|
-
mat-form-field {
|
7
|
-
width: 100%;
|
8
|
-
.mat-mdc-text-field-wrapper {
|
9
|
-
.mat-mdc-form-field-infix {
|
10
|
-
display: flex;
|
11
|
-
align-items: center;
|
12
|
-
min-height: 40px !important;
|
13
|
-
padding: unset !important;
|
14
|
-
}
|
15
|
-
.mat-mdc-floating-label {
|
16
|
-
&:not(.mdc-floating-label--float-above) {
|
17
|
-
top: 1.2rem !important;
|
18
|
-
}
|
19
|
-
}
|
20
|
-
}
|
21
|
-
mat-chip-row {
|
22
|
-
margin-top: 8px !important;
|
23
|
-
margin-bottom: 8px !important;
|
24
|
-
}
|
25
|
-
.mat-mdc-standard-chip .mdc-evolution-chip__cell--primary,
|
26
|
-
.mat-mdc-standard-chip .mdc-evolution-chip__action--primary,
|
27
|
-
.mat-mdc-standard-chip .mat-mdc-chip-action-label {
|
28
|
-
overflow: hidden !important;
|
29
|
-
}
|
30
|
-
}
|
31
|
-
}
|
@@ -1,83 +0,0 @@
|
|
1
|
-
import { COMMA, ENTER } from '@angular/cdk/keycodes';
|
2
|
-
import { AsyncPipe, JsonPipe } from '@angular/common';
|
3
|
-
import { Component, forwardRef, Input, ViewEncapsulation } from '@angular/core';
|
4
|
-
import { NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms';
|
5
|
-
import { MatAutocompleteModule, MatAutocompleteSelectedEvent } from '@angular/material/autocomplete';
|
6
|
-
import { MatChipInputEvent, MatChipsModule } from '@angular/material/chips';
|
7
|
-
import { MatIconModule } from '@angular/material/icon';
|
8
|
-
|
9
|
-
import { Observable } from 'rxjs';
|
10
|
-
import {BaseInput} from "../core/base-input";
|
11
|
-
import {MatError, MatFormField, MatLabel} from "@angular/material/form-field";
|
12
|
-
import {MatInput} from "@angular/material/input";
|
13
|
-
|
14
|
-
@Component({
|
15
|
-
selector: 'gerandon-basic-chips',
|
16
|
-
templateUrl: 'basic-chips.component.html',
|
17
|
-
styleUrls: ['basic-chips.component.scss'],
|
18
|
-
standalone: true,
|
19
|
-
encapsulation: ViewEncapsulation.None,
|
20
|
-
providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => BasicChipsComponent), multi: true }],
|
21
|
-
imports: [
|
22
|
-
MatChipsModule,
|
23
|
-
MatIconModule,
|
24
|
-
ReactiveFormsModule,
|
25
|
-
MatAutocompleteModule,
|
26
|
-
AsyncPipe,
|
27
|
-
JsonPipe,
|
28
|
-
MatFormField,
|
29
|
-
MatInput,
|
30
|
-
MatLabel,
|
31
|
-
MatError,
|
32
|
-
],
|
33
|
-
})
|
34
|
-
export class BasicChipsComponent<T> extends BaseInput<T[]> {
|
35
|
-
|
36
|
-
@Input() public asyncOptions?: Observable<T[]>;
|
37
|
-
@Input() public labelProperty?: keyof T;
|
38
|
-
public readonly separatorKeysCodes = [ENTER, COMMA] as const;
|
39
|
-
|
40
|
-
remove(item: T) {
|
41
|
-
const values: T[] = this.control.value;
|
42
|
-
const index = values.indexOf(item);
|
43
|
-
if (index >= 0) {
|
44
|
-
values.splice(index, 1);
|
45
|
-
this.control.setValue(values);
|
46
|
-
}
|
47
|
-
|
48
|
-
this.mark();
|
49
|
-
}
|
50
|
-
|
51
|
-
add(event: MatChipInputEvent): void {
|
52
|
-
const value = (event.value || '').trim();
|
53
|
-
if (value) {
|
54
|
-
this.updateValue(value as T);
|
55
|
-
}
|
56
|
-
event.chipInput!.clear();
|
57
|
-
|
58
|
-
this.mark();
|
59
|
-
}
|
60
|
-
|
61
|
-
selected(event: MatAutocompleteSelectedEvent): void {
|
62
|
-
if (!this.control.value?.includes(event.option.value)) {
|
63
|
-
this.updateValue(<T>event.option.value);
|
64
|
-
}
|
65
|
-
this.inputElement.nativeElement.value = '';
|
66
|
-
|
67
|
-
this.mark();
|
68
|
-
}
|
69
|
-
|
70
|
-
private updateValue(value: T) {
|
71
|
-
this.control.setValue([
|
72
|
-
...(this.control.value || []),
|
73
|
-
value,
|
74
|
-
]);
|
75
|
-
}
|
76
|
-
|
77
|
-
private mark() {
|
78
|
-
if (!this.control.touched) {
|
79
|
-
this.control.markAsTouched();
|
80
|
-
this.control.markAsDirty();
|
81
|
-
}
|
82
|
-
}
|
83
|
-
}
|
@@ -1,47 +0,0 @@
|
|
1
|
-
<div class="basic-input cva-input">
|
2
|
-
<mat-form-field appearance="outline" [subscriptSizing]="subscriptSizing" [hintLabel]="hintLabel" [floatLabel]="floatLabel">
|
3
|
-
@if (label) {
|
4
|
-
<mat-label [class.disabled]="isDisabled">{{label}}</mat-label>
|
5
|
-
}
|
6
|
-
<input
|
7
|
-
[id]="id"
|
8
|
-
#inputElement
|
9
|
-
#input="ngForm"
|
10
|
-
matInput
|
11
|
-
[style.padding-right]="(suffix || prefixIcon) && '35px'"
|
12
|
-
[type]="type"
|
13
|
-
[attr.disabled]="isDisabled || control.disabled ? '' : null"
|
14
|
-
[readonly]="isDisabled"
|
15
|
-
[placeholder]="placeholder"
|
16
|
-
[formControl]="control"
|
17
|
-
[maxLength]="maxLength"
|
18
|
-
[name]="name"
|
19
|
-
[required]="!!control.errors?.['required']"/>
|
20
|
-
@if (prefixIcon) {
|
21
|
-
<mat-icon matPrefix color="accent">
|
22
|
-
{{prefixIcon}}
|
23
|
-
</mat-icon>
|
24
|
-
}
|
25
|
-
@if (suffixIcon) {
|
26
|
-
<mat-icon matSuffix color="accent">
|
27
|
-
{{suffixIcon}}
|
28
|
-
</mat-icon>
|
29
|
-
}
|
30
|
-
@if (suffix) {
|
31
|
-
<span matSuffix style="margin-right: 10px">{{suffix}}</span>
|
32
|
-
}
|
33
|
-
@if (control.errors?.['server']) {
|
34
|
-
<mat-error>{{ control.errors?.['server'] }}</mat-error>
|
35
|
-
} @else if (control.errors?.['required']) {
|
36
|
-
@if (validationTranslations.required) {
|
37
|
-
<mat-error>{{ validationTranslations.required }}</mat-error>
|
38
|
-
} @else {
|
39
|
-
@for (error of validatorMessagesArray; track error) {
|
40
|
-
@if (control.errors?.[error.key]) {
|
41
|
-
<mat-error>{{ error.value }}</mat-error>
|
42
|
-
}
|
43
|
-
}
|
44
|
-
}
|
45
|
-
}
|
46
|
-
</mat-form-field>
|
47
|
-
</div>
|
@@ -1,26 +0,0 @@
|
|
1
|
-
gerandon-basic-input {
|
2
|
-
display: block;
|
3
|
-
.basic-input {
|
4
|
-
height: inherit;
|
5
|
-
.disabled {
|
6
|
-
color: #CED4DAFF;
|
7
|
-
}
|
8
|
-
mat-form-field {
|
9
|
-
width: 100%;
|
10
|
-
.mat-icon {
|
11
|
-
padding: unset;
|
12
|
-
margin-left: 10px;
|
13
|
-
margin-right: 10px;
|
14
|
-
}
|
15
|
-
input {
|
16
|
-
&::placeholder {
|
17
|
-
color: #ADB5BDFF;
|
18
|
-
font-style: italic;
|
19
|
-
}
|
20
|
-
&:disabled {
|
21
|
-
cursor: not-allowed;
|
22
|
-
}
|
23
|
-
}
|
24
|
-
}
|
25
|
-
}
|
26
|
-
}
|
@@ -1,41 +0,0 @@
|
|
1
|
-
import {
|
2
|
-
Component,
|
3
|
-
EventEmitter,
|
4
|
-
forwardRef,
|
5
|
-
OnInit,
|
6
|
-
Output,
|
7
|
-
ViewEncapsulation,
|
8
|
-
} from '@angular/core';
|
9
|
-
import { NG_ASYNC_VALIDATORS, NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms';
|
10
|
-
import { MatFormFieldModule } from '@angular/material/form-field';
|
11
|
-
import { MatIconModule } from '@angular/material/icon';
|
12
|
-
import { MatInputModule } from '@angular/material/input';
|
13
|
-
|
14
|
-
import { BaseTextInput } from '../core/base-text-input';
|
15
|
-
|
16
|
-
@Component({
|
17
|
-
selector: 'gerandon-basic-input',
|
18
|
-
templateUrl: './basic-input.component.html',
|
19
|
-
styleUrls: ['./basic-input.component.scss'],
|
20
|
-
encapsulation: ViewEncapsulation.None,
|
21
|
-
standalone: true,
|
22
|
-
imports: [
|
23
|
-
ReactiveFormsModule,
|
24
|
-
MatIconModule,
|
25
|
-
MatFormFieldModule,
|
26
|
-
MatInputModule,
|
27
|
-
],
|
28
|
-
providers: [
|
29
|
-
{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => BasicInputComponent), multi: true },
|
30
|
-
{ provide: NG_ASYNC_VALIDATORS, useExisting: forwardRef(() => BasicInputComponent), multi: true },
|
31
|
-
],
|
32
|
-
})
|
33
|
-
export class BasicInputComponent extends BaseTextInput<string> implements OnInit {
|
34
|
-
|
35
|
-
@Output() iconClick = new EventEmitter();
|
36
|
-
|
37
|
-
override ngOnInit() {
|
38
|
-
super.ngOnInit();
|
39
|
-
this.id = this.id || this.name;
|
40
|
-
}
|
41
|
-
}
|
@@ -1,69 +0,0 @@
|
|
1
|
-
import {
|
2
|
-
AfterViewInit,
|
3
|
-
Directive, Inject, inject, InjectionToken,
|
4
|
-
Input, OnChanges,
|
5
|
-
OnInit, Optional, SimpleChanges,
|
6
|
-
} from '@angular/core';
|
7
|
-
import { FloatLabelType, SubscriptSizing } from '@angular/material/form-field';
|
8
|
-
|
9
|
-
import { BaseValueAccessor } from './base-value-accessor';
|
10
|
-
import { isEmpty, keys } from 'lodash-es';
|
11
|
-
|
12
|
-
export interface NgxWidgetsValidationErrorTypes {
|
13
|
-
required?: string;
|
14
|
-
selectGlobalPlaceholder?: string;
|
15
|
-
}
|
16
|
-
export const NGX_WIDGETS_VALIDATION_TRANSLATIONS = new InjectionToken<NgxWidgetsValidationErrorTypes>('NGX_WIDGETS_VALIDATION_TRANSLATIONS');
|
17
|
-
|
18
|
-
@Directive()
|
19
|
-
export class BaseInput<T> extends BaseValueAccessor<T> implements OnInit, AfterViewInit, OnChanges {
|
20
|
-
|
21
|
-
@Input() public id!: string;
|
22
|
-
@Input() public name!: string;
|
23
|
-
@Input() public label!: string;
|
24
|
-
@Input() public translateParams?: unknown;
|
25
|
-
@Input() public placeholder!: string;
|
26
|
-
@Input() public isDisabled? = false;
|
27
|
-
@Input() public floatLabel: FloatLabelType = 'auto';
|
28
|
-
@Input() public prefixIcon?: string;
|
29
|
-
@Input() public suffixIcon?: string;
|
30
|
-
@Input() public suffix?: string;
|
31
|
-
@Input() public formControlName?: string;
|
32
|
-
@Input() public validatorMessages?: { [key: string]: string };
|
33
|
-
@Input() public subscriptSizing: SubscriptSizing = 'fixed';
|
34
|
-
@Input() public hintLabel = '';
|
35
|
-
public validatorMessagesArray: { key: string, value: unknown }[] = [];
|
36
|
-
|
37
|
-
constructor(@Optional() @Inject(NGX_WIDGETS_VALIDATION_TRANSLATIONS) protected readonly validationTranslations: NgxWidgetsValidationErrorTypes) {
|
38
|
-
super();
|
39
|
-
}
|
40
|
-
|
41
|
-
ngOnInit() {
|
42
|
-
this.placeholder = this.placeholder === undefined ? this.label : this.placeholder;
|
43
|
-
if (!this.name) {
|
44
|
-
this.name = this.formControlName!;
|
45
|
-
/*
|
46
|
-
console.warn(`name attribute is not defined for ${this.formControlName}! Please beware, that using this control multiple
|
47
|
-
times with the same control name could result in wrong focus, clicking on the label!`);
|
48
|
-
*/
|
49
|
-
}
|
50
|
-
// *ngIf seems like does not re-render component when label is used with dynamic value (e.g.: translate pipe). Strange
|
51
|
-
this.label = this.label || ' ';
|
52
|
-
}
|
53
|
-
|
54
|
-
ngOnChanges(changes: SimpleChanges) {
|
55
|
-
if (changes['validatorMessages']) {
|
56
|
-
if (!isEmpty(this.validatorMessages)) {
|
57
|
-
this.validatorMessagesArray = keys(this.validatorMessages).map((key) => ({
|
58
|
-
key,
|
59
|
-
value: this.validatorMessages![key],
|
60
|
-
}));
|
61
|
-
}
|
62
|
-
}
|
63
|
-
}
|
64
|
-
|
65
|
-
override ngAfterViewInit() {
|
66
|
-
super.ngAfterViewInit();
|
67
|
-
this.cdr.detectChanges();
|
68
|
-
}
|
69
|
-
}
|
@@ -1,13 +0,0 @@
|
|
1
|
-
import {
|
2
|
-
Directive,
|
3
|
-
Input,
|
4
|
-
} from '@angular/core';
|
5
|
-
|
6
|
-
import { BaseInput } from './base-input';
|
7
|
-
|
8
|
-
@Directive()
|
9
|
-
export class BaseTextInput<T> extends BaseInput<T> {
|
10
|
-
|
11
|
-
@Input() public type: ('text' | 'password' | 'number' | 'email' | 'tel') = 'text';
|
12
|
-
@Input() public maxLength? = 512;
|
13
|
-
}
|
@@ -1,80 +0,0 @@
|
|
1
|
-
import {
|
2
|
-
AfterViewInit,
|
3
|
-
ChangeDetectorRef, Directive,
|
4
|
-
ElementRef, inject,
|
5
|
-
Injector, Input, OnDestroy, Type,
|
6
|
-
ViewChild,
|
7
|
-
} from '@angular/core';
|
8
|
-
import {
|
9
|
-
AbstractControl,
|
10
|
-
ControlValueAccessor, FormControl,
|
11
|
-
NgControl,
|
12
|
-
ValidationErrors,
|
13
|
-
Validator, ValidatorFn,
|
14
|
-
} from '@angular/forms';
|
15
|
-
|
16
|
-
import {Observable, of, Subject} from 'rxjs';
|
17
|
-
|
18
|
-
@Directive()
|
19
|
-
export class BaseValueAccessor<T> implements ControlValueAccessor, AfterViewInit, Validator, OnDestroy {
|
20
|
-
|
21
|
-
@Input() public validator: Observable<ValidationErrors> = of({});
|
22
|
-
@ViewChild('inputElement') inputElement!: ElementRef;
|
23
|
-
@ViewChild('input') input!: NgControl;
|
24
|
-
|
25
|
-
public control: FormControl;
|
26
|
-
|
27
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
28
|
-
private onChange = (value: T) => {
|
29
|
-
};
|
30
|
-
private onTouched = () => {
|
31
|
-
};
|
32
|
-
private readonly injector: Injector = inject(Injector);
|
33
|
-
protected controlDir!: NgControl;
|
34
|
-
protected readonly cdr: ChangeDetectorRef = inject(ChangeDetectorRef);
|
35
|
-
protected _validate: ValidatorFn;
|
36
|
-
protected readonly _defaultValidate: ValidatorFn = () => null;
|
37
|
-
|
38
|
-
protected readonly destroy$ = new Subject<void>();
|
39
|
-
|
40
|
-
constructor() {
|
41
|
-
this._validate = this._defaultValidate;
|
42
|
-
// Temporarily, AfterViewInit will handle the correct setting
|
43
|
-
this.control = new FormControl();
|
44
|
-
}
|
45
|
-
|
46
|
-
validate(control: AbstractControl): Observable<ValidationErrors> {
|
47
|
-
control.setErrors({ ...control.errors, pending: true });
|
48
|
-
return this.validator;
|
49
|
-
}
|
50
|
-
|
51
|
-
ngAfterViewInit() {
|
52
|
-
this.controlDir = this.injector.get<NgControl>(NgControl as Type<NgControl>);
|
53
|
-
this.control = <FormControl>this.controlDir.control;
|
54
|
-
// For ng-valid expression changed error workaround purposes
|
55
|
-
this.cdr.detectChanges();
|
56
|
-
}
|
57
|
-
|
58
|
-
writeValue(obj: T): void {
|
59
|
-
this.valueAccessor?.writeValue(obj);
|
60
|
-
}
|
61
|
-
|
62
|
-
registerOnChange(fn: (value: T) => unknown): void {
|
63
|
-
this.onChange = fn;
|
64
|
-
this.valueAccessor?.registerOnChange(fn);
|
65
|
-
}
|
66
|
-
|
67
|
-
registerOnTouched(fn: () => unknown) {
|
68
|
-
this.onTouched = fn;
|
69
|
-
this.valueAccessor?.registerOnTouched(fn);
|
70
|
-
}
|
71
|
-
|
72
|
-
protected get valueAccessor(): ControlValueAccessor | null {
|
73
|
-
return this.input ? this.input.valueAccessor : null;
|
74
|
-
}
|
75
|
-
|
76
|
-
ngOnDestroy() {
|
77
|
-
this.destroy$.next();
|
78
|
-
this.destroy$.complete();
|
79
|
-
}
|
80
|
-
}
|