@gerandon/ngx-widgets 18.0.0 → 18.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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/gerandon-ngx-widgets-18.0.2.tgz +0 -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 -39
- 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 -44
- 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 -36
- 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 -45
- 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.2",
|
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,39 +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
|
-
<mat-error>{{ validationTranslations.required }}</mat-error>
|
35
|
-
@for (error of validatorMessagesArray; track error) {
|
36
|
-
<mat-error>{{ error.value }}</mat-error>
|
37
|
-
}
|
38
|
-
}
|
39
|
-
</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,44 +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
|
-
<mat-error>{{ validationTranslations.required }}</mat-error>
|
37
|
-
@for (error of validatorMessagesArray; track error) {
|
38
|
-
@if (control.errors?.[error.key]) {
|
39
|
-
<mat-error>{{ error.value }}</mat-error>
|
40
|
-
}
|
41
|
-
}
|
42
|
-
}
|
43
|
-
</mat-form-field>
|
44
|
-
</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
|
-
}
|