@abp/ng.components 10.5.0 → 10.6.0-rc.1

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,13 +1,13 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, Injectable, InjectionToken, forwardRef, input, ChangeDetectorRef, DestroyRef, Injector, ChangeDetectionStrategy, Component, viewChild, ViewContainerRef, effect, output } from '@angular/core';
2
+ import { inject, Injectable, InjectionToken, forwardRef, input, DestroyRef, Injector, signal, computed, ChangeDetectionStrategy, Component, viewChild, ViewContainerRef, effect, output } from '@angular/core';
3
3
  import * as i2 from '@angular/forms';
4
4
  import { FormBuilder, FormControl, Validators, NG_VALUE_ACCESSOR, NgControl, FormGroupDirective, ReactiveFormsModule } from '@angular/forms';
5
5
  import * as i1 from '@angular/common';
6
6
  import { NgTemplateOutlet, AsyncPipe, CommonModule } from '@angular/common';
7
7
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
8
8
  import { RestService, LocalizationPipe } from '@abp/ng.core';
9
+ import { of, merge } from 'rxjs';
9
10
  import { FormCheckboxComponent } from '@abp/ng.theme.shared';
10
- import { of } from 'rxjs';
11
11
 
12
12
  class DynamicFormService {
13
13
  constructor() {
@@ -109,10 +109,10 @@ class DynamicFormService {
109
109
  return '';
110
110
  }
111
111
  }
112
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: DynamicFormService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
113
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: DynamicFormService, providedIn: 'root' }); }
112
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: DynamicFormService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
113
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: DynamicFormService, providedIn: 'root' }); }
114
114
  }
115
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: DynamicFormService, decorators: [{
115
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: DynamicFormService, decorators: [{
116
116
  type: Injectable,
117
117
  args: [{
118
118
  providedIn: 'root'
@@ -145,14 +145,52 @@ class DynamicFormFieldComponent {
145
145
  return `${this.fieldId}-help`;
146
146
  }
147
147
  constructor() {
148
- this.field = input.required(...(ngDevMode ? [{ debugName: "field" }] : /* istanbul ignore next */ []));
149
- this.visible = input(true, ...(ngDevMode ? [{ debugName: "visible" }] : /* istanbul ignore next */ []));
150
- this.changeDetectorRef = inject(ChangeDetectorRef);
148
+ this.field = input.required(/* @ts-ignore */
149
+ ...(ngDevMode ? [{ debugName: "field" }] : /* istanbul ignore next */ []));
150
+ this.visible = input(true, /* @ts-ignore */
151
+ ...(ngDevMode ? [{ debugName: "visible" }] : /* istanbul ignore next */ []));
151
152
  this.destroyRef = inject(DestroyRef);
152
153
  this.injector = inject(Injector);
153
154
  this.formBuilder = inject(FormBuilder);
154
155
  this.dynamicFormService = inject(DynamicFormService);
156
+ this.controlStateTick = signal(0, /* @ts-ignore */
157
+ ...(ngDevMode ? [{ debugName: "controlStateTick" }] : /* istanbul ignore next */ []));
155
158
  this.options$ = of([]);
159
+ this.isInvalid = computed(() => {
160
+ this.controlStateTick();
161
+ if (this.control) {
162
+ return this.control.invalid && (this.control.dirty || this.control.touched);
163
+ }
164
+ return false;
165
+ }, /* @ts-ignore */
166
+ ...(ngDevMode ? [{ debugName: "isInvalid" }] : /* istanbul ignore next */ []));
167
+ this.errors = computed(() => {
168
+ this.controlStateTick();
169
+ if (!this.control?.errors)
170
+ return [];
171
+ if (this.control && this.control.errors) {
172
+ const errorKeys = Object.keys(this.control.errors);
173
+ const validators = this.field().validators || [];
174
+ return errorKeys.map(key => {
175
+ const validator = validators.find(v => v.type.toLowerCase() === key.toLowerCase());
176
+ if (validator && validator.message) {
177
+ return validator.message;
178
+ }
179
+ // Fallback error messages
180
+ if (key === 'required')
181
+ return `${this.field().label} is required`;
182
+ if (key === 'email')
183
+ return 'Please enter a valid email address';
184
+ if (key === 'minlength')
185
+ return `Minimum length is ${this.control.errors[key].requiredLength}`;
186
+ if (key === 'maxlength')
187
+ return `Maximum length is ${this.control.errors[key].requiredLength}`;
188
+ return `${this.field().label} is invalid due to ${key} validation.`;
189
+ });
190
+ }
191
+ return [];
192
+ }, /* @ts-ignore */
193
+ ...(ngDevMode ? [{ debugName: "errors" }] : /* istanbul ignore next */ []));
156
194
  this.onChange = () => { };
157
195
  this.onTouched = () => { };
158
196
  this.fieldFormGroup = this.formBuilder.group({
@@ -163,6 +201,9 @@ class DynamicFormFieldComponent {
163
201
  const ngControl = this.injector.get(NgControl, null);
164
202
  if (ngControl) {
165
203
  this.control = this.injector.get(FormGroupDirective).getControl(ngControl);
204
+ merge(this.control.statusChanges, this.control.valueChanges)
205
+ .pipe(takeUntilDestroyed(this.destroyRef))
206
+ .subscribe(() => this.controlStateTick.update(tick => tick + 1));
166
207
  }
167
208
  this.value.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(value => {
168
209
  this.onChange(value);
@@ -175,7 +216,7 @@ class DynamicFormFieldComponent {
175
216
  this.options$ = of(options.defaultValues.map(item => {
176
217
  return {
177
218
  key: item[options.valueProp || 'key'] || item,
178
- value: item[options.labelProp || 'value'] || item
219
+ value: item[options.labelProp || 'value'] || item,
179
220
  };
180
221
  }));
181
222
  }
@@ -185,7 +226,6 @@ class DynamicFormFieldComponent {
185
226
  }
186
227
  writeValue(value) {
187
228
  this.value.setValue(value || '');
188
- this.changeDetectorRef.markForCheck();
189
229
  }
190
230
  registerOnChange(fn) {
191
231
  this.onChange = fn;
@@ -200,38 +240,6 @@ class DynamicFormFieldComponent {
200
240
  else {
201
241
  this.value.enable();
202
242
  }
203
- this.changeDetectorRef.markForCheck();
204
- }
205
- get isInvalid() {
206
- if (this.control) {
207
- return this.control.invalid && (this.control.dirty || this.control.touched);
208
- }
209
- return false;
210
- }
211
- get errors() {
212
- if (!this.control?.errors)
213
- return [];
214
- if (this.control && this.control.errors) {
215
- const errorKeys = Object.keys(this.control.errors);
216
- const validators = this.field().validators || [];
217
- return errorKeys.map(key => {
218
- const validator = validators.find(v => v.type.toLowerCase() === key.toLowerCase());
219
- if (validator && validator.message) {
220
- return validator.message;
221
- }
222
- // Fallback error messages
223
- if (key === 'required')
224
- return `${this.field().label} is required`;
225
- if (key === 'email')
226
- return 'Please enter a valid email address';
227
- if (key === 'minlength')
228
- return `Minimum length is ${this.control.errors[key].requiredLength}`;
229
- if (key === 'maxlength')
230
- return `Maximum length is ${this.control.errors[key].requiredLength}`;
231
- return `${this.field().label} is invalid due to ${key} validation.`;
232
- });
233
- }
234
- return [];
235
243
  }
236
244
  get value() {
237
245
  return this.fieldFormGroup.get('value');
@@ -245,24 +253,32 @@ class DynamicFormFieldComponent {
245
253
  this.onChange(value);
246
254
  }
247
255
  }
248
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: DynamicFormFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
249
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: DynamicFormFieldComponent, isStandalone: true, selector: "abp-dynamic-form-field", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "abp-dynamic-form-field" }, providers: [
256
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: DynamicFormFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
257
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: DynamicFormFieldComponent, isStandalone: true, selector: "abp-dynamic-form-field", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "abp-dynamic-form-field" }, providers: [
250
258
  { provide: ABP_DYNAMIC_FORM_FIELD, useExisting: DynamicFormFieldComponent },
251
259
  DYNAMIC_FORM_FIELD_CONTROL_VALUE_ACCESSOR,
252
- ], exportAs: ["abpDynamicFormField"], ngImport: i0, template: "@if (visible()) {\r\n<div [formGroup]=\"fieldFormGroup\" role=\"group\" [attr.aria-labelledby]=\"fieldId + '-label'\">\r\n \r\n <!-- NOTE: Group and Array types are NOT rendered here, they should be rendered at parent level -->\r\n <!-- This component only handles leaf/primitive field types -->\r\n \r\n @if (field().type === 'text') {\r\n <!-- Text Input -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <input \r\n [id]=\"fieldId\"\r\n [placeholder]=\"(field().placeholder || '') | abpLocalization\" \r\n formControlName=\"value\"\r\n [class.is-invalid]=\"isInvalid\" \r\n class=\"form-control\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid || null\"\r\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\">\r\n @if (isInvalid) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'select') {\r\n <!-- Select Dropdown -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <select \r\n [id]=\"fieldId\"\r\n formControlName=\"value\" \r\n [class.is-invalid]=\"isInvalid\" \r\n class=\"form-control\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid || null\"\r\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\">\r\n <option value=\"\">{{ '::Select' | abpLocalization }}</option>\r\n @for (option of options$ | async; track option.key) {\r\n <option [value]=\"option.key\">\r\n {{ option.value | abpLocalization }}\r\n </option>\r\n }\r\n </select>\r\n @if (isInvalid) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'checkbox') {\r\n <!-- Checkbox -->\r\n <div class=\"form-group form-check mb-3\" role=\"group\">\r\n <abp-checkbox \r\n [label]=\"field().label | abpLocalization\" \r\n formControlName=\"value\" \r\n [id]=\"fieldId\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid || null\"\r\n [attr.aria-describedby]=\"isInvalid ? errorId : null\" />\r\n @if (isInvalid) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'email') {\r\n <!-- Email Input -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <input \r\n type=\"email\" \r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [placeholder]=\"(field().placeholder || '') | abpLocalization\" \r\n [class.is-invalid]=\"isInvalid\" \r\n class=\"form-control\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid || null\"\r\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\"\r\n autocomplete=\"email\">\r\n @if (isInvalid) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'textarea') {\r\n <!-- Textarea -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <textarea \r\n [id]=\"fieldId\"\r\n formControlName=\"value\" \r\n [placeholder]=\"(field().placeholder || '') | abpLocalization\"\r\n [class.is-invalid]=\"isInvalid\" \r\n rows=\"4\" \r\n class=\"form-control\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid || null\"\r\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\">\r\n </textarea>\r\n @if (isInvalid) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'number') {\r\n <!-- Number Input -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <input \r\n type=\"number\" \r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [placeholder]=\"(field().placeholder || '') | abpLocalization\" \r\n [class.is-invalid]=\"isInvalid\" \r\n class=\"form-control\"\r\n [attr.min]=\"field().min || null\"\r\n [attr.max]=\"field().max || null\"\r\n [attr.step]=\"field().step || null\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid || null\"\r\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\">\r\n @if (isInvalid) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'date') {\r\n <!-- Date Input -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <input \r\n type=\"date\" \r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [class.is-invalid]=\"isInvalid\" \r\n class=\"form-control\"\r\n [attr.min]=\"field().min || null\"\r\n [attr.max]=\"field().max || null\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid || null\"\r\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\">\r\n @if (isInvalid) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'datetime-local') {\r\n <!-- DateTime Local Input -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <input \r\n type=\"datetime-local\" \r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [class.is-invalid]=\"isInvalid\" \r\n class=\"form-control\"\r\n [attr.min]=\"field().min || null\"\r\n [attr.max]=\"field().max || null\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid || null\"\r\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\">\r\n @if (isInvalid) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'time') {\r\n <!-- Time Input -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <input \r\n type=\"time\" \r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [class.is-invalid]=\"isInvalid\" \r\n class=\"form-control\"\r\n [attr.min]=\"field().min || null\"\r\n [attr.max]=\"field().max || null\"\r\n [attr.step]=\"field().step || null\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid || null\"\r\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\">\r\n @if (isInvalid) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'password') {\r\n <!-- Password Input -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <input \r\n type=\"password\" \r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [placeholder]=\"(field().placeholder || '') | abpLocalization\" \r\n [class.is-invalid]=\"isInvalid\" \r\n class=\"form-control\"\r\n [attr.minlength]=\"field().minLength || null\"\r\n [attr.maxlength]=\"field().maxLength || null\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid || null\"\r\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\"\r\n autocomplete=\"new-password\">\r\n @if (isInvalid) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'tel') {\r\n <!-- Tel Input -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <input \r\n type=\"tel\" \r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [placeholder]=\"(field().placeholder || '') | abpLocalization\" \r\n [class.is-invalid]=\"isInvalid\" \r\n class=\"form-control\"\r\n [attr.pattern]=\"field().pattern || null\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid || null\"\r\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\"\r\n autocomplete=\"tel\">\r\n @if (isInvalid) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'url') {\r\n <!-- URL Input -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <input \r\n type=\"url\" \r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [placeholder]=\"(field().placeholder || '') | abpLocalization\" \r\n [class.is-invalid]=\"isInvalid\" \r\n class=\"form-control\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid || null\"\r\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\"\r\n autocomplete=\"url\">\r\n @if (isInvalid) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'radio') {\r\n <!-- Radio Group -->\r\n <div class=\"form-group mb-3\" role=\"radiogroup\" [attr.aria-labelledby]=\"fieldId + '-label'\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <div class=\"radio-group\">\r\n @for (option of options$ | async; track option.key) {\r\n <div class=\"form-check\">\r\n <input \r\n type=\"radio\" \r\n [id]=\"fieldId + '-' + option.key\"\r\n [value]=\"option.key\"\r\n formControlName=\"value\"\r\n [class.is-invalid]=\"isInvalid\" \r\n class=\"form-check-input\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid || null\"\r\n [attr.aria-describedby]=\"isInvalid ? errorId : null\">\r\n <label [for]=\"fieldId + '-' + option.key\" class=\"form-check-label\">\r\n {{ option.value | abpLocalization }}\r\n </label>\r\n </div>\r\n }\r\n </div>\r\n @if (isInvalid) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'file') {\r\n <!-- File Input -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <input \r\n type=\"file\" \r\n [id]=\"fieldId\"\r\n (change)=\"onFileChange($event)\"\r\n [class.is-invalid]=\"isInvalid\" \r\n class=\"form-control\"\r\n [attr.accept]=\"field().accept || null\"\r\n [attr.multiple]=\"field().multiple || null\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid || null\"\r\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\">\r\n @if (isInvalid) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'range') {\r\n <!-- Range Slider -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <div class=\"d-flex align-items-center gap-3\">\r\n <input \r\n type=\"range\" \r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [class.is-invalid]=\"isInvalid\" \r\n class=\"form-range flex-grow-1\"\r\n [attr.min]=\"field().min || 0\"\r\n [attr.max]=\"field().max || 100\"\r\n [attr.step]=\"field().step || 1\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid || null\"\r\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\"\r\n [attr.aria-valuenow]=\"value.value\"\r\n [attr.aria-valuemin]=\"field().min || 0\"\r\n [attr.aria-valuemax]=\"field().max || 100\">\r\n <output [for]=\"fieldId\" class=\"badge bg-primary\">{{ value.value }}</output>\r\n </div>\r\n @if (isInvalid) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'color') {\r\n <!-- Color Picker -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <div class=\"d-flex align-items-center gap-3\">\r\n <input \r\n type=\"color\" \r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [class.is-invalid]=\"isInvalid\" \r\n class=\"form-control form-control-color\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid || null\"\r\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\">\r\n <code class=\"text-muted\">{{ value.value || '#000000' }}</code>\r\n </div>\r\n @if (isInvalid) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n }\r\n</div>\r\n}\r\n\r\n<ng-template #labelTemplate>\r\n <label \r\n [for]=\"fieldId\"\r\n [id]=\"fieldId + '-label'\"\r\n [class.required]=\"field().required\">\r\n {{ field().label | abpLocalization }}\r\n @if (field().required) {\r\n <span class=\"text-danger\" aria-label=\"required\">*</span>\r\n }\r\n </label>\r\n</ng-template>\r\n\r\n<ng-template #errorTemplate>\r\n <div \r\n class=\"invalid-feedback\" \r\n [id]=\"errorId\"\r\n role=\"alert\"\r\n aria-live=\"polite\"\r\n aria-atomic=\"true\">\r\n @for (error of errors; track error) {\r\n <div>{{ error | abpLocalization }}</div>\r\n }\r\n </div>\r\n</ng-template>", styles: [".form-group{display:flex;flex-direction:column}.form-group .radio-group{display:flex;flex-direction:column;gap:.5rem}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.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: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.RangeValueAccessor, selector: "input[type=range][formControlName],input[type=range][formControl],input[type=range][ngModel]" }, { kind: "directive", type: i2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: FormCheckboxComponent, selector: "abp-checkbox", inputs: ["label", "labelClass", "checkboxId", "checkboxStyle", "checkboxClass", "checkboxReadonly"], outputs: ["checkboxBlur", "checkboxFocus"] }, { kind: "pipe", type: LocalizationPipe, name: "abpLocalization" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
260
+ ], exportAs: ["abpDynamicFormField"], ngImport: i0, template: "@if (visible()) {\r\n <div [formGroup]=\"fieldFormGroup\" role=\"group\" [attr.aria-labelledby]=\"fieldId + '-label'\">\r\n <!-- NOTE: Group and Array types are NOT rendered here, they should be rendered at parent level -->\r\n <!-- This component only handles leaf/primitive field types -->\r\n\r\n @if (field().type === 'text') {\r\n <!-- Text Input -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <input\r\n [id]=\"fieldId\"\r\n [placeholder]=\"field().placeholder || '' | abpLocalization\"\r\n formControlName=\"value\"\r\n [class.is-invalid]=\"isInvalid()\"\r\n class=\"form-control\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid() || null\"\r\n [attr.aria-describedby]=\"isInvalid() ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\"\r\n />\r\n @if (isInvalid()) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'select') {\r\n <!-- Select Dropdown -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <select\r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [class.is-invalid]=\"isInvalid()\"\r\n class=\"form-control\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid() || null\"\r\n [attr.aria-describedby]=\"isInvalid() ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\"\r\n >\r\n <option value=\"\">{{ '::Select' | abpLocalization }}</option>\r\n @for (option of options$ | async; track option.key) {\r\n <option [value]=\"option.key\">\r\n {{ option.value | abpLocalization }}\r\n </option>\r\n }\r\n </select>\r\n @if (isInvalid()) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'checkbox') {\r\n <!-- Checkbox -->\r\n <div class=\"form-group form-check mb-3\" role=\"group\">\r\n <abp-checkbox\r\n [label]=\"field().label | abpLocalization\"\r\n formControlName=\"value\"\r\n [checkboxId]=\"fieldId\"\r\n [id]=\"fieldId\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid() || null\"\r\n [attr.aria-describedby]=\"isInvalid() ? errorId : null\"\r\n />\r\n @if (isInvalid()) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'email') {\r\n <!-- Email Input -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <input\r\n type=\"email\"\r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [placeholder]=\"field().placeholder || '' | abpLocalization\"\r\n [class.is-invalid]=\"isInvalid()\"\r\n class=\"form-control\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid() || null\"\r\n [attr.aria-describedby]=\"isInvalid() ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\"\r\n autocomplete=\"email\"\r\n />\r\n @if (isInvalid()) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'textarea') {\r\n <!-- Textarea -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <textarea\r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [placeholder]=\"field().placeholder || '' | abpLocalization\"\r\n [class.is-invalid]=\"isInvalid()\"\r\n rows=\"4\"\r\n class=\"form-control\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid() || null\"\r\n [attr.aria-describedby]=\"isInvalid() ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\"\r\n >\r\n </textarea>\r\n @if (isInvalid()) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'number') {\r\n <!-- Number Input -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <input\r\n type=\"number\"\r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [placeholder]=\"field().placeholder || '' | abpLocalization\"\r\n [class.is-invalid]=\"isInvalid()\"\r\n class=\"form-control\"\r\n [attr.min]=\"field().min || null\"\r\n [attr.max]=\"field().max || null\"\r\n [attr.step]=\"field().step || null\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid() || null\"\r\n [attr.aria-describedby]=\"isInvalid() ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\"\r\n />\r\n @if (isInvalid()) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'date') {\r\n <!-- Date Input -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <input\r\n type=\"date\"\r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [class.is-invalid]=\"isInvalid()\"\r\n class=\"form-control\"\r\n [attr.min]=\"field().min || null\"\r\n [attr.max]=\"field().max || null\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid() || null\"\r\n [attr.aria-describedby]=\"isInvalid() ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\"\r\n />\r\n @if (isInvalid()) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'datetime-local') {\r\n <!-- DateTime Local Input -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <input\r\n type=\"datetime-local\"\r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [class.is-invalid]=\"isInvalid()\"\r\n class=\"form-control\"\r\n [attr.min]=\"field().min || null\"\r\n [attr.max]=\"field().max || null\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid() || null\"\r\n [attr.aria-describedby]=\"isInvalid() ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\"\r\n />\r\n @if (isInvalid()) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'time') {\r\n <!-- Time Input -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <input\r\n type=\"time\"\r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [class.is-invalid]=\"isInvalid()\"\r\n class=\"form-control\"\r\n [attr.min]=\"field().min || null\"\r\n [attr.max]=\"field().max || null\"\r\n [attr.step]=\"field().step || null\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid() || null\"\r\n [attr.aria-describedby]=\"isInvalid() ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\"\r\n />\r\n @if (isInvalid()) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'password') {\r\n <!-- Password Input -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <input\r\n type=\"password\"\r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [placeholder]=\"field().placeholder || '' | abpLocalization\"\r\n [class.is-invalid]=\"isInvalid()\"\r\n class=\"form-control\"\r\n [attr.minlength]=\"field().minLength || null\"\r\n [attr.maxlength]=\"field().maxLength || null\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid() || null\"\r\n [attr.aria-describedby]=\"isInvalid() ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\"\r\n autocomplete=\"new-password\"\r\n />\r\n @if (isInvalid()) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'tel') {\r\n <!-- Tel Input -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <input\r\n type=\"tel\"\r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [placeholder]=\"field().placeholder || '' | abpLocalization\"\r\n [class.is-invalid]=\"isInvalid()\"\r\n class=\"form-control\"\r\n [attr.pattern]=\"field().pattern || null\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid() || null\"\r\n [attr.aria-describedby]=\"isInvalid() ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\"\r\n autocomplete=\"tel\"\r\n />\r\n @if (isInvalid()) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'url') {\r\n <!-- URL Input -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <input\r\n type=\"url\"\r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [placeholder]=\"field().placeholder || '' | abpLocalization\"\r\n [class.is-invalid]=\"isInvalid()\"\r\n class=\"form-control\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid() || null\"\r\n [attr.aria-describedby]=\"isInvalid() ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\"\r\n autocomplete=\"url\"\r\n />\r\n @if (isInvalid()) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'radio') {\r\n <!-- Radio Group -->\r\n <div class=\"form-group mb-3\" role=\"radiogroup\" [attr.aria-labelledby]=\"fieldId + '-label'\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <div class=\"radio-group\">\r\n @for (option of options$ | async; track option.key) {\r\n <div class=\"form-check\">\r\n <input\r\n type=\"radio\"\r\n [id]=\"fieldId + '-' + option.key\"\r\n [value]=\"option.key\"\r\n formControlName=\"value\"\r\n [class.is-invalid]=\"isInvalid()\"\r\n class=\"form-check-input\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid() || null\"\r\n [attr.aria-describedby]=\"isInvalid() ? errorId : null\"\r\n />\r\n <label [for]=\"fieldId + '-' + option.key\" class=\"form-check-label\">\r\n {{ option.value | abpLocalization }}\r\n </label>\r\n </div>\r\n }\r\n </div>\r\n @if (isInvalid()) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'file') {\r\n <!-- File Input -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <input\r\n type=\"file\"\r\n [id]=\"fieldId\"\r\n (change)=\"onFileChange($event)\"\r\n [class.is-invalid]=\"isInvalid()\"\r\n class=\"form-control\"\r\n [attr.accept]=\"field().accept || null\"\r\n [attr.multiple]=\"field().multiple || null\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid() || null\"\r\n [attr.aria-describedby]=\"isInvalid() ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\"\r\n />\r\n @if (isInvalid()) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'range') {\r\n <!-- Range Slider -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <div class=\"d-flex align-items-center gap-3\">\r\n <input\r\n type=\"range\"\r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [class.is-invalid]=\"isInvalid()\"\r\n class=\"form-range flex-grow-1\"\r\n [attr.min]=\"field().min || 0\"\r\n [attr.max]=\"field().max || 100\"\r\n [attr.step]=\"field().step || 1\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid() || null\"\r\n [attr.aria-describedby]=\"isInvalid() ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\"\r\n [attr.aria-valuenow]=\"value.value\"\r\n [attr.aria-valuemin]=\"field().min || 0\"\r\n [attr.aria-valuemax]=\"field().max || 100\"\r\n />\r\n <output [for]=\"fieldId\" class=\"badge bg-primary\">{{ value.value }}</output>\r\n </div>\r\n @if (isInvalid()) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'color') {\r\n <!-- Color Picker -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <div class=\"d-flex align-items-center gap-3\">\r\n <input\r\n type=\"color\"\r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [class.is-invalid]=\"isInvalid()\"\r\n class=\"form-control form-control-color\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid() || null\"\r\n [attr.aria-describedby]=\"isInvalid() ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\"\r\n />\r\n <code class=\"text-muted\">{{ value.value || '#000000' }}</code>\r\n </div>\r\n @if (isInvalid()) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n }\r\n </div>\r\n}\r\n\r\n<ng-template #labelTemplate>\r\n <label [for]=\"fieldId\" [id]=\"fieldId + '-label'\" [class.required]=\"field().required\">\r\n {{ field().label | abpLocalization }}\r\n @if (field().required) {\r\n <span class=\"text-danger\" aria-label=\"required\">*</span>\r\n }\r\n </label>\r\n</ng-template>\r\n\r\n<ng-template #errorTemplate>\r\n <div class=\"invalid-feedback\" [id]=\"errorId\" role=\"alert\" aria-live=\"polite\" aria-atomic=\"true\">\r\n @for (error of errors(); track error) {\r\n <div>{{ error | abpLocalization }}</div>\r\n }\r\n </div>\r\n</ng-template>\r\n", styles: [".form-group{display:flex;flex-direction:column}.form-group .radio-group{display:flex;flex-direction:column;gap:.5rem}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NumberValueAccessor, selector: "input[type=number]:not([ngNoCva])[formControlName],input[type=number]:not([ngNoCva])[formControl],input[type=number]:not([ngNoCva])[ngModel]" }, { kind: "directive", type: i2.RangeValueAccessor, selector: "input[type=range]:not([ngNoCva])[formControlName],input[type=range]:not([ngNoCva])[formControl],input[type=range]:not([ngNoCva])[ngModel]" }, { kind: "directive", type: i2.SelectControlValueAccessor, selector: "select:not([multiple]):not([ngNoCva])[formControlName],select:not([multiple]):not([ngNoCva])[formControl],select:not([multiple]):not([ngNoCva])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2.RadioControlValueAccessor, selector: "input[type=radio]:not([ngNoCva])[formControlName],input[type=radio]:not([ngNoCva])[formControl],input[type=radio]:not([ngNoCva])[ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: FormCheckboxComponent, selector: "abp-checkbox", inputs: ["label", "labelClass", "checkboxId", "checkboxStyle", "checkboxClass", "checkboxReadonly"], outputs: ["checkboxBlur", "checkboxFocus"] }, { kind: "pipe", type: LocalizationPipe, name: "abpLocalization" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
253
261
  }
254
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: DynamicFormFieldComponent, decorators: [{
262
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: DynamicFormFieldComponent, decorators: [{
255
263
  type: Component,
256
264
  args: [{ selector: 'abp-dynamic-form-field', providers: [
257
265
  { provide: ABP_DYNAMIC_FORM_FIELD, useExisting: DynamicFormFieldComponent },
258
266
  DYNAMIC_FORM_FIELD_CONTROL_VALUE_ACCESSOR,
259
- ], host: { class: 'abp-dynamic-form-field' }, exportAs: 'abpDynamicFormField', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgTemplateOutlet, LocalizationPipe, ReactiveFormsModule, FormCheckboxComponent, AsyncPipe], template: "@if (visible()) {\r\n<div [formGroup]=\"fieldFormGroup\" role=\"group\" [attr.aria-labelledby]=\"fieldId + '-label'\">\r\n \r\n <!-- NOTE: Group and Array types are NOT rendered here, they should be rendered at parent level -->\r\n <!-- This component only handles leaf/primitive field types -->\r\n \r\n @if (field().type === 'text') {\r\n <!-- Text Input -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <input \r\n [id]=\"fieldId\"\r\n [placeholder]=\"(field().placeholder || '') | abpLocalization\" \r\n formControlName=\"value\"\r\n [class.is-invalid]=\"isInvalid\" \r\n class=\"form-control\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid || null\"\r\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\">\r\n @if (isInvalid) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'select') {\r\n <!-- Select Dropdown -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <select \r\n [id]=\"fieldId\"\r\n formControlName=\"value\" \r\n [class.is-invalid]=\"isInvalid\" \r\n class=\"form-control\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid || null\"\r\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\">\r\n <option value=\"\">{{ '::Select' | abpLocalization }}</option>\r\n @for (option of options$ | async; track option.key) {\r\n <option [value]=\"option.key\">\r\n {{ option.value | abpLocalization }}\r\n </option>\r\n }\r\n </select>\r\n @if (isInvalid) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'checkbox') {\r\n <!-- Checkbox -->\r\n <div class=\"form-group form-check mb-3\" role=\"group\">\r\n <abp-checkbox \r\n [label]=\"field().label | abpLocalization\" \r\n formControlName=\"value\" \r\n [id]=\"fieldId\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid || null\"\r\n [attr.aria-describedby]=\"isInvalid ? errorId : null\" />\r\n @if (isInvalid) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'email') {\r\n <!-- Email Input -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <input \r\n type=\"email\" \r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [placeholder]=\"(field().placeholder || '') | abpLocalization\" \r\n [class.is-invalid]=\"isInvalid\" \r\n class=\"form-control\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid || null\"\r\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\"\r\n autocomplete=\"email\">\r\n @if (isInvalid) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'textarea') {\r\n <!-- Textarea -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <textarea \r\n [id]=\"fieldId\"\r\n formControlName=\"value\" \r\n [placeholder]=\"(field().placeholder || '') | abpLocalization\"\r\n [class.is-invalid]=\"isInvalid\" \r\n rows=\"4\" \r\n class=\"form-control\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid || null\"\r\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\">\r\n </textarea>\r\n @if (isInvalid) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'number') {\r\n <!-- Number Input -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <input \r\n type=\"number\" \r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [placeholder]=\"(field().placeholder || '') | abpLocalization\" \r\n [class.is-invalid]=\"isInvalid\" \r\n class=\"form-control\"\r\n [attr.min]=\"field().min || null\"\r\n [attr.max]=\"field().max || null\"\r\n [attr.step]=\"field().step || null\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid || null\"\r\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\">\r\n @if (isInvalid) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'date') {\r\n <!-- Date Input -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <input \r\n type=\"date\" \r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [class.is-invalid]=\"isInvalid\" \r\n class=\"form-control\"\r\n [attr.min]=\"field().min || null\"\r\n [attr.max]=\"field().max || null\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid || null\"\r\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\">\r\n @if (isInvalid) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'datetime-local') {\r\n <!-- DateTime Local Input -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <input \r\n type=\"datetime-local\" \r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [class.is-invalid]=\"isInvalid\" \r\n class=\"form-control\"\r\n [attr.min]=\"field().min || null\"\r\n [attr.max]=\"field().max || null\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid || null\"\r\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\">\r\n @if (isInvalid) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'time') {\r\n <!-- Time Input -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <input \r\n type=\"time\" \r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [class.is-invalid]=\"isInvalid\" \r\n class=\"form-control\"\r\n [attr.min]=\"field().min || null\"\r\n [attr.max]=\"field().max || null\"\r\n [attr.step]=\"field().step || null\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid || null\"\r\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\">\r\n @if (isInvalid) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'password') {\r\n <!-- Password Input -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <input \r\n type=\"password\" \r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [placeholder]=\"(field().placeholder || '') | abpLocalization\" \r\n [class.is-invalid]=\"isInvalid\" \r\n class=\"form-control\"\r\n [attr.minlength]=\"field().minLength || null\"\r\n [attr.maxlength]=\"field().maxLength || null\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid || null\"\r\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\"\r\n autocomplete=\"new-password\">\r\n @if (isInvalid) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'tel') {\r\n <!-- Tel Input -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <input \r\n type=\"tel\" \r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [placeholder]=\"(field().placeholder || '') | abpLocalization\" \r\n [class.is-invalid]=\"isInvalid\" \r\n class=\"form-control\"\r\n [attr.pattern]=\"field().pattern || null\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid || null\"\r\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\"\r\n autocomplete=\"tel\">\r\n @if (isInvalid) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'url') {\r\n <!-- URL Input -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <input \r\n type=\"url\" \r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [placeholder]=\"(field().placeholder || '') | abpLocalization\" \r\n [class.is-invalid]=\"isInvalid\" \r\n class=\"form-control\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid || null\"\r\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\"\r\n autocomplete=\"url\">\r\n @if (isInvalid) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'radio') {\r\n <!-- Radio Group -->\r\n <div class=\"form-group mb-3\" role=\"radiogroup\" [attr.aria-labelledby]=\"fieldId + '-label'\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <div class=\"radio-group\">\r\n @for (option of options$ | async; track option.key) {\r\n <div class=\"form-check\">\r\n <input \r\n type=\"radio\" \r\n [id]=\"fieldId + '-' + option.key\"\r\n [value]=\"option.key\"\r\n formControlName=\"value\"\r\n [class.is-invalid]=\"isInvalid\" \r\n class=\"form-check-input\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid || null\"\r\n [attr.aria-describedby]=\"isInvalid ? errorId : null\">\r\n <label [for]=\"fieldId + '-' + option.key\" class=\"form-check-label\">\r\n {{ option.value | abpLocalization }}\r\n </label>\r\n </div>\r\n }\r\n </div>\r\n @if (isInvalid) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'file') {\r\n <!-- File Input -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <input \r\n type=\"file\" \r\n [id]=\"fieldId\"\r\n (change)=\"onFileChange($event)\"\r\n [class.is-invalid]=\"isInvalid\" \r\n class=\"form-control\"\r\n [attr.accept]=\"field().accept || null\"\r\n [attr.multiple]=\"field().multiple || null\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid || null\"\r\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\">\r\n @if (isInvalid) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'range') {\r\n <!-- Range Slider -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <div class=\"d-flex align-items-center gap-3\">\r\n <input \r\n type=\"range\" \r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [class.is-invalid]=\"isInvalid\" \r\n class=\"form-range flex-grow-1\"\r\n [attr.min]=\"field().min || 0\"\r\n [attr.max]=\"field().max || 100\"\r\n [attr.step]=\"field().step || 1\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid || null\"\r\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\"\r\n [attr.aria-valuenow]=\"value.value\"\r\n [attr.aria-valuemin]=\"field().min || 0\"\r\n [attr.aria-valuemax]=\"field().max || 100\">\r\n <output [for]=\"fieldId\" class=\"badge bg-primary\">{{ value.value }}</output>\r\n </div>\r\n @if (isInvalid) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'color') {\r\n <!-- Color Picker -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <div class=\"d-flex align-items-center gap-3\">\r\n <input \r\n type=\"color\" \r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [class.is-invalid]=\"isInvalid\" \r\n class=\"form-control form-control-color\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid || null\"\r\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\">\r\n <code class=\"text-muted\">{{ value.value || '#000000' }}</code>\r\n </div>\r\n @if (isInvalid) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n }\r\n</div>\r\n}\r\n\r\n<ng-template #labelTemplate>\r\n <label \r\n [for]=\"fieldId\"\r\n [id]=\"fieldId + '-label'\"\r\n [class.required]=\"field().required\">\r\n {{ field().label | abpLocalization }}\r\n @if (field().required) {\r\n <span class=\"text-danger\" aria-label=\"required\">*</span>\r\n }\r\n </label>\r\n</ng-template>\r\n\r\n<ng-template #errorTemplate>\r\n <div \r\n class=\"invalid-feedback\" \r\n [id]=\"errorId\"\r\n role=\"alert\"\r\n aria-live=\"polite\"\r\n aria-atomic=\"true\">\r\n @for (error of errors; track error) {\r\n <div>{{ error | abpLocalization }}</div>\r\n }\r\n </div>\r\n</ng-template>", styles: [".form-group{display:flex;flex-direction:column}.form-group .radio-group{display:flex;flex-direction:column;gap:.5rem}\n"] }]
267
+ ], host: { class: 'abp-dynamic-form-field' }, exportAs: 'abpDynamicFormField', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
268
+ NgTemplateOutlet,
269
+ LocalizationPipe,
270
+ ReactiveFormsModule,
271
+ FormCheckboxComponent,
272
+ AsyncPipe,
273
+ ], template: "@if (visible()) {\r\n <div [formGroup]=\"fieldFormGroup\" role=\"group\" [attr.aria-labelledby]=\"fieldId + '-label'\">\r\n <!-- NOTE: Group and Array types are NOT rendered here, they should be rendered at parent level -->\r\n <!-- This component only handles leaf/primitive field types -->\r\n\r\n @if (field().type === 'text') {\r\n <!-- Text Input -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <input\r\n [id]=\"fieldId\"\r\n [placeholder]=\"field().placeholder || '' | abpLocalization\"\r\n formControlName=\"value\"\r\n [class.is-invalid]=\"isInvalid()\"\r\n class=\"form-control\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid() || null\"\r\n [attr.aria-describedby]=\"isInvalid() ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\"\r\n />\r\n @if (isInvalid()) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'select') {\r\n <!-- Select Dropdown -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <select\r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [class.is-invalid]=\"isInvalid()\"\r\n class=\"form-control\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid() || null\"\r\n [attr.aria-describedby]=\"isInvalid() ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\"\r\n >\r\n <option value=\"\">{{ '::Select' | abpLocalization }}</option>\r\n @for (option of options$ | async; track option.key) {\r\n <option [value]=\"option.key\">\r\n {{ option.value | abpLocalization }}\r\n </option>\r\n }\r\n </select>\r\n @if (isInvalid()) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'checkbox') {\r\n <!-- Checkbox -->\r\n <div class=\"form-group form-check mb-3\" role=\"group\">\r\n <abp-checkbox\r\n [label]=\"field().label | abpLocalization\"\r\n formControlName=\"value\"\r\n [checkboxId]=\"fieldId\"\r\n [id]=\"fieldId\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid() || null\"\r\n [attr.aria-describedby]=\"isInvalid() ? errorId : null\"\r\n />\r\n @if (isInvalid()) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'email') {\r\n <!-- Email Input -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <input\r\n type=\"email\"\r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [placeholder]=\"field().placeholder || '' | abpLocalization\"\r\n [class.is-invalid]=\"isInvalid()\"\r\n class=\"form-control\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid() || null\"\r\n [attr.aria-describedby]=\"isInvalid() ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\"\r\n autocomplete=\"email\"\r\n />\r\n @if (isInvalid()) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'textarea') {\r\n <!-- Textarea -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <textarea\r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [placeholder]=\"field().placeholder || '' | abpLocalization\"\r\n [class.is-invalid]=\"isInvalid()\"\r\n rows=\"4\"\r\n class=\"form-control\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid() || null\"\r\n [attr.aria-describedby]=\"isInvalid() ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\"\r\n >\r\n </textarea>\r\n @if (isInvalid()) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'number') {\r\n <!-- Number Input -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <input\r\n type=\"number\"\r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [placeholder]=\"field().placeholder || '' | abpLocalization\"\r\n [class.is-invalid]=\"isInvalid()\"\r\n class=\"form-control\"\r\n [attr.min]=\"field().min || null\"\r\n [attr.max]=\"field().max || null\"\r\n [attr.step]=\"field().step || null\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid() || null\"\r\n [attr.aria-describedby]=\"isInvalid() ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\"\r\n />\r\n @if (isInvalid()) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'date') {\r\n <!-- Date Input -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <input\r\n type=\"date\"\r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [class.is-invalid]=\"isInvalid()\"\r\n class=\"form-control\"\r\n [attr.min]=\"field().min || null\"\r\n [attr.max]=\"field().max || null\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid() || null\"\r\n [attr.aria-describedby]=\"isInvalid() ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\"\r\n />\r\n @if (isInvalid()) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'datetime-local') {\r\n <!-- DateTime Local Input -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <input\r\n type=\"datetime-local\"\r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [class.is-invalid]=\"isInvalid()\"\r\n class=\"form-control\"\r\n [attr.min]=\"field().min || null\"\r\n [attr.max]=\"field().max || null\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid() || null\"\r\n [attr.aria-describedby]=\"isInvalid() ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\"\r\n />\r\n @if (isInvalid()) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'time') {\r\n <!-- Time Input -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <input\r\n type=\"time\"\r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [class.is-invalid]=\"isInvalid()\"\r\n class=\"form-control\"\r\n [attr.min]=\"field().min || null\"\r\n [attr.max]=\"field().max || null\"\r\n [attr.step]=\"field().step || null\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid() || null\"\r\n [attr.aria-describedby]=\"isInvalid() ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\"\r\n />\r\n @if (isInvalid()) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'password') {\r\n <!-- Password Input -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <input\r\n type=\"password\"\r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [placeholder]=\"field().placeholder || '' | abpLocalization\"\r\n [class.is-invalid]=\"isInvalid()\"\r\n class=\"form-control\"\r\n [attr.minlength]=\"field().minLength || null\"\r\n [attr.maxlength]=\"field().maxLength || null\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid() || null\"\r\n [attr.aria-describedby]=\"isInvalid() ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\"\r\n autocomplete=\"new-password\"\r\n />\r\n @if (isInvalid()) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'tel') {\r\n <!-- Tel Input -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <input\r\n type=\"tel\"\r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [placeholder]=\"field().placeholder || '' | abpLocalization\"\r\n [class.is-invalid]=\"isInvalid()\"\r\n class=\"form-control\"\r\n [attr.pattern]=\"field().pattern || null\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid() || null\"\r\n [attr.aria-describedby]=\"isInvalid() ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\"\r\n autocomplete=\"tel\"\r\n />\r\n @if (isInvalid()) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'url') {\r\n <!-- URL Input -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <input\r\n type=\"url\"\r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [placeholder]=\"field().placeholder || '' | abpLocalization\"\r\n [class.is-invalid]=\"isInvalid()\"\r\n class=\"form-control\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid() || null\"\r\n [attr.aria-describedby]=\"isInvalid() ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\"\r\n autocomplete=\"url\"\r\n />\r\n @if (isInvalid()) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'radio') {\r\n <!-- Radio Group -->\r\n <div class=\"form-group mb-3\" role=\"radiogroup\" [attr.aria-labelledby]=\"fieldId + '-label'\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <div class=\"radio-group\">\r\n @for (option of options$ | async; track option.key) {\r\n <div class=\"form-check\">\r\n <input\r\n type=\"radio\"\r\n [id]=\"fieldId + '-' + option.key\"\r\n [value]=\"option.key\"\r\n formControlName=\"value\"\r\n [class.is-invalid]=\"isInvalid()\"\r\n class=\"form-check-input\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid() || null\"\r\n [attr.aria-describedby]=\"isInvalid() ? errorId : null\"\r\n />\r\n <label [for]=\"fieldId + '-' + option.key\" class=\"form-check-label\">\r\n {{ option.value | abpLocalization }}\r\n </label>\r\n </div>\r\n }\r\n </div>\r\n @if (isInvalid()) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'file') {\r\n <!-- File Input -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <input\r\n type=\"file\"\r\n [id]=\"fieldId\"\r\n (change)=\"onFileChange($event)\"\r\n [class.is-invalid]=\"isInvalid()\"\r\n class=\"form-control\"\r\n [attr.accept]=\"field().accept || null\"\r\n [attr.multiple]=\"field().multiple || null\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid() || null\"\r\n [attr.aria-describedby]=\"isInvalid() ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\"\r\n />\r\n @if (isInvalid()) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'range') {\r\n <!-- Range Slider -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <div class=\"d-flex align-items-center gap-3\">\r\n <input\r\n type=\"range\"\r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [class.is-invalid]=\"isInvalid()\"\r\n class=\"form-range flex-grow-1\"\r\n [attr.min]=\"field().min || 0\"\r\n [attr.max]=\"field().max || 100\"\r\n [attr.step]=\"field().step || 1\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid() || null\"\r\n [attr.aria-describedby]=\"isInvalid() ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\"\r\n [attr.aria-valuenow]=\"value.value\"\r\n [attr.aria-valuemin]=\"field().min || 0\"\r\n [attr.aria-valuemax]=\"field().max || 100\"\r\n />\r\n <output [for]=\"fieldId\" class=\"badge bg-primary\">{{ value.value }}</output>\r\n </div>\r\n @if (isInvalid()) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n } @else if (field().type === 'color') {\r\n <!-- Color Picker -->\r\n <div class=\"form-group mb-3\">\r\n <ng-container [ngTemplateOutlet]=\"labelTemplate\" />\r\n <div class=\"d-flex align-items-center gap-3\">\r\n <input\r\n type=\"color\"\r\n [id]=\"fieldId\"\r\n formControlName=\"value\"\r\n [class.is-invalid]=\"isInvalid()\"\r\n class=\"form-control form-control-color\"\r\n [attr.aria-required]=\"field().required || null\"\r\n [attr.aria-invalid]=\"isInvalid() || null\"\r\n [attr.aria-describedby]=\"isInvalid() ? errorId : null\"\r\n [attr.aria-label]=\"field().label | abpLocalization\"\r\n />\r\n <code class=\"text-muted\">{{ value.value || '#000000' }}</code>\r\n </div>\r\n @if (isInvalid()) {\r\n <ng-container [ngTemplateOutlet]=\"errorTemplate\" />\r\n }\r\n </div>\r\n }\r\n </div>\r\n}\r\n\r\n<ng-template #labelTemplate>\r\n <label [for]=\"fieldId\" [id]=\"fieldId + '-label'\" [class.required]=\"field().required\">\r\n {{ field().label | abpLocalization }}\r\n @if (field().required) {\r\n <span class=\"text-danger\" aria-label=\"required\">*</span>\r\n }\r\n </label>\r\n</ng-template>\r\n\r\n<ng-template #errorTemplate>\r\n <div class=\"invalid-feedback\" [id]=\"errorId\" role=\"alert\" aria-live=\"polite\" aria-atomic=\"true\">\r\n @for (error of errors(); track error) {\r\n <div>{{ error | abpLocalization }}</div>\r\n }\r\n </div>\r\n</ng-template>\r\n", styles: [".form-group{display:flex;flex-direction:column}.form-group .radio-group{display:flex;flex-direction:column;gap:.5rem}\n"] }]
260
274
  }], ctorParameters: () => [], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], visible: [{ type: i0.Input, args: [{ isSignal: true, alias: "visible", required: false }] }] } });
261
275
 
262
276
  class DynamicFieldHostComponent {
263
277
  constructor() {
264
- this.component = input(...(ngDevMode ? [undefined, { debugName: "component" }] : /* istanbul ignore next */ []));
265
- this.inputs = input({}, ...(ngDevMode ? [{ debugName: "inputs" }] : /* istanbul ignore next */ []));
278
+ this.component = input(/* @ts-ignore */
279
+ ...(ngDevMode ? [undefined, { debugName: "component" }] : /* istanbul ignore next */ []));
280
+ this.inputs = input({}, /* @ts-ignore */
281
+ ...(ngDevMode ? [{ debugName: "inputs" }] : /* istanbul ignore next */ []));
266
282
  this.viewContainerRef = viewChild.required('vcRef', { read: ViewContainerRef });
267
283
  this.disabled = false;
268
284
  // if child has not implemented ControlValueAccessor. Create form control
@@ -349,14 +365,14 @@ class DynamicFieldHostComponent {
349
365
  isDisabled ? inst.formControl.disable({ emitEvent: false }) : inst.formControl.enable({ emitEvent: false });
350
366
  }
351
367
  }
352
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: DynamicFieldHostComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
353
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.17", type: DynamicFieldHostComponent, isStandalone: true, selector: "abp-dynamic-form-field-host", inputs: { component: { classPropertyName: "component", publicName: "component", isSignal: true, isRequired: false, transformFunction: null }, inputs: { classPropertyName: "inputs", publicName: "inputs", isSignal: true, isRequired: false, transformFunction: null } }, providers: [{
368
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: DynamicFieldHostComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
369
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.0.5", type: DynamicFieldHostComponent, isStandalone: true, selector: "abp-dynamic-form-field-host", inputs: { component: { classPropertyName: "component", publicName: "component", isSignal: true, isRequired: false, transformFunction: null }, inputs: { classPropertyName: "inputs", publicName: "inputs", isSignal: true, isRequired: false, transformFunction: null } }, providers: [{
354
370
  provide: NG_VALUE_ACCESSOR,
355
371
  useExisting: forwardRef(() => DynamicFieldHostComponent),
356
372
  multi: true
357
373
  }], viewQueries: [{ propertyName: "viewContainerRef", first: true, predicate: ["vcRef"], descendants: true, read: ViewContainerRef, isSignal: true }], ngImport: i0, template: `<ng-template #vcRef></ng-template>`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
358
374
  }
359
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: DynamicFieldHostComponent, decorators: [{
375
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: DynamicFieldHostComponent, decorators: [{
360
376
  type: Component,
361
377
  args: [{
362
378
  selector: 'abp-dynamic-form-field-host',
@@ -373,12 +389,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
373
389
 
374
390
  class DynamicFormArrayComponent {
375
391
  constructor() {
376
- this.arrayConfig = input.required(...(ngDevMode ? [{ debugName: "arrayConfig" }] : /* istanbul ignore next */ []));
377
- this.formGroup = input.required(...(ngDevMode ? [{ debugName: "formGroup" }] : /* istanbul ignore next */ []));
378
- this.visible = input(true, ...(ngDevMode ? [{ debugName: "visible" }] : /* istanbul ignore next */ []));
392
+ this.arrayConfig = input.required(/* @ts-ignore */
393
+ ...(ngDevMode ? [{ debugName: "arrayConfig" }] : /* istanbul ignore next */ []));
394
+ this.formGroup = input.required(/* @ts-ignore */
395
+ ...(ngDevMode ? [{ debugName: "formGroup" }] : /* istanbul ignore next */ []));
396
+ this.visible = input(true, /* @ts-ignore */
397
+ ...(ngDevMode ? [{ debugName: "visible" }] : /* istanbul ignore next */ []));
379
398
  this.fb = inject(FormBuilder);
380
399
  this.dynamicFormService = inject(DynamicFormService);
381
- this.cdr = inject(ChangeDetectorRef);
400
+ this.formArrayVersion = signal(0, /* @ts-ignore */
401
+ ...(ngDevMode ? [{ debugName: "formArrayVersion" }] : /* istanbul ignore next */ []));
382
402
  }
383
403
  get formArray() {
384
404
  return this.formGroup().get(this.arrayConfig().key);
@@ -400,13 +420,13 @@ class DynamicFormArrayComponent {
400
420
  return;
401
421
  const itemGroup = this.dynamicFormService.createFormGroup(this.arrayConfig().children || []);
402
422
  this.formArray.push(itemGroup);
403
- this.cdr.markForCheck();
423
+ this.formArrayVersion.update(version => version + 1);
404
424
  }
405
425
  removeItem(index) {
406
426
  if (!this.canRemoveItem)
407
427
  return;
408
428
  this.formArray.removeAt(index);
409
- this.cdr.markForCheck();
429
+ this.formArrayVersion.update(version => version + 1);
410
430
  }
411
431
  getItemFormGroup(index) {
412
432
  return this.formArray.at(index);
@@ -417,10 +437,10 @@ class DynamicFormArrayComponent {
417
437
  trackByIndex(index) {
418
438
  return index;
419
439
  }
420
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: DynamicFormArrayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
421
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: DynamicFormArrayComponent, isStandalone: true, selector: "abp-dynamic-form-array", inputs: { arrayConfig: { classPropertyName: "arrayConfig", publicName: "arrayConfig", isSignal: true, isRequired: true, transformFunction: null }, formGroup: { classPropertyName: "formGroup", publicName: "formGroup", isSignal: true, isRequired: true, transformFunction: null }, visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (visible()) {\r\n <div class=\"form-array-container\" role=\"region\" [attr.aria-label]=\"arrayConfig().label | abpLocalization\">\r\n \r\n <!-- Header with Add Button -->\r\n <div class=\"array-header d-flex justify-content-between align-items-center mb-3\">\r\n <label class=\"form-array-label\">\r\n {{ arrayConfig().label | abpLocalization }}\r\n @if (arrayConfig().required) {\r\n <span class=\"text-danger\" aria-label=\"required\">*</span>\r\n }\r\n </label>\r\n <button \r\n type=\"button\" \r\n class=\"btn btn-sm btn-primary\"\r\n (click)=\"addItem()\"\r\n [disabled]=\"!canAddItem\"\r\n [attr.aria-label]=\"'Add ' + (arrayConfig().label | abpLocalization)\">\r\n <i class=\"fa fa-plus me-1\"></i>\r\n {{ '::Add' | abpLocalization }}\r\n </button>\r\n </div>\r\n\r\n <!-- Array Items -->\r\n <div class=\"array-items\" role=\"list\">\r\n @for (item of formArray.controls; track trackByIndex($index)) {\r\n <div class=\"array-item border rounded p-3 mb-3\" role=\"listitem\" [formGroup]=\"getItemFormGroup($index)\">\r\n \r\n <!-- Item Header -->\r\n <div class=\"item-header d-flex justify-content-between align-items-center mb-3\">\r\n <strong class=\"item-title\">\r\n {{ arrayConfig().label | abpLocalization }} #{{ $index + 1 }}\r\n </strong>\r\n <button \r\n type=\"button\" \r\n class=\"btn btn-sm btn-danger\"\r\n (click)=\"removeItem($index)\"\r\n [disabled]=\"!canRemoveItem\"\r\n [attr.aria-label]=\"'Remove ' + (arrayConfig().label | abpLocalization) + ' #' + ($index + 1)\">\r\n <i class=\"fa fa-trash me-1\"></i>\r\n {{ '::Remove' | abpLocalization }}\r\n </button>\r\n </div>\r\n\r\n <!-- Item Fields -->\r\n <div class=\"row\">\r\n @for (field of sortedChildren; track field.key) {\r\n <div [ngClass]=\"'col-md-' + (field.gridSize || 12)\">\r\n \r\n <!-- Nested Group -->\r\n @if (field.type === 'group') {\r\n <abp-dynamic-form-group\r\n [groupConfig]=\"field\"\r\n [formGroup]=\"getNestedFormGroup($index, field.key)\" />\r\n }\r\n \r\n <!-- Nested Array (recursive) -->\r\n @else if (field.type === 'array') {\r\n <abp-dynamic-form-array\r\n [arrayConfig]=\"field\"\r\n [formGroup]=\"getItemFormGroup($index)\" />\r\n }\r\n \r\n <!-- Regular Field -->\r\n @else {\r\n <abp-dynamic-form-field\r\n [field]=\"field\"\r\n [formControlName]=\"field.key\" />\r\n }\r\n \r\n </div>\r\n }\r\n </div>\r\n </div>\r\n } @empty {\r\n <div class=\"alert alert-info\" role=\"status\">\r\n <i class=\"fa fa-info-circle me-2\"></i>\r\n {{ '::NoItemsAdded' | abpLocalization }}\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Item Count -->\r\n <div class=\"array-footer text-muted small\" aria-live=\"polite\" aria-atomic=\"true\">\r\n {{ formArray.length }} {{ '::Items' | abpLocalization }}\r\n @if (arrayConfig().minItems) {\r\n ({{ '::Min' | abpLocalization }}: {{ arrayConfig().minItems }})\r\n }\r\n @if (arrayConfig().maxItems) {\r\n ({{ '::Max' | abpLocalization }}: {{ arrayConfig().maxItems }})\r\n }\r\n </div>\r\n </div>\r\n}\r\n", styles: [".form-array-container{margin-bottom:1.5rem}.array-header{border-bottom:2px solid var(--bs-primary, #007bff);padding-bottom:.5rem}.form-array-label{font-size:1.1rem;font-weight:600;color:var(--bs-dark, #212529);margin-bottom:0}.array-items{margin-top:1rem}.array-item{background-color:var(--bs-white, #fff);transition:all .2s ease;position:relative}.array-item:hover{box-shadow:0 .125rem .25rem #00000013;transform:translateY(-1px)}.array-item .array-item{background-color:var(--bs-light, #f8f9fa)}.item-header{border-bottom:1px solid var(--bs-border-color, #dee2e6);padding-bottom:.75rem}.item-title{color:var(--bs-primary, #007bff);font-size:.95rem}.array-footer{margin-top:.5rem;padding-top:.5rem;border-top:1px solid var(--bs-border-color, #dee2e6)}button:focus-visible{outline:2px solid var(--bs-primary, #007bff);outline-offset:2px}@keyframes slideIn{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.array-item{animation:slideIn .3s ease}\n"], dependencies: [{ kind: "component", type: i0.forwardRef(() => DynamicFormArrayComponent), selector: "abp-dynamic-form-array", inputs: ["arrayConfig", "formGroup", "visible"] }, { kind: "ngmodule", type: i0.forwardRef(() => CommonModule) }, { kind: "directive", type: i0.forwardRef(() => i1.NgClass), selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: i0.forwardRef(() => ReactiveFormsModule) }, { kind: "directive", type: i0.forwardRef(() => i2.NgControlStatus), selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i0.forwardRef(() => i2.NgControlStatusGroup), selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i0.forwardRef(() => i2.FormGroupDirective), selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i0.forwardRef(() => i2.FormControlName), selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i0.forwardRef(() => DynamicFormFieldComponent), selector: "abp-dynamic-form-field", inputs: ["field", "visible"], exportAs: ["abpDynamicFormField"] }, { kind: "component", type: i0.forwardRef(() => DynamicFormGroupComponent), selector: "abp-dynamic-form-group", inputs: ["groupConfig", "formGroup", "visible"] }, { kind: "pipe", type: i0.forwardRef(() => LocalizationPipe), name: "abpLocalization" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
440
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: DynamicFormArrayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
441
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: DynamicFormArrayComponent, isStandalone: true, selector: "abp-dynamic-form-array", inputs: { arrayConfig: { classPropertyName: "arrayConfig", publicName: "arrayConfig", isSignal: true, isRequired: true, transformFunction: null }, formGroup: { classPropertyName: "formGroup", publicName: "formGroup", isSignal: true, isRequired: true, transformFunction: null }, visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (visible()) {\r\n <div class=\"form-array-container\" role=\"region\" [attr.aria-label]=\"arrayConfig().label | abpLocalization\">\r\n \r\n <!-- Header with Add Button -->\r\n <div class=\"array-header d-flex justify-content-between align-items-center mb-3\">\r\n <label class=\"form-array-label\">\r\n {{ arrayConfig().label | abpLocalization }}\r\n @if (arrayConfig().required) {\r\n <span class=\"text-danger\" aria-label=\"required\">*</span>\r\n }\r\n </label>\r\n <button \r\n type=\"button\" \r\n class=\"btn btn-sm btn-primary\"\r\n (click)=\"addItem()\"\r\n [disabled]=\"!canAddItem\"\r\n [attr.aria-label]=\"'Add ' + (arrayConfig().label | abpLocalization)\">\r\n <i class=\"fa fa-plus me-1\"></i>\r\n {{ '::Add' | abpLocalization }}\r\n </button>\r\n </div>\r\n\r\n <!-- Array Items -->\r\n <div class=\"array-items\" role=\"list\">\r\n @for (item of formArray.controls; track $index + '-' + formArrayVersion()) {\r\n <div class=\"array-item border rounded p-3 mb-3\" role=\"listitem\" [formGroup]=\"getItemFormGroup($index)\">\r\n \r\n <!-- Item Header -->\r\n <div class=\"item-header d-flex justify-content-between align-items-center mb-3\">\r\n <strong class=\"item-title\">\r\n {{ arrayConfig().label | abpLocalization }} #{{ $index + 1 }}\r\n </strong>\r\n <button \r\n type=\"button\" \r\n class=\"btn btn-sm btn-danger\"\r\n (click)=\"removeItem($index)\"\r\n [disabled]=\"!canRemoveItem\"\r\n [attr.aria-label]=\"'Remove ' + (arrayConfig().label | abpLocalization) + ' #' + ($index + 1)\">\r\n <i class=\"fa fa-trash me-1\"></i>\r\n {{ '::Remove' | abpLocalization }}\r\n </button>\r\n </div>\r\n\r\n <!-- Item Fields -->\r\n <div class=\"row\">\r\n @for (field of sortedChildren; track field.key) {\r\n <div [ngClass]=\"'col-md-' + (field.gridSize || 12)\">\r\n \r\n <!-- Nested Group -->\r\n @if (field.type === 'group') {\r\n <abp-dynamic-form-group\r\n [groupConfig]=\"field\"\r\n [formGroup]=\"getNestedFormGroup($index, field.key)\" />\r\n }\r\n \r\n <!-- Nested Array (recursive) -->\r\n @else if (field.type === 'array') {\r\n <abp-dynamic-form-array\r\n [arrayConfig]=\"field\"\r\n [formGroup]=\"getItemFormGroup($index)\" />\r\n }\r\n \r\n <!-- Regular Field -->\r\n @else {\r\n <abp-dynamic-form-field\r\n [field]=\"field\"\r\n [formControlName]=\"field.key\" />\r\n }\r\n \r\n </div>\r\n }\r\n </div>\r\n </div>\r\n } @empty {\r\n <div class=\"alert alert-info\" role=\"status\">\r\n <i class=\"fa fa-info-circle me-2\"></i>\r\n {{ '::NoItemsAdded' | abpLocalization }}\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Item Count -->\r\n <div class=\"array-footer text-muted small\" aria-live=\"polite\" aria-atomic=\"true\">\r\n {{ formArray.length }} {{ '::Items' | abpLocalization }}\r\n @if (arrayConfig().minItems) {\r\n ({{ '::Min' | abpLocalization }}: {{ arrayConfig().minItems }})\r\n }\r\n @if (arrayConfig().maxItems) {\r\n ({{ '::Max' | abpLocalization }}: {{ arrayConfig().maxItems }})\r\n }\r\n </div>\r\n </div>\r\n}\r\n", styles: [".form-array-container{margin-bottom:1.5rem}.array-header{border-bottom:2px solid var(--bs-primary, #007bff);padding-bottom:.5rem}.form-array-label{font-size:1.1rem;font-weight:600;color:var(--bs-dark, #212529);margin-bottom:0}.array-items{margin-top:1rem}.array-item{background-color:var(--bs-white, #fff);transition:all .2s ease;position:relative}.array-item:hover{box-shadow:0 .125rem .25rem #00000013;transform:translateY(-1px)}.array-item .array-item{background-color:var(--bs-light, #f8f9fa)}.item-header{border-bottom:1px solid var(--bs-border-color, #dee2e6);padding-bottom:.75rem}.item-title{color:var(--bs-primary, #007bff);font-size:.95rem}.array-footer{margin-top:.5rem;padding-top:.5rem;border-top:1px solid var(--bs-border-color, #dee2e6)}button:focus-visible{outline:2px solid var(--bs-primary, #007bff);outline-offset:2px}@keyframes slideIn{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.array-item{animation:slideIn .3s ease}\n"], dependencies: [{ kind: "component", type: i0.forwardRef(() => DynamicFormArrayComponent), selector: "abp-dynamic-form-array", inputs: ["arrayConfig", "formGroup", "visible"] }, { kind: "ngmodule", type: i0.forwardRef(() => CommonModule) }, { kind: "directive", type: i0.forwardRef(() => i1.NgClass), selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: i0.forwardRef(() => ReactiveFormsModule) }, { kind: "directive", type: i0.forwardRef(() => i2.NgControlStatus), selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i0.forwardRef(() => i2.NgControlStatusGroup), selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i0.forwardRef(() => i2.FormGroupDirective), selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i0.forwardRef(() => i2.FormControlName), selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i0.forwardRef(() => DynamicFormFieldComponent), selector: "abp-dynamic-form-field", inputs: ["field", "visible"], exportAs: ["abpDynamicFormField"] }, { kind: "component", type: i0.forwardRef(() => DynamicFormGroupComponent), selector: "abp-dynamic-form-group", inputs: ["groupConfig", "formGroup", "visible"] }, { kind: "pipe", type: i0.forwardRef(() => LocalizationPipe), name: "abpLocalization" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
422
442
  }
423
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: DynamicFormArrayComponent, decorators: [{
443
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: DynamicFormArrayComponent, decorators: [{
424
444
  type: Component,
425
445
  args: [{ selector: 'abp-dynamic-form-array', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
426
446
  CommonModule,
@@ -429,14 +449,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
429
449
  DynamicFormFieldComponent,
430
450
  DynamicFormGroupComponent,
431
451
  forwardRef(() => DynamicFormArrayComponent), // Self reference for recursion
432
- ], template: "@if (visible()) {\r\n <div class=\"form-array-container\" role=\"region\" [attr.aria-label]=\"arrayConfig().label | abpLocalization\">\r\n \r\n <!-- Header with Add Button -->\r\n <div class=\"array-header d-flex justify-content-between align-items-center mb-3\">\r\n <label class=\"form-array-label\">\r\n {{ arrayConfig().label | abpLocalization }}\r\n @if (arrayConfig().required) {\r\n <span class=\"text-danger\" aria-label=\"required\">*</span>\r\n }\r\n </label>\r\n <button \r\n type=\"button\" \r\n class=\"btn btn-sm btn-primary\"\r\n (click)=\"addItem()\"\r\n [disabled]=\"!canAddItem\"\r\n [attr.aria-label]=\"'Add ' + (arrayConfig().label | abpLocalization)\">\r\n <i class=\"fa fa-plus me-1\"></i>\r\n {{ '::Add' | abpLocalization }}\r\n </button>\r\n </div>\r\n\r\n <!-- Array Items -->\r\n <div class=\"array-items\" role=\"list\">\r\n @for (item of formArray.controls; track trackByIndex($index)) {\r\n <div class=\"array-item border rounded p-3 mb-3\" role=\"listitem\" [formGroup]=\"getItemFormGroup($index)\">\r\n \r\n <!-- Item Header -->\r\n <div class=\"item-header d-flex justify-content-between align-items-center mb-3\">\r\n <strong class=\"item-title\">\r\n {{ arrayConfig().label | abpLocalization }} #{{ $index + 1 }}\r\n </strong>\r\n <button \r\n type=\"button\" \r\n class=\"btn btn-sm btn-danger\"\r\n (click)=\"removeItem($index)\"\r\n [disabled]=\"!canRemoveItem\"\r\n [attr.aria-label]=\"'Remove ' + (arrayConfig().label | abpLocalization) + ' #' + ($index + 1)\">\r\n <i class=\"fa fa-trash me-1\"></i>\r\n {{ '::Remove' | abpLocalization }}\r\n </button>\r\n </div>\r\n\r\n <!-- Item Fields -->\r\n <div class=\"row\">\r\n @for (field of sortedChildren; track field.key) {\r\n <div [ngClass]=\"'col-md-' + (field.gridSize || 12)\">\r\n \r\n <!-- Nested Group -->\r\n @if (field.type === 'group') {\r\n <abp-dynamic-form-group\r\n [groupConfig]=\"field\"\r\n [formGroup]=\"getNestedFormGroup($index, field.key)\" />\r\n }\r\n \r\n <!-- Nested Array (recursive) -->\r\n @else if (field.type === 'array') {\r\n <abp-dynamic-form-array\r\n [arrayConfig]=\"field\"\r\n [formGroup]=\"getItemFormGroup($index)\" />\r\n }\r\n \r\n <!-- Regular Field -->\r\n @else {\r\n <abp-dynamic-form-field\r\n [field]=\"field\"\r\n [formControlName]=\"field.key\" />\r\n }\r\n \r\n </div>\r\n }\r\n </div>\r\n </div>\r\n } @empty {\r\n <div class=\"alert alert-info\" role=\"status\">\r\n <i class=\"fa fa-info-circle me-2\"></i>\r\n {{ '::NoItemsAdded' | abpLocalization }}\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Item Count -->\r\n <div class=\"array-footer text-muted small\" aria-live=\"polite\" aria-atomic=\"true\">\r\n {{ formArray.length }} {{ '::Items' | abpLocalization }}\r\n @if (arrayConfig().minItems) {\r\n ({{ '::Min' | abpLocalization }}: {{ arrayConfig().minItems }})\r\n }\r\n @if (arrayConfig().maxItems) {\r\n ({{ '::Max' | abpLocalization }}: {{ arrayConfig().maxItems }})\r\n }\r\n </div>\r\n </div>\r\n}\r\n", styles: [".form-array-container{margin-bottom:1.5rem}.array-header{border-bottom:2px solid var(--bs-primary, #007bff);padding-bottom:.5rem}.form-array-label{font-size:1.1rem;font-weight:600;color:var(--bs-dark, #212529);margin-bottom:0}.array-items{margin-top:1rem}.array-item{background-color:var(--bs-white, #fff);transition:all .2s ease;position:relative}.array-item:hover{box-shadow:0 .125rem .25rem #00000013;transform:translateY(-1px)}.array-item .array-item{background-color:var(--bs-light, #f8f9fa)}.item-header{border-bottom:1px solid var(--bs-border-color, #dee2e6);padding-bottom:.75rem}.item-title{color:var(--bs-primary, #007bff);font-size:.95rem}.array-footer{margin-top:.5rem;padding-top:.5rem;border-top:1px solid var(--bs-border-color, #dee2e6)}button:focus-visible{outline:2px solid var(--bs-primary, #007bff);outline-offset:2px}@keyframes slideIn{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.array-item{animation:slideIn .3s ease}\n"] }]
452
+ ], template: "@if (visible()) {\r\n <div class=\"form-array-container\" role=\"region\" [attr.aria-label]=\"arrayConfig().label | abpLocalization\">\r\n \r\n <!-- Header with Add Button -->\r\n <div class=\"array-header d-flex justify-content-between align-items-center mb-3\">\r\n <label class=\"form-array-label\">\r\n {{ arrayConfig().label | abpLocalization }}\r\n @if (arrayConfig().required) {\r\n <span class=\"text-danger\" aria-label=\"required\">*</span>\r\n }\r\n </label>\r\n <button \r\n type=\"button\" \r\n class=\"btn btn-sm btn-primary\"\r\n (click)=\"addItem()\"\r\n [disabled]=\"!canAddItem\"\r\n [attr.aria-label]=\"'Add ' + (arrayConfig().label | abpLocalization)\">\r\n <i class=\"fa fa-plus me-1\"></i>\r\n {{ '::Add' | abpLocalization }}\r\n </button>\r\n </div>\r\n\r\n <!-- Array Items -->\r\n <div class=\"array-items\" role=\"list\">\r\n @for (item of formArray.controls; track $index + '-' + formArrayVersion()) {\r\n <div class=\"array-item border rounded p-3 mb-3\" role=\"listitem\" [formGroup]=\"getItemFormGroup($index)\">\r\n \r\n <!-- Item Header -->\r\n <div class=\"item-header d-flex justify-content-between align-items-center mb-3\">\r\n <strong class=\"item-title\">\r\n {{ arrayConfig().label | abpLocalization }} #{{ $index + 1 }}\r\n </strong>\r\n <button \r\n type=\"button\" \r\n class=\"btn btn-sm btn-danger\"\r\n (click)=\"removeItem($index)\"\r\n [disabled]=\"!canRemoveItem\"\r\n [attr.aria-label]=\"'Remove ' + (arrayConfig().label | abpLocalization) + ' #' + ($index + 1)\">\r\n <i class=\"fa fa-trash me-1\"></i>\r\n {{ '::Remove' | abpLocalization }}\r\n </button>\r\n </div>\r\n\r\n <!-- Item Fields -->\r\n <div class=\"row\">\r\n @for (field of sortedChildren; track field.key) {\r\n <div [ngClass]=\"'col-md-' + (field.gridSize || 12)\">\r\n \r\n <!-- Nested Group -->\r\n @if (field.type === 'group') {\r\n <abp-dynamic-form-group\r\n [groupConfig]=\"field\"\r\n [formGroup]=\"getNestedFormGroup($index, field.key)\" />\r\n }\r\n \r\n <!-- Nested Array (recursive) -->\r\n @else if (field.type === 'array') {\r\n <abp-dynamic-form-array\r\n [arrayConfig]=\"field\"\r\n [formGroup]=\"getItemFormGroup($index)\" />\r\n }\r\n \r\n <!-- Regular Field -->\r\n @else {\r\n <abp-dynamic-form-field\r\n [field]=\"field\"\r\n [formControlName]=\"field.key\" />\r\n }\r\n \r\n </div>\r\n }\r\n </div>\r\n </div>\r\n } @empty {\r\n <div class=\"alert alert-info\" role=\"status\">\r\n <i class=\"fa fa-info-circle me-2\"></i>\r\n {{ '::NoItemsAdded' | abpLocalization }}\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Item Count -->\r\n <div class=\"array-footer text-muted small\" aria-live=\"polite\" aria-atomic=\"true\">\r\n {{ formArray.length }} {{ '::Items' | abpLocalization }}\r\n @if (arrayConfig().minItems) {\r\n ({{ '::Min' | abpLocalization }}: {{ arrayConfig().minItems }})\r\n }\r\n @if (arrayConfig().maxItems) {\r\n ({{ '::Max' | abpLocalization }}: {{ arrayConfig().maxItems }})\r\n }\r\n </div>\r\n </div>\r\n}\r\n", styles: [".form-array-container{margin-bottom:1.5rem}.array-header{border-bottom:2px solid var(--bs-primary, #007bff);padding-bottom:.5rem}.form-array-label{font-size:1.1rem;font-weight:600;color:var(--bs-dark, #212529);margin-bottom:0}.array-items{margin-top:1rem}.array-item{background-color:var(--bs-white, #fff);transition:all .2s ease;position:relative}.array-item:hover{box-shadow:0 .125rem .25rem #00000013;transform:translateY(-1px)}.array-item .array-item{background-color:var(--bs-light, #f8f9fa)}.item-header{border-bottom:1px solid var(--bs-border-color, #dee2e6);padding-bottom:.75rem}.item-title{color:var(--bs-primary, #007bff);font-size:.95rem}.array-footer{margin-top:.5rem;padding-top:.5rem;border-top:1px solid var(--bs-border-color, #dee2e6)}button:focus-visible{outline:2px solid var(--bs-primary, #007bff);outline-offset:2px}@keyframes slideIn{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.array-item{animation:slideIn .3s ease}\n"] }]
433
453
  }], propDecorators: { arrayConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "arrayConfig", required: true }] }], formGroup: [{ type: i0.Input, args: [{ isSignal: true, alias: "formGroup", required: true }] }], visible: [{ type: i0.Input, args: [{ isSignal: true, alias: "visible", required: false }] }] } });
434
454
 
435
455
  class DynamicFormGroupComponent {
436
456
  constructor() {
437
- this.groupConfig = input.required(...(ngDevMode ? [{ debugName: "groupConfig" }] : /* istanbul ignore next */ []));
438
- this.formGroup = input.required(...(ngDevMode ? [{ debugName: "formGroup" }] : /* istanbul ignore next */ []));
439
- this.visible = input(true, ...(ngDevMode ? [{ debugName: "visible" }] : /* istanbul ignore next */ []));
457
+ this.groupConfig = input.required(/* @ts-ignore */
458
+ ...(ngDevMode ? [{ debugName: "groupConfig" }] : /* istanbul ignore next */ []));
459
+ this.formGroup = input.required(/* @ts-ignore */
460
+ ...(ngDevMode ? [{ debugName: "formGroup" }] : /* istanbul ignore next */ []));
461
+ this.visible = input(true, /* @ts-ignore */
462
+ ...(ngDevMode ? [{ debugName: "visible" }] : /* istanbul ignore next */ []));
440
463
  }
441
464
  get sortedChildren() {
442
465
  const children = this.groupConfig().children || [];
@@ -448,10 +471,10 @@ class DynamicFormGroupComponent {
448
471
  getChildControl(key) {
449
472
  return this.formGroup().get(key);
450
473
  }
451
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: DynamicFormGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
452
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: DynamicFormGroupComponent, isStandalone: true, selector: "abp-dynamic-form-group", inputs: { groupConfig: { classPropertyName: "groupConfig", publicName: "groupConfig", isSignal: true, isRequired: true, transformFunction: null }, formGroup: { classPropertyName: "formGroup", publicName: "formGroup", isSignal: true, isRequired: true, transformFunction: null }, visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (visible()) {\r\n <fieldset class=\"form-group-container\" [formGroup]=\"formGroup()\" role=\"group\" [attr.aria-labelledby]=\"groupConfig().key + '-legend'\">\r\n <legend [id]=\"groupConfig().key + '-legend'\" class=\"form-group-legend\">\r\n {{ groupConfig().label | abpLocalization }}\r\n </legend>\r\n \r\n <div class=\"row\">\r\n @for (field of sortedChildren; track field.key) {\r\n <div [ngClass]=\"'col-md-' + (field.gridSize || 12)\">\r\n \r\n <!-- Nested Group (Recursive) -->\r\n @if (field.type === 'group') {\r\n <abp-dynamic-form-group\r\n [groupConfig]=\"field\"\r\n [formGroup]=\"getChildFormGroup(field.key)\" />\r\n }\r\n \r\n <!-- Nested Array -->\r\n @else if (field.type === 'array') {\r\n <abp-dynamic-form-array\r\n [arrayConfig]=\"field\"\r\n [formGroup]=\"formGroup()\" />\r\n }\r\n \r\n <!-- Regular Field -->\r\n @else {\r\n <abp-dynamic-form-field\r\n [field]=\"field\"\r\n [formControlName]=\"field.key\" />\r\n }\r\n \r\n </div>\r\n }\r\n </div>\r\n </fieldset>\r\n}\r\n", styles: [".form-group-container{border-left:3px solid var(--bs-primary, #007bff);padding-left:1rem;margin-bottom:1.5rem;border:1px solid var(--bs-border-color, #dee2e6);border-radius:.375rem;padding:1rem;background-color:var(--bs-light, #f8f9fa)}.form-group-container .form-group-container{border-left-color:var(--bs-secondary, #6c757d);padding-left:.75rem;background-color:var(--bs-white, #fff)}.form-group-legend{font-size:1.1rem;font-weight:600;color:var(--bs-primary, #007bff);margin-bottom:1rem;padding:0 .5rem;float:none;width:auto}\n"], dependencies: [{ kind: "component", type: i0.forwardRef(() => DynamicFormGroupComponent), selector: "abp-dynamic-form-group", inputs: ["groupConfig", "formGroup", "visible"] }, { kind: "ngmodule", type: i0.forwardRef(() => CommonModule) }, { kind: "directive", type: i0.forwardRef(() => i1.NgClass), selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: i0.forwardRef(() => ReactiveFormsModule) }, { kind: "directive", type: i0.forwardRef(() => i2.NgControlStatus), selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i0.forwardRef(() => i2.NgControlStatusGroup), selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i0.forwardRef(() => i2.FormGroupDirective), selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i0.forwardRef(() => i2.FormControlName), selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i0.forwardRef(() => DynamicFormFieldComponent), selector: "abp-dynamic-form-field", inputs: ["field", "visible"], exportAs: ["abpDynamicFormField"] }, { kind: "component", type: i0.forwardRef(() => DynamicFormArrayComponent), selector: "abp-dynamic-form-array", inputs: ["arrayConfig", "formGroup", "visible"] }, { kind: "pipe", type: i0.forwardRef(() => LocalizationPipe), name: "abpLocalization" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
474
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: DynamicFormGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
475
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: DynamicFormGroupComponent, isStandalone: true, selector: "abp-dynamic-form-group", inputs: { groupConfig: { classPropertyName: "groupConfig", publicName: "groupConfig", isSignal: true, isRequired: true, transformFunction: null }, formGroup: { classPropertyName: "formGroup", publicName: "formGroup", isSignal: true, isRequired: true, transformFunction: null }, visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (visible()) {\r\n <fieldset class=\"form-group-container\" [formGroup]=\"formGroup()\" role=\"group\" [attr.aria-labelledby]=\"groupConfig().key + '-legend'\">\r\n <legend [id]=\"groupConfig().key + '-legend'\" class=\"form-group-legend\">\r\n {{ groupConfig().label | abpLocalization }}\r\n </legend>\r\n \r\n <div class=\"row\">\r\n @for (field of sortedChildren; track field.key) {\r\n <div [ngClass]=\"'col-md-' + (field.gridSize || 12)\">\r\n \r\n <!-- Nested Group (Recursive) -->\r\n @if (field.type === 'group') {\r\n <abp-dynamic-form-group\r\n [groupConfig]=\"field\"\r\n [formGroup]=\"getChildFormGroup(field.key)\" />\r\n }\r\n \r\n <!-- Nested Array -->\r\n @else if (field.type === 'array') {\r\n <abp-dynamic-form-array\r\n [arrayConfig]=\"field\"\r\n [formGroup]=\"formGroup()\" />\r\n }\r\n \r\n <!-- Regular Field -->\r\n @else {\r\n <abp-dynamic-form-field\r\n [field]=\"field\"\r\n [formControlName]=\"field.key\" />\r\n }\r\n \r\n </div>\r\n }\r\n </div>\r\n </fieldset>\r\n}\r\n", styles: [".form-group-container{border-left:3px solid var(--bs-primary, #007bff);padding-left:1rem;margin-bottom:1.5rem;border:1px solid var(--bs-border-color, #dee2e6);border-radius:.375rem;padding:1rem;background-color:var(--bs-light, #f8f9fa)}.form-group-container .form-group-container{border-left-color:var(--bs-secondary, #6c757d);padding-left:.75rem;background-color:var(--bs-white, #fff)}.form-group-legend{font-size:1.1rem;font-weight:600;color:var(--bs-primary, #007bff);margin-bottom:1rem;padding:0 .5rem;float:none;width:auto}\n"], dependencies: [{ kind: "component", type: i0.forwardRef(() => DynamicFormGroupComponent), selector: "abp-dynamic-form-group", inputs: ["groupConfig", "formGroup", "visible"] }, { kind: "ngmodule", type: i0.forwardRef(() => CommonModule) }, { kind: "directive", type: i0.forwardRef(() => i1.NgClass), selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: i0.forwardRef(() => ReactiveFormsModule) }, { kind: "directive", type: i0.forwardRef(() => i2.NgControlStatus), selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i0.forwardRef(() => i2.NgControlStatusGroup), selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i0.forwardRef(() => i2.FormGroupDirective), selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i0.forwardRef(() => i2.FormControlName), selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i0.forwardRef(() => DynamicFormFieldComponent), selector: "abp-dynamic-form-field", inputs: ["field", "visible"], exportAs: ["abpDynamicFormField"] }, { kind: "component", type: i0.forwardRef(() => DynamicFormArrayComponent), selector: "abp-dynamic-form-array", inputs: ["arrayConfig", "formGroup", "visible"] }, { kind: "pipe", type: i0.forwardRef(() => LocalizationPipe), name: "abpLocalization" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
453
476
  }
454
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: DynamicFormGroupComponent, decorators: [{
477
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: DynamicFormGroupComponent, decorators: [{
455
478
  type: Component,
456
479
  args: [{ selector: 'abp-dynamic-form-group', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
457
480
  CommonModule,
@@ -465,17 +488,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
465
488
 
466
489
  class DynamicFormComponent {
467
490
  constructor() {
468
- this.fields = input([], ...(ngDevMode ? [{ debugName: "fields" }] : /* istanbul ignore next */ []));
469
- this.values = input(...(ngDevMode ? [undefined, { debugName: "values" }] : /* istanbul ignore next */ []));
470
- this.submitButtonText = input('Submit', ...(ngDevMode ? [{ debugName: "submitButtonText" }] : /* istanbul ignore next */ []));
471
- this.submitInProgress = input(false, ...(ngDevMode ? [{ debugName: "submitInProgress" }] : /* istanbul ignore next */ []));
472
- this.showCancelButton = input(false, ...(ngDevMode ? [{ debugName: "showCancelButton" }] : /* istanbul ignore next */ []));
491
+ this.fields = input([], /* @ts-ignore */
492
+ ...(ngDevMode ? [{ debugName: "fields" }] : /* istanbul ignore next */ []));
493
+ this.values = input(/* @ts-ignore */
494
+ ...(ngDevMode ? [undefined, { debugName: "values" }] : /* istanbul ignore next */ []));
495
+ this.submitButtonText = input('Submit', /* @ts-ignore */
496
+ ...(ngDevMode ? [{ debugName: "submitButtonText" }] : /* istanbul ignore next */ []));
497
+ this.submitInProgress = input(false, /* @ts-ignore */
498
+ ...(ngDevMode ? [{ debugName: "submitInProgress" }] : /* istanbul ignore next */ []));
499
+ this.showCancelButton = input(false, /* @ts-ignore */
500
+ ...(ngDevMode ? [{ debugName: "showCancelButton" }] : /* istanbul ignore next */ []));
473
501
  this.onSubmit = output();
474
502
  this.formCancel = output();
475
503
  this.dynamicFormService = inject(DynamicFormService);
476
504
  this.destroyRef = inject(DestroyRef);
477
- this.changeDetectorRef = inject(ChangeDetectorRef);
478
- this.fieldVisibility = {};
505
+ this.fieldVisibility = signal({}, /* @ts-ignore */
506
+ ...(ngDevMode ? [{ debugName: "fieldVisibility" }] : /* istanbul ignore next */ []));
479
507
  }
480
508
  ngOnInit() {
481
509
  this.setupFormAndLogic();
@@ -499,7 +527,7 @@ class DynamicFormComponent {
499
527
  this.evaluateConditionalLogic(event.fieldKey);
500
528
  }
501
529
  isFieldVisible(field) {
502
- return this.fieldVisibility[field.key] !== false;
530
+ return this.fieldVisibility()[field.key] !== false;
503
531
  }
504
532
  getChildFormGroup(key) {
505
533
  return this.dynamicForm.get(key);
@@ -509,15 +537,13 @@ class DynamicFormComponent {
509
537
  this.dynamicForm.reset({ ...initialValues });
510
538
  this.dynamicForm.markAsUntouched();
511
539
  this.dynamicForm.markAsPristine();
512
- this.changeDetectorRef.markForCheck();
513
540
  }
514
541
  initializeFieldVisibility() {
542
+ const visibility = {};
515
543
  this.fields().forEach(field => {
516
- this.fieldVisibility = {
517
- ...this.fieldVisibility,
518
- [field.key]: !field.conditionalLogic?.length,
519
- };
544
+ visibility[field.key] = !field.conditionalLogic?.length;
520
545
  });
546
+ this.fieldVisibility.set(visibility);
521
547
  }
522
548
  setupConditionalLogic() {
523
549
  this.fields().forEach(field => {
@@ -566,10 +592,10 @@ class DynamicFormComponent {
566
592
  const control = this.dynamicForm.get(fieldKey);
567
593
  switch (action) {
568
594
  case ConditionalAction.SHOW:
569
- this.fieldVisibility = { ...this.fieldVisibility, [fieldKey]: shouldApply };
595
+ this.fieldVisibility.update(visibility => ({ ...visibility, [fieldKey]: shouldApply }));
570
596
  break;
571
597
  case ConditionalAction.HIDE:
572
- this.fieldVisibility = { ...this.fieldVisibility, [fieldKey]: !shouldApply };
598
+ this.fieldVisibility.update(visibility => ({ ...visibility, [fieldKey]: !shouldApply }));
573
599
  break;
574
600
  case ConditionalAction.ENABLE:
575
601
  if (control) {
@@ -587,7 +613,6 @@ class DynamicFormComponent {
587
613
  this.dynamicForm = this.dynamicFormService.createFormGroup(this.fields());
588
614
  this.initializeFieldVisibility();
589
615
  this.setupConditionalLogic();
590
- this.changeDetectorRef.markForCheck();
591
616
  }
592
617
  markAllFieldsAsTouched() {
593
618
  Object.keys(this.dynamicForm.controls).forEach(key => {
@@ -610,10 +635,10 @@ class DynamicFormComponent {
610
635
  }, 100);
611
636
  }
612
637
  }
613
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: DynamicFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
614
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: DynamicFormComponent, isStandalone: true, selector: "abp-dynamic-form", inputs: { fields: { classPropertyName: "fields", publicName: "fields", isSignal: true, isRequired: false, transformFunction: null }, values: { classPropertyName: "values", publicName: "values", isSignal: true, isRequired: false, transformFunction: null }, submitButtonText: { classPropertyName: "submitButtonText", publicName: "submitButtonText", isSignal: true, isRequired: false, transformFunction: null }, submitInProgress: { classPropertyName: "submitInProgress", publicName: "submitInProgress", isSignal: true, isRequired: false, transformFunction: null }, showCancelButton: { classPropertyName: "showCancelButton", publicName: "showCancelButton", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onSubmit: "onSubmit", formCancel: "formCancel" }, host: { classAttribute: "abp-dynamic-form" }, exportAs: ["abpDynamicForm"], ngImport: i0, template: "<div class=\"form-wrapper\">\r\n<form \r\n [formGroup]=\"dynamicForm\" \r\n (ngSubmit)=\"submit()\" \r\n class=\"dynamic-form\"\r\n role=\"form\"\r\n [attr.aria-label]=\"'Dynamic Form'\">\r\n <div class=\"row\" role=\"group\">\r\n @for (field of sortedFields; track field.key) {\r\n <div [ngClass]=\"'col-md-' + (field.gridSize || 12)\">\r\n \r\n <!-- Custom Component -->\r\n @if (field.component) {\r\n <abp-dynamic-form-field-host\r\n [component]=\"field.component\"\r\n [inputs]=\"{ field: field, visible: isFieldVisible(field) }\"\r\n formControlName=\"{{ field.key }}\">\r\n </abp-dynamic-form-field-host>\r\n }\r\n \r\n <!-- Nested Group -->\r\n @else if (field.type === 'group') {\r\n <abp-dynamic-form-group\r\n [groupConfig]=\"field\"\r\n [formGroup]=\"getChildFormGroup(field.key)\"\r\n [visible]=\"isFieldVisible(field)\">\r\n </abp-dynamic-form-group>\r\n }\r\n \r\n <!-- Nested Array -->\r\n @else if (field.type === 'array') {\r\n <abp-dynamic-form-array\r\n [arrayConfig]=\"field\"\r\n [formGroup]=\"dynamicForm\"\r\n [visible]=\"isFieldVisible(field)\">\r\n </abp-dynamic-form-array>\r\n }\r\n \r\n <!-- Regular Field -->\r\n @else {\r\n <abp-dynamic-form-field\r\n [field]=\"field\"\r\n [formControlName]=\"field.key\"\r\n [visible]=\"isFieldVisible(field)\">\r\n </abp-dynamic-form-field>\r\n }\r\n \r\n </div>\r\n }\r\n </div>\r\n <ng-content select=\"[actions]\">\r\n <ng-container [ngTemplateOutlet]=\"defaultActions\"></ng-container>\r\n </ng-content>\r\n\r\n</form>\r\n\r\n<ng-template #defaultActions>\r\n <div class=\"form-actions\" role=\"group\" aria-label=\"Form actions\">\r\n @if (showCancelButton()) {\r\n <button\r\n type=\"button\"\r\n class=\"btn btn-secondary\"\r\n (click)=\"onCancel()\"\r\n aria-label=\"Cancel form\">\r\n Cancel\r\n </button>\r\n }\r\n <button\r\n type=\"submit\"\r\n class=\"btn btn-primary\"\r\n [disabled]=\"!dynamicForm.valid || submitInProgress()\"\r\n [attr.aria-busy]=\"submitInProgress() || null\"\r\n [attr.aria-label]=\"submitInProgress() ? 'Submitting form...' : submitButtonText()\">\r\n {{ submitButtonText() }}\r\n </button>\r\n </div>\r\n</ng-template>\r\n</div>\r\n", styles: [":host(.abp-dynamic-form) form{display:flex;flex-direction:column;gap:.5rem}:host(.abp-dynamic-form) .form-wrapper{text-align:left}.form-actions{display:flex;justify-content:flex-end;gap:.5rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: DynamicFormFieldComponent, selector: "abp-dynamic-form-field", inputs: ["field", "visible"], exportAs: ["abpDynamicFormField"] }, { kind: "component", type: DynamicFormGroupComponent, selector: "abp-dynamic-form-group", inputs: ["groupConfig", "formGroup", "visible"] }, { kind: "component", type: DynamicFormArrayComponent, selector: "abp-dynamic-form-array", inputs: ["arrayConfig", "formGroup", "visible"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: DynamicFieldHostComponent, selector: "abp-dynamic-form-field-host", inputs: ["component", "inputs"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
638
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: DynamicFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
639
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: DynamicFormComponent, isStandalone: true, selector: "abp-dynamic-form", inputs: { fields: { classPropertyName: "fields", publicName: "fields", isSignal: true, isRequired: false, transformFunction: null }, values: { classPropertyName: "values", publicName: "values", isSignal: true, isRequired: false, transformFunction: null }, submitButtonText: { classPropertyName: "submitButtonText", publicName: "submitButtonText", isSignal: true, isRequired: false, transformFunction: null }, submitInProgress: { classPropertyName: "submitInProgress", publicName: "submitInProgress", isSignal: true, isRequired: false, transformFunction: null }, showCancelButton: { classPropertyName: "showCancelButton", publicName: "showCancelButton", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onSubmit: "onSubmit", formCancel: "formCancel" }, host: { classAttribute: "abp-dynamic-form" }, exportAs: ["abpDynamicForm"], ngImport: i0, template: "<div class=\"form-wrapper\">\r\n<form \r\n [formGroup]=\"dynamicForm\" \r\n (ngSubmit)=\"submit()\" \r\n class=\"dynamic-form\"\r\n role=\"form\"\r\n [attr.aria-label]=\"'Dynamic Form'\">\r\n <div class=\"row\" role=\"group\">\r\n @for (field of sortedFields; track field.key) {\r\n <div [ngClass]=\"'col-md-' + (field.gridSize || 12)\">\r\n \r\n <!-- Custom Component -->\r\n @if (field.component) {\r\n <abp-dynamic-form-field-host\r\n [component]=\"field.component\"\r\n [inputs]=\"{ field: field, visible: isFieldVisible(field) }\"\r\n formControlName=\"{{ field.key }}\">\r\n </abp-dynamic-form-field-host>\r\n }\r\n \r\n <!-- Nested Group -->\r\n @else if (field.type === 'group') {\r\n <abp-dynamic-form-group\r\n [groupConfig]=\"field\"\r\n [formGroup]=\"getChildFormGroup(field.key)\"\r\n [visible]=\"isFieldVisible(field)\">\r\n </abp-dynamic-form-group>\r\n }\r\n \r\n <!-- Nested Array -->\r\n @else if (field.type === 'array') {\r\n <abp-dynamic-form-array\r\n [arrayConfig]=\"field\"\r\n [formGroup]=\"dynamicForm\"\r\n [visible]=\"isFieldVisible(field)\">\r\n </abp-dynamic-form-array>\r\n }\r\n \r\n <!-- Regular Field -->\r\n @else {\r\n <abp-dynamic-form-field\r\n [field]=\"field\"\r\n [formControlName]=\"field.key\"\r\n [visible]=\"isFieldVisible(field)\">\r\n </abp-dynamic-form-field>\r\n }\r\n \r\n </div>\r\n }\r\n </div>\r\n <ng-content select=\"[actions]\">\r\n <ng-container [ngTemplateOutlet]=\"defaultActions\"></ng-container>\r\n </ng-content>\r\n\r\n</form>\r\n\r\n<ng-template #defaultActions>\r\n <div class=\"form-actions\" role=\"group\" aria-label=\"Form actions\">\r\n @if (showCancelButton()) {\r\n <button\r\n type=\"button\"\r\n class=\"btn btn-secondary\"\r\n (click)=\"onCancel()\"\r\n aria-label=\"Cancel form\">\r\n Cancel\r\n </button>\r\n }\r\n <button\r\n type=\"submit\"\r\n class=\"btn btn-primary\"\r\n [disabled]=\"!dynamicForm.valid || submitInProgress()\"\r\n [attr.aria-busy]=\"submitInProgress() || null\"\r\n [attr.aria-label]=\"submitInProgress() ? 'Submitting form...' : submitButtonText()\">\r\n {{ submitButtonText() }}\r\n </button>\r\n </div>\r\n</ng-template>\r\n</div>\r\n", styles: [":host(.abp-dynamic-form) form{display:flex;flex-direction:column;gap:.5rem}:host(.abp-dynamic-form) .form-wrapper{text-align:left}.form-actions{display:flex;justify-content:flex-end;gap:.5rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: DynamicFormFieldComponent, selector: "abp-dynamic-form-field", inputs: ["field", "visible"], exportAs: ["abpDynamicFormField"] }, { kind: "component", type: DynamicFormGroupComponent, selector: "abp-dynamic-form-group", inputs: ["groupConfig", "formGroup", "visible"] }, { kind: "component", type: DynamicFormArrayComponent, selector: "abp-dynamic-form-array", inputs: ["arrayConfig", "formGroup", "visible"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: DynamicFieldHostComponent, selector: "abp-dynamic-form-field-host", inputs: ["component", "inputs"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
615
640
  }
616
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: DynamicFormComponent, decorators: [{
641
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: DynamicFormComponent, decorators: [{
617
642
  type: Component,
618
643
  args: [{ selector: 'abp-dynamic-form', host: { class: 'abp-dynamic-form' }, changeDetection: ChangeDetectionStrategy.OnPush, exportAs: 'abpDynamicForm', imports: [
619
644
  CommonModule,