@webilix/ngx-form-m3 0.0.31 → 0.0.38

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.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { HostBinding, Directive, Input, HostListener, Optional, Pipe, InjectionToken, inject, Component, Injector, makeEnvironmentProviders, EventEmitter, Output, ViewChild, Inject } from '@angular/core';
2
+ import { HostBinding, Directive, Input, HostListener, Optional, Pipe, InjectionToken, inject, Component, Injector, EventEmitter, Output, makeEnvironmentProviders, ViewChild, Inject } from '@angular/core';
3
3
  import * as i1 from '@angular/forms';
4
4
  import { ReactiveFormsModule, FormControl, Validators, FormsModule, FormGroup } from '@angular/forms';
5
5
  import { MatIconButton, MatButton } from '@angular/material/button';
@@ -8,21 +8,23 @@ import { MatAutocompleteModule } from '@angular/material/autocomplete';
8
8
  import { MatFormField } from '@angular/material/form-field';
9
9
  import { MatIcon } from '@angular/material/icon';
10
10
  import * as i2$1 from '@angular/material/input';
11
- import { MatInputModule } from '@angular/material/input';
11
+ import { MatInputModule, MatInput } from '@angular/material/input';
12
12
  import { Helper } from '@webilix/helper-library';
13
13
  import * as i1$1 from '@angular/platform-browser';
14
14
  import { NgxMaskDirective, provideNgxMask } from 'ngx-mask';
15
15
  import { JalaliDateTime } from '@webilix/jalali-date-time';
16
16
  import { NgComponentOutlet, NgClass, DecimalPipe } from '@angular/common';
17
17
  import * as i1$2 from '@webilix/ngx-helper-m3';
18
- import { NgxHelperDatePipe, NgxHelperFileSizePipe } from '@webilix/ngx-helper-m3';
18
+ import { NgxHelperDatePipe, NgxHelperFileSizePipe, NgxHelperNumberPipe } from '@webilix/ngx-helper-m3';
19
19
  import * as i1$3 from '@webilix/ngx-calendar-m3';
20
20
  import * as i3 from '@angular/cdk/bidi';
21
+ import * as i1$4 from '@angular/cdk/drag-drop';
22
+ import { CdkDragHandle, moveItemInArray, DragDropModule } from '@angular/cdk/drag-drop';
21
23
  import * as i3$1 from '@angular/material/menu';
22
24
  import { MatMenuModule } from '@angular/material/menu';
23
25
  import * as i4 from '@angular/material/select';
24
26
  import { MatSelectModule } from '@angular/material/select';
25
- import * as i1$4 from '@angular/router';
27
+ import * as i1$5 from '@angular/router';
26
28
 
27
29
  class AutoCompleteDirective {
28
30
  autocomplete = 'one-time-code';
@@ -196,6 +198,8 @@ class InputErrorPipe {
196
198
  return `انتخاب حداقل ${Helper.NUMBER.format(value)} گزینه الزامی است.`;
197
199
  case 'maxcount':
198
200
  return `امکان انتخاب بیشتر از ${Helper.NUMBER.format(value)} گزینه وجود ندارد.`;
201
+ case 'duplicate':
202
+ return 'امکان انتخاب مقادیر تکراری وجود ندارد.';
199
203
  case 'bank-card':
200
204
  return `شماره کارت بانکی صحیح مشخص نشده است.`;
201
205
  case 'bank-sheba':
@@ -468,6 +472,15 @@ const MultiplyOfNumberValidator = (multiplyOf) => {
468
472
  };
469
473
  };
470
474
 
475
+ const DuplicateValidator = (callback) => {
476
+ return (formControl) => {
477
+ const values = Array.isArray(formControl.value) ? formControl.value : [];
478
+ const check = values.map((value) => callback(value));
479
+ const unique = check.filter((v, i, a) => a.indexOf(v) === i);
480
+ return check.length !== unique.length ? { duplicate: true } : null;
481
+ };
482
+ };
483
+
471
484
  const LengthValidator = (length) => {
472
485
  return (formControl) => {
473
486
  const value = formControl.value;
@@ -681,11 +694,11 @@ class InputCoordinatesComponent {
681
694
  this.formControl.markAsTouched();
682
695
  }
683
696
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: InputCoordinatesComponent, deps: [{ token: i1$2.NgxHelperCoordinatesService }], target: i0.ɵɵFactoryTarget.Component });
684
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type: InputCoordinatesComponent, isStandalone: true, selector: "ng-component", inputs: { values: "values", isButtonDisabled: "isButtonDisabled" }, host: { attributes: { "selector": "input-coordinates" } }, ngImport: i0, template: "<mat-form-field [appearance]=\"input.appearance || config.appearance\" [floatLabel]=\"formControl.value ? 'always' : 'auto'\">\n <mat-label>{{ input.title || '\u0645\u0648\u0642\u0639\u06CC\u062A \u062C\u063A\u0631\u0627\u0641\u06CC\u0627\u06CC\u06CC' }}</mat-label>\n @if (formControl.invalid) { <mat-error>{{ formControl.errors | InputErrorPipe : input.type }}</mat-error> }\n\n <!-- HINT -->\n @if (input.hint) { <mat-hint>{{ input.hint }}</mat-hint> }\n\n <!-- SUFFIX -->\n <span matTextSuffix class=\"ngx-form-m3-input-suffix click\" [class.ngx-form-m3-disabled-input]=\"formControl.disabled\">\n <span>&nbsp;</span>\n <mat-icon (click)=\"formControl.value ? resetCoordinates() : setCoordinates(); formControl.markAsTouched()\">\n {{ formControl.value ? 'close' : 'calendar_month' }}\n </mat-icon>\n </span>\n\n <!-- BUTTON -->\n @if (input.button) {\n <span matIconSuffix>\n <button\n mat-icon-button\n type=\"button\"\n [disabled]=\"isButtonDisabled\"\n (click)=\"input.button.onClick(values)\"\n [tabIndex]=\"-1\"\n >\n <mat-icon [style.color]=\"isButtonDisabled ? undefined : input.button.color\">\n {{ input.button.icon }}\n </mat-icon>\n </button>\n </span>\n }\n\n <!-- INPUT -->\n <input matInput type=\"text\" [name]=\"input.name\" [formControl]=\"formControl\" [style.display]=\"'none !important'\" />\n <input\n type=\"text\"\n matInput\n [readonly]=\"true\"\n class=\"ngx-helper-form-m3-coordinates-input ngx-form-m3-en\"\n [disabled]=\"formControl.disabled\"\n (click)=\"setCoordinates()\"\n [value]=\"formControl.value ? coordinates?.latitude + ', ' + coordinates?.longitude : ''\"\n />\n\n <!-- DESCRIPTION -->\n @if (input.description) {\n <div\n class=\"ngx-form-m3-input-description\"\n [class.ngx-form-m3-disabled-input]=\"formControl.disabled\"\n [innerHTML]=\"input.description | MultiLinePipe\"\n ></div>\n }\n</mat-form-field>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i2$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "pipe", type: InputErrorPipe, name: "InputErrorPipe" }, { kind: "pipe", type: MultiLinePipe, name: "MultiLinePipe" }] });
697
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type: InputCoordinatesComponent, isStandalone: true, selector: "ng-component", inputs: { values: "values", isButtonDisabled: "isButtonDisabled" }, host: { attributes: { "selector": "input-coordinates" } }, ngImport: i0, template: "<mat-form-field [appearance]=\"input.appearance || config.appearance\" [floatLabel]=\"formControl.value ? 'always' : 'auto'\">\n <mat-label>{{ input.title || '\u0645\u0648\u0642\u0639\u06CC\u062A \u062C\u063A\u0631\u0627\u0641\u06CC\u0627\u06CC\u06CC' }}</mat-label>\n @if (formControl.invalid) { <mat-error>{{ formControl.errors | InputErrorPipe : input.type }}</mat-error> }\n\n <!-- HINT -->\n @if (input.hint) { <mat-hint>{{ input.hint }}</mat-hint> }\n\n <!-- SUFFIX -->\n <span matTextSuffix class=\"ngx-form-m3-input-suffix click\" [class.ngx-form-m3-disabled-input]=\"formControl.disabled\">\n <span>&nbsp;</span>\n <mat-icon (click)=\"formControl.value ? resetCoordinates() : setCoordinates(); formControl.markAsTouched()\">\n {{ formControl.value ? 'close' : 'location_on' }}\n </mat-icon>\n </span>\n\n <!-- BUTTON -->\n @if (input.button) {\n <span matIconSuffix>\n <button\n mat-icon-button\n type=\"button\"\n [disabled]=\"isButtonDisabled\"\n (click)=\"input.button.onClick(values)\"\n [tabIndex]=\"-1\"\n >\n <mat-icon [style.color]=\"isButtonDisabled ? undefined : input.button.color\">\n {{ input.button.icon }}\n </mat-icon>\n </button>\n </span>\n }\n\n <!-- INPUT -->\n <input matInput type=\"text\" [name]=\"input.name\" [formControl]=\"formControl\" [style.display]=\"'none !important'\" />\n <input\n type=\"text\"\n matInput\n [readonly]=\"true\"\n class=\"ngx-helper-form-m3-coordinates-input ngx-form-m3-en\"\n [disabled]=\"formControl.disabled\"\n (click)=\"setCoordinates()\"\n [value]=\"formControl.value ? coordinates?.latitude + ', ' + coordinates?.longitude : ''\"\n />\n\n <!-- DESCRIPTION -->\n @if (input.description) {\n <div\n class=\"ngx-form-m3-input-description\"\n [class.ngx-form-m3-disabled-input]=\"formControl.disabled\"\n [innerHTML]=\"input.description | MultiLinePipe\"\n ></div>\n }\n</mat-form-field>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i2$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "pipe", type: InputErrorPipe, name: "InputErrorPipe" }, { kind: "pipe", type: MultiLinePipe, name: "MultiLinePipe" }] });
685
698
  }
686
699
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: InputCoordinatesComponent, decorators: [{
687
700
  type: Component,
688
- args: [{ host: { selector: 'input-coordinates' }, imports: [ReactiveFormsModule, MatFormField, MatIcon, MatIconButton, MatInputModule, InputErrorPipe, MultiLinePipe], template: "<mat-form-field [appearance]=\"input.appearance || config.appearance\" [floatLabel]=\"formControl.value ? 'always' : 'auto'\">\n <mat-label>{{ input.title || '\u0645\u0648\u0642\u0639\u06CC\u062A \u062C\u063A\u0631\u0627\u0641\u06CC\u0627\u06CC\u06CC' }}</mat-label>\n @if (formControl.invalid) { <mat-error>{{ formControl.errors | InputErrorPipe : input.type }}</mat-error> }\n\n <!-- HINT -->\n @if (input.hint) { <mat-hint>{{ input.hint }}</mat-hint> }\n\n <!-- SUFFIX -->\n <span matTextSuffix class=\"ngx-form-m3-input-suffix click\" [class.ngx-form-m3-disabled-input]=\"formControl.disabled\">\n <span>&nbsp;</span>\n <mat-icon (click)=\"formControl.value ? resetCoordinates() : setCoordinates(); formControl.markAsTouched()\">\n {{ formControl.value ? 'close' : 'calendar_month' }}\n </mat-icon>\n </span>\n\n <!-- BUTTON -->\n @if (input.button) {\n <span matIconSuffix>\n <button\n mat-icon-button\n type=\"button\"\n [disabled]=\"isButtonDisabled\"\n (click)=\"input.button.onClick(values)\"\n [tabIndex]=\"-1\"\n >\n <mat-icon [style.color]=\"isButtonDisabled ? undefined : input.button.color\">\n {{ input.button.icon }}\n </mat-icon>\n </button>\n </span>\n }\n\n <!-- INPUT -->\n <input matInput type=\"text\" [name]=\"input.name\" [formControl]=\"formControl\" [style.display]=\"'none !important'\" />\n <input\n type=\"text\"\n matInput\n [readonly]=\"true\"\n class=\"ngx-helper-form-m3-coordinates-input ngx-form-m3-en\"\n [disabled]=\"formControl.disabled\"\n (click)=\"setCoordinates()\"\n [value]=\"formControl.value ? coordinates?.latitude + ', ' + coordinates?.longitude : ''\"\n />\n\n <!-- DESCRIPTION -->\n @if (input.description) {\n <div\n class=\"ngx-form-m3-input-description\"\n [class.ngx-form-m3-disabled-input]=\"formControl.disabled\"\n [innerHTML]=\"input.description | MultiLinePipe\"\n ></div>\n }\n</mat-form-field>\n" }]
701
+ args: [{ host: { selector: 'input-coordinates' }, imports: [ReactiveFormsModule, MatFormField, MatIcon, MatIconButton, MatInputModule, InputErrorPipe, MultiLinePipe], template: "<mat-form-field [appearance]=\"input.appearance || config.appearance\" [floatLabel]=\"formControl.value ? 'always' : 'auto'\">\n <mat-label>{{ input.title || '\u0645\u0648\u0642\u0639\u06CC\u062A \u062C\u063A\u0631\u0627\u0641\u06CC\u0627\u06CC\u06CC' }}</mat-label>\n @if (formControl.invalid) { <mat-error>{{ formControl.errors | InputErrorPipe : input.type }}</mat-error> }\n\n <!-- HINT -->\n @if (input.hint) { <mat-hint>{{ input.hint }}</mat-hint> }\n\n <!-- SUFFIX -->\n <span matTextSuffix class=\"ngx-form-m3-input-suffix click\" [class.ngx-form-m3-disabled-input]=\"formControl.disabled\">\n <span>&nbsp;</span>\n <mat-icon (click)=\"formControl.value ? resetCoordinates() : setCoordinates(); formControl.markAsTouched()\">\n {{ formControl.value ? 'close' : 'location_on' }}\n </mat-icon>\n </span>\n\n <!-- BUTTON -->\n @if (input.button) {\n <span matIconSuffix>\n <button\n mat-icon-button\n type=\"button\"\n [disabled]=\"isButtonDisabled\"\n (click)=\"input.button.onClick(values)\"\n [tabIndex]=\"-1\"\n >\n <mat-icon [style.color]=\"isButtonDisabled ? undefined : input.button.color\">\n {{ input.button.icon }}\n </mat-icon>\n </button>\n </span>\n }\n\n <!-- INPUT -->\n <input matInput type=\"text\" [name]=\"input.name\" [formControl]=\"formControl\" [style.display]=\"'none !important'\" />\n <input\n type=\"text\"\n matInput\n [readonly]=\"true\"\n class=\"ngx-helper-form-m3-coordinates-input ngx-form-m3-en\"\n [disabled]=\"formControl.disabled\"\n (click)=\"setCoordinates()\"\n [value]=\"formControl.value ? coordinates?.latitude + ', ' + coordinates?.longitude : ''\"\n />\n\n <!-- DESCRIPTION -->\n @if (input.description) {\n <div\n class=\"ngx-form-m3-input-description\"\n [class.ngx-form-m3-disabled-input]=\"formControl.disabled\"\n [innerHTML]=\"input.description | MultiLinePipe\"\n ></div>\n }\n</mat-form-field>\n" }]
689
702
  }], ctorParameters: () => [{ type: i1$2.NgxHelperCoordinatesService }], propDecorators: { values: [{
690
703
  type: Input,
691
704
  args: [{ required: true }]
@@ -938,6 +951,158 @@ class InputIpMethods extends InputMethods {
938
951
  }
939
952
  }
940
953
 
954
+ class ListInputComponent {
955
+ english;
956
+ disabled;
957
+ autoFocus;
958
+ onFocus = new EventEmitter();
959
+ onInput = new EventEmitter();
960
+ checkValue(input) {
961
+ const value = input.value.trim();
962
+ if (this.disabled || value === '')
963
+ return;
964
+ this.onInput.next(value);
965
+ input.value = '';
966
+ }
967
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: ListInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
968
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.0.0", type: ListInputComponent, isStandalone: true, selector: "list-input", inputs: { english: "english", disabled: "disabled", autoFocus: "autoFocus" }, outputs: { onFocus: "onFocus", onInput: "onInput" }, ngImport: i0, template: "<input\n matInput\n type=\"text\"\n [placeholder]=\"english ? 'New Item' : '\u06AF\u0632\u06CC\u0646\u0647 \u062C\u062F\u06CC\u062F'\"\n [class.ngx-form-m3-en]=\"english\"\n [AutoFocusDirective]=\"autoFocus\"\n [disabled]=\"disabled\"\n (blur)=\"checkValue(input); onFocus.next(false)\"\n (focus)=\"onFocus.next(true)\"\n (keydown.enter)=\"$event.preventDefault(); checkValue(input)\"\n #input\n/>\n", styles: [":host{display:flex;align-items:center}input::placeholder{font-size:85%}\n"], dependencies: [{ kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "directive", type: AutoFocusDirective, selector: "[AutoFocusDirective]", inputs: ["AutoFocusDirective"] }] });
969
+ }
970
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: ListInputComponent, decorators: [{
971
+ type: Component,
972
+ args: [{ selector: 'list-input', imports: [MatInput, AutoFocusDirective], template: "<input\n matInput\n type=\"text\"\n [placeholder]=\"english ? 'New Item' : '\u06AF\u0632\u06CC\u0646\u0647 \u062C\u062F\u06CC\u062F'\"\n [class.ngx-form-m3-en]=\"english\"\n [AutoFocusDirective]=\"autoFocus\"\n [disabled]=\"disabled\"\n (blur)=\"checkValue(input); onFocus.next(false)\"\n (focus)=\"onFocus.next(true)\"\n (keydown.enter)=\"$event.preventDefault(); checkValue(input)\"\n #input\n/>\n", styles: [":host{display:flex;align-items:center}input::placeholder{font-size:85%}\n"] }]
973
+ }], propDecorators: { english: [{
974
+ type: Input,
975
+ args: [{ required: true }]
976
+ }], disabled: [{
977
+ type: Input,
978
+ args: [{ required: true }]
979
+ }], autoFocus: [{
980
+ type: Input,
981
+ args: [{ required: true }]
982
+ }], onFocus: [{
983
+ type: Output
984
+ }], onInput: [{
985
+ type: Output
986
+ }] } });
987
+
988
+ class ListItemComponent {
989
+ value;
990
+ english;
991
+ disabled;
992
+ disableSort;
993
+ onUpdate = new EventEmitter();
994
+ onDelete = new EventEmitter();
995
+ view = 'VALUE';
996
+ checkValue(input) {
997
+ if (this.disabled)
998
+ return;
999
+ const value = input.value.trim();
1000
+ if (value !== '' && value !== this.value)
1001
+ this.onUpdate.next(value);
1002
+ this.view = 'VALUE';
1003
+ }
1004
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: ListItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1005
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type: ListItemComponent, isStandalone: true, selector: "list-item", inputs: { value: "value", english: "english", disabled: "disabled", disableSort: "disableSort" }, outputs: { onUpdate: "onUpdate", onDelete: "onDelete" }, ngImport: i0, template: "<!-- SORT -->\n@if (view === 'VALUE' && !disableSort) {\n<mat-icon class=\"drag\" [class.ngx-form-m3-disabled-input]=\"disabled\" cdkDragHandle>drag_indicator</mat-icon>\n}\n\n<!-- VALUE -->\n@if (view === 'VALUE') {\n<div [class.ngx-form-m3-en]=\"english\" [class.ngx-form-m3-disabled-input]=\"disabled\">\n {{ value }}\n</div>\n\n<button mat-icon-button [type]=\"'button'\" [disabled]=\"disabled\" (click)=\"view = 'UPDATE'\" [tabIndex]=\"-1\">\n <mat-icon>edit</mat-icon>\n</button>\n\n<button mat-icon-button [type]=\"'button'\" [disabled]=\"disabled\" (click)=\"view = 'DELETE'\" [tabIndex]=\"-1\">\n <mat-icon [style.color]=\"'var(--error)'\" [class.ngx-form-m3-disabled-input]=\"disabled\">delete</mat-icon>\n</button>\n}\n\n<!-- UPDATE -->\n@if (view === 'UPDATE') {\n<input\n matInput\n type=\"text\"\n [ngModel]=\"value\"\n [class.ngx-form-m3-en]=\"english\"\n [AutoFocusDirective]=\"true\"\n [disabled]=\"disabled\"\n (blur)=\"checkValue(input)\"\n (keydown.enter)=\"$event.preventDefault(); checkValue(input)\"\n #input\n/>\n\n<button mat-icon-button [type]=\"'button'\" [disabled]=\"disabled\" (click)=\"checkValue(input)\" [tabIndex]=\"-1\">\n <mat-icon>done_all</mat-icon>\n</button>\n\n<button mat-icon-button [type]=\"'button'\" [disabled]=\"disabled\" (click)=\"view = 'VALUE'\" [tabIndex]=\"-1\">\n <mat-icon>close</mat-icon>\n</button>\n}\n\n<!-- DELETE -->\n@if (view === 'DELETE') {\n<div [class.ngx-form-m3-disabled-input]=\"disabled\">\u0645\u06CC\u200C\u062E\u0648\u0627\u0647\u06CC\u062F \u0627\u06CC\u0646 \u06AF\u0632\u06CC\u0646\u0647 \u0631\u0627 \u062D\u0630\u0641 \u06A9\u0646\u06CC\u062F\u061F</div>\n\n<button mat-icon-button [type]=\"'button'\" [disabled]=\"disabled\" (click)=\"onDelete.next(); view = 'VALUE'\" [tabIndex]=\"-1\">\n <mat-icon [style.color]=\"'var(--error)'\" [class.ngx-form-m3-disabled-input]=\"disabled\">done_all</mat-icon>\n</button>\n\n<button mat-icon-button [type]=\"'button'\" [disabled]=\"disabled\" (click)=\"view = 'VALUE'\" [tabIndex]=\"-1\">\n <mat-icon>close</mat-icon>\n</button>\n}\n", styles: [":host{display:flex;align-items:center;direction:rtl;overflow:hidden}:host .drag{cursor:pointer;padding-left:.25rem}:host div{flex:1;width:0;text-align:right;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host button{display:flex;align-items:center;justify-content:center}:host button mat-icon{font-size:70%}\n"], dependencies: [{ kind: "directive", type: CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "directive", type: AutoFocusDirective, selector: "[AutoFocusDirective]", inputs: ["AutoFocusDirective"] }] });
1006
+ }
1007
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: ListItemComponent, decorators: [{
1008
+ type: Component,
1009
+ args: [{ selector: 'list-item', imports: [CdkDragHandle, FormsModule, MatIcon, MatIconButton, MatInput, AutoFocusDirective], template: "<!-- SORT -->\n@if (view === 'VALUE' && !disableSort) {\n<mat-icon class=\"drag\" [class.ngx-form-m3-disabled-input]=\"disabled\" cdkDragHandle>drag_indicator</mat-icon>\n}\n\n<!-- VALUE -->\n@if (view === 'VALUE') {\n<div [class.ngx-form-m3-en]=\"english\" [class.ngx-form-m3-disabled-input]=\"disabled\">\n {{ value }}\n</div>\n\n<button mat-icon-button [type]=\"'button'\" [disabled]=\"disabled\" (click)=\"view = 'UPDATE'\" [tabIndex]=\"-1\">\n <mat-icon>edit</mat-icon>\n</button>\n\n<button mat-icon-button [type]=\"'button'\" [disabled]=\"disabled\" (click)=\"view = 'DELETE'\" [tabIndex]=\"-1\">\n <mat-icon [style.color]=\"'var(--error)'\" [class.ngx-form-m3-disabled-input]=\"disabled\">delete</mat-icon>\n</button>\n}\n\n<!-- UPDATE -->\n@if (view === 'UPDATE') {\n<input\n matInput\n type=\"text\"\n [ngModel]=\"value\"\n [class.ngx-form-m3-en]=\"english\"\n [AutoFocusDirective]=\"true\"\n [disabled]=\"disabled\"\n (blur)=\"checkValue(input)\"\n (keydown.enter)=\"$event.preventDefault(); checkValue(input)\"\n #input\n/>\n\n<button mat-icon-button [type]=\"'button'\" [disabled]=\"disabled\" (click)=\"checkValue(input)\" [tabIndex]=\"-1\">\n <mat-icon>done_all</mat-icon>\n</button>\n\n<button mat-icon-button [type]=\"'button'\" [disabled]=\"disabled\" (click)=\"view = 'VALUE'\" [tabIndex]=\"-1\">\n <mat-icon>close</mat-icon>\n</button>\n}\n\n<!-- DELETE -->\n@if (view === 'DELETE') {\n<div [class.ngx-form-m3-disabled-input]=\"disabled\">\u0645\u06CC\u200C\u062E\u0648\u0627\u0647\u06CC\u062F \u0627\u06CC\u0646 \u06AF\u0632\u06CC\u0646\u0647 \u0631\u0627 \u062D\u0630\u0641 \u06A9\u0646\u06CC\u062F\u061F</div>\n\n<button mat-icon-button [type]=\"'button'\" [disabled]=\"disabled\" (click)=\"onDelete.next(); view = 'VALUE'\" [tabIndex]=\"-1\">\n <mat-icon [style.color]=\"'var(--error)'\" [class.ngx-form-m3-disabled-input]=\"disabled\">done_all</mat-icon>\n</button>\n\n<button mat-icon-button [type]=\"'button'\" [disabled]=\"disabled\" (click)=\"view = 'VALUE'\" [tabIndex]=\"-1\">\n <mat-icon>close</mat-icon>\n</button>\n}\n", styles: [":host{display:flex;align-items:center;direction:rtl;overflow:hidden}:host .drag{cursor:pointer;padding-left:.25rem}:host div{flex:1;width:0;text-align:right;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host button{display:flex;align-items:center;justify-content:center}:host button mat-icon{font-size:70%}\n"] }]
1010
+ }], propDecorators: { value: [{
1011
+ type: Input,
1012
+ args: [{ required: true }]
1013
+ }], english: [{
1014
+ type: Input,
1015
+ args: [{ required: true }]
1016
+ }], disabled: [{
1017
+ type: Input,
1018
+ args: [{ required: true }]
1019
+ }], disableSort: [{
1020
+ type: Input,
1021
+ args: [{ required: true }]
1022
+ }], onUpdate: [{
1023
+ type: Output
1024
+ }], onDelete: [{
1025
+ type: Output
1026
+ }] } });
1027
+
1028
+ class InputItemListComponent {
1029
+ formControl = inject(INPUT_CONTROL);
1030
+ input = inject(INPUT_TYPE);
1031
+ config = inject(INPUT_CONFIG);
1032
+ values;
1033
+ isButtonDisabled;
1034
+ focused = false;
1035
+ options = [];
1036
+ ngOnInit() {
1037
+ this.options = Array.isArray(this.formControl.value) ? this.formControl.value : [];
1038
+ }
1039
+ setValue() {
1040
+ this.formControl.setValue([...this.options]);
1041
+ this.formControl.markAsTouched();
1042
+ }
1043
+ dropOption(event) {
1044
+ if (event.previousIndex === event.currentIndex)
1045
+ return;
1046
+ moveItemInArray(this.options, event.previousIndex, event.currentIndex);
1047
+ this.setValue();
1048
+ }
1049
+ addOption(option) {
1050
+ this.options.push(option);
1051
+ this.setValue();
1052
+ }
1053
+ updateOption(index, option) {
1054
+ if (!this.options[index])
1055
+ return;
1056
+ this.options.splice(index, 1, option);
1057
+ this.setValue();
1058
+ }
1059
+ deleteOption(index) {
1060
+ if (!this.options[index])
1061
+ return;
1062
+ this.options.splice(index, 1);
1063
+ this.setValue();
1064
+ }
1065
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: InputItemListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1066
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type: InputItemListComponent, isStandalone: true, selector: "ng-component", inputs: { values: "values", isButtonDisabled: "isButtonDisabled" }, host: { attributes: { "selector": "input-item-list" } }, ngImport: i0, template: "<mat-form-field [appearance]=\"input.appearance || config.appearance\" [floatLabel]=\"focused ? 'always' : 'auto'\">\n <mat-label>{{ input.title }}</mat-label>\n @if (formControl.invalid) { <mat-error>{{ formControl.errors | InputErrorPipe : input.type }}</mat-error> }\n\n <!-- HINT -->\n @if (input.hint) { <mat-hint>{{ input.hint }}</mat-hint> }\n\n <!-- BUTTON -->\n @if (input.button) {\n <span matIconSuffix>\n <button\n mat-icon-button\n type=\"button\"\n [disabled]=\"isButtonDisabled\"\n (click)=\"input.button.onClick(values)\"\n [tabIndex]=\"-1\"\n >\n <mat-icon [style.color]=\"isButtonDisabled ? undefined : input.button.color\">\n {{ input.button.icon }}\n </mat-icon>\n </button>\n </span>\n }\n\n <input matInput type=\"text\" [name]=\"input.name\" [formControl]=\"formControl\" [style.display]=\"'none !important'\" />\n <!-- OPTIONS -->\n @if (options.length > 0) {\n <div\n class=\"options\"\n cdkDropList\n (cdkDropListDropped)=\"dropOption($event)\"\n [style.border-color]=\"formControl.disabled ? 'var(--outline-variant)' : 'var(--outline)'\"\n >\n @for (item of options; track $index) {\n <list-item\n cdkDrag\n cdkDragLockAxis=\"y\"\n cdkDragBoundary=\".options\"\n [cdkDragDisabled]=\"input.disableSort\"\n class=\"option\"\n [value]=\"item\"\n [english]=\"!!input.english\"\n [disabled]=\"!!formControl.disabled\"\n [disableSort]=\"!!input.disableSort\"\n (onUpdate)=\"updateOption($index, $event)\"\n (onDelete)=\"deleteOption($index)\"\n ></list-item>\n }\n </div>\n }\n <!-- INPUT -->\n <list-input\n [english]=\"!!input.english\"\n [disabled]=\"!!formControl.disabled\"\n [autoFocus]=\"config.autoFocus === input.name\"\n (onFocus)=\"focused = $event\"\n (onInput)=\"addOption($event)\"\n ></list-input>\n\n <!-- DESCRIPTION -->\n @if (input.description) {\n <div\n class=\"ngx-form-m3-input-description\"\n [class.ngx-form-m3-disabled-input]=\"formControl.disabled\"\n [innerHTML]=\"input.description | MultiLinePipe\"\n ></div>\n }\n</mat-form-field>\n", styles: [".options{margin-bottom:5px;border-bottom:1px solid var(--outline)}.options.cdk-drop-list-dragging .option:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.cdk-drag-preview{box-sizing:border-box;background-color:var(--surface-container);box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}\n"], dependencies: [{ kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i1$4.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i1$4.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i2$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "pipe", type: InputErrorPipe, name: "InputErrorPipe" }, { kind: "pipe", type: MultiLinePipe, name: "MultiLinePipe" }, { kind: "component", type: ListInputComponent, selector: "list-input", inputs: ["english", "disabled", "autoFocus"], outputs: ["onFocus", "onInput"] }, { kind: "component", type: ListItemComponent, selector: "list-item", inputs: ["value", "english", "disabled", "disableSort"], outputs: ["onUpdate", "onDelete"] }] });
1067
+ }
1068
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: InputItemListComponent, decorators: [{
1069
+ type: Component,
1070
+ args: [{ host: { selector: 'input-item-list' }, imports: [
1071
+ DragDropModule,
1072
+ ReactiveFormsModule,
1073
+ MatFormField,
1074
+ MatIcon,
1075
+ MatIconButton,
1076
+ MatInputModule,
1077
+ InputErrorPipe,
1078
+ MultiLinePipe,
1079
+ ListInputComponent,
1080
+ ListItemComponent,
1081
+ ], template: "<mat-form-field [appearance]=\"input.appearance || config.appearance\" [floatLabel]=\"focused ? 'always' : 'auto'\">\n <mat-label>{{ input.title }}</mat-label>\n @if (formControl.invalid) { <mat-error>{{ formControl.errors | InputErrorPipe : input.type }}</mat-error> }\n\n <!-- HINT -->\n @if (input.hint) { <mat-hint>{{ input.hint }}</mat-hint> }\n\n <!-- BUTTON -->\n @if (input.button) {\n <span matIconSuffix>\n <button\n mat-icon-button\n type=\"button\"\n [disabled]=\"isButtonDisabled\"\n (click)=\"input.button.onClick(values)\"\n [tabIndex]=\"-1\"\n >\n <mat-icon [style.color]=\"isButtonDisabled ? undefined : input.button.color\">\n {{ input.button.icon }}\n </mat-icon>\n </button>\n </span>\n }\n\n <input matInput type=\"text\" [name]=\"input.name\" [formControl]=\"formControl\" [style.display]=\"'none !important'\" />\n <!-- OPTIONS -->\n @if (options.length > 0) {\n <div\n class=\"options\"\n cdkDropList\n (cdkDropListDropped)=\"dropOption($event)\"\n [style.border-color]=\"formControl.disabled ? 'var(--outline-variant)' : 'var(--outline)'\"\n >\n @for (item of options; track $index) {\n <list-item\n cdkDrag\n cdkDragLockAxis=\"y\"\n cdkDragBoundary=\".options\"\n [cdkDragDisabled]=\"input.disableSort\"\n class=\"option\"\n [value]=\"item\"\n [english]=\"!!input.english\"\n [disabled]=\"!!formControl.disabled\"\n [disableSort]=\"!!input.disableSort\"\n (onUpdate)=\"updateOption($index, $event)\"\n (onDelete)=\"deleteOption($index)\"\n ></list-item>\n }\n </div>\n }\n <!-- INPUT -->\n <list-input\n [english]=\"!!input.english\"\n [disabled]=\"!!formControl.disabled\"\n [autoFocus]=\"config.autoFocus === input.name\"\n (onFocus)=\"focused = $event\"\n (onInput)=\"addOption($event)\"\n ></list-input>\n\n <!-- DESCRIPTION -->\n @if (input.description) {\n <div\n class=\"ngx-form-m3-input-description\"\n [class.ngx-form-m3-disabled-input]=\"formControl.disabled\"\n [innerHTML]=\"input.description | MultiLinePipe\"\n ></div>\n }\n</mat-form-field>\n", styles: [".options{margin-bottom:5px;border-bottom:1px solid var(--outline)}.options.cdk-drop-list-dragging .option:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.cdk-drag-preview{box-sizing:border-box;background-color:var(--surface-container);box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}\n"] }]
1082
+ }], propDecorators: { values: [{
1083
+ type: Input,
1084
+ args: [{ required: true }]
1085
+ }], isButtonDisabled: [{
1086
+ type: Input,
1087
+ args: [{ required: true }]
1088
+ }] } });
1089
+
1090
+ class InputItemListMethods extends InputMethods {
1091
+ control(input, validators) {
1092
+ if (!input.allowDuplicates)
1093
+ validators.push(DuplicateValidator((value) => value));
1094
+ if (input.minCount)
1095
+ validators.push(MinCountValidator(input.minCount));
1096
+ if (input.maxCount)
1097
+ validators.push(MaxCountValidator(input.maxCount));
1098
+ const value = (Array.isArray(input.value) ? input.value : []).filter((value) => Helper.IS.string(value) && value !== '');
1099
+ return new FormControl(value, validators);
1100
+ }
1101
+ value(value, input) {
1102
+ return Array.isArray(value) && value.length > 0 ? value : null;
1103
+ }
1104
+ }
1105
+
941
1106
  class InputMobileComponent {
942
1107
  formControl = inject(INPUT_CONTROL);
943
1108
  input = inject(INPUT_TYPE);
@@ -1262,6 +1427,93 @@ class InputNumberMethods extends InputMethods {
1262
1427
  }
1263
1428
  }
1264
1429
 
1430
+ class InputOptionListComponent {
1431
+ formControl = inject(INPUT_CONTROL);
1432
+ input = inject(INPUT_TYPE);
1433
+ config = inject(INPUT_CONFIG);
1434
+ values;
1435
+ isButtonDisabled;
1436
+ focused = false;
1437
+ options = [];
1438
+ ngOnInit() {
1439
+ this.options = Array.isArray(this.formControl.value) ? this.formControl.value : [];
1440
+ }
1441
+ setValue() {
1442
+ this.formControl.setValue([...this.options]);
1443
+ this.formControl.markAsTouched();
1444
+ }
1445
+ dropOption(event) {
1446
+ if (event.previousIndex === event.currentIndex)
1447
+ return;
1448
+ moveItemInArray(this.options, event.previousIndex, event.currentIndex);
1449
+ this.setValue();
1450
+ }
1451
+ addOption(title) {
1452
+ this.options.push({ id: null, title });
1453
+ this.setValue();
1454
+ }
1455
+ updateOption(index, title) {
1456
+ if (!this.options[index])
1457
+ return;
1458
+ const option = { id: this.options[index].id, title };
1459
+ this.options.splice(index, 1, option);
1460
+ this.setValue();
1461
+ }
1462
+ deleteOption(index) {
1463
+ if (!this.options[index])
1464
+ return;
1465
+ this.options.splice(index, 1);
1466
+ this.setValue();
1467
+ }
1468
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: InputOptionListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1469
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type: InputOptionListComponent, isStandalone: true, selector: "ng-component", inputs: { values: "values", isButtonDisabled: "isButtonDisabled" }, host: { attributes: { "selector": "input-option-list" } }, ngImport: i0, template: "<mat-form-field [appearance]=\"input.appearance || config.appearance\" [floatLabel]=\"focused ? 'always' : 'auto'\">\n <mat-label>{{ input.title }}</mat-label>\n @if (formControl.invalid) { <mat-error>{{ formControl.errors | InputErrorPipe : input.type }}</mat-error> }\n\n <!-- HINT -->\n @if (input.hint) { <mat-hint>{{ input.hint }}</mat-hint> }\n\n <!-- BUTTON -->\n @if (input.button) {\n <span matIconSuffix>\n <button\n mat-icon-button\n type=\"button\"\n [disabled]=\"isButtonDisabled\"\n (click)=\"input.button.onClick(values)\"\n [tabIndex]=\"-1\"\n >\n <mat-icon [style.color]=\"isButtonDisabled ? undefined : input.button.color\">\n {{ input.button.icon }}\n </mat-icon>\n </button>\n </span>\n }\n\n <input matInput type=\"text\" [name]=\"input.name\" [formControl]=\"formControl\" [style.display]=\"'none !important'\" />\n <!-- OPTIONS -->\n @if (options.length > 0) {\n <div\n class=\"options\"\n cdkDropList\n (cdkDropListDropped)=\"dropOption($event)\"\n [style.border-color]=\"formControl.disabled ? 'var(--outline-variant)' : 'var(--outline)'\"\n >\n @for (item of options; track $index) {\n <list-item\n cdkDrag\n cdkDragLockAxis=\"y\"\n cdkDragBoundary=\".options\"\n [cdkDragDisabled]=\"input.disableSort\"\n class=\"option\"\n [value]=\"item.title\"\n [english]=\"!!input.english\"\n [disabled]=\"!!formControl.disabled\"\n [disableSort]=\"!!input.disableSort\"\n (onUpdate)=\"updateOption($index, $event)\"\n (onDelete)=\"deleteOption($index)\"\n ></list-item>\n }\n </div>\n }\n <!-- INPUT -->\n <list-input\n [english]=\"!!input.english\"\n [disabled]=\"!!formControl.disabled\"\n [autoFocus]=\"config.autoFocus === input.name\"\n (onFocus)=\"focused = $event\"\n (onInput)=\"addOption($event)\"\n ></list-input>\n\n <!-- DESCRIPTION -->\n @if (input.description) {\n <div\n class=\"ngx-form-m3-input-description\"\n [class.ngx-form-m3-disabled-input]=\"formControl.disabled\"\n [innerHTML]=\"input.description | MultiLinePipe\"\n ></div>\n }\n</mat-form-field>\n", styles: [".options{margin-bottom:5px;border-bottom:1px solid var(--outline)}.options.cdk-drop-list-dragging .option:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.cdk-drag-preview{box-sizing:border-box;background-color:var(--surface-container);box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}\n"], dependencies: [{ kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i1$4.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i1$4.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i2$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "pipe", type: InputErrorPipe, name: "InputErrorPipe" }, { kind: "pipe", type: MultiLinePipe, name: "MultiLinePipe" }, { kind: "component", type: ListInputComponent, selector: "list-input", inputs: ["english", "disabled", "autoFocus"], outputs: ["onFocus", "onInput"] }, { kind: "component", type: ListItemComponent, selector: "list-item", inputs: ["value", "english", "disabled", "disableSort"], outputs: ["onUpdate", "onDelete"] }] });
1470
+ }
1471
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: InputOptionListComponent, decorators: [{
1472
+ type: Component,
1473
+ args: [{ host: { selector: 'input-option-list' }, imports: [
1474
+ DragDropModule,
1475
+ ReactiveFormsModule,
1476
+ MatFormField,
1477
+ MatIcon,
1478
+ MatIconButton,
1479
+ MatInputModule,
1480
+ InputErrorPipe,
1481
+ MultiLinePipe,
1482
+ ListInputComponent,
1483
+ ListItemComponent,
1484
+ ], template: "<mat-form-field [appearance]=\"input.appearance || config.appearance\" [floatLabel]=\"focused ? 'always' : 'auto'\">\n <mat-label>{{ input.title }}</mat-label>\n @if (formControl.invalid) { <mat-error>{{ formControl.errors | InputErrorPipe : input.type }}</mat-error> }\n\n <!-- HINT -->\n @if (input.hint) { <mat-hint>{{ input.hint }}</mat-hint> }\n\n <!-- BUTTON -->\n @if (input.button) {\n <span matIconSuffix>\n <button\n mat-icon-button\n type=\"button\"\n [disabled]=\"isButtonDisabled\"\n (click)=\"input.button.onClick(values)\"\n [tabIndex]=\"-1\"\n >\n <mat-icon [style.color]=\"isButtonDisabled ? undefined : input.button.color\">\n {{ input.button.icon }}\n </mat-icon>\n </button>\n </span>\n }\n\n <input matInput type=\"text\" [name]=\"input.name\" [formControl]=\"formControl\" [style.display]=\"'none !important'\" />\n <!-- OPTIONS -->\n @if (options.length > 0) {\n <div\n class=\"options\"\n cdkDropList\n (cdkDropListDropped)=\"dropOption($event)\"\n [style.border-color]=\"formControl.disabled ? 'var(--outline-variant)' : 'var(--outline)'\"\n >\n @for (item of options; track $index) {\n <list-item\n cdkDrag\n cdkDragLockAxis=\"y\"\n cdkDragBoundary=\".options\"\n [cdkDragDisabled]=\"input.disableSort\"\n class=\"option\"\n [value]=\"item.title\"\n [english]=\"!!input.english\"\n [disabled]=\"!!formControl.disabled\"\n [disableSort]=\"!!input.disableSort\"\n (onUpdate)=\"updateOption($index, $event)\"\n (onDelete)=\"deleteOption($index)\"\n ></list-item>\n }\n </div>\n }\n <!-- INPUT -->\n <list-input\n [english]=\"!!input.english\"\n [disabled]=\"!!formControl.disabled\"\n [autoFocus]=\"config.autoFocus === input.name\"\n (onFocus)=\"focused = $event\"\n (onInput)=\"addOption($event)\"\n ></list-input>\n\n <!-- DESCRIPTION -->\n @if (input.description) {\n <div\n class=\"ngx-form-m3-input-description\"\n [class.ngx-form-m3-disabled-input]=\"formControl.disabled\"\n [innerHTML]=\"input.description | MultiLinePipe\"\n ></div>\n }\n</mat-form-field>\n", styles: [".options{margin-bottom:5px;border-bottom:1px solid var(--outline)}.options.cdk-drop-list-dragging .option:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.cdk-drag-preview{box-sizing:border-box;background-color:var(--surface-container);box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}\n"] }]
1485
+ }], propDecorators: { values: [{
1486
+ type: Input,
1487
+ args: [{ required: true }]
1488
+ }], isButtonDisabled: [{
1489
+ type: Input,
1490
+ args: [{ required: true }]
1491
+ }] } });
1492
+
1493
+ class InputOptionListMethods extends InputMethods {
1494
+ control(input, validators) {
1495
+ if (!input.allowDuplicates)
1496
+ validators.push(DuplicateValidator((value) => value.title));
1497
+ if (input.minCount)
1498
+ validators.push(MinCountValidator(input.minCount));
1499
+ if (input.maxCount)
1500
+ validators.push(MaxCountValidator(input.maxCount));
1501
+ const value = (Array.isArray(input.value) ? input.value : []).filter((value) => {
1502
+ if (!Helper.IS.object(value))
1503
+ return false;
1504
+ if (value.id !== null && (!Helper.IS.string(value.id) || value.id.length === 0))
1505
+ return false;
1506
+ if (!Helper.IS.string(value.title) || value.title.length === 0)
1507
+ return false;
1508
+ return true;
1509
+ });
1510
+ return new FormControl(value, validators);
1511
+ }
1512
+ value(value, input) {
1513
+ return Array.isArray(value) && value.length > 0 ? value : null;
1514
+ }
1515
+ }
1516
+
1265
1517
  class InputPasswordComponent {
1266
1518
  formControl = inject(INPUT_CONTROL);
1267
1519
  input = inject(INPUT_TYPE);
@@ -1379,6 +1631,75 @@ class InputPriceMethods extends InputMethods {
1379
1631
  }
1380
1632
  }
1381
1633
 
1634
+ class InputRouteComponent {
1635
+ ngxHelperRouteService;
1636
+ formControl = inject(INPUT_CONTROL);
1637
+ input = inject(INPUT_TYPE);
1638
+ config = inject(INPUT_CONFIG);
1639
+ values;
1640
+ isButtonDisabled;
1641
+ route = this.formControl.value || [];
1642
+ distance = Helper.GEO.routeLength(this.route);
1643
+ constructor(ngxHelperRouteService) {
1644
+ this.ngxHelperRouteService = ngxHelperRouteService;
1645
+ }
1646
+ setRoute() {
1647
+ if (this.formControl.disabled)
1648
+ return;
1649
+ const get = this.route.length > 0
1650
+ ? this.ngxHelperRouteService.get(this.route, { view: this.input.center, zoom: this.input.zoom })
1651
+ : this.ngxHelperRouteService.get({ view: this.input.center, zoom: this.input.zoom });
1652
+ get.then((route) => {
1653
+ this.route = route;
1654
+ this.formControl.setValue(route);
1655
+ this.formControl.markAsTouched();
1656
+ this.distance = Helper.GEO.routeLength(this.route);
1657
+ }, () => this.formControl.markAsTouched());
1658
+ }
1659
+ resetRoute() {
1660
+ if (this.formControl.disabled)
1661
+ return;
1662
+ this.route = [];
1663
+ this.formControl.setValue(null);
1664
+ this.formControl.markAsTouched();
1665
+ }
1666
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: InputRouteComponent, deps: [{ token: i1$2.NgxHelperRouteService }], target: i0.ɵɵFactoryTarget.Component });
1667
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type: InputRouteComponent, isStandalone: true, selector: "ng-component", inputs: { values: "values", isButtonDisabled: "isButtonDisabled" }, host: { attributes: { "selector": "input-route" } }, ngImport: i0, template: "<mat-form-field [appearance]=\"input.appearance || config.appearance\" [floatLabel]=\"route.length > 0 ? 'always' : 'auto'\">\n <mat-label>{{ input.title || '\u0645\u0633\u06CC\u0631' }}</mat-label>\n @if (formControl.invalid) { <mat-error>{{ formControl.errors | InputErrorPipe : input.type }}</mat-error> }\n\n <!-- HINT -->\n @if (input.hint) { <mat-hint>{{ input.hint }}</mat-hint> }\n\n <!-- SUFFIX -->\n <span matTextSuffix class=\"ngx-form-m3-input-suffix click\" [class.ngx-form-m3-disabled-input]=\"formControl.disabled\">\n <span>&nbsp;</span>\n <mat-icon (click)=\"route.length > 0 ? resetRoute() : setRoute(); formControl.markAsTouched()\">\n {{ route.length > 0 ? 'close' : 'call_split' }}\n </mat-icon>\n </span>\n\n <!-- BUTTON -->\n @if (input.button) {\n <span matIconSuffix>\n <button\n mat-icon-button\n type=\"button\"\n [disabled]=\"isButtonDisabled\"\n (click)=\"input.button.onClick(values)\"\n [tabIndex]=\"-1\"\n >\n <mat-icon [style.color]=\"isButtonDisabled ? undefined : input.button.color\">\n {{ input.button.icon }}\n </mat-icon>\n </button>\n </span>\n }\n\n <!-- INPUT -->\n <input matInput type=\"text\" [name]=\"input.name\" [formControl]=\"formControl\" [style.display]=\"'none !important'\" />\n <div\n class=\"ngx-helper-form-m3-route-input\"\n [class.ngx-form-m3-disabled-input]=\"formControl.disabled\"\n (click)=\"setRoute()\"\n >\n <div class=\"distance\">{{ route.length > 0 ? (distance.length | ngxHelperNumber) + ' \u0645\u062A\u0631' : '&nbsp;' }}</div>\n <div class=\"point\">{{ route.length > 0 ? (route.length | ngxHelperNumber) + ' \u0646\u0642\u0637\u0647' : '&nbsp;' }}</div>\n </div>\n\n <!-- DESCRIPTION -->\n @if (input.description) {\n <div\n class=\"ngx-form-m3-input-description\"\n [class.ngx-form-m3-disabled-input]=\"formControl.disabled\"\n [innerHTML]=\"input.description | MultiLinePipe\"\n ></div>\n }\n</mat-form-field>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i2$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "pipe", type: NgxHelperNumberPipe, name: "ngxHelperNumber" }, { kind: "pipe", type: InputErrorPipe, name: "InputErrorPipe" }, { kind: "pipe", type: MultiLinePipe, name: "MultiLinePipe" }] });
1668
+ }
1669
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: InputRouteComponent, decorators: [{
1670
+ type: Component,
1671
+ args: [{ host: { selector: 'input-route' }, imports: [
1672
+ ReactiveFormsModule,
1673
+ MatFormField,
1674
+ MatIcon,
1675
+ MatIconButton,
1676
+ MatInputModule,
1677
+ NgxHelperNumberPipe,
1678
+ InputErrorPipe,
1679
+ MultiLinePipe,
1680
+ ], template: "<mat-form-field [appearance]=\"input.appearance || config.appearance\" [floatLabel]=\"route.length > 0 ? 'always' : 'auto'\">\n <mat-label>{{ input.title || '\u0645\u0633\u06CC\u0631' }}</mat-label>\n @if (formControl.invalid) { <mat-error>{{ formControl.errors | InputErrorPipe : input.type }}</mat-error> }\n\n <!-- HINT -->\n @if (input.hint) { <mat-hint>{{ input.hint }}</mat-hint> }\n\n <!-- SUFFIX -->\n <span matTextSuffix class=\"ngx-form-m3-input-suffix click\" [class.ngx-form-m3-disabled-input]=\"formControl.disabled\">\n <span>&nbsp;</span>\n <mat-icon (click)=\"route.length > 0 ? resetRoute() : setRoute(); formControl.markAsTouched()\">\n {{ route.length > 0 ? 'close' : 'call_split' }}\n </mat-icon>\n </span>\n\n <!-- BUTTON -->\n @if (input.button) {\n <span matIconSuffix>\n <button\n mat-icon-button\n type=\"button\"\n [disabled]=\"isButtonDisabled\"\n (click)=\"input.button.onClick(values)\"\n [tabIndex]=\"-1\"\n >\n <mat-icon [style.color]=\"isButtonDisabled ? undefined : input.button.color\">\n {{ input.button.icon }}\n </mat-icon>\n </button>\n </span>\n }\n\n <!-- INPUT -->\n <input matInput type=\"text\" [name]=\"input.name\" [formControl]=\"formControl\" [style.display]=\"'none !important'\" />\n <div\n class=\"ngx-helper-form-m3-route-input\"\n [class.ngx-form-m3-disabled-input]=\"formControl.disabled\"\n (click)=\"setRoute()\"\n >\n <div class=\"distance\">{{ route.length > 0 ? (distance.length | ngxHelperNumber) + ' \u0645\u062A\u0631' : '&nbsp;' }}</div>\n <div class=\"point\">{{ route.length > 0 ? (route.length | ngxHelperNumber) + ' \u0646\u0642\u0637\u0647' : '&nbsp;' }}</div>\n </div>\n\n <!-- DESCRIPTION -->\n @if (input.description) {\n <div\n class=\"ngx-form-m3-input-description\"\n [class.ngx-form-m3-disabled-input]=\"formControl.disabled\"\n [innerHTML]=\"input.description | MultiLinePipe\"\n ></div>\n }\n</mat-form-field>\n" }]
1681
+ }], ctorParameters: () => [{ type: i1$2.NgxHelperRouteService }], propDecorators: { values: [{
1682
+ type: Input,
1683
+ args: [{ required: true }]
1684
+ }], isButtonDisabled: [{
1685
+ type: Input,
1686
+ args: [{ required: true }]
1687
+ }] } });
1688
+
1689
+ class InputRouteMethods extends InputMethods {
1690
+ control(input, validators) {
1691
+ const value = input.value && Helper.IS.array(input.value)
1692
+ ? input.value.filter((coordinates) => Helper.IS.object(coordinates) &&
1693
+ Helper.IS.number(coordinates.latitude) &&
1694
+ Helper.IS.number(coordinates.longitude))
1695
+ : [];
1696
+ return new FormControl(value.length > 1 ? value : [], validators);
1697
+ }
1698
+ value(value, input) {
1699
+ return Helper.IS.array(value) && value.length > 0 ? value : null;
1700
+ }
1701
+ }
1702
+
1382
1703
  class InputSelectComponent {
1383
1704
  formControl = inject(INPUT_CONTROL);
1384
1705
  input = inject(INPUT_TYPE);
@@ -1625,13 +1946,16 @@ const InputInfo = {
1625
1946
  FILE: { title: 'فایل', methods: new InputFileMethods(), component: InputFileComponent },
1626
1947
  ICON: { title: 'آیکون', methods: new InputIconMethods(), component: InputIconComponent },
1627
1948
  IP: { title: 'آدرس آی‌پی', methods: new InputIpMethods(), component: InputIpComponent },
1949
+ 'ITEM-LIST': { title: 'لیست مقادیر', methods: new InputItemListMethods(), component: InputItemListComponent },
1628
1950
  MOBILE: { title: 'موبایل', methods: new InputMobileMethods(), component: InputMobileComponent },
1629
1951
  MOMENT: { title: 'زمان', methods: new InputMomentMethods(), component: InputMomentComponent },
1630
1952
  'MULTI-SELECT': { title: 'چند انتخابی', methods: new InputMultiSelectMethods(), component: InputMultiSelectComponent },
1631
1953
  NAME: { title: 'نام و نام خانوادگی', methods: new InputNameMethods(), component: InputNameComponent },
1632
1954
  NUMBER: { title: 'مقدار عددی', methods: new InputNumberMethods(), component: InputNumberComponent },
1955
+ 'OPTION-LIST': { title: 'لیست گزینه‌ها', methods: new InputOptionListMethods(), component: InputOptionListComponent },
1633
1956
  PASSWORD: { title: 'کلمه عبور', methods: new InputPasswordMethods(), component: InputPasswordComponent },
1634
1957
  PRICE: { title: 'قیمت', methods: new InputPriceMethods(), component: InputPriceComponent },
1958
+ ROUTE: { title: 'مسیر', methods: new InputRouteMethods(), component: InputRouteComponent },
1635
1959
  SELECT: { title: 'لیست کشویی', methods: new InputSelectMethods(), component: InputSelectComponent },
1636
1960
  TEXT: { title: 'متن یک خطی', methods: new InputTextMethods(), component: InputTextComponent },
1637
1961
  TEXTAREA: { title: 'متن چند خطی', methods: new InputTextareaMethods(), component: InputTextareaComponent },
@@ -1683,6 +2007,9 @@ class NgxFormComponent {
1683
2007
  appearance: this.ngxForm.appearance || this.config?.appearance || 'fill',
1684
2008
  autoFocus,
1685
2009
  };
2010
+ // UPDATE VALUES
2011
+ if (this.ngxForm.updateValues)
2012
+ this.updateValues([]);
1686
2013
  // REGISTER VALUE CHANGE
1687
2014
  this.formGroup.valueChanges.subscribe({
1688
2015
  next: () => {
@@ -1698,20 +2025,7 @@ class NgxFormComponent {
1698
2025
  this.lastValues = { ...this.formGroup.value };
1699
2026
  this.checkInputs();
1700
2027
  if (this.ngxForm.updateValues) {
1701
- const values = this.getValues();
1702
- const changes = this.ngxForm.updateValues(values);
1703
- Object.keys(changes)
1704
- .filter((key) => !changedInputs.includes(key))
1705
- .forEach((key) => {
1706
- const input = this.getInputs().find((i) => i.name === key);
1707
- if (!input)
1708
- return;
1709
- const formInput = this.formGroup.get(key);
1710
- if (!formInput)
1711
- return;
1712
- const value = InputInfo[input.type].methods.value(changes[key], input);
1713
- formInput.setValue(value);
1714
- });
2028
+ this.updateValues(changedInputs);
1715
2029
  this.lastValues = { ...this.formGroup.value };
1716
2030
  }
1717
2031
  this.values = this.getValues();
@@ -1827,10 +2141,33 @@ class NgxFormComponent {
1827
2141
  });
1828
2142
  return values;
1829
2143
  }
2144
+ updateValues(changedInputs) {
2145
+ if (!this.ngxForm.updateValues)
2146
+ return;
2147
+ const values = this.getValues();
2148
+ const changes = this.ngxForm.updateValues(values);
2149
+ Object.keys(changes)
2150
+ .filter((key) => !changedInputs.includes(key))
2151
+ .forEach((key) => {
2152
+ const input = this.getInputs().find((i) => i.name === key);
2153
+ if (!input)
2154
+ return;
2155
+ const formInput = this.formGroup.get(key);
2156
+ if (!formInput)
2157
+ return;
2158
+ const value = InputInfo[input.type].methods.value(changes[key], input);
2159
+ formInput.setValue(value);
2160
+ });
2161
+ }
1830
2162
  setInput(input) {
1831
2163
  const name = input.name;
1832
2164
  const readonly = 'readonly' in input && !!input.readonly;
1833
- const validators = input.type === 'CHECKBOX' || input.type === 'MULTI-SELECT' || input.optional || readonly
2165
+ const validators = input.type === 'CHECKBOX' ||
2166
+ input.type === 'ITEM-LIST' ||
2167
+ input.type === 'MULTI-SELECT' ||
2168
+ input.type === 'OPTION-LIST' ||
2169
+ input.optional ||
2170
+ readonly
1834
2171
  ? []
1835
2172
  : [Validators.required];
1836
2173
  this.formGroup.setControl(name, InputInfo[input.type].methods.control(input, validators));
@@ -1910,13 +2247,13 @@ class NgxFormComponent {
1910
2247
  else
1911
2248
  this.router.navigate(action);
1912
2249
  }
1913
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: NgxFormComponent, deps: [{ token: i1$4.Router }, { token: NGX_FORM_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Component });
2250
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: NgxFormComponent, deps: [{ token: i1$5.Router }, { token: NGX_FORM_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Component });
1914
2251
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type: NgxFormComponent, isStandalone: true, selector: "ngx-form", inputs: { ngxForm: "ngxForm" }, outputs: { onInit: "onInit", onSubmit: "onSubmit", onChange: "onChange" }, host: { listeners: { "window:resize": "onResize($event)" } }, viewQueries: [{ propertyName: "ngForm", first: true, predicate: ["formObject"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<form [formGroup]=\"formGroup\" (ngSubmit)=\"checkSubmit()\" dir=\"rtl\" class=\"ngx-form\" #formObject=\"ngForm\">\n <section class=\"sections\">\n @for (section of sections; track $index) {\n <!-- CHECK SECTION VIEW -->\n @if (showSection(section)) {\n <!-- SECTION HEADER -->\n @if (section.header) {\n <div class=\"ngx-form-m3-header section-header\">{{ section.header }}</div>\n }\n\n <div class=\"section\" [class.section-mobile]=\"isMobile\">\n <!-- SECTIONS -->\n @for (column of section.columns; track $index) {\n <!-- CHECK COLUMN VIEW -->\n @if (showColumn(column)) {\n <div class=\"column\" [style.flex]=\"section.flex[$index]\">\n <!-- COLUMN HEADER -->\n @if (column.header) {\n <div class=\"ngx-form-m3-header column-header\">{{ column.header }}</div>\n }\n\n <!-- ROWS -->\n @for (row of column.rows; track $index) {\n <!-- CHECK Row VIEW -->\n @if (showRow(row)) {\n <!-- ROW HEADER -->\n @if (row.header) {\n <div class=\"ngx-form-m3-header row-header\">{{ row.header }}</div>\n }\n\n <div class=\"inputs\">\n <!-- INPUTS -->\n @for (input of row.inputs; track $index) {\n <!-- CHECK Row VIEW -->\n @if (showInput(input)) {\n <div class=\"input\" [style.flex]=\"row.flex[$index]\">\n <form-input\n [formGroup]=\"formGroup\"\n [input]=\"input\"\n [config]=\"inputConfig\"\n [values]=\"values\"\n ></form-input>\n </div>\n } }\n </div>\n } }\n </div>\n } }\n </div>\n } }\n </section>\n\n <section class=\"ngx-form-m3-form-buttons\" [class.mobile-view]=\"isMobile\">\n <!-- EXTRA BUTTONS -->\n @for (item of (ngxForm.buttons || []); track $index) {\n <button type=\"button\" mat-stroked-button (click)=\"onClick(item.action)\">{{ item.title }}</button>\n }\n <!-- SUBMIT BUTTON -->\n <button type=\"submit\" mat-flat-button>{{ ngxForm.submit }}</button>\n </section>\n</form>\n", styles: [".sections{display:flex;flex-direction:column}.sections .column-header,.sections .section-header{margin-bottom:1rem}.sections .row-header{margin:1rem 0}.sections .section,.sections .section .column .inputs{display:flex;align-items:flex-start;column-gap:1rem}.sections .section-mobile{display:block}:host ::ng-deep mat-form-field{width:100%;margin-bottom:.5rem}:host ::ng-deep .mat-mdc-form-field-infix{width:100%!important}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: InputComponent, selector: "form-input", inputs: ["formGroup", "input", "config", "values"] }, { kind: "directive", type: FormErrorDirective, selector: "form.ngx-form" }] });
1915
2252
  }
1916
2253
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: NgxFormComponent, decorators: [{
1917
2254
  type: Component,
1918
2255
  args: [{ selector: 'ngx-form', imports: [ReactiveFormsModule, MatButton, InputComponent, FormErrorDirective], template: "<form [formGroup]=\"formGroup\" (ngSubmit)=\"checkSubmit()\" dir=\"rtl\" class=\"ngx-form\" #formObject=\"ngForm\">\n <section class=\"sections\">\n @for (section of sections; track $index) {\n <!-- CHECK SECTION VIEW -->\n @if (showSection(section)) {\n <!-- SECTION HEADER -->\n @if (section.header) {\n <div class=\"ngx-form-m3-header section-header\">{{ section.header }}</div>\n }\n\n <div class=\"section\" [class.section-mobile]=\"isMobile\">\n <!-- SECTIONS -->\n @for (column of section.columns; track $index) {\n <!-- CHECK COLUMN VIEW -->\n @if (showColumn(column)) {\n <div class=\"column\" [style.flex]=\"section.flex[$index]\">\n <!-- COLUMN HEADER -->\n @if (column.header) {\n <div class=\"ngx-form-m3-header column-header\">{{ column.header }}</div>\n }\n\n <!-- ROWS -->\n @for (row of column.rows; track $index) {\n <!-- CHECK Row VIEW -->\n @if (showRow(row)) {\n <!-- ROW HEADER -->\n @if (row.header) {\n <div class=\"ngx-form-m3-header row-header\">{{ row.header }}</div>\n }\n\n <div class=\"inputs\">\n <!-- INPUTS -->\n @for (input of row.inputs; track $index) {\n <!-- CHECK Row VIEW -->\n @if (showInput(input)) {\n <div class=\"input\" [style.flex]=\"row.flex[$index]\">\n <form-input\n [formGroup]=\"formGroup\"\n [input]=\"input\"\n [config]=\"inputConfig\"\n [values]=\"values\"\n ></form-input>\n </div>\n } }\n </div>\n } }\n </div>\n } }\n </div>\n } }\n </section>\n\n <section class=\"ngx-form-m3-form-buttons\" [class.mobile-view]=\"isMobile\">\n <!-- EXTRA BUTTONS -->\n @for (item of (ngxForm.buttons || []); track $index) {\n <button type=\"button\" mat-stroked-button (click)=\"onClick(item.action)\">{{ item.title }}</button>\n }\n <!-- SUBMIT BUTTON -->\n <button type=\"submit\" mat-flat-button>{{ ngxForm.submit }}</button>\n </section>\n</form>\n", styles: [".sections{display:flex;flex-direction:column}.sections .column-header,.sections .section-header{margin-bottom:1rem}.sections .row-header{margin:1rem 0}.sections .section,.sections .section .column .inputs{display:flex;align-items:flex-start;column-gap:1rem}.sections .section-mobile{display:block}:host ::ng-deep mat-form-field{width:100%;margin-bottom:.5rem}:host ::ng-deep .mat-mdc-form-field-infix{width:100%!important}\n"] }]
1919
- }], ctorParameters: () => [{ type: i1$4.Router }, { type: undefined, decorators: [{
2256
+ }], ctorParameters: () => [{ type: i1$5.Router }, { type: undefined, decorators: [{
1920
2257
  type: Optional
1921
2258
  }, {
1922
2259
  type: Inject,