@vipsolucoes/dynamic-form 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,536 @@
1
+ import * as i1$1 from '@angular/common';
2
+ import { CommonModule, NgComponentOutlet } from '@angular/common';
3
+ import * as i0 from '@angular/core';
4
+ import { InjectionToken, input, inject, Component, computed, ChangeDetectionStrategy, signal, Injectable, DestroyRef, output } from '@angular/core';
5
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
6
+ import * as i1 from '@angular/forms';
7
+ import { ReactiveFormsModule, FormGroup, FormControl } from '@angular/forms';
8
+ import * as i3 from 'primeng/datepicker';
9
+ import { DatePickerModule } from 'primeng/datepicker';
10
+ import * as i2 from 'primeng/iftalabel';
11
+ import { IftaLabelModule } from 'primeng/iftalabel';
12
+ import * as i3$1 from 'primeng/inputtext';
13
+ import { InputTextModule } from 'primeng/inputtext';
14
+ import * as i3$2 from 'primeng/inputnumber';
15
+ import { InputNumberModule } from 'primeng/inputnumber';
16
+ import * as i3$3 from 'primeng/password';
17
+ import { PasswordModule } from 'primeng/password';
18
+ import * as i3$4 from 'primeng/select';
19
+ import { SelectModule } from 'primeng/select';
20
+ import * as i3$5 from 'primeng/textarea';
21
+ import { TextareaModule } from 'primeng/textarea';
22
+ import * as i2$1 from 'primeng/toggleswitch';
23
+ import { ToggleSwitchModule } from 'primeng/toggleswitch';
24
+
25
+ /**
26
+ * InjectionToken para prover mensagens de erro customizadas.
27
+ */
28
+ const DYNAMIC_FORM_ERROR_MESSAGES = new InjectionToken('DYNAMIC_FORM_ERROR_MESSAGES');
29
+
30
+ class DynamicFormErrorComponent {
31
+ control = input.required(...(ngDevMode ? [{ debugName: "control" }] : []));
32
+ customMessages = inject(DYNAMIC_FORM_ERROR_MESSAGES, { optional: true });
33
+ // Mapeamento de erros para mensagens
34
+ defaultErrorMessages = {
35
+ required: () => this.customMessages?.required ?? 'Este campo é obrigatório.',
36
+ email: () => this.customMessages?.email ?? 'Por favor, insira um e-mail válido.',
37
+ minlength: (err) => this.customMessages?.minlength?.(err.requiredLength) ?? `Mínimo de ${err.requiredLength} caracteres.`,
38
+ maxlength: (err) => this.customMessages?.maxlength?.(err.requiredLength) ?? `Máximo de ${err.requiredLength} caracteres.`,
39
+ custom: (err) => (this.customMessages?.custom ? this.customMessages.custom(err) : err),
40
+ };
41
+ // Getter simples - Angular detecta mudanças automaticamente
42
+ get errorMessage() {
43
+ const ctrl = this.control();
44
+ if (!ctrl || !ctrl.errors || (!ctrl.touched && !ctrl.dirty)) {
45
+ return null;
46
+ }
47
+ const errorKey = Object.keys(ctrl.errors)[0];
48
+ return this.defaultErrorMessages[errorKey] ? this.defaultErrorMessages[errorKey](ctrl.errors[errorKey]) : 'Campo inválido.';
49
+ }
50
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.7", ngImport: i0, type: DynamicFormErrorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
51
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.7", type: DynamicFormErrorComponent, isStandalone: true, selector: "vp-form-field-error", inputs: { control: { classPropertyName: "control", publicName: "control", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
52
+ @if (errorMessage) {
53
+ <small class="p-error">{{ errorMessage }}</small>
54
+ }
55
+ `, isInline: true, styles: [":host{display:block;margin-top:.5rem;min-height:1rem}.p-error{color:var(--p-red-500, #ef4444);font-size:.875rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
56
+ }
57
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.7", ngImport: i0, type: DynamicFormErrorComponent, decorators: [{
58
+ type: Component,
59
+ args: [{ selector: 'vp-form-field-error', standalone: true, imports: [CommonModule], template: `
60
+ @if (errorMessage) {
61
+ <small class="p-error">{{ errorMessage }}</small>
62
+ }
63
+ `, styles: [":host{display:block;margin-top:.5rem;min-height:1rem}.p-error{color:var(--p-red-500, #ef4444);font-size:.875rem}\n"] }]
64
+ }], propDecorators: { control: [{ type: i0.Input, args: [{ isSignal: true, alias: "control", required: true }] }] } });
65
+
66
+ class DatePickerFieldComponent {
67
+ form = input.required(...(ngDevMode ? [{ debugName: "form" }] : []));
68
+ field = input.required(...(ngDevMode ? [{ debugName: "field" }] : []));
69
+ dateFormat = computed(() => {
70
+ const viewType = this.field().dateViewType || 'date';
71
+ const customFormat = this.field().dateFormat;
72
+ if (viewType === 'month') {
73
+ return 'mm/yy';
74
+ }
75
+ if (viewType === 'year') {
76
+ return 'yy';
77
+ }
78
+ return customFormat || 'dd/mm/yyyy';
79
+ }, ...(ngDevMode ? [{ debugName: "dateFormat" }] : []));
80
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.7", ngImport: i0, type: DatePickerFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
81
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.7", type: DatePickerFieldComponent, isStandalone: true, selector: "vp-datepicker-field", inputs: { form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: true, transformFunction: null }, field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
82
+ <div [formGroup]="form()">
83
+ <p-iftalabel>
84
+ <p-datepicker
85
+ [inputId]="field().key"
86
+ [formControlName]="field().key"
87
+ [showButtonBar]="true"
88
+ [iconDisplay]="'input'"
89
+ [placeholder]="field().placeholder || ''"
90
+ [dateFormat]="dateFormat()"
91
+ [view]="field().dateViewType || 'date'"
92
+ [disabled]="field().disabled ?? false" />
93
+ <label [for]="field().key">{{ field().label }}</label>
94
+ </p-iftalabel>
95
+ </div>
96
+ `, isInline: true, styles: [":host{display:block;width:100%}p-iftalabel{display:block;width:100%}p-datepicker{width:100%}\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],[formArray],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: IftaLabelModule }, { kind: "component", type: i2.IftaLabel, selector: "p-iftalabel, p-iftaLabel, p-ifta-label" }, { kind: "ngmodule", type: DatePickerModule }, { kind: "component", type: i3.DatePicker, selector: "p-datePicker, p-datepicker, p-date-picker", inputs: ["iconDisplay", "styleClass", "inputStyle", "inputId", "inputStyleClass", "placeholder", "ariaLabelledBy", "ariaLabel", "iconAriaLabel", "dateFormat", "multipleSeparator", "rangeSeparator", "inline", "showOtherMonths", "selectOtherMonths", "showIcon", "icon", "readonlyInput", "shortYearCutoff", "hourFormat", "timeOnly", "stepHour", "stepMinute", "stepSecond", "showSeconds", "showOnFocus", "showWeek", "startWeekFromFirstDayOfYear", "showClear", "dataType", "selectionMode", "maxDateCount", "showButtonBar", "todayButtonStyleClass", "clearButtonStyleClass", "autofocus", "autoZIndex", "baseZIndex", "panelStyleClass", "panelStyle", "keepInvalid", "hideOnDateTimeSelect", "touchUI", "timeSeparator", "focusTrap", "showTransitionOptions", "hideTransitionOptions", "tabindex", "minDate", "maxDate", "disabledDates", "disabledDays", "showTime", "responsiveOptions", "numberOfMonths", "firstDayOfWeek", "view", "defaultDate", "appendTo", "motionOptions"], outputs: ["onFocus", "onBlur", "onClose", "onSelect", "onClear", "onInput", "onTodayClick", "onClearClick", "onMonthChange", "onYearChange", "onClickOutside", "onShow"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
97
+ }
98
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.7", ngImport: i0, type: DatePickerFieldComponent, decorators: [{
99
+ type: Component,
100
+ args: [{ selector: 'vp-datepicker-field', standalone: true, imports: [ReactiveFormsModule, IftaLabelModule, DatePickerModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
101
+ <div [formGroup]="form()">
102
+ <p-iftalabel>
103
+ <p-datepicker
104
+ [inputId]="field().key"
105
+ [formControlName]="field().key"
106
+ [showButtonBar]="true"
107
+ [iconDisplay]="'input'"
108
+ [placeholder]="field().placeholder || ''"
109
+ [dateFormat]="dateFormat()"
110
+ [view]="field().dateViewType || 'date'"
111
+ [disabled]="field().disabled ?? false" />
112
+ <label [for]="field().key">{{ field().label }}</label>
113
+ </p-iftalabel>
114
+ </div>
115
+ `, styles: [":host{display:block;width:100%}p-iftalabel{display:block;width:100%}p-datepicker{width:100%}\n"] }]
116
+ }], propDecorators: { form: [{ type: i0.Input, args: [{ isSignal: true, alias: "form", required: true }] }], field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }] } });
117
+
118
+ class InputTextFieldComponent {
119
+ form = input.required(...(ngDevMode ? [{ debugName: "form" }] : []));
120
+ field = input.required(...(ngDevMode ? [{ debugName: "field" }] : []));
121
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.7", ngImport: i0, type: InputTextFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
122
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.7", type: InputTextFieldComponent, isStandalone: true, selector: "vp-input-text-field", inputs: { form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: true, transformFunction: null }, field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
123
+ <div [formGroup]="form()">
124
+ <p-iftalabel>
125
+ <input pInputText [id]="field().key" [type]="field().controlType" [formControlName]="field().key" [placeholder]="field().placeholder || ''" [disabled]="field().disabled ?? false" />
126
+ <label [for]="field().key">{{ field().label }}</label>
127
+ </p-iftalabel>
128
+ </div>
129
+ `, isInline: true, styles: [":host{display:block;width:100%}p-iftalabel{display:block;width:100%}input{width:100%}\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],[formArray],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: IftaLabelModule }, { kind: "component", type: i2.IftaLabel, selector: "p-iftalabel, p-iftaLabel, p-ifta-label" }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$1.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
130
+ }
131
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.7", ngImport: i0, type: InputTextFieldComponent, decorators: [{
132
+ type: Component,
133
+ args: [{ selector: 'vp-input-text-field', standalone: true, imports: [ReactiveFormsModule, IftaLabelModule, InputTextModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
134
+ <div [formGroup]="form()">
135
+ <p-iftalabel>
136
+ <input pInputText [id]="field().key" [type]="field().controlType" [formControlName]="field().key" [placeholder]="field().placeholder || ''" [disabled]="field().disabled ?? false" />
137
+ <label [for]="field().key">{{ field().label }}</label>
138
+ </p-iftalabel>
139
+ </div>
140
+ `, styles: [":host{display:block;width:100%}p-iftalabel{display:block;width:100%}input{width:100%}\n"] }]
141
+ }], propDecorators: { form: [{ type: i0.Input, args: [{ isSignal: true, alias: "form", required: true }] }], field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }] } });
142
+
143
+ class NumberInputFieldComponent {
144
+ form = input.required(...(ngDevMode ? [{ debugName: "form" }] : []));
145
+ field = input.required(...(ngDevMode ? [{ debugName: "field" }] : []));
146
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.7", ngImport: i0, type: NumberInputFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
147
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.7", type: NumberInputFieldComponent, isStandalone: true, selector: "vp-number-input-field", inputs: { form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: true, transformFunction: null }, field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
148
+ <div [formGroup]="form()">
149
+ <p-iftalabel>
150
+ <p-inputNumber [id]="field().key" [formControlName]="field().key" [placeholder]="field().placeholder || ''" [disabled]="field().disabled ?? false" styleClass="w-full" class="w-full" />
151
+ <label [for]="field().key">{{ field().label }}</label>
152
+ </p-iftalabel>
153
+ </div>
154
+ `, isInline: true, styles: [":host{display:block;width:100%}p-iftalabel{display:block;width:100%}:host ::ng-deep p-inputNumber,:host ::ng-deep .p-inputnumber,:host ::ng-deep .p-inputnumber input{width:100%}\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],[formArray],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: IftaLabelModule }, { kind: "component", type: i2.IftaLabel, selector: "p-iftalabel, p-iftaLabel, p-ifta-label" }, { kind: "ngmodule", type: InputNumberModule }, { kind: "component", type: i3$2.InputNumber, selector: "p-inputNumber, p-inputnumber, p-input-number", inputs: ["showButtons", "format", "buttonLayout", "inputId", "styleClass", "placeholder", "tabindex", "title", "ariaLabelledBy", "ariaDescribedBy", "ariaLabel", "ariaRequired", "autocomplete", "incrementButtonClass", "decrementButtonClass", "incrementButtonIcon", "decrementButtonIcon", "readonly", "allowEmpty", "locale", "localeMatcher", "mode", "currency", "currencyDisplay", "useGrouping", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "inputStyle", "inputStyleClass", "showClear", "autofocus"], outputs: ["onInput", "onFocus", "onBlur", "onKeyDown", "onClear"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
155
+ }
156
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.7", ngImport: i0, type: NumberInputFieldComponent, decorators: [{
157
+ type: Component,
158
+ args: [{ selector: 'vp-number-input-field', standalone: true, imports: [ReactiveFormsModule, IftaLabelModule, InputNumberModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
159
+ <div [formGroup]="form()">
160
+ <p-iftalabel>
161
+ <p-inputNumber [id]="field().key" [formControlName]="field().key" [placeholder]="field().placeholder || ''" [disabled]="field().disabled ?? false" styleClass="w-full" class="w-full" />
162
+ <label [for]="field().key">{{ field().label }}</label>
163
+ </p-iftalabel>
164
+ </div>
165
+ `, styles: [":host{display:block;width:100%}p-iftalabel{display:block;width:100%}:host ::ng-deep p-inputNumber,:host ::ng-deep .p-inputnumber,:host ::ng-deep .p-inputnumber input{width:100%}\n"] }]
166
+ }], propDecorators: { form: [{ type: i0.Input, args: [{ isSignal: true, alias: "form", required: true }] }], field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }] } });
167
+
168
+ class PasswordFieldComponent {
169
+ form = input.required(...(ngDevMode ? [{ debugName: "form" }] : []));
170
+ field = input.required(...(ngDevMode ? [{ debugName: "field" }] : []));
171
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.7", ngImport: i0, type: PasswordFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
172
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.7", type: PasswordFieldComponent, isStandalone: true, selector: "vp-password-field", inputs: { form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: true, transformFunction: null }, field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
173
+ <div [formGroup]="form()">
174
+ <p-iftalabel>
175
+ <p-password
176
+ [id]="field().key"
177
+ [formControlName]="field().key"
178
+ [feedback]="false"
179
+ [toggleMask]="true"
180
+ [placeholder]="field().placeholder || ''"
181
+ [disabled]="field().disabled ?? false"
182
+ styleClass="w-full"
183
+ class="w-full" />
184
+ <label [for]="field().key">{{ field().label }}</label>
185
+ </p-iftalabel>
186
+ </div>
187
+ `, isInline: true, styles: [":host{display:block;width:100%}p-iftalabel{display:block;width:100%}:host ::ng-deep .p-password,:host ::ng-deep .p-password input{width:100%}\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],[formArray],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: IftaLabelModule }, { kind: "component", type: i2.IftaLabel, selector: "p-iftalabel, p-iftaLabel, p-ifta-label" }, { kind: "ngmodule", type: PasswordModule }, { kind: "component", type: i3$3.Password, selector: "p-password", inputs: ["ariaLabel", "ariaLabelledBy", "label", "promptLabel", "mediumRegex", "strongRegex", "weakLabel", "mediumLabel", "maxLength", "strongLabel", "inputId", "feedback", "toggleMask", "inputStyleClass", "styleClass", "inputStyle", "showTransitionOptions", "hideTransitionOptions", "autocomplete", "placeholder", "showClear", "autofocus", "tabindex", "appendTo", "motionOptions", "overlayOptions"], outputs: ["onFocus", "onBlur", "onClear"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
188
+ }
189
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.7", ngImport: i0, type: PasswordFieldComponent, decorators: [{
190
+ type: Component,
191
+ args: [{ selector: 'vp-password-field', standalone: true, imports: [ReactiveFormsModule, IftaLabelModule, PasswordModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
192
+ <div [formGroup]="form()">
193
+ <p-iftalabel>
194
+ <p-password
195
+ [id]="field().key"
196
+ [formControlName]="field().key"
197
+ [feedback]="false"
198
+ [toggleMask]="true"
199
+ [placeholder]="field().placeholder || ''"
200
+ [disabled]="field().disabled ?? false"
201
+ styleClass="w-full"
202
+ class="w-full" />
203
+ <label [for]="field().key">{{ field().label }}</label>
204
+ </p-iftalabel>
205
+ </div>
206
+ `, styles: [":host{display:block;width:100%}p-iftalabel{display:block;width:100%}:host ::ng-deep .p-password,:host ::ng-deep .p-password input{width:100%}\n"] }]
207
+ }], propDecorators: { form: [{ type: i0.Input, args: [{ isSignal: true, alias: "form", required: true }] }], field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }] } });
208
+
209
+ class SelectFieldComponent {
210
+ form = input.required(...(ngDevMode ? [{ debugName: "form" }] : []));
211
+ field = input.required(...(ngDevMode ? [{ debugName: "field" }] : []));
212
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.7", ngImport: i0, type: SelectFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
213
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.7", type: SelectFieldComponent, isStandalone: true, selector: "vp-select-field", inputs: { form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: true, transformFunction: null }, field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
214
+ <div [formGroup]="form()">
215
+ <p-iftalabel>
216
+ <p-select
217
+ [inputId]="field().key"
218
+ [formControlName]="field().key"
219
+ [options]="field().options!"
220
+ [placeholder]="field().placeholder || 'Selecione'"
221
+ [disabled]="field().disabled ?? false"
222
+ optionLabel="label"
223
+ optionValue="value"
224
+ class="w-full" />
225
+ <label [for]="field().key">{{ field().label }}</label>
226
+ </p-iftalabel>
227
+ </div>
228
+ `, isInline: true, styles: [":host{display:block;width:100%}p-iftalabel{display:block;width:100%}p-select{width:100%}\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],[formArray],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: IftaLabelModule }, { kind: "component", type: i2.IftaLabel, selector: "p-iftalabel, p-iftaLabel, p-ifta-label" }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i3$4.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
229
+ }
230
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.7", ngImport: i0, type: SelectFieldComponent, decorators: [{
231
+ type: Component,
232
+ args: [{ selector: 'vp-select-field', standalone: true, imports: [ReactiveFormsModule, IftaLabelModule, SelectModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
233
+ <div [formGroup]="form()">
234
+ <p-iftalabel>
235
+ <p-select
236
+ [inputId]="field().key"
237
+ [formControlName]="field().key"
238
+ [options]="field().options!"
239
+ [placeholder]="field().placeholder || 'Selecione'"
240
+ [disabled]="field().disabled ?? false"
241
+ optionLabel="label"
242
+ optionValue="value"
243
+ class="w-full" />
244
+ <label [for]="field().key">{{ field().label }}</label>
245
+ </p-iftalabel>
246
+ </div>
247
+ `, styles: [":host{display:block;width:100%}p-iftalabel{display:block;width:100%}p-select{width:100%}\n"] }]
248
+ }], propDecorators: { form: [{ type: i0.Input, args: [{ isSignal: true, alias: "form", required: true }] }], field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }] } });
249
+
250
+ class TextareaFieldComponent {
251
+ form = input.required(...(ngDevMode ? [{ debugName: "form" }] : []));
252
+ field = input.required(...(ngDevMode ? [{ debugName: "field" }] : []));
253
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.7", ngImport: i0, type: TextareaFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
254
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.7", type: TextareaFieldComponent, isStandalone: true, selector: "vp-textarea-field", inputs: { form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: true, transformFunction: null }, field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
255
+ <div [formGroup]="form()">
256
+ <p-iftalabel>
257
+ <textarea
258
+ pTextarea
259
+ [id]="field().key"
260
+ [formControlName]="field().key"
261
+ [placeholder]="field().placeholder || ''"
262
+ [rows]="field().textareaRows ?? 1"
263
+ [cols]="field().textareaCols"
264
+ [autoResize]="field().textareaAutoResize ?? false"
265
+ [disabled]="field().disabled ?? false"
266
+ ></textarea>
267
+ <label [for]="field().key">{{ field().label }}</label>
268
+ </p-iftalabel>
269
+ </div>
270
+ `, isInline: true, styles: [":host{display:block;width:100%}p-iftalabel{display:block;width:100%}textarea{width:100%}\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],[formArray],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: IftaLabelModule }, { kind: "component", type: i2.IftaLabel, selector: "p-iftalabel, p-iftaLabel, p-ifta-label" }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i3$5.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["pTextareaPT", "pTextareaUnstyled", "autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
271
+ }
272
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.7", ngImport: i0, type: TextareaFieldComponent, decorators: [{
273
+ type: Component,
274
+ args: [{ selector: 'vp-textarea-field', standalone: true, imports: [ReactiveFormsModule, IftaLabelModule, TextareaModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
275
+ <div [formGroup]="form()">
276
+ <p-iftalabel>
277
+ <textarea
278
+ pTextarea
279
+ [id]="field().key"
280
+ [formControlName]="field().key"
281
+ [placeholder]="field().placeholder || ''"
282
+ [rows]="field().textareaRows ?? 1"
283
+ [cols]="field().textareaCols"
284
+ [autoResize]="field().textareaAutoResize ?? false"
285
+ [disabled]="field().disabled ?? false"
286
+ ></textarea>
287
+ <label [for]="field().key">{{ field().label }}</label>
288
+ </p-iftalabel>
289
+ </div>
290
+ `, styles: [":host{display:block;width:100%}p-iftalabel{display:block;width:100%}textarea{width:100%}\n"] }]
291
+ }], propDecorators: { form: [{ type: i0.Input, args: [{ isSignal: true, alias: "form", required: true }] }], field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }] } });
292
+
293
+ class ToggleSwitchFieldComponent {
294
+ form = input.required(...(ngDevMode ? [{ debugName: "form" }] : []));
295
+ field = input.required(...(ngDevMode ? [{ debugName: "field" }] : []));
296
+ isInvalid = computed(() => {
297
+ const control = this.form().get(this.field().key);
298
+ return control ? control.invalid && (control.touched || control.dirty) : false;
299
+ }, ...(ngDevMode ? [{ debugName: "isInvalid" }] : []));
300
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.7", ngImport: i0, type: ToggleSwitchFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
301
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.7", type: ToggleSwitchFieldComponent, isStandalone: true, selector: "vp-toggleswitch-field", inputs: { form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: true, transformFunction: null }, field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
302
+ <div [formGroup]="form()" class="toggleswitch-field">
303
+ <p-toggleswitch
304
+ [formControlName]="field().key"
305
+ [inputId]="field().key"
306
+ [invalid]="isInvalid()"
307
+ [disabled]="field().disabled ?? false"
308
+ [trueValue]="field().toggleTrueValue ?? true"
309
+ [falseValue]="field().toggleFalseValue ?? false" />
310
+ <label [for]="field().key" class="toggleswitch-label">{{ field().label }}</label>
311
+ </div>
312
+ `, isInline: true, styles: [":host{display:block;width:100%}.toggleswitch-field{display:flex;align-items:center;gap:.75rem;width:100%}.toggleswitch-label{cursor:pointer;-webkit-user-select:none;user-select:none;font-size:.875rem;color:var(--p-text-color, #333);margin:0}p-toggleswitch{flex-shrink:0}\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],[formArray],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: ToggleSwitchModule }, { kind: "component", type: i2$1.ToggleSwitch, selector: "p-toggleswitch, p-toggleSwitch, p-toggle-switch", inputs: ["styleClass", "tabindex", "inputId", "readonly", "trueValue", "falseValue", "ariaLabel", "size", "ariaLabelledBy", "autofocus"], outputs: ["onChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
313
+ }
314
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.7", ngImport: i0, type: ToggleSwitchFieldComponent, decorators: [{
315
+ type: Component,
316
+ args: [{ selector: 'vp-toggleswitch-field', standalone: true, imports: [ReactiveFormsModule, ToggleSwitchModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
317
+ <div [formGroup]="form()" class="toggleswitch-field">
318
+ <p-toggleswitch
319
+ [formControlName]="field().key"
320
+ [inputId]="field().key"
321
+ [invalid]="isInvalid()"
322
+ [disabled]="field().disabled ?? false"
323
+ [trueValue]="field().toggleTrueValue ?? true"
324
+ [falseValue]="field().toggleFalseValue ?? false" />
325
+ <label [for]="field().key" class="toggleswitch-label">{{ field().label }}</label>
326
+ </div>
327
+ `, styles: [":host{display:block;width:100%}.toggleswitch-field{display:flex;align-items:center;gap:.75rem;width:100%}.toggleswitch-label{cursor:pointer;-webkit-user-select:none;user-select:none;font-size:.875rem;color:var(--p-text-color, #333);margin:0}p-toggleswitch{flex-shrink:0}\n"] }]
328
+ }], propDecorators: { form: [{ type: i0.Input, args: [{ isSignal: true, alias: "form", required: true }] }], field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }] } });
329
+
330
+ /**
331
+ * Serviço para registro de campos customizados.
332
+ * Permite adicionar novos tipos de campos dinamicamente.
333
+ */
334
+ class FieldRegistryService {
335
+ registry = signal(new Map(), ...(ngDevMode ? [{ debugName: "registry" }] : []));
336
+ /**
337
+ * Registra um novo tipo de campo.
338
+ * @param type Tipo do campo (ex: 'custom', 'file', etc.)
339
+ * @param component Componente Angular que renderiza o campo
340
+ */
341
+ registerField(type, component) {
342
+ this.registry.update((map) => new Map(map).set(type, component));
343
+ }
344
+ /**
345
+ * Obtém o componente registrado para um tipo de campo.
346
+ * @param type Tipo do campo
347
+ * @returns Componente Angular ou undefined se não encontrado
348
+ */
349
+ getField(type) {
350
+ return this.registry().get(type);
351
+ }
352
+ /**
353
+ * Remove um tipo de campo do registro.
354
+ * @param type Tipo do campo a ser removido
355
+ */
356
+ unregisterField(type) {
357
+ this.registry.update((map) => {
358
+ const newMap = new Map(map);
359
+ newMap.delete(type);
360
+ return newMap;
361
+ });
362
+ }
363
+ /**
364
+ * Limpa todos os campos registrados.
365
+ */
366
+ clear() {
367
+ this.registry.set(new Map());
368
+ }
369
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.7", ngImport: i0, type: FieldRegistryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
370
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.7", ngImport: i0, type: FieldRegistryService, providedIn: 'root' });
371
+ }
372
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.7", ngImport: i0, type: FieldRegistryService, decorators: [{
373
+ type: Injectable,
374
+ args: [{ providedIn: 'root' }]
375
+ }] });
376
+
377
+ class DynamicFormComponent {
378
+ destroyRef = inject(DestroyRef);
379
+ fieldRegistry = inject(FieldRegistryService);
380
+ config = input.required(...(ngDevMode ? [{ debugName: "config" }] : []));
381
+ formReady = output();
382
+ form = new FormGroup({});
383
+ fieldComponents = {
384
+ text: InputTextFieldComponent,
385
+ email: InputTextFieldComponent,
386
+ password: PasswordFieldComponent,
387
+ number: NumberInputFieldComponent,
388
+ select: SelectFieldComponent,
389
+ datepicker: DatePickerFieldComponent,
390
+ textarea: TextareaFieldComponent,
391
+ toggleswitch: ToggleSwitchFieldComponent,
392
+ };
393
+ ngOnInit() {
394
+ const configValue = this.config();
395
+ if (configValue && configValue.length > 0) {
396
+ this.buildForm(configValue);
397
+ this.setupFieldDependencies(configValue);
398
+ this.formReady.emit(this.form);
399
+ }
400
+ }
401
+ buildForm(config) {
402
+ config.forEach((field) => {
403
+ // Para toggle switch, o valor padrão é false se não especificado
404
+ const defaultValue = field.controlType === 'toggleswitch' ? (field.value ?? false) : (field.value ?? '');
405
+ // Se o campo tem enabledWhen, ele deve começar desabilitado a menos que o toggle já esteja ativo
406
+ const shouldBeDisabled = field.disabled ?? (field.enabledWhen ? !this.getToggleValue(field.enabledWhen, config) : false);
407
+ const control = shouldBeDisabled
408
+ ? new FormControl({ value: defaultValue, disabled: true }, {
409
+ validators: field.validators ?? [],
410
+ })
411
+ : new FormControl(defaultValue, {
412
+ validators: field.validators ?? [],
413
+ });
414
+ this.form.addControl(field.key, control);
415
+ });
416
+ }
417
+ setupFieldDependencies(config) {
418
+ config.forEach((field) => {
419
+ if (!field.enabledWhen) {
420
+ return;
421
+ }
422
+ const toggleField = config.find((f) => f.key === field.enabledWhen);
423
+ if (!toggleField) {
424
+ console.warn(`DynamicFormComponent: Campo '${field.key}' referencia '${field.enabledWhen}' em enabledWhen, mas este campo não existe no formulário.`);
425
+ return;
426
+ }
427
+ if (toggleField.controlType !== 'toggleswitch') {
428
+ console.warn(`DynamicFormComponent: Campo '${field.key}' referencia '${field.enabledWhen}' em enabledWhen, mas este campo não é do tipo 'toggleswitch'.`);
429
+ return;
430
+ }
431
+ const toggleControl = this.form.get(field.enabledWhen);
432
+ const dependentControl = this.form.get(field.key);
433
+ if (!toggleControl || !dependentControl) {
434
+ console.warn(`DynamicFormComponent: Não foi possível encontrar os controles para configurar a dependência entre '${field.enabledWhen}' e '${field.key}'.`);
435
+ return;
436
+ }
437
+ // Configura a subscription para reagir às mudanças do toggle
438
+ toggleControl.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((toggleValue) => {
439
+ const isToggleActive = toggleValue === (toggleField.toggleTrueValue ?? true);
440
+ if (isToggleActive) {
441
+ dependentControl.enable();
442
+ }
443
+ else {
444
+ // Limpa o valor do campo antes de desabilitá-lo
445
+ const resetValue = this.getResetValueForFieldType(field.controlType);
446
+ dependentControl.setValue(resetValue, { emitEvent: false });
447
+ dependentControl.disable();
448
+ }
449
+ });
450
+ });
451
+ }
452
+ getToggleValue(toggleKey, config) {
453
+ const toggleField = config.find((f) => f.key === toggleKey);
454
+ if (!toggleField || toggleField.controlType !== 'toggleswitch') {
455
+ return false;
456
+ }
457
+ const toggleTrueValue = toggleField.toggleTrueValue ?? true;
458
+ const toggleValue = toggleField.value ?? false;
459
+ return toggleValue === toggleTrueValue;
460
+ }
461
+ /**
462
+ * Retorna o valor padrão de reset para cada tipo de campo.
463
+ * Usado quando um campo dependente é desabilitado e precisa ser limpo.
464
+ */
465
+ getResetValueForFieldType(controlType) {
466
+ switch (controlType) {
467
+ case 'text':
468
+ case 'email':
469
+ case 'password':
470
+ case 'textarea':
471
+ return '';
472
+ case 'number':
473
+ return null;
474
+ case 'select':
475
+ return null;
476
+ case 'datepicker':
477
+ return null;
478
+ default:
479
+ return '';
480
+ }
481
+ }
482
+ /**
483
+ * Obtém o componente a ser renderizado para um tipo de campo.
484
+ * Primeiro verifica no registro customizado, depois nos componentes padrão.
485
+ */
486
+ getFieldComponent(controlType) {
487
+ // Verifica primeiro no registro customizado
488
+ const customComponent = this.fieldRegistry.getField(controlType);
489
+ if (customComponent) {
490
+ return customComponent;
491
+ }
492
+ // Fallback para componentes padrão
493
+ return this.fieldComponents[controlType] || null;
494
+ }
495
+ getControl(key) {
496
+ const control = this.form.get(key);
497
+ if (!control) {
498
+ console.warn(`DynamicFormComponent: Controle não encontrado para a chave: ${key}`);
499
+ }
500
+ return control;
501
+ }
502
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.7", ngImport: i0, type: DynamicFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
503
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.7", type: DynamicFormComponent, isStandalone: true, selector: "vp-dynamic-form", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { formReady: "formReady" }, ngImport: i0, template: "<form [formGroup]=\"form\" class=\"dynamic-form-container\">\n @for (field of config(); track field.key) {\n @if (getFieldComponent(field.controlType); as fieldComponent) {\n <div [class]=\"'form-field-wrapper ' + (field.styleClass || '')\">\n <!-- Dynamically render the correct field component -->\n <ng-container [ngComponentOutlet]=\"fieldComponent\" [ngComponentOutletInputs]=\"{ form: form, field: field }\" />\n\n @if (field.hint) {\n <small class=\"hint-text\">{{ field.hint }}</small>\n }\n\n <!-- Reusable error display component -->\n <vp-form-field-error [control]=\"getControl(field.key)\" />\n </div>\n } @else {\n <div class=\"form-field-wrapper\">\n <small class=\"p-error\">Tipo de campo '{{ field.controlType }}' n\u00E3o encontrado.</small>\n </div>\n }\n }\n</form>\n", styles: ["@charset \"UTF-8\";:host{display:block;width:100%}.dynamic-form-container{display:flex;flex-direction:column;gap:1.75rem;padding:1rem;border:1px solid var(--p-surface-border);border-radius:var(--p-border-radius);background-color:var(--p-surface-section)}.form-field-wrapper{display:flex;flex-direction:column;position:relative}:is(p-inputNumber,p-password,p-select,p-iftalabel){width:100%}:host ::ng-deep .p-password,:host ::ng-deep .p-password input,:host ::ng-deep .p-inputnumber,:host ::ng-deep .p-inputnumber input,:host ::ng-deep .p-datepicker input,:host ::ng-deep .p-select{width:100%!important}input[pInputText]{width:100%}.hint-text{margin-top:.5rem;color:var(--p-text-muted-color)}.error-messages{margin-top:.5rem;display:flex;flex-direction:column}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: DynamicFormErrorComponent, selector: "vp-form-field-error", inputs: ["control"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
504
+ }
505
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.7", ngImport: i0, type: DynamicFormComponent, decorators: [{
506
+ type: Component,
507
+ args: [{ selector: 'vp-dynamic-form', standalone: true, imports: [CommonModule, ReactiveFormsModule, NgComponentOutlet, DynamicFormErrorComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<form [formGroup]=\"form\" class=\"dynamic-form-container\">\n @for (field of config(); track field.key) {\n @if (getFieldComponent(field.controlType); as fieldComponent) {\n <div [class]=\"'form-field-wrapper ' + (field.styleClass || '')\">\n <!-- Dynamically render the correct field component -->\n <ng-container [ngComponentOutlet]=\"fieldComponent\" [ngComponentOutletInputs]=\"{ form: form, field: field }\" />\n\n @if (field.hint) {\n <small class=\"hint-text\">{{ field.hint }}</small>\n }\n\n <!-- Reusable error display component -->\n <vp-form-field-error [control]=\"getControl(field.key)\" />\n </div>\n } @else {\n <div class=\"form-field-wrapper\">\n <small class=\"p-error\">Tipo de campo '{{ field.controlType }}' n\u00E3o encontrado.</small>\n </div>\n }\n }\n</form>\n", styles: ["@charset \"UTF-8\";:host{display:block;width:100%}.dynamic-form-container{display:flex;flex-direction:column;gap:1.75rem;padding:1rem;border:1px solid var(--p-surface-border);border-radius:var(--p-border-radius);background-color:var(--p-surface-section)}.form-field-wrapper{display:flex;flex-direction:column;position:relative}:is(p-inputNumber,p-password,p-select,p-iftalabel){width:100%}:host ::ng-deep .p-password,:host ::ng-deep .p-password input,:host ::ng-deep .p-inputnumber,:host ::ng-deep .p-inputnumber input,:host ::ng-deep .p-datepicker input,:host ::ng-deep .p-select{width:100%!important}input[pInputText]{width:100%}.hint-text{margin-top:.5rem;color:var(--p-text-muted-color)}.error-messages{margin-top:.5rem;display:flex;flex-direction:column}\n"] }]
508
+ }], propDecorators: { config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }], formReady: [{ type: i0.Output, args: ["formReady"] }] } });
509
+
510
+ /**
511
+ * Provider para configurar mensagens de erro customizadas.
512
+ * @param messages Mensagens de erro customizadas
513
+ * @returns Provider configurado
514
+ */
515
+ function provideDynamicFormConfig(messages) {
516
+ const providers = [];
517
+ if (messages) {
518
+ providers.push({
519
+ provide: DYNAMIC_FORM_ERROR_MESSAGES,
520
+ useValue: messages,
521
+ });
522
+ }
523
+ return providers;
524
+ }
525
+
526
+ /*
527
+ * Public API Surface of @vipsolucoes/dynamic-form
528
+ */
529
+ // Componentes
530
+
531
+ /**
532
+ * Generated bundle index. Do not edit.
533
+ */
534
+
535
+ export { DYNAMIC_FORM_ERROR_MESSAGES, DatePickerFieldComponent, DynamicFormComponent, DynamicFormErrorComponent, FieldRegistryService, InputTextFieldComponent, NumberInputFieldComponent, PasswordFieldComponent, SelectFieldComponent, TextareaFieldComponent, ToggleSwitchFieldComponent, provideDynamicFormConfig };
536
+ //# sourceMappingURL=vipsolucoes-dynamic-form.mjs.map