@olafvv/ngx-dynamic-form 20.0.0 → 20.1.0

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,9 +1,9 @@
1
1
  import { AsyncPipe, NgClass } from '@angular/common';
2
2
  import * as i0 from '@angular/core';
3
- import { InjectionToken, Injectable, Inject, Optional, EventEmitter, Output, Input, Component, signal, ViewChild, inject, Injector, ChangeDetectorRef, ViewContainerRef, ChangeDetectionStrategy } from '@angular/core';
3
+ import { InjectionToken, Injectable, Inject, Optional, signal, input, Component, viewChild, inject, Injector, ViewContainerRef, ChangeDetectorRef, ChangeDetectionStrategy } from '@angular/core';
4
4
  import * as i1 from '@angular/forms';
5
- import { UntypedFormControl, ReactiveFormsModule, Validators } from '@angular/forms';
6
- import { map, BehaviorSubject, of, isObservable, startWith, distinctUntilChanged, Subscription } from 'rxjs';
5
+ import { FormControl, ReactiveFormsModule, Validators } from '@angular/forms';
6
+ import { BehaviorSubject, of, isObservable, map, startWith, distinctUntilChanged, Subscription } from 'rxjs';
7
7
  import * as i1$1 from '@angular/material/button-toggle';
8
8
  import { MatButtonToggleModule } from '@angular/material/button-toggle';
9
9
  import * as i2$1 from '@angular/material/form-field';
@@ -27,7 +27,7 @@ import * as i3$1 from '@angular/material/select';
27
27
  import { MatSelectModule } from '@angular/material/select';
28
28
  import * as i3$2 from '@angular/cdk/text-field';
29
29
 
30
- const DYNAMIC_FORM_FIELD_MAP_FN = new InjectionToken('DYNAMIC_FORM_FIELD_MAP_FN');
30
+ const DYNAMIC_FORM_FIELD_MAP$1 = new InjectionToken('DYNAMIC_FORM_FIELD_MAP');
31
31
 
32
32
  class DynamicFormValidationsService {
33
33
  /**
@@ -65,24 +65,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
65
65
  }] });
66
66
 
67
67
  class DynamicFormService {
68
- constructor(DYNAMIC_FORM_FIELD_MAP_FN, fb, validatorsService) {
69
- this.DYNAMIC_FORM_FIELD_MAP_FN = DYNAMIC_FORM_FIELD_MAP_FN;
68
+ constructor(customMap, fb, validatorsService) {
69
+ this.customMap = customMap;
70
70
  this.fb = fb;
71
71
  this.validatorsService = validatorsService;
72
72
  }
73
73
  /**
74
- * Check if there is a function provided to use custom form controls
74
+ * Check if there is a mapping provided to use custom form controls
75
75
  * @param model
76
76
  * @returns
77
77
  */
78
78
  getCustomControlComponentType(model) {
79
- return typeof this.DYNAMIC_FORM_FIELD_MAP_FN === 'function' ? this.DYNAMIC_FORM_FIELD_MAP_FN(model) : null;
79
+ return this.customMap && this.customMap[model.type] ? this.customMap[model.type] : null;
80
80
  }
81
81
  /**
82
82
  * Create a FormGroup from the provided form configuration.
83
83
  * Returns a FormGroup.
84
84
  * @param {DynamicFormConfig} config Configuration object of a form
85
- * @returns {UntypedFormGroup}
85
+ * @returns {FormGroup}
86
86
  */
87
87
  createFormGroup(config) {
88
88
  const group = this.fb.group({});
@@ -93,37 +93,13 @@ class DynamicFormService {
93
93
  validators: this.validatorsService.getValidatorFns(controlConfig.validators)
94
94
  };
95
95
  const controlValueConfig = controlConfig;
96
- const control = new UntypedFormControl({ value: controlValueConfig.value ?? controlValueConfig.defaultValue, disabled: controlValueConfig.disabled }, controlOptions);
96
+ const control = new FormControl({ value: controlValueConfig.value ?? controlValueConfig.defaultValue, disabled: controlValueConfig.disabled }, controlOptions);
97
97
  group.addControl(controlConfig.name, control);
98
98
  });
99
99
  });
100
100
  return group;
101
101
  }
102
- /**
103
- * Transform any list (Observable) to a list of DynamicFormFieldOption which is used in any Dynamic Form Field with options (e.g. DynamicSelect).
104
- * Possible to provide the method with Type definitions to define the provided list type and desired option value type:
105
- *
106
- * `dynamicFormService.toDynamicOptionList<T, K>(...)`
107
- *
108
- * Generic types:
109
- * - T = The type of the items in the provided list
110
- * - K = The type of the value inside an DynamicFormFieldOption. Default is 'string'
111
- * @param listObs An Observable of a list of items of type T
112
- * @param labelCb Callback to define the label of the options in the template
113
- * @param valueCb Callback to define the value of the options. Must return a value of type K (default string)
114
- * @returns
115
- */
116
- toDynamicOptionListObs(listObs, labelCb, valueCb) {
117
- return listObs.pipe(map((list) => {
118
- return list.map((item) => {
119
- return {
120
- label: labelCb(item),
121
- value: valueCb(item)
122
- };
123
- });
124
- }));
125
- }
126
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DynamicFormService, deps: [{ token: DYNAMIC_FORM_FIELD_MAP_FN, optional: true }, { token: i1.FormBuilder }, { token: DynamicFormValidationsService }], target: i0.ɵɵFactoryTarget.Injectable }); }
102
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DynamicFormService, deps: [{ token: DYNAMIC_FORM_FIELD_MAP$1, optional: true }, { token: i1.FormBuilder }, { token: DynamicFormValidationsService }], target: i0.ɵɵFactoryTarget.Injectable }); }
127
103
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DynamicFormService, providedIn: 'root' }); }
128
104
  }
129
105
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DynamicFormService, decorators: [{
@@ -133,61 +109,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
133
109
  }]
134
110
  }], ctorParameters: () => [{ type: undefined, decorators: [{
135
111
  type: Inject,
136
- args: [DYNAMIC_FORM_FIELD_MAP_FN]
112
+ args: [DYNAMIC_FORM_FIELD_MAP$1]
137
113
  }, {
138
114
  type: Optional
139
115
  }] }, { type: i1.FormBuilder }, { type: DynamicFormValidationsService }] });
140
116
 
141
- /**
142
- * Base class for the DynamicFormField component classes
143
- */
144
- class DynamicFormFieldBase {
145
- get id() {
146
- return this.model.id ?? this.model.name;
147
- }
148
- get control() {
149
- const ctrl = this.group.get(this.model.name);
150
- if (!ctrl) {
151
- throw new Error(`Provided FormGroup does not contain a control with the name ${this.model.name}`);
152
- }
153
- return ctrl;
154
- }
155
- get isValid() {
156
- return this.control.valid;
157
- }
158
- get isInvalid() {
159
- return this.control.invalid;
160
- }
161
- onChange(event) {
162
- this.change.emit(event);
163
- }
164
- resetControl() {
165
- this.group.get(this.model.name)?.reset();
166
- }
167
- hasError(name) {
168
- return this.control.hasError(name);
169
- }
170
- }
171
-
172
- class DynamicButtonTogglesComponent extends DynamicFormFieldBase {
173
- constructor() {
174
- super(...arguments);
175
- this.change = new EventEmitter();
176
- }
177
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DynamicButtonTogglesComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
178
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DynamicButtonTogglesComponent, isStandalone: true, selector: "dynamic-button-toggles", inputs: { model: "model", group: "group" }, outputs: { change: "change" }, usesInheritance: true, ngImport: i0, template: "<div class=\"dynamic-button-toggles-wrapper\"\n [formGroup]=\"group\">\n <mat-button-toggle-group [id]=\"id\"\n [formControlName]=\"model.name\"\n [multiple]=\"model.multiple\"\n [vertical]=\"model.vertical\"\n (change)=\"onChange($event)\">\n\n @for(option of model.options$ | async; track option.value) {\n <mat-button-toggle [value]=\"option.value\">{{option.label}}</mat-button-toggle>\n }\n </mat-button-toggle-group>\n</div>", styles: [".dynamic-button-toggles-wrapper{height:var(--mat-form-field-container-height, 56px);display:flex;align-items:center}.dynamic-button-toggles-wrapper label{font-size:var(--mat-typography-body2-font-size, 14px)}.dynamic-button-toggles-wrapper label.above{display:block;margin-bottom:8px}.dynamic-button-toggles-wrapper label.before{display:inline-block;margin-right:8px}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonToggleModule }, { kind: "directive", type: i1$1.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i1$1.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled", "disabledInteractive"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
179
- }
180
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DynamicButtonTogglesComponent, decorators: [{
181
- type: Component,
182
- args: [{ imports: [MatButtonToggleModule, ReactiveFormsModule, AsyncPipe, MatFormFieldModule], selector: 'dynamic-button-toggles', template: "<div class=\"dynamic-button-toggles-wrapper\"\n [formGroup]=\"group\">\n <mat-button-toggle-group [id]=\"id\"\n [formControlName]=\"model.name\"\n [multiple]=\"model.multiple\"\n [vertical]=\"model.vertical\"\n (change)=\"onChange($event)\">\n\n @for(option of model.options$ | async; track option.value) {\n <mat-button-toggle [value]=\"option.value\">{{option.label}}</mat-button-toggle>\n }\n </mat-button-toggle-group>\n</div>", styles: [".dynamic-button-toggles-wrapper{height:var(--mat-form-field-container-height, 56px);display:flex;align-items:center}.dynamic-button-toggles-wrapper label{font-size:var(--mat-typography-body2-font-size, 14px)}.dynamic-button-toggles-wrapper label.above{display:block;margin-bottom:8px}.dynamic-button-toggles-wrapper label.before{display:inline-block;margin-right:8px}\n"] }]
183
- }], propDecorators: { model: [{
184
- type: Input
185
- }], group: [{
186
- type: Input
187
- }], change: [{
188
- type: Output
189
- }] } });
190
-
191
117
  /**
192
118
  * Base class for all DynamicFormFields
193
119
  */
@@ -242,6 +168,79 @@ class DynamicFormFieldValueModel extends DynamicFormFieldModel {
242
168
  }
243
169
  }
244
170
 
171
+ /**
172
+ * Base class for the DynamicFormField component classes
173
+ */
174
+ class DynamicFormFieldBase {
175
+ get id() {
176
+ return this.model().id ?? this.model().name;
177
+ }
178
+ get control() {
179
+ const ctrl = this.group().get(this.model().name);
180
+ if (!ctrl) {
181
+ throw new Error(`Provided FormGroup does not contain a control with the name ${this.model().name}`);
182
+ }
183
+ return ctrl;
184
+ }
185
+ get isValid() {
186
+ return this.control.valid;
187
+ }
188
+ get isInvalid() {
189
+ return this.control.invalid;
190
+ }
191
+ resetControl() {
192
+ this.group().get(this.model().name)?.reset();
193
+ }
194
+ hasError(name) {
195
+ return this.control.hasError(name);
196
+ }
197
+ }
198
+
199
+ class DynamicButtonTogglesComponent extends DynamicFormFieldBase {
200
+ constructor() {
201
+ super(...arguments);
202
+ this.model = input.required(...(ngDevMode ? [{ debugName: "model" }] : []));
203
+ this.group = input.required(...(ngDevMode ? [{ debugName: "group" }] : []));
204
+ }
205
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DynamicButtonTogglesComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
206
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DynamicButtonTogglesComponent, isStandalone: true, selector: "dynamic-button-toggles", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null }, group: { classPropertyName: "group", publicName: "group", isSignal: true, isRequired: true, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<div\n class=\"dynamic-button-toggles-wrapper\"\n [formGroup]=\"group()\">\n <mat-button-toggle-group\n [id]=\"id\"\n [formControlName]=\"model().name\"\n [multiple]=\"model().multiple\"\n [vertical]=\"model().vertical\">\n @for (option of model().options$ | async; track option.value) {\n <mat-button-toggle [value]=\"option.value\">{{ option.label }}</mat-button-toggle>\n }\n </mat-button-toggle-group>\n</div>\n", styles: [".dynamic-button-toggles-wrapper{height:var(--mat-form-field-container-height, 56px);display:flex;align-items:center}.dynamic-button-toggles-wrapper label{font-size:var(--mat-typography-body2-font-size, 14px)}.dynamic-button-toggles-wrapper label.above{display:block;margin-bottom:8px}.dynamic-button-toggles-wrapper label.before{display:inline-block;margin-right:8px}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonToggleModule }, { kind: "directive", type: i1$1.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i1$1.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled", "disabledInteractive"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
207
+ }
208
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DynamicButtonTogglesComponent, decorators: [{
209
+ type: Component,
210
+ args: [{ imports: [MatButtonToggleModule, ReactiveFormsModule, AsyncPipe, MatFormFieldModule], selector: 'dynamic-button-toggles', template: "<div\n class=\"dynamic-button-toggles-wrapper\"\n [formGroup]=\"group()\">\n <mat-button-toggle-group\n [id]=\"id\"\n [formControlName]=\"model().name\"\n [multiple]=\"model().multiple\"\n [vertical]=\"model().vertical\">\n @for (option of model().options$ | async; track option.value) {\n <mat-button-toggle [value]=\"option.value\">{{ option.label }}</mat-button-toggle>\n }\n </mat-button-toggle-group>\n</div>\n", styles: [".dynamic-button-toggles-wrapper{height:var(--mat-form-field-container-height, 56px);display:flex;align-items:center}.dynamic-button-toggles-wrapper label{font-size:var(--mat-typography-body2-font-size, 14px)}.dynamic-button-toggles-wrapper label.above{display:block;margin-bottom:8px}.dynamic-button-toggles-wrapper label.before{display:inline-block;margin-right:8px}\n"] }]
211
+ }], propDecorators: { model: [{ type: i0.Input, args: [{ isSignal: true, alias: "model", required: true }] }], group: [{ type: i0.Input, args: [{ isSignal: true, alias: "group", required: true }] }] } });
212
+
213
+ class DynamicButtonComponent extends DynamicFormFieldBase {
214
+ constructor() {
215
+ super(...arguments);
216
+ this.model = input.required(...(ngDevMode ? [{ debugName: "model" }] : []));
217
+ this.group = input.required(...(ngDevMode ? [{ debugName: "group" }] : []));
218
+ }
219
+ onClick() {
220
+ this.model().clicked();
221
+ }
222
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DynamicButtonComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
223
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.16", type: DynamicButtonComponent, isStandalone: true, selector: "dynamic-button", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null }, group: { classPropertyName: "group", publicName: "group", isSignal: true, isRequired: true, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<div class=\"dynamic-button-wrapper\">\n <button\n mat-button\n [id]=\"id\"\n [disabled]=\"model().disabled\"\n (click)=\"onClick()\">\n <span>{{ model().label }}</span>\n </button>\n</div>\n", styles: [".dynamic-button-wrapper{height:var(--mat-form-field-container-height, 56px);display:flex;align-items:center}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1$2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }] }); }
224
+ }
225
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DynamicButtonComponent, decorators: [{
226
+ type: Component,
227
+ args: [{ imports: [MatButtonModule], selector: 'dynamic-button', template: "<div class=\"dynamic-button-wrapper\">\n <button\n mat-button\n [id]=\"id\"\n [disabled]=\"model().disabled\"\n (click)=\"onClick()\">\n <span>{{ model().label }}</span>\n </button>\n</div>\n", styles: [".dynamic-button-wrapper{height:var(--mat-form-field-container-height, 56px);display:flex;align-items:center}\n"] }]
228
+ }], propDecorators: { model: [{ type: i0.Input, args: [{ isSignal: true, alias: "model", required: true }] }], group: [{ type: i0.Input, args: [{ isSignal: true, alias: "group", required: true }] }] } });
229
+
230
+ class DynamicCheckboxComponent extends DynamicFormFieldBase {
231
+ constructor() {
232
+ super(...arguments);
233
+ this.model = input.required(...(ngDevMode ? [{ debugName: "model" }] : []));
234
+ this.group = input.required(...(ngDevMode ? [{ debugName: "group" }] : []));
235
+ }
236
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DynamicCheckboxComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
237
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.16", type: DynamicCheckboxComponent, isStandalone: true, selector: "dynamic-checkbox", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null }, group: { classPropertyName: "group", publicName: "group", isSignal: true, isRequired: true, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<ng-container [formGroup]=\"group()\">\n <mat-checkbox\n [checked]=\"model().checked\"\n [formControlName]=\"model().name\"\n [indeterminate]=\"model().indeterminate\"\n [labelPosition]=\"model().labelPosition\"\n [name]=\"model().name\"\n [id]=\"id\">\n <span class=\"checkbox-label\">{{ model().label }}</span>\n </mat-checkbox>\n</ng-container>\n", dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i2.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }] }); }
238
+ }
239
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DynamicCheckboxComponent, decorators: [{
240
+ type: Component,
241
+ args: [{ selector: 'dynamic-checkbox', imports: [ReactiveFormsModule, MatCheckboxModule], template: "<ng-container [formGroup]=\"group()\">\n <mat-checkbox\n [checked]=\"model().checked\"\n [formControlName]=\"model().name\"\n [indeterminate]=\"model().indeterminate\"\n [labelPosition]=\"model().labelPosition\"\n [name]=\"model().name\"\n [id]=\"id\">\n <span class=\"checkbox-label\">{{ model().label }}</span>\n </mat-checkbox>\n</ng-container>\n" }]
242
+ }], propDecorators: { model: [{ type: i0.Input, args: [{ isSignal: true, alias: "model", required: true }] }], group: [{ type: i0.Input, args: [{ isSignal: true, alias: "group", required: true }] }] } });
243
+
245
244
  /**
246
245
  * Base class for any DynamicFormField with options (e.g. DynamicSelect or DynamicAutocomplete)
247
246
  */
@@ -298,50 +297,15 @@ class DynamicButtonToggles extends DynamicFormFieldOptionModel {
298
297
  }
299
298
  }
300
299
 
301
- class DynamicButtonComponent extends DynamicFormFieldBase {
302
- onClick() {
303
- this.model.onClick();
304
- }
305
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DynamicButtonComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
306
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: DynamicButtonComponent, isStandalone: true, selector: "dynamic-button", inputs: { model: "model", group: "group" }, usesInheritance: true, ngImport: i0, template: "<div class=\"dynamic-button-wrapper\">\n <button mat-button\n [id]=\"id\"\n [disabled]=\"model.disabled\"\n (click)=\"onClick()\">\n <span>{{model.label}}</span>\n </button>\n</div>", styles: [".dynamic-button-wrapper{height:var(--mat-form-field-container-height, 56px);display:flex;align-items:center}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1$2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }] }); }
307
- }
308
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DynamicButtonComponent, decorators: [{
309
- type: Component,
310
- args: [{ imports: [MatButtonModule], selector: 'dynamic-button', template: "<div class=\"dynamic-button-wrapper\">\n <button mat-button\n [id]=\"id\"\n [disabled]=\"model.disabled\"\n (click)=\"onClick()\">\n <span>{{model.label}}</span>\n </button>\n</div>", styles: [".dynamic-button-wrapper{height:var(--mat-form-field-container-height, 56px);display:flex;align-items:center}\n"] }]
311
- }], propDecorators: { model: [{
312
- type: Input
313
- }], group: [{
314
- type: Input
315
- }] } });
316
-
317
300
  const DYNAMIC_FORM_FIELD_BUTTON = 'button';
318
301
  class DynamicButton extends DynamicFormFieldModel {
319
302
  constructor(config) {
320
303
  super(config);
321
304
  this.type = DYNAMIC_FORM_FIELD_BUTTON;
322
305
  this.label = config.label ?? null;
323
- this.onClick = config.onClick;
324
- }
325
- }
326
-
327
- class DynamicCheckboxComponent extends DynamicFormFieldBase {
328
- constructor() {
329
- super(...arguments);
330
- this.change = new EventEmitter();
306
+ this.clicked = config.clicked;
331
307
  }
332
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DynamicCheckboxComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
333
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: DynamicCheckboxComponent, isStandalone: true, selector: "dynamic-checkbox", inputs: { model: "model", group: "group" }, outputs: { change: "change" }, usesInheritance: true, ngImport: i0, template: "<ng-container [formGroup]=\"group\">\n <mat-checkbox [checked]=\"model.checked\"\n [formControlName]=\"model.name\"\n [indeterminate]=\"model.indeterminate\"\n [labelPosition]=\"model.labelPosition\"\n [name]=\"model.name\"\n [id]=\"id\"\n (change)=\"onChange($event)\">\n\n <span class=\"checkbox-label\">{{model.label}}</span>\n </mat-checkbox>\n</ng-container>", dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i2.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }] }); }
334
308
  }
335
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DynamicCheckboxComponent, decorators: [{
336
- type: Component,
337
- args: [{ selector: 'dynamic-checkbox', imports: [ReactiveFormsModule, MatCheckboxModule], template: "<ng-container [formGroup]=\"group\">\n <mat-checkbox [checked]=\"model.checked\"\n [formControlName]=\"model.name\"\n [indeterminate]=\"model.indeterminate\"\n [labelPosition]=\"model.labelPosition\"\n [name]=\"model.name\"\n [id]=\"id\"\n (change)=\"onChange($event)\">\n\n <span class=\"checkbox-label\">{{model.label}}</span>\n </mat-checkbox>\n</ng-container>" }]
338
- }], propDecorators: { model: [{
339
- type: Input
340
- }], group: [{
341
- type: Input
342
- }], change: [{
343
- type: Output
344
- }] } });
345
309
 
346
310
  const DYNAMIC_FORM_FIELD_CHECKBOX = 'checkbox';
347
311
  class DynamicCheckbox extends DynamicFormFieldValueModel {
@@ -363,25 +327,6 @@ class DynamicCheckbox extends DynamicFormFieldValueModel {
363
327
  }
364
328
  }
365
329
 
366
- class DynamicDatepickerComponent extends DynamicFormFieldBase {
367
- constructor() {
368
- super(...arguments);
369
- this.change = new EventEmitter();
370
- }
371
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DynamicDatepickerComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
372
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DynamicDatepickerComponent, isStandalone: true, selector: "dynamic-datepicker", inputs: { model: "model", group: "group" }, outputs: { change: "change" }, usesInheritance: true, ngImport: i0, template: "<mat-form-field\n [formGroup]=\"group\"\n [id]=\"model.id\"\n color=\"primary\">\n @if (model.label) {\n <mat-label>{{ model.label }}</mat-label>\n }\n\n <input\n matInput\n [min]=\"model.min\"\n [max]=\"model.max\"\n [matDatepicker]=\"picker\" />\n\n @if (model.hint) {\n <mat-hint>{{ model.hint }}</mat-hint>\n }\n\n <mat-datepicker-toggle\n matIconSuffix\n [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker\n #picker\n [startAt]=\"model.startAt\"\n [startView]=\"model.startView\"></mat-datepicker>\n\n @for (validator of model.validators; track validator.name) {\n <ng-container ngProjectAs=\"mat-error\">\n @if (hasError(validator.name)) {\n <mat-error>{{ validator.message }}</mat-error>\n }\n </ng-container>\n }\n</mat-form-field>\n", styles: ["mat-form-field{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i4.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i4.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i4.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }] }); }
373
- }
374
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DynamicDatepickerComponent, decorators: [{
375
- type: Component,
376
- args: [{ imports: [ReactiveFormsModule, MatFormFieldModule, MatInputModule, MatDatepickerModule], selector: 'dynamic-datepicker', template: "<mat-form-field\n [formGroup]=\"group\"\n [id]=\"model.id\"\n color=\"primary\">\n @if (model.label) {\n <mat-label>{{ model.label }}</mat-label>\n }\n\n <input\n matInput\n [min]=\"model.min\"\n [max]=\"model.max\"\n [matDatepicker]=\"picker\" />\n\n @if (model.hint) {\n <mat-hint>{{ model.hint }}</mat-hint>\n }\n\n <mat-datepicker-toggle\n matIconSuffix\n [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker\n #picker\n [startAt]=\"model.startAt\"\n [startView]=\"model.startView\"></mat-datepicker>\n\n @for (validator of model.validators; track validator.name) {\n <ng-container ngProjectAs=\"mat-error\">\n @if (hasError(validator.name)) {\n <mat-error>{{ validator.message }}</mat-error>\n }\n </ng-container>\n }\n</mat-form-field>\n", styles: ["mat-form-field{width:100%}\n"] }]
377
- }], propDecorators: { model: [{
378
- type: Input
379
- }], group: [{
380
- type: Input
381
- }], change: [{
382
- type: Output
383
- }] } });
384
-
385
330
  const DYNAMIC_FORM_FIELD_DATEPICKER = 'datepicker';
386
331
  class DynamicDatepicker extends DynamicFormFieldValueModel {
387
332
  constructor(config) {
@@ -394,44 +339,6 @@ class DynamicDatepicker extends DynamicFormFieldValueModel {
394
339
  }
395
340
  }
396
341
 
397
- class DynamicInputComponent extends DynamicFormFieldBase {
398
- constructor() {
399
- super(...arguments);
400
- this.change = new EventEmitter();
401
- }
402
- get valueCount() {
403
- return this.input?.value ? this.input.value.length : 0;
404
- }
405
- get maxCountText() {
406
- return `${this.valueCount} / ${this.model.maxLength}`;
407
- }
408
- get showClear() {
409
- return !!this.control.value && !this.control.disabled && !this.model.showLoader;
410
- }
411
- onChange(event) {
412
- // Ignore the native HTML 5 change event
413
- if (event instanceof Event) {
414
- event.stopPropagation();
415
- }
416
- this.change.emit(event);
417
- }
418
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DynamicInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
419
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DynamicInputComponent, isStandalone: true, selector: "dynamic-input", inputs: { model: "model", group: "group" }, outputs: { change: "change" }, viewQueries: [{ propertyName: "input", first: true, predicate: MatInput, descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<mat-form-field\n [formGroup]=\"group\"\n [id]=\"id\"\n color=\"primary\">\n @if (model.label) {\n <mat-label>{{ model.label }}</mat-label>\n }\n\n @if (model.prefix) {\n <span matTextPrefix>{{ model.prefix }}</span>\n }\n\n <input\n matInput\n [type]=\"model.inputType\"\n [formControlName]=\"model.name\"\n [placeholder]=\"model.placeholder\"\n [attr.min]=\"model.min\"\n [attr.max]=\"model.max\"\n [attr.minLength]=\"model.minLength\"\n [attr.maxLength]=\"model.maxLength\"\n [pattern]=\"model.pattern\"\n [autocomplete]=\"model.autocomplete\"\n (change)=\"onChange($event)\" />\n\n @if (showClear) {\n <button\n matSuffix\n mat-icon-button\n (click)=\"resetControl()\">\n <mat-icon fontIcon=\"clear\"></mat-icon>\n </button>\n }\n\n @if (model.showLoader()) {\n <div\n matSuffix\n class=\"loader-icon\">\n <mat-spinner\n diameter=\"16\"\n color=\"primary\"></mat-spinner>\n </div>\n }\n\n @if (model.hint) {\n <mat-hint align=\"start\">{{ model.hint }}</mat-hint>\n }\n\n @if (model.maxLength) {\n <mat-hint align=\"end\">{{ maxCountText }}</mat-hint>\n }\n\n @for (validator of model.validators; track validator.name) {\n <ng-container ngProjectAs=\"mat-error\">\n @if (hasError(validator.name)) {\n <mat-error>{{ validator.message }}</mat-error>\n }\n </ng-container>\n }\n</mat-form-field>\n", styles: ["mat-form-field{width:100%}mat-form-field .loader-icon{padding:8px}input::-webkit-outer-spin-button,input::-webkit-inner-spin-button{appearance:none;margin:0}input[type=number]{appearance:textfield}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i2$1.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1$2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i6.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }] }); }
420
- }
421
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DynamicInputComponent, decorators: [{
422
- type: Component,
423
- args: [{ imports: [ReactiveFormsModule, MatFormFieldModule, MatInputModule, MatButtonModule, MatIconModule, MatProgressSpinnerModule], selector: 'dynamic-input', template: "<mat-form-field\n [formGroup]=\"group\"\n [id]=\"id\"\n color=\"primary\">\n @if (model.label) {\n <mat-label>{{ model.label }}</mat-label>\n }\n\n @if (model.prefix) {\n <span matTextPrefix>{{ model.prefix }}</span>\n }\n\n <input\n matInput\n [type]=\"model.inputType\"\n [formControlName]=\"model.name\"\n [placeholder]=\"model.placeholder\"\n [attr.min]=\"model.min\"\n [attr.max]=\"model.max\"\n [attr.minLength]=\"model.minLength\"\n [attr.maxLength]=\"model.maxLength\"\n [pattern]=\"model.pattern\"\n [autocomplete]=\"model.autocomplete\"\n (change)=\"onChange($event)\" />\n\n @if (showClear) {\n <button\n matSuffix\n mat-icon-button\n (click)=\"resetControl()\">\n <mat-icon fontIcon=\"clear\"></mat-icon>\n </button>\n }\n\n @if (model.showLoader()) {\n <div\n matSuffix\n class=\"loader-icon\">\n <mat-spinner\n diameter=\"16\"\n color=\"primary\"></mat-spinner>\n </div>\n }\n\n @if (model.hint) {\n <mat-hint align=\"start\">{{ model.hint }}</mat-hint>\n }\n\n @if (model.maxLength) {\n <mat-hint align=\"end\">{{ maxCountText }}</mat-hint>\n }\n\n @for (validator of model.validators; track validator.name) {\n <ng-container ngProjectAs=\"mat-error\">\n @if (hasError(validator.name)) {\n <mat-error>{{ validator.message }}</mat-error>\n }\n </ng-container>\n }\n</mat-form-field>\n", styles: ["mat-form-field{width:100%}mat-form-field .loader-icon{padding:8px}input::-webkit-outer-spin-button,input::-webkit-inner-spin-button{appearance:none;margin:0}input[type=number]{appearance:textfield}\n"] }]
424
- }], propDecorators: { input: [{
425
- type: ViewChild,
426
- args: [MatInput, { static: true }]
427
- }], model: [{
428
- type: Input
429
- }], group: [{
430
- type: Input
431
- }], change: [{
432
- type: Output
433
- }] } });
434
-
435
342
  const DYNAMIC_FORM_FIELD_INPUT = 'input';
436
343
  class DynamicInput extends DynamicFormFieldValueModel {
437
344
  constructor(config) {
@@ -452,25 +359,6 @@ class DynamicInput extends DynamicFormFieldValueModel {
452
359
  }
453
360
  }
454
361
 
455
- class DymamicRadioGroupComponent extends DynamicFormFieldBase {
456
- constructor() {
457
- super(...arguments);
458
- this.change = new EventEmitter();
459
- }
460
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DymamicRadioGroupComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
461
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DymamicRadioGroupComponent, isStandalone: true, selector: "dynamic-radio-group", inputs: { model: "model", group: "group" }, outputs: { change: "change" }, usesInheritance: true, ngImport: i0, template: "<div\n class=\"dynamic-radio-group-wrapper\"\n [formGroup]=\"group\">\n @if (model.label) {\n <label>{{ model.label }}</label>\n }\n <mat-radio-group\n [formControlName]=\"model.name\"\n class=\"radio-group\"\n [ngClass]=\"{ inline: model.inline }\"\n (change)=\"onChange($event)\">\n @for (option of model.options$ | async; track option.value) {\n <mat-radio-button\n [value]=\"option.value\"\n [labelPosition]=\"model.labelPosition\">\n {{ option.label }}\n </mat-radio-button>\n }\n </mat-radio-group>\n</div>\n", styles: [".dynamic-radio-group-wrapper label{display:block;font-size:var(--mat-typography-body2-font-size, 14px);margin-bottom:8px}.dynamic-radio-group-wrapper .radio-group:not(.inline){display:flex;flex-direction:column;align-items:flex-start}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatRadioModule }, { kind: "directive", type: i2$2.MatRadioGroup, selector: "mat-radio-group", inputs: ["color", "name", "labelPosition", "value", "selected", "disabled", "required", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioGroup"] }, { kind: "component", type: i2$2.MatRadioButton, selector: "mat-radio-button", inputs: ["id", "name", "aria-label", "aria-labelledby", "aria-describedby", "disableRipple", "tabIndex", "checked", "value", "labelPosition", "disabled", "required", "color", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioButton"] }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
462
- }
463
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DymamicRadioGroupComponent, decorators: [{
464
- type: Component,
465
- args: [{ imports: [NgClass, ReactiveFormsModule, MatRadioModule, AsyncPipe], selector: 'dynamic-radio-group', template: "<div\n class=\"dynamic-radio-group-wrapper\"\n [formGroup]=\"group\">\n @if (model.label) {\n <label>{{ model.label }}</label>\n }\n <mat-radio-group\n [formControlName]=\"model.name\"\n class=\"radio-group\"\n [ngClass]=\"{ inline: model.inline }\"\n (change)=\"onChange($event)\">\n @for (option of model.options$ | async; track option.value) {\n <mat-radio-button\n [value]=\"option.value\"\n [labelPosition]=\"model.labelPosition\">\n {{ option.label }}\n </mat-radio-button>\n }\n </mat-radio-group>\n</div>\n", styles: [".dynamic-radio-group-wrapper label{display:block;font-size:var(--mat-typography-body2-font-size, 14px);margin-bottom:8px}.dynamic-radio-group-wrapper .radio-group:not(.inline){display:flex;flex-direction:column;align-items:flex-start}\n"] }]
466
- }], propDecorators: { model: [{
467
- type: Input
468
- }], group: [{
469
- type: Input
470
- }], change: [{
471
- type: Output
472
- }] } });
473
-
474
362
  const DYNAMIC_FORM_FIELD_RADIO_GROUP = 'radio-group';
475
363
  class DynamicRadioGroup extends DynamicFormFieldOptionModel {
476
364
  constructor(config) {
@@ -481,19 +369,6 @@ class DynamicRadioGroup extends DynamicFormFieldOptionModel {
481
369
  }
482
370
  }
483
371
 
484
- class DynamicReadonlyComponent extends DynamicFormFieldBase {
485
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DynamicReadonlyComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
486
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: DynamicReadonlyComponent, isStandalone: true, selector: "dynamic-readonly", inputs: { model: "model", group: "group" }, usesInheritance: true, ngImport: i0, template: "<div class=\"dynamic-form-field-readonly\"\n [formGroup]=\"group\"\n [id]=\"id\">\n <div class=\"label\">{{model.label}}</div>\n <span>{{model.value}}</span>\n</div>", styles: [".dynamic-form-field-readonly{width:100%;margin:8px 0;color:var(--mat-theme-text-primary-on-background, rgba(0, 0, 0, .87))}.dynamic-form-field-readonly .label{font-size:var(--mat-typography-body2-font-size, 14px);line-height:var(--mat-typography-body2-line-height, 20px);margin-bottom:8px}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }] }); }
487
- }
488
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DynamicReadonlyComponent, decorators: [{
489
- type: Component,
490
- args: [{ imports: [ReactiveFormsModule], selector: 'dynamic-readonly', template: "<div class=\"dynamic-form-field-readonly\"\n [formGroup]=\"group\"\n [id]=\"id\">\n <div class=\"label\">{{model.label}}</div>\n <span>{{model.value}}</span>\n</div>", styles: [".dynamic-form-field-readonly{width:100%;margin:8px 0;color:var(--mat-theme-text-primary-on-background, rgba(0, 0, 0, .87))}.dynamic-form-field-readonly .label{font-size:var(--mat-typography-body2-font-size, 14px);line-height:var(--mat-typography-body2-line-height, 20px);margin-bottom:8px}\n"] }]
491
- }], propDecorators: { model: [{
492
- type: Input
493
- }], group: [{
494
- type: Input
495
- }] } });
496
-
497
372
  const DYNAMIC_FORM_FIELD_READONLY = 'readonly';
498
373
  class DynamicReadonly extends DynamicFormFieldValueModel {
499
374
  constructor(config) {
@@ -502,25 +377,6 @@ class DynamicReadonly extends DynamicFormFieldValueModel {
502
377
  }
503
378
  }
504
379
 
505
- class DynamicSelectComponent extends DynamicFormFieldBase {
506
- constructor() {
507
- super(...arguments);
508
- this.change = new EventEmitter();
509
- }
510
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DynamicSelectComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
511
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DynamicSelectComponent, isStandalone: true, selector: "dynamic-select", inputs: { model: "model", group: "group" }, outputs: { change: "change" }, usesInheritance: true, ngImport: i0, template: "<mat-form-field\n [formGroup]=\"group\"\n [id]=\"id\"\n color=\"primary\">\n <mat-label>{{ model.label }}</mat-label>\n\n <!-- Template for select without grouped options -->\n @if (model.options$ | async; as options) {\n @if (!model.native) {\n <mat-select\n [formControlName]=\"model.name\"\n [multiple]=\"model.multiple\"\n (selectionChange)=\"onChange($event)\">\n @for (option of options; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.label }}\n </mat-option>\n }\n </mat-select>\n } @else {\n <select\n matNativeControl\n (selectionchange)=\"onChange($event)\">\n @for (option of options; track option.value) {\n <option [value]=\"option.value\">\n {{ option.label }}\n </option>\n }\n </select>\n }\n }\n\n <!-- Template for select with grouped options -->\n @if (model.groupedOptions$ | async; as groupedOptions) {\n @if (!model.native) {\n <mat-select\n [formControlName]=\"model.name\"\n (selectionChange)=\"onChange($event)\">\n @for (group of groupedOptions; track group.name) {\n <mat-optgroup [label]=\"group.name\">\n @for (option of group.options; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.label }}\n </mat-option>\n }\n </mat-optgroup>\n }\n </mat-select>\n } @else {\n <select\n matNativeControl\n (selectionchange)=\"onChange($event)\">\n @for (group of groupedOptions; track group.name) {\n =\n <optgroup [label]=\"group.name\">\n @for (option of group.options; track option.value) {\n <option [value]=\"option.value\">\n {{ option.label }}\n </option>\n }\n </optgroup>\n }\n </select>\n }\n }\n\n @if (model.hint) {\n <mat-hint align=\"start\">{{ model.hint }}</mat-hint>\n }\n\n @for (validator of model.validators; track validator.name) {\n <ng-container ngProjectAs=\"mat-error\">\n @if (hasError(validator.name)) {\n <mat-error>{{ validator.message }}</mat-error>\n }\n </ng-container>\n }\n</mat-form-field>\n", styles: ["mat-form-field{width:100%}mat-option{padding-top:8px;padding-bottom:8px}\n"], dependencies: [{ kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i3$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i3$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i3$1.MatOptgroup, selector: "mat-optgroup", inputs: ["label", "disabled"], exportAs: ["matOptgroup"] }, { kind: "ngmodule", type: MatOptionModule }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
512
- }
513
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DynamicSelectComponent, decorators: [{
514
- type: Component,
515
- args: [{ imports: [MatFormFieldModule, ReactiveFormsModule, MatSelectModule, MatOptionModule, AsyncPipe, MatInputModule], selector: 'dynamic-select', template: "<mat-form-field\n [formGroup]=\"group\"\n [id]=\"id\"\n color=\"primary\">\n <mat-label>{{ model.label }}</mat-label>\n\n <!-- Template for select without grouped options -->\n @if (model.options$ | async; as options) {\n @if (!model.native) {\n <mat-select\n [formControlName]=\"model.name\"\n [multiple]=\"model.multiple\"\n (selectionChange)=\"onChange($event)\">\n @for (option of options; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.label }}\n </mat-option>\n }\n </mat-select>\n } @else {\n <select\n matNativeControl\n (selectionchange)=\"onChange($event)\">\n @for (option of options; track option.value) {\n <option [value]=\"option.value\">\n {{ option.label }}\n </option>\n }\n </select>\n }\n }\n\n <!-- Template for select with grouped options -->\n @if (model.groupedOptions$ | async; as groupedOptions) {\n @if (!model.native) {\n <mat-select\n [formControlName]=\"model.name\"\n (selectionChange)=\"onChange($event)\">\n @for (group of groupedOptions; track group.name) {\n <mat-optgroup [label]=\"group.name\">\n @for (option of group.options; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.label }}\n </mat-option>\n }\n </mat-optgroup>\n }\n </mat-select>\n } @else {\n <select\n matNativeControl\n (selectionchange)=\"onChange($event)\">\n @for (group of groupedOptions; track group.name) {\n =\n <optgroup [label]=\"group.name\">\n @for (option of group.options; track option.value) {\n <option [value]=\"option.value\">\n {{ option.label }}\n </option>\n }\n </optgroup>\n }\n </select>\n }\n }\n\n @if (model.hint) {\n <mat-hint align=\"start\">{{ model.hint }}</mat-hint>\n }\n\n @for (validator of model.validators; track validator.name) {\n <ng-container ngProjectAs=\"mat-error\">\n @if (hasError(validator.name)) {\n <mat-error>{{ validator.message }}</mat-error>\n }\n </ng-container>\n }\n</mat-form-field>\n", styles: ["mat-form-field{width:100%}mat-option{padding-top:8px;padding-bottom:8px}\n"] }]
516
- }], propDecorators: { model: [{
517
- type: Input
518
- }], group: [{
519
- type: Input
520
- }], change: [{
521
- type: Output
522
- }] } });
523
-
524
380
  const DYNAMIC_FORM_FIELD_SELECT = 'select';
525
381
  class DynamicSelect extends DynamicFormFieldOptionModel {
526
382
  constructor(config) {
@@ -531,41 +387,6 @@ class DynamicSelect extends DynamicFormFieldOptionModel {
531
387
  }
532
388
  }
533
389
 
534
- class DynamicTextareaComponent extends DynamicFormFieldBase {
535
- constructor() {
536
- super(...arguments);
537
- this.change = new EventEmitter();
538
- }
539
- get valueCount() {
540
- return this.textarea?.value ? this.textarea.value.length : 0;
541
- }
542
- get maxCountText() {
543
- return `${this.valueCount} / ${this.model.maxLength}`;
544
- }
545
- onChange(event) {
546
- // Ignore the native HTML 5 change event
547
- if (event instanceof Event) {
548
- event.stopPropagation();
549
- }
550
- this.change.emit(event);
551
- }
552
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DynamicTextareaComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
553
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DynamicTextareaComponent, isStandalone: true, selector: "dynamic-textarea", inputs: { model: "model", group: "group" }, outputs: { change: "change" }, viewQueries: [{ propertyName: "textarea", first: true, predicate: MatInput, descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<mat-form-field\n [formGroup]=\"group\"\n [id]=\"id\"\n color=\"primary\">\n @if (model.label) {\n <mat-label>{{ model.label }}</mat-label>\n }\n\n <textarea\n matInput\n [cdkTextareaAutosize]=\"model.resize\"\n [cdkAutosizeMinRows]=\"model.rows\"\n [cdkAutosizeMaxRows]=\"model.resizeMaxRows\"\n [id]=\"id\"\n [formControlName]=\"model.name\"\n [placeholder]=\"model.placeholder\"\n [attr.minLength]=\"model.minLength\"\n [attr.maxLength]=\"model.maxLength\"\n [rows]=\"model.rows\"\n [autocomplete]=\"model.autocomplete\"\n (change)=\"onChange($event)\">\n </textarea>\n\n @if (model.hint) {\n <mat-hint align=\"start\">{{ model.hint }}</mat-hint>\n }\n\n @if (model.maxLength) {\n <mat-hint align=\"end\">{{ maxCountText }}</mat-hint>\n }\n\n @for (validator of model.validators; track validator.name) {\n <ng-container ngProjectAs=\"mat-error\">\n @if (hasError(validator.name)) {\n <mat-error>{{ validator.message }}</mat-error>\n }\n </ng-container>\n }\n</mat-form-field>\n", styles: ["mat-form-field{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "directive", type: i3$2.CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }] }); }
554
- }
555
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DynamicTextareaComponent, decorators: [{
556
- type: Component,
557
- args: [{ imports: [MatFormFieldModule, MatInputModule, ReactiveFormsModule], selector: 'dynamic-textarea', template: "<mat-form-field\n [formGroup]=\"group\"\n [id]=\"id\"\n color=\"primary\">\n @if (model.label) {\n <mat-label>{{ model.label }}</mat-label>\n }\n\n <textarea\n matInput\n [cdkTextareaAutosize]=\"model.resize\"\n [cdkAutosizeMinRows]=\"model.rows\"\n [cdkAutosizeMaxRows]=\"model.resizeMaxRows\"\n [id]=\"id\"\n [formControlName]=\"model.name\"\n [placeholder]=\"model.placeholder\"\n [attr.minLength]=\"model.minLength\"\n [attr.maxLength]=\"model.maxLength\"\n [rows]=\"model.rows\"\n [autocomplete]=\"model.autocomplete\"\n (change)=\"onChange($event)\">\n </textarea>\n\n @if (model.hint) {\n <mat-hint align=\"start\">{{ model.hint }}</mat-hint>\n }\n\n @if (model.maxLength) {\n <mat-hint align=\"end\">{{ maxCountText }}</mat-hint>\n }\n\n @for (validator of model.validators; track validator.name) {\n <ng-container ngProjectAs=\"mat-error\">\n @if (hasError(validator.name)) {\n <mat-error>{{ validator.message }}</mat-error>\n }\n </ng-container>\n }\n</mat-form-field>\n", styles: ["mat-form-field{width:100%}\n"] }]
558
- }], propDecorators: { textarea: [{
559
- type: ViewChild,
560
- args: [MatInput, { static: true }]
561
- }], model: [{
562
- type: Input
563
- }], group: [{
564
- type: Input
565
- }], change: [{
566
- type: Output
567
- }] } });
568
-
569
390
  const DYNAMIC_FORM_FIELD_TEXTAREA = 'textarea';
570
391
  class DynamicTextarea extends DynamicFormFieldValueModel {
571
392
  constructor(config) {
@@ -581,6 +402,119 @@ class DynamicTextarea extends DynamicFormFieldValueModel {
581
402
  }
582
403
  }
583
404
 
405
+ class DynamicDatepickerComponent extends DynamicFormFieldBase {
406
+ constructor() {
407
+ super(...arguments);
408
+ this.model = input.required(...(ngDevMode ? [{ debugName: "model" }] : []));
409
+ this.group = input.required(...(ngDevMode ? [{ debugName: "group" }] : []));
410
+ }
411
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DynamicDatepickerComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
412
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DynamicDatepickerComponent, isStandalone: true, selector: "dynamic-datepicker", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null }, group: { classPropertyName: "group", publicName: "group", isSignal: true, isRequired: true, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<mat-form-field\n [formGroup]=\"group()\"\n [id]=\"model().id\"\n color=\"primary\">\n @if (model().label) {\n <mat-label>{{ model().label }}</mat-label>\n }\n\n <input\n matInput\n [min]=\"model().min\"\n [max]=\"model().max\"\n [matDatepicker]=\"picker\" />\n\n @if (model().hint) {\n <mat-hint>{{ model().hint }}</mat-hint>\n }\n\n <mat-datepicker-toggle\n matIconSuffix\n [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker\n #picker\n [startAt]=\"model().startAt\"\n [startView]=\"model().startView\"></mat-datepicker>\n\n @for (validator of model().validators; track validator.name) {\n <ng-container ngProjectAs=\"mat-error\">\n @if (hasError(validator.name)) {\n <mat-error>{{ validator.message }}</mat-error>\n }\n </ng-container>\n }\n</mat-form-field>\n", styles: ["mat-form-field{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i4.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i4.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i4.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }] }); }
413
+ }
414
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DynamicDatepickerComponent, decorators: [{
415
+ type: Component,
416
+ args: [{ imports: [ReactiveFormsModule, MatFormFieldModule, MatInputModule, MatDatepickerModule], selector: 'dynamic-datepicker', template: "<mat-form-field\n [formGroup]=\"group()\"\n [id]=\"model().id\"\n color=\"primary\">\n @if (model().label) {\n <mat-label>{{ model().label }}</mat-label>\n }\n\n <input\n matInput\n [min]=\"model().min\"\n [max]=\"model().max\"\n [matDatepicker]=\"picker\" />\n\n @if (model().hint) {\n <mat-hint>{{ model().hint }}</mat-hint>\n }\n\n <mat-datepicker-toggle\n matIconSuffix\n [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker\n #picker\n [startAt]=\"model().startAt\"\n [startView]=\"model().startView\"></mat-datepicker>\n\n @for (validator of model().validators; track validator.name) {\n <ng-container ngProjectAs=\"mat-error\">\n @if (hasError(validator.name)) {\n <mat-error>{{ validator.message }}</mat-error>\n }\n </ng-container>\n }\n</mat-form-field>\n", styles: ["mat-form-field{width:100%}\n"] }]
417
+ }], propDecorators: { model: [{ type: i0.Input, args: [{ isSignal: true, alias: "model", required: true }] }], group: [{ type: i0.Input, args: [{ isSignal: true, alias: "group", required: true }] }] } });
418
+
419
+ class DynamicInputComponent extends DynamicFormFieldBase {
420
+ constructor() {
421
+ super(...arguments);
422
+ this.input = viewChild.required(MatInput);
423
+ this.model = input.required(...(ngDevMode ? [{ debugName: "model" }] : []));
424
+ this.group = input.required(...(ngDevMode ? [{ debugName: "group" }] : []));
425
+ }
426
+ get valueCount() {
427
+ return this.input()?.value ? this.input().value.length : 0;
428
+ }
429
+ get maxCountText() {
430
+ return `${this.valueCount} / ${this.model().maxLength}`;
431
+ }
432
+ get showClear() {
433
+ return !!this.control.value && !this.control.disabled && !this.model().showLoader;
434
+ }
435
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DynamicInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
436
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DynamicInputComponent, isStandalone: true, selector: "dynamic-input", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null }, group: { classPropertyName: "group", publicName: "group", isSignal: true, isRequired: true, transformFunction: null } }, viewQueries: [{ propertyName: "input", first: true, predicate: MatInput, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<mat-form-field\n [formGroup]=\"group()\"\n [id]=\"id\"\n color=\"primary\">\n @if (model().label) {\n <mat-label>{{ model().label }}</mat-label>\n }\n\n @if (model().prefix) {\n <span matTextPrefix>{{ model().prefix }}</span>\n }\n\n <input\n matInput\n [type]=\"model().inputType\"\n [formControlName]=\"model().name\"\n [placeholder]=\"model().placeholder\"\n [attr.min]=\"model().min\"\n [attr.max]=\"model().max\"\n [attr.minLength]=\"model().minLength\"\n [attr.maxLength]=\"model().maxLength\"\n [pattern]=\"model().pattern\"\n [autocomplete]=\"model().autocomplete\" />\n\n @if (showClear) {\n <button\n matSuffix\n mat-icon-button\n (click)=\"resetControl()\">\n <mat-icon fontIcon=\"clear\"></mat-icon>\n </button>\n }\n\n @if (model().showLoader()) {\n <div\n matSuffix\n class=\"loader-icon\">\n <mat-spinner\n diameter=\"16\"\n color=\"primary\"></mat-spinner>\n </div>\n }\n\n @if (model().hint) {\n <mat-hint align=\"start\">{{ model().hint }}</mat-hint>\n }\n\n @if (model().maxLength) {\n <mat-hint align=\"end\">{{ maxCountText }}</mat-hint>\n }\n\n @for (validator of model().validators; track validator.name) {\n <ng-container ngProjectAs=\"mat-error\">\n @if (hasError(validator.name)) {\n <mat-error>{{ validator.message }}</mat-error>\n }\n </ng-container>\n }\n</mat-form-field>\n", styles: ["mat-form-field{width:100%}mat-form-field .loader-icon{padding:8px}input::-webkit-outer-spin-button,input::-webkit-inner-spin-button{appearance:none;margin:0}input[type=number]{appearance:textfield}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i2$1.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1$2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i6.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }] }); }
437
+ }
438
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DynamicInputComponent, decorators: [{
439
+ type: Component,
440
+ args: [{ imports: [ReactiveFormsModule, MatFormFieldModule, MatInputModule, MatButtonModule, MatIconModule, MatProgressSpinnerModule], selector: 'dynamic-input', template: "<mat-form-field\n [formGroup]=\"group()\"\n [id]=\"id\"\n color=\"primary\">\n @if (model().label) {\n <mat-label>{{ model().label }}</mat-label>\n }\n\n @if (model().prefix) {\n <span matTextPrefix>{{ model().prefix }}</span>\n }\n\n <input\n matInput\n [type]=\"model().inputType\"\n [formControlName]=\"model().name\"\n [placeholder]=\"model().placeholder\"\n [attr.min]=\"model().min\"\n [attr.max]=\"model().max\"\n [attr.minLength]=\"model().minLength\"\n [attr.maxLength]=\"model().maxLength\"\n [pattern]=\"model().pattern\"\n [autocomplete]=\"model().autocomplete\" />\n\n @if (showClear) {\n <button\n matSuffix\n mat-icon-button\n (click)=\"resetControl()\">\n <mat-icon fontIcon=\"clear\"></mat-icon>\n </button>\n }\n\n @if (model().showLoader()) {\n <div\n matSuffix\n class=\"loader-icon\">\n <mat-spinner\n diameter=\"16\"\n color=\"primary\"></mat-spinner>\n </div>\n }\n\n @if (model().hint) {\n <mat-hint align=\"start\">{{ model().hint }}</mat-hint>\n }\n\n @if (model().maxLength) {\n <mat-hint align=\"end\">{{ maxCountText }}</mat-hint>\n }\n\n @for (validator of model().validators; track validator.name) {\n <ng-container ngProjectAs=\"mat-error\">\n @if (hasError(validator.name)) {\n <mat-error>{{ validator.message }}</mat-error>\n }\n </ng-container>\n }\n</mat-form-field>\n", styles: ["mat-form-field{width:100%}mat-form-field .loader-icon{padding:8px}input::-webkit-outer-spin-button,input::-webkit-inner-spin-button{appearance:none;margin:0}input[type=number]{appearance:textfield}\n"] }]
441
+ }], propDecorators: { input: [{ type: i0.ViewChild, args: [i0.forwardRef(() => MatInput), { isSignal: true }] }], model: [{ type: i0.Input, args: [{ isSignal: true, alias: "model", required: true }] }], group: [{ type: i0.Input, args: [{ isSignal: true, alias: "group", required: true }] }] } });
442
+
443
+ class DymamicRadioGroupComponent extends DynamicFormFieldBase {
444
+ constructor() {
445
+ super(...arguments);
446
+ this.model = input.required(...(ngDevMode ? [{ debugName: "model" }] : []));
447
+ this.group = input.required(...(ngDevMode ? [{ debugName: "group" }] : []));
448
+ }
449
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DymamicRadioGroupComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
450
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DymamicRadioGroupComponent, isStandalone: true, selector: "dynamic-radio-group", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null }, group: { classPropertyName: "group", publicName: "group", isSignal: true, isRequired: true, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<div\n class=\"dynamic-radio-group-wrapper\"\n [formGroup]=\"group()\">\n @if (model().label) {\n <label>{{ model().label }}</label>\n }\n <mat-radio-group\n [formControlName]=\"model().name\"\n class=\"radio-group\"\n [class.inlint]=\"model().inline\">\n @for (option of model().options$ | async; track option.value) {\n <mat-radio-button\n [value]=\"option.value\"\n [labelPosition]=\"model().labelPosition\">\n {{ option.label }}\n </mat-radio-button>\n }\n </mat-radio-group>\n</div>\n", styles: [".dynamic-radio-group-wrapper label{display:block;font-size:var(--mat-typography-body2-font-size, 14px);margin-bottom:8px}.dynamic-radio-group-wrapper .radio-group:not(.inline){display:flex;flex-direction:column;align-items:flex-start}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatRadioModule }, { kind: "directive", type: i2$2.MatRadioGroup, selector: "mat-radio-group", inputs: ["color", "name", "labelPosition", "value", "selected", "disabled", "required", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioGroup"] }, { kind: "component", type: i2$2.MatRadioButton, selector: "mat-radio-button", inputs: ["id", "name", "aria-label", "aria-labelledby", "aria-describedby", "disableRipple", "tabIndex", "checked", "value", "labelPosition", "disabled", "required", "color", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioButton"] }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
451
+ }
452
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DymamicRadioGroupComponent, decorators: [{
453
+ type: Component,
454
+ args: [{ imports: [ReactiveFormsModule, MatRadioModule, AsyncPipe], selector: 'dynamic-radio-group', template: "<div\n class=\"dynamic-radio-group-wrapper\"\n [formGroup]=\"group()\">\n @if (model().label) {\n <label>{{ model().label }}</label>\n }\n <mat-radio-group\n [formControlName]=\"model().name\"\n class=\"radio-group\"\n [class.inlint]=\"model().inline\">\n @for (option of model().options$ | async; track option.value) {\n <mat-radio-button\n [value]=\"option.value\"\n [labelPosition]=\"model().labelPosition\">\n {{ option.label }}\n </mat-radio-button>\n }\n </mat-radio-group>\n</div>\n", styles: [".dynamic-radio-group-wrapper label{display:block;font-size:var(--mat-typography-body2-font-size, 14px);margin-bottom:8px}.dynamic-radio-group-wrapper .radio-group:not(.inline){display:flex;flex-direction:column;align-items:flex-start}\n"] }]
455
+ }], propDecorators: { model: [{ type: i0.Input, args: [{ isSignal: true, alias: "model", required: true }] }], group: [{ type: i0.Input, args: [{ isSignal: true, alias: "group", required: true }] }] } });
456
+
457
+ class DynamicReadonlyComponent extends DynamicFormFieldBase {
458
+ constructor() {
459
+ super(...arguments);
460
+ this.model = input.required(...(ngDevMode ? [{ debugName: "model" }] : []));
461
+ this.group = input.required(...(ngDevMode ? [{ debugName: "group" }] : []));
462
+ }
463
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DynamicReadonlyComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
464
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.16", type: DynamicReadonlyComponent, isStandalone: true, selector: "dynamic-readonly", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null }, group: { classPropertyName: "group", publicName: "group", isSignal: true, isRequired: true, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<div\n class=\"dynamic-form-field-readonly\"\n [formGroup]=\"group()\"\n [id]=\"model().id\">\n <div class=\"label\">{{ model().label }}</div>\n <span>{{ model().value }}</span>\n</div>\n", styles: [".dynamic-form-field-readonly{width:100%;margin:8px 0;color:var(--mat-theme-text-primary-on-background, rgba(0, 0, 0, .87))}.dynamic-form-field-readonly .label{font-size:var(--mat-typography-body2-font-size, 14px);line-height:var(--mat-typography-body2-line-height, 20px);margin-bottom:8px}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }] }); }
465
+ }
466
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DynamicReadonlyComponent, decorators: [{
467
+ type: Component,
468
+ args: [{ imports: [ReactiveFormsModule], selector: 'dynamic-readonly', template: "<div\n class=\"dynamic-form-field-readonly\"\n [formGroup]=\"group()\"\n [id]=\"model().id\">\n <div class=\"label\">{{ model().label }}</div>\n <span>{{ model().value }}</span>\n</div>\n", styles: [".dynamic-form-field-readonly{width:100%;margin:8px 0;color:var(--mat-theme-text-primary-on-background, rgba(0, 0, 0, .87))}.dynamic-form-field-readonly .label{font-size:var(--mat-typography-body2-font-size, 14px);line-height:var(--mat-typography-body2-line-height, 20px);margin-bottom:8px}\n"] }]
469
+ }], propDecorators: { model: [{ type: i0.Input, args: [{ isSignal: true, alias: "model", required: true }] }], group: [{ type: i0.Input, args: [{ isSignal: true, alias: "group", required: true }] }] } });
470
+
471
+ class DynamicSelectComponent extends DynamicFormFieldBase {
472
+ constructor() {
473
+ super(...arguments);
474
+ this.model = input.required(...(ngDevMode ? [{ debugName: "model" }] : []));
475
+ this.group = input.required(...(ngDevMode ? [{ debugName: "group" }] : []));
476
+ }
477
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DynamicSelectComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
478
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DynamicSelectComponent, isStandalone: true, selector: "dynamic-select", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null }, group: { classPropertyName: "group", publicName: "group", isSignal: true, isRequired: true, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<mat-form-field\n [formGroup]=\"group()\"\n [id]=\"model().id\"\n color=\"primary\">\n <mat-label>{{ model().label }}</mat-label>\n\n <!-- Template for select without grouped options -->\n @if (model().options$ | async; as options) {\n @if (!model().native) {\n <mat-select\n [formControlName]=\"model().name\"\n [multiple]=\"model().multiple\">\n @for (option of options; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.label }}\n </mat-option>\n }\n </mat-select>\n } @else {\n <select matNativeControl>\n @for (option of options; track option.value) {\n <option [value]=\"option.value\">\n {{ option.label }}\n </option>\n }\n </select>\n }\n }\n\n <!-- Template for select with grouped options -->\n @if (model().groupedOptions$ | async; as groupedOptions) {\n @if (!model().native) {\n <mat-select [formControlName]=\"model().name\">\n @for (group of groupedOptions; track group.name) {\n <mat-optgroup [label]=\"group.name\">\n @for (option of group.options; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.label }}\n </mat-option>\n }\n </mat-optgroup>\n }\n </mat-select>\n } @else {\n <select matNativeControl>\n @for (group of groupedOptions; track group.name) {\n =\n <optgroup [label]=\"group.name\">\n @for (option of group.options; track option.value) {\n <option [value]=\"option.value\">\n {{ option.label }}\n </option>\n }\n </optgroup>\n }\n </select>\n }\n }\n\n @if (model().hint) {\n <mat-hint align=\"start\">{{ model().hint }}</mat-hint>\n }\n\n @for (validator of model().validators; track validator.name) {\n <ng-container ngProjectAs=\"mat-error\">\n @if (hasError(validator.name)) {\n <mat-error>{{ validator.message }}</mat-error>\n }\n </ng-container>\n }\n</mat-form-field>\n", styles: ["mat-form-field{width:100%}mat-option{padding-top:8px;padding-bottom:8px}\n"], dependencies: [{ kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i3$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i3$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i3$1.MatOptgroup, selector: "mat-optgroup", inputs: ["label", "disabled"], exportAs: ["matOptgroup"] }, { kind: "ngmodule", type: MatOptionModule }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
479
+ }
480
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DynamicSelectComponent, decorators: [{
481
+ type: Component,
482
+ args: [{ imports: [MatFormFieldModule, ReactiveFormsModule, MatSelectModule, MatOptionModule, AsyncPipe, MatInputModule], selector: 'dynamic-select', template: "<mat-form-field\n [formGroup]=\"group()\"\n [id]=\"model().id\"\n color=\"primary\">\n <mat-label>{{ model().label }}</mat-label>\n\n <!-- Template for select without grouped options -->\n @if (model().options$ | async; as options) {\n @if (!model().native) {\n <mat-select\n [formControlName]=\"model().name\"\n [multiple]=\"model().multiple\">\n @for (option of options; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.label }}\n </mat-option>\n }\n </mat-select>\n } @else {\n <select matNativeControl>\n @for (option of options; track option.value) {\n <option [value]=\"option.value\">\n {{ option.label }}\n </option>\n }\n </select>\n }\n }\n\n <!-- Template for select with grouped options -->\n @if (model().groupedOptions$ | async; as groupedOptions) {\n @if (!model().native) {\n <mat-select [formControlName]=\"model().name\">\n @for (group of groupedOptions; track group.name) {\n <mat-optgroup [label]=\"group.name\">\n @for (option of group.options; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.label }}\n </mat-option>\n }\n </mat-optgroup>\n }\n </mat-select>\n } @else {\n <select matNativeControl>\n @for (group of groupedOptions; track group.name) {\n =\n <optgroup [label]=\"group.name\">\n @for (option of group.options; track option.value) {\n <option [value]=\"option.value\">\n {{ option.label }}\n </option>\n }\n </optgroup>\n }\n </select>\n }\n }\n\n @if (model().hint) {\n <mat-hint align=\"start\">{{ model().hint }}</mat-hint>\n }\n\n @for (validator of model().validators; track validator.name) {\n <ng-container ngProjectAs=\"mat-error\">\n @if (hasError(validator.name)) {\n <mat-error>{{ validator.message }}</mat-error>\n }\n </ng-container>\n }\n</mat-form-field>\n", styles: ["mat-form-field{width:100%}mat-option{padding-top:8px;padding-bottom:8px}\n"] }]
483
+ }], propDecorators: { model: [{ type: i0.Input, args: [{ isSignal: true, alias: "model", required: true }] }], group: [{ type: i0.Input, args: [{ isSignal: true, alias: "group", required: true }] }] } });
484
+
485
+ class DynamicTextareaComponent extends DynamicFormFieldBase {
486
+ constructor() {
487
+ super(...arguments);
488
+ this.textarea = viewChild.required(MatInput);
489
+ this.model = input.required(...(ngDevMode ? [{ debugName: "model" }] : []));
490
+ this.group = input.required(...(ngDevMode ? [{ debugName: "group" }] : []));
491
+ }
492
+ get valueCount() {
493
+ return this.textarea()?.value ? this.textarea().value.length : 0;
494
+ }
495
+ get maxCountText() {
496
+ return `${this.valueCount} / ${this.model().maxLength}`;
497
+ }
498
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DynamicTextareaComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
499
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DynamicTextareaComponent, isStandalone: true, selector: "dynamic-textarea", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null }, group: { classPropertyName: "group", publicName: "group", isSignal: true, isRequired: true, transformFunction: null } }, viewQueries: [{ propertyName: "textarea", first: true, predicate: MatInput, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<mat-form-field\n [formGroup]=\"group()\"\n [id]=\"id\"\n color=\"primary\">\n @if (model().label) {\n <mat-label>{{ model().label }}</mat-label>\n }\n\n <textarea\n matInput\n [cdkTextareaAutosize]=\"model().resize\"\n [cdkAutosizeMinRows]=\"model().rows\"\n [cdkAutosizeMaxRows]=\"model().resizeMaxRows\"\n [id]=\"id\"\n [formControlName]=\"model().name\"\n [placeholder]=\"model().placeholder\"\n [attr.minLength]=\"model().minLength\"\n [attr.maxLength]=\"model().maxLength\"\n [rows]=\"model().rows\"\n [autocomplete]=\"model().autocomplete\">\n </textarea>\n\n @if (model().hint) {\n <mat-hint align=\"start\">{{ model().hint }}</mat-hint>\n }\n\n @if (model().maxLength) {\n <mat-hint align=\"end\">{{ maxCountText }}</mat-hint>\n }\n\n @for (validator of model().validators; track validator.name) {\n <ng-container ngProjectAs=\"mat-error\">\n @if (hasError(validator.name)) {\n <mat-error>{{ validator.message }}</mat-error>\n }\n </ng-container>\n }\n</mat-form-field>\n", styles: ["mat-form-field{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "directive", type: i3$2.CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }] }); }
500
+ }
501
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DynamicTextareaComponent, decorators: [{
502
+ type: Component,
503
+ args: [{ imports: [MatFormFieldModule, MatInputModule, ReactiveFormsModule], selector: 'dynamic-textarea', template: "<mat-form-field\n [formGroup]=\"group()\"\n [id]=\"id\"\n color=\"primary\">\n @if (model().label) {\n <mat-label>{{ model().label }}</mat-label>\n }\n\n <textarea\n matInput\n [cdkTextareaAutosize]=\"model().resize\"\n [cdkAutosizeMinRows]=\"model().rows\"\n [cdkAutosizeMaxRows]=\"model().resizeMaxRows\"\n [id]=\"id\"\n [formControlName]=\"model().name\"\n [placeholder]=\"model().placeholder\"\n [attr.minLength]=\"model().minLength\"\n [attr.maxLength]=\"model().maxLength\"\n [rows]=\"model().rows\"\n [autocomplete]=\"model().autocomplete\">\n </textarea>\n\n @if (model().hint) {\n <mat-hint align=\"start\">{{ model().hint }}</mat-hint>\n }\n\n @if (model().maxLength) {\n <mat-hint align=\"end\">{{ maxCountText }}</mat-hint>\n }\n\n @for (validator of model().validators; track validator.name) {\n <ng-container ngProjectAs=\"mat-error\">\n @if (hasError(validator.name)) {\n <mat-error>{{ validator.message }}</mat-error>\n }\n </ng-container>\n }\n</mat-form-field>\n", styles: ["mat-form-field{width:100%}\n"] }]
504
+ }], propDecorators: { textarea: [{ type: i0.ViewChild, args: [i0.forwardRef(() => MatInput), { isSignal: true }] }], model: [{ type: i0.Input, args: [{ isSignal: true, alias: "model", required: true }] }], group: [{ type: i0.Input, args: [{ isSignal: true, alias: "group", required: true }] }] } });
505
+
506
+ const DYNAMIC_FORM_FIELD_MAP = {
507
+ [DYNAMIC_FORM_FIELD_BUTTON]: DynamicButtonComponent,
508
+ [DYNAMIC_FORM_FIELD_BUTTON_TOGGLES]: DynamicButtonTogglesComponent,
509
+ [DYNAMIC_FORM_FIELD_CHECKBOX]: DynamicCheckboxComponent,
510
+ [DYNAMIC_FORM_FIELD_DATEPICKER]: DynamicDatepickerComponent,
511
+ [DYNAMIC_FORM_FIELD_INPUT]: DynamicInputComponent,
512
+ [DYNAMIC_FORM_FIELD_RADIO_GROUP]: DymamicRadioGroupComponent,
513
+ [DYNAMIC_FORM_FIELD_READONLY]: DynamicReadonlyComponent,
514
+ [DYNAMIC_FORM_FIELD_SELECT]: DynamicSelectComponent,
515
+ [DYNAMIC_FORM_FIELD_TEXTAREA]: DynamicTextareaComponent
516
+ };
517
+
584
518
  class DynamicFormValidators {
585
519
  /**
586
520
  * Default email validator, the value of the control has to be a valid email address
@@ -729,9 +663,7 @@ class DynamicFormRelationsService {
729
663
  const conditionReducer = (controls, condition) => {
730
664
  const fieldName = condition.path ?? condition.fieldName;
731
665
  // Get the control using the provided path or fieldName
732
- const control = condition.path
733
- ? group.root.get(condition.path)
734
- : group.get(condition.fieldName);
666
+ const control = condition.path ? group.root.get(condition.path) : group.get(condition.fieldName);
735
667
  if (!control) {
736
668
  console.warn(`No related form control with the name ${fieldName} found`);
737
669
  return controls;
@@ -820,19 +752,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
820
752
 
821
753
  class DynamicFormFieldComponent {
822
754
  constructor() {
823
- this.change = new EventEmitter();
755
+ this.componentViewContainer = viewChild.required('componentViewContainer', { read: ViewContainerRef });
756
+ this.model = input.required(...(ngDevMode ? [{ debugName: "model" }] : []));
757
+ this.group = input.required(...(ngDevMode ? [{ debugName: "group" }] : []));
824
758
  this.dynamicFormService = inject(DynamicFormService);
825
759
  this.relationService = inject(DynamicFormRelationsService);
826
760
  this.cdRef = inject(ChangeDetectorRef);
827
761
  this._subs = new Subscription();
828
762
  }
829
- /** Get the instance of a control component using the injected custom method or local method */
763
+ /**
764
+ * Get the instance of a control component using the injected custom method or local method
765
+ */
830
766
  get componentType() {
831
- return this.dynamicFormService.getCustomControlComponentType(this.model) || this.getControlComponentType();
767
+ return this.dynamicFormService.getCustomControlComponentType(this.model()) || this.getControlComponentType();
832
768
  }
833
769
  ngOnInit() {
834
- if (this.group) {
835
- this._control = this.group.get(this.model.name);
770
+ if (this.group()) {
771
+ this._control = this.group().get(this.model().name);
836
772
  this.createFormControlComponent();
837
773
  this.setSubscriptions();
838
774
  }
@@ -845,51 +781,32 @@ class DynamicFormFieldComponent {
845
781
  * @returns
846
782
  */
847
783
  getControlComponentType() {
848
- switch (this.model.type) {
849
- case DYNAMIC_FORM_FIELD_BUTTON:
850
- return DynamicButtonComponent;
851
- case DYNAMIC_FORM_FIELD_BUTTON_TOGGLES:
852
- return DynamicButtonTogglesComponent;
853
- case DYNAMIC_FORM_FIELD_CHECKBOX:
854
- return DynamicCheckboxComponent;
855
- case DYNAMIC_FORM_FIELD_DATEPICKER:
856
- return DynamicDatepickerComponent;
857
- case DYNAMIC_FORM_FIELD_INPUT:
858
- return DynamicInputComponent;
859
- case DYNAMIC_FORM_FIELD_RADIO_GROUP:
860
- return DymamicRadioGroupComponent;
861
- case DYNAMIC_FORM_FIELD_READONLY:
862
- return DynamicReadonlyComponent;
863
- case DYNAMIC_FORM_FIELD_SELECT:
864
- return DynamicSelectComponent;
865
- case DYNAMIC_FORM_FIELD_TEXTAREA:
866
- return DynamicTextareaComponent;
867
- default:
868
- console.warn(`Model of type 'dynamic-${this.model.type}' is not implemented yet. Add this type to dynamic-form-field.component.ts to add support`);
869
- return null;
784
+ const field = DYNAMIC_FORM_FIELD_MAP[this.model().type];
785
+ if (!field) {
786
+ console.warn(`Model of type 'dynamic-${this.model().type}' is not implemented yet. Add this type to dynamic-form-field.component.ts to add support`);
787
+ return null;
870
788
  }
789
+ return field;
871
790
  }
872
791
  createFormControlComponent() {
873
792
  const component = this.componentType;
874
793
  if (component != null) {
875
- let componentRef = this.componentViewContainer.createComponent(component);
876
- const componentInstance = componentRef.instance;
877
- this._subs.add(componentInstance.change?.subscribe((event) => this.onChange(event)));
878
- componentInstance.group = this.group;
879
- componentInstance.model = this.model;
794
+ let componentRef = this.componentViewContainer().createComponent(component);
795
+ componentRef.setInput('group', this.group());
796
+ componentRef.setInput('model', this.model());
880
797
  }
881
798
  }
882
799
  /**
883
800
  * Setup all necessary subscriptions of the FormControl
884
801
  */
885
802
  setSubscriptions() {
886
- const model = this.model;
803
+ const model = this.model();
887
804
  // Subscribe to the value change inside the control to change the value inside the model as well
888
805
  this._subs.add(this._control.valueChanges.subscribe((value) => this.onValueChange(value)));
889
806
  // Subscribe to the disabled change inside the model to change the disabled state of the FormControl
890
807
  this._subs.add(model.disabledChange.subscribe((disabled) => this.onDisabledChange(disabled)));
891
808
  // Setup subscriptions for any possible relation
892
- if (this.model.relations?.length) {
809
+ if (this.model().relations?.length) {
893
810
  this.setUpRelations();
894
811
  }
895
812
  }
@@ -898,8 +815,8 @@ class DynamicFormFieldComponent {
898
815
  */
899
816
  setUpRelations() {
900
817
  // Array of all FormControls the current model has a relation to
901
- const relatedFormControls = this.relationService.findRelatedFormField(this.model, this.group);
902
- const subs = this.relationService.getRelationSubscriptions(relatedFormControls, this.model, this._control);
818
+ const relatedFormControls = this.relationService.findRelatedFormField(this.model(), this.group());
819
+ const subs = this.relationService.getRelationSubscriptions(relatedFormControls, this.model(), this._control);
903
820
  // Add all relations as subscription to the main Subscription object
904
821
  subs.forEach((sub) => this._subs.add(sub));
905
822
  }
@@ -908,8 +825,8 @@ class DynamicFormFieldComponent {
908
825
  * @param value
909
826
  */
910
827
  onValueChange(value) {
911
- if (this.model instanceof DynamicFormFieldValueModel && this.model.value !== value) {
912
- this.model.value = value;
828
+ if (this.model() instanceof DynamicFormFieldValueModel && this.model().value !== value) {
829
+ this.model().value = value;
913
830
  }
914
831
  }
915
832
  /**
@@ -921,45 +838,31 @@ class DynamicFormFieldComponent {
921
838
  disabled ? this._control.disable() : this._control.enable();
922
839
  this.cdRef.markForCheck();
923
840
  }
924
- onChange(ev) {
925
- this.change.emit(this.createDynamicFormEvent(ev, 'change'));
926
- }
927
- createDynamicFormEvent(event, type) {
928
- return { event, type, control: this._control, form: this.group, model: this.model };
929
- }
930
841
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DynamicFormFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
931
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: DynamicFormFieldComponent, isStandalone: true, selector: "dynamic-form-field", inputs: { model: "model", group: "group" }, outputs: { change: "change" }, viewQueries: [{ propertyName: "componentViewContainer", first: true, predicate: ["componentViewContainer"], descendants: true, read: ViewContainerRef, static: true }], ngImport: i0, template: "<div [formGroup]=\"group\"\n [ngClass]=\"['dynamic-form-field-container', 'dynamic-form-field-' + model.type]\">\n <ng-container #componentViewContainer></ng-container>\n</div>", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
842
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.3.16", type: DynamicFormFieldComponent, isStandalone: true, selector: "dynamic-form-field", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null }, group: { classPropertyName: "group", publicName: "group", isSignal: true, isRequired: true, transformFunction: null } }, viewQueries: [{ propertyName: "componentViewContainer", first: true, predicate: ["componentViewContainer"], descendants: true, read: ViewContainerRef, isSignal: true }], ngImport: i0, template: "<div\n [formGroup]=\"group()\"\n [ngClass]=\"['dynamic-form-field-container', 'dynamic-form-field-' + model().type]\">\n <ng-container #componentViewContainer></ng-container>\n</div>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
932
843
  }
933
844
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DynamicFormFieldComponent, decorators: [{
934
845
  type: Component,
935
- args: [{ imports: [NgClass, ReactiveFormsModule], selector: 'dynamic-form-field', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [formGroup]=\"group\"\n [ngClass]=\"['dynamic-form-field-container', 'dynamic-form-field-' + model.type]\">\n <ng-container #componentViewContainer></ng-container>\n</div>" }]
936
- }], propDecorators: { componentViewContainer: [{
937
- type: ViewChild,
938
- args: ['componentViewContainer', { read: ViewContainerRef, static: true }]
939
- }], model: [{
940
- type: Input
941
- }], group: [{
942
- type: Input
943
- }], change: [{
944
- type: Output
945
- }] } });
846
+ args: [{ imports: [NgClass, ReactiveFormsModule], selector: 'dynamic-form-field', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n [formGroup]=\"group()\"\n [ngClass]=\"['dynamic-form-field-container', 'dynamic-form-field-' + model().type]\">\n <ng-container #componentViewContainer></ng-container>\n</div>\n" }]
847
+ }], propDecorators: { componentViewContainer: [{ type: i0.ViewChild, args: ['componentViewContainer', { ...{ read: ViewContainerRef }, isSignal: true }] }], model: [{ type: i0.Input, args: [{ isSignal: true, alias: "model", required: true }] }], group: [{ type: i0.Input, args: [{ isSignal: true, alias: "group", required: true }] }] } });
946
848
 
947
849
  class DynamicFormComponent {
948
850
  constructor() {
949
- this.change = new EventEmitter();
851
+ this.group = input.required(...(ngDevMode ? [{ debugName: "group" }] : []));
852
+ this.formConfig = input.required(...(ngDevMode ? [{ debugName: "formConfig" }] : []));
950
853
  }
951
854
  /**
952
855
  * Get the formConfig as flat array.
953
856
  */
954
857
  get flatFormConfig() {
955
- return this.formConfig.reduce((acc, curr) => acc.concat(curr), []);
858
+ return this.formConfig().reduce((acc, curr) => acc.concat(curr), []);
956
859
  }
957
860
  /**
958
861
  * Get the current value of the form.
959
862
  * @param includeDisabledFields Include the disabled fields of the form, is enabled by default
960
863
  */
961
864
  getFormValue(includeDisabledFields = true) {
962
- const formValue = includeDisabledFields ? this.group.getRawValue() : this.group.value;
865
+ const formValue = includeDisabledFields ? this.group().getRawValue() : this.group().value;
963
866
  return formValue;
964
867
  }
965
868
  /**
@@ -969,30 +872,59 @@ class DynamicFormComponent {
969
872
  * @returns Observable<unknown>
970
873
  */
971
874
  onControlChange(name) {
972
- const field = this.group.get(name);
875
+ const field = this.group().get(name);
973
876
  if (!field) {
974
877
  throw new Error(`Cannot find a field with the name ${name} in the FormGroup`);
975
878
  }
976
879
  return field.valueChanges;
977
880
  }
978
- onChange(event) {
979
- this.change.emit(event);
980
- }
981
881
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DynamicFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
982
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DynamicFormComponent, isStandalone: true, selector: "dynamic-form", inputs: { group: "group", formConfig: "formConfig" }, outputs: { change: "change" }, providers: [DynamicFormService], ngImport: i0, template: "@for(row of formConfig; track $index) {\n<div class=\"dynamic-form-row\">\n @for(field of row; track field.id) {\n <dynamic-form-field class=\"dynamic-form-field\"\n [id]=\"field.id\"\n [hidden]=\"field.hidden\"\n [ngClass]=\"[field.type, 'form-field-width-' + field.width]\"\n [group]=\"group\"\n [model]=\"field\"\n (change)=\"onChange($event)\">\n </dynamic-form-field>\n }\n</div>\n}", styles: [".dynamic-form-row{display:flex}.dynamic-form-row .dynamic-form-field{width:100%}.dynamic-form-row .dynamic-form-field:not(:last-of-type){margin-right:12px}.dynamic-form-row .dynamic-form-field.button{flex:0}.dynamic-form-row .form-field-width-5{width:5%}.dynamic-form-row .form-field-width-10{width:10%}.dynamic-form-row .form-field-width-15{width:15%}.dynamic-form-row .form-field-width-20{width:20%}.dynamic-form-row .form-field-width-25{width:25%}.dynamic-form-row .form-field-width-30{width:30%}.dynamic-form-row .form-field-width-35{width:35%}.dynamic-form-row .form-field-width-40{width:40%}.dynamic-form-row .form-field-width-45{width:45%}.dynamic-form-row .form-field-width-50{width:50%}.dynamic-form-row .form-field-width-55{width:55%}.dynamic-form-row .form-field-width-60{width:60%}.dynamic-form-row .form-field-width-65{width:65%}.dynamic-form-row .form-field-width-70{width:70%}.dynamic-form-row .form-field-width-75{width:75%}.dynamic-form-row .form-field-width-80{width:80%}.dynamic-form-row .form-field-width-85{width:85%}.dynamic-form-row .form-field-width-90{width:90%}.dynamic-form-row .form-field-width-95{width:95%}.dynamic-form-row .form-field-width-100{width:100%}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: DynamicFormFieldComponent, selector: "dynamic-form-field", inputs: ["model", "group"], outputs: ["change"] }, { kind: "ngmodule", type: ReactiveFormsModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
882
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DynamicFormComponent, isStandalone: true, selector: "dynamic-form", inputs: { group: { classPropertyName: "group", publicName: "group", isSignal: true, isRequired: true, transformFunction: null }, formConfig: { classPropertyName: "formConfig", publicName: "formConfig", isSignal: true, isRequired: true, transformFunction: null } }, providers: [DynamicFormService], ngImport: i0, template: "@for (row of formConfig(); track $index) {\n <div class=\"dynamic-form-row\">\n @for (field of row; track field.id) {\n <dynamic-form-field\n class=\"dynamic-form-field\"\n [id]=\"field.id\"\n [hidden]=\"field.hidden\"\n [ngClass]=\"[field.type, 'form-field-width-' + field.width]\"\n [group]=\"group()\"\n [model]=\"field\">\n </dynamic-form-field>\n }\n </div>\n}\n", styles: [".dynamic-form-row{display:flex;gap:var(--form-field-spacing, 1rem)}.dynamic-form-row .dynamic-form-field{width:100%}.dynamic-form-row .dynamic-form-field.button{flex:0}.dynamic-form-row .form-field-width-5{width:5%}.dynamic-form-row .form-field-width-10{width:10%}.dynamic-form-row .form-field-width-15{width:15%}.dynamic-form-row .form-field-width-20{width:20%}.dynamic-form-row .form-field-width-25{width:25%}.dynamic-form-row .form-field-width-30{width:30%}.dynamic-form-row .form-field-width-35{width:35%}.dynamic-form-row .form-field-width-40{width:40%}.dynamic-form-row .form-field-width-45{width:45%}.dynamic-form-row .form-field-width-50{width:50%}.dynamic-form-row .form-field-width-55{width:55%}.dynamic-form-row .form-field-width-60{width:60%}.dynamic-form-row .form-field-width-65{width:65%}.dynamic-form-row .form-field-width-70{width:70%}.dynamic-form-row .form-field-width-75{width:75%}.dynamic-form-row .form-field-width-80{width:80%}.dynamic-form-row .form-field-width-85{width:85%}.dynamic-form-row .form-field-width-90{width:90%}.dynamic-form-row .form-field-width-95{width:95%}.dynamic-form-row .form-field-width-100{width:100%}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: DynamicFormFieldComponent, selector: "dynamic-form-field", inputs: ["model", "group"] }, { kind: "ngmodule", type: ReactiveFormsModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
983
883
  }
984
884
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DynamicFormComponent, decorators: [{
985
885
  type: Component,
986
- args: [{ imports: [NgClass, DynamicFormFieldComponent, ReactiveFormsModule], selector: 'dynamic-form', providers: [DynamicFormService], changeDetection: ChangeDetectionStrategy.OnPush, template: "@for(row of formConfig; track $index) {\n<div class=\"dynamic-form-row\">\n @for(field of row; track field.id) {\n <dynamic-form-field class=\"dynamic-form-field\"\n [id]=\"field.id\"\n [hidden]=\"field.hidden\"\n [ngClass]=\"[field.type, 'form-field-width-' + field.width]\"\n [group]=\"group\"\n [model]=\"field\"\n (change)=\"onChange($event)\">\n </dynamic-form-field>\n }\n</div>\n}", styles: [".dynamic-form-row{display:flex}.dynamic-form-row .dynamic-form-field{width:100%}.dynamic-form-row .dynamic-form-field:not(:last-of-type){margin-right:12px}.dynamic-form-row .dynamic-form-field.button{flex:0}.dynamic-form-row .form-field-width-5{width:5%}.dynamic-form-row .form-field-width-10{width:10%}.dynamic-form-row .form-field-width-15{width:15%}.dynamic-form-row .form-field-width-20{width:20%}.dynamic-form-row .form-field-width-25{width:25%}.dynamic-form-row .form-field-width-30{width:30%}.dynamic-form-row .form-field-width-35{width:35%}.dynamic-form-row .form-field-width-40{width:40%}.dynamic-form-row .form-field-width-45{width:45%}.dynamic-form-row .form-field-width-50{width:50%}.dynamic-form-row .form-field-width-55{width:55%}.dynamic-form-row .form-field-width-60{width:60%}.dynamic-form-row .form-field-width-65{width:65%}.dynamic-form-row .form-field-width-70{width:70%}.dynamic-form-row .form-field-width-75{width:75%}.dynamic-form-row .form-field-width-80{width:80%}.dynamic-form-row .form-field-width-85{width:85%}.dynamic-form-row .form-field-width-90{width:90%}.dynamic-form-row .form-field-width-95{width:95%}.dynamic-form-row .form-field-width-100{width:100%}\n"] }]
987
- }], propDecorators: { group: [{
988
- type: Input,
989
- args: [{ required: true }]
990
- }], formConfig: [{
991
- type: Input,
992
- args: [{ required: true }]
993
- }], change: [{
994
- type: Output
995
- }] } });
886
+ args: [{ imports: [NgClass, DynamicFormFieldComponent, ReactiveFormsModule], selector: 'dynamic-form', providers: [DynamicFormService], changeDetection: ChangeDetectionStrategy.OnPush, template: "@for (row of formConfig(); track $index) {\n <div class=\"dynamic-form-row\">\n @for (field of row; track field.id) {\n <dynamic-form-field\n class=\"dynamic-form-field\"\n [id]=\"field.id\"\n [hidden]=\"field.hidden\"\n [ngClass]=\"[field.type, 'form-field-width-' + field.width]\"\n [group]=\"group()\"\n [model]=\"field\">\n </dynamic-form-field>\n }\n </div>\n}\n", styles: [".dynamic-form-row{display:flex;gap:var(--form-field-spacing, 1rem)}.dynamic-form-row .dynamic-form-field{width:100%}.dynamic-form-row .dynamic-form-field.button{flex:0}.dynamic-form-row .form-field-width-5{width:5%}.dynamic-form-row .form-field-width-10{width:10%}.dynamic-form-row .form-field-width-15{width:15%}.dynamic-form-row .form-field-width-20{width:20%}.dynamic-form-row .form-field-width-25{width:25%}.dynamic-form-row .form-field-width-30{width:30%}.dynamic-form-row .form-field-width-35{width:35%}.dynamic-form-row .form-field-width-40{width:40%}.dynamic-form-row .form-field-width-45{width:45%}.dynamic-form-row .form-field-width-50{width:50%}.dynamic-form-row .form-field-width-55{width:55%}.dynamic-form-row .form-field-width-60{width:60%}.dynamic-form-row .form-field-width-65{width:65%}.dynamic-form-row .form-field-width-70{width:70%}.dynamic-form-row .form-field-width-75{width:75%}.dynamic-form-row .form-field-width-80{width:80%}.dynamic-form-row .form-field-width-85{width:85%}.dynamic-form-row .form-field-width-90{width:90%}.dynamic-form-row .form-field-width-95{width:95%}.dynamic-form-row .form-field-width-100{width:100%}\n"] }]
887
+ }], propDecorators: { group: [{ type: i0.Input, args: [{ isSignal: true, alias: "group", required: true }] }], formConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "formConfig", required: true }] }] } });
888
+
889
+ /**
890
+ * Transform any list to a list of DynamicFormFieldOption which is used in any Dynamic Form Field with options (e.g. DynamicSelect).
891
+ * Possible to provide the method with type definitions to define the provided list type `<T>` and desired option value type `<K>`:
892
+ *
893
+ * `dynamicFormService.toDynamicOptionList<T, K>(...)`
894
+ *
895
+ * Generic types:
896
+ * - T = The type of the items in the provided list
897
+ * - K = The type of the value inside an DynamicFormFieldOption. Default is 'string'
898
+ * @param arr An array of items of type T
899
+ * @param labelFn Callback to define the label of the options in the template
900
+ * @param valueFn Callback to define the value of the options. Must return a value of type K (default string)
901
+ * @returns
902
+ */
903
+ function arrToDynamicFormOptions(arr, labelFn, valueFn) {
904
+ return arr.map((item) => {
905
+ return {
906
+ label: labelFn(item),
907
+ value: valueFn(item)
908
+ };
909
+ });
910
+ }
911
+ /**
912
+ * Transform any Observable of a list to a list of DynamicFormFieldOption which is used in any Dynamic Form Field with options (e.g. DynamicSelect).
913
+ * Possible to provide the method with type definitions to define the provided list type `<T>` and desired option value type `<K>`:
914
+ *
915
+ * `dynamicFormService.toDynamicOptionList<T, K>(...)`
916
+ *
917
+ * Generic types:
918
+ * - T = The type of the items in the provided list
919
+ * - K = The type of the value inside an DynamicFormFieldOption. Default is 'string'
920
+ * @param obs An Observable of a list of items of type T
921
+ * @param labelFn Callback to define the label of the options in the template
922
+ * @param valueFn Callback to define the value of the options. Must return a value of type K (default string)
923
+ * @returns
924
+ */
925
+ function obsToDynamicFormOptions(obs, labelFn, valueFn) {
926
+ return obs.pipe(map((arr) => arrToDynamicFormOptions(arr, labelFn, valueFn)));
927
+ }
996
928
 
997
929
  /*
998
930
  * Public API Surface of ngx-dynamic-form
@@ -1002,5 +934,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
1002
934
  * Generated bundle index. Do not edit.
1003
935
  */
1004
936
 
1005
- export { DYNAMIC_FORM_FIELD_BUTTON, DYNAMIC_FORM_FIELD_BUTTON_TOGGLES, DYNAMIC_FORM_FIELD_CHECKBOX, DYNAMIC_FORM_FIELD_DATEPICKER, DYNAMIC_FORM_FIELD_INPUT, DYNAMIC_FORM_FIELD_MAP_FN, DYNAMIC_FORM_FIELD_RADIO_GROUP, DYNAMIC_FORM_FIELD_READONLY, DYNAMIC_FORM_FIELD_SELECT, DYNAMIC_FORM_FIELD_TEXTAREA, DynamicButton, DynamicButtonToggles, DynamicCheckbox, DynamicDatepicker, DynamicFormComponent, DynamicFormFieldBase, DynamicFormFieldModel, DynamicFormFieldOptionModel, DynamicFormFieldValueModel, DynamicFormService, DynamicFormValidators, DynamicInput, DynamicRadioGroup, DynamicReadonly, DynamicSelect, DynamicTextarea, RelationActionType, RelationOperator };
937
+ export { DYNAMIC_FORM_FIELD_BUTTON, DYNAMIC_FORM_FIELD_BUTTON_TOGGLES, DYNAMIC_FORM_FIELD_CHECKBOX, DYNAMIC_FORM_FIELD_DATEPICKER, DYNAMIC_FORM_FIELD_INPUT, DYNAMIC_FORM_FIELD_MAP$1 as DYNAMIC_FORM_FIELD_MAP, DYNAMIC_FORM_FIELD_RADIO_GROUP, DYNAMIC_FORM_FIELD_READONLY, DYNAMIC_FORM_FIELD_SELECT, DYNAMIC_FORM_FIELD_TEXTAREA, DynamicButton, DynamicButtonToggles, DynamicCheckbox, DynamicDatepicker, DynamicFormComponent, DynamicFormFieldBase, DynamicFormFieldModel, DynamicFormFieldOptionModel, DynamicFormFieldValueModel, DynamicFormService, DynamicFormValidators, DynamicInput, DynamicRadioGroup, DynamicReadonly, DynamicSelect, DynamicTextarea, RelationActionType, RelationOperator, arrToDynamicFormOptions, obsToDynamicFormOptions };
1006
938
  //# sourceMappingURL=olafvv-ngx-dynamic-form.mjs.map