@ngx-json-forms/primeng 1.0.1 → 1.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.
@@ -345,8 +345,13 @@ class NgxJsonFormComponent {
345
345
  this.formService.updateFieldAttributes(field.formControlName, { suggestions: remaining });
346
346
  this.formGroup().get(field.formControlName)?.setValue(remaining);
347
347
  }
348
+ // A button with buttonRole === 'submit' / 'reset' / 'cancel' / 'custom'
349
+ // should fire its action whether or not 'click' was explicitly listed
350
+ // in acceptedEvents — leaving it off is the most common cause of
351
+ // "my submit button does nothing" support tickets. (Added 1.1.0.)
352
+ const isButtonClick = type === 'click' && field.config.attributes.inputType === 'button';
348
353
  const allowed = field.config.attributes.acceptedEvents ?? [];
349
- if (!allowed.includes(type))
354
+ if (!isButtonClick && !allowed.includes(type))
350
355
  return;
351
356
  const payload = this.buildPayload(field, type, event);
352
357
  if (type === 'click') {
@@ -510,18 +515,24 @@ class NgxJsonFormStepperComponent {
510
515
  }
511
516
  </ol>
512
517
 
513
- <!-- Step body -->
514
- @if (activeStep(); as step) {
515
- @if (step.description) {
516
- <p class="ngx-stepper-desc">{{ step.description }}</p>
517
- }
518
- <ngx-json-form
519
- [schema]="schema()"
520
- [stepFields]="step.fields"
521
- (formChange)="formChange.emit($event)"
522
- (formSubmit)="onSubmit($event)"
523
- />
518
+ <!--
519
+ Step body resolve the active step from the schema INPUT (not
520
+ from formService.activeStep()) so the inner <ngx-json-form>
521
+ always renders. formService.activeStep() only becomes non-null
522
+ AFTER the inner form calls register(), which only happens once
523
+ the inner form is in the DOM; gating on activeStep() created a
524
+ chicken-and-egg that left the body permanently blank.
525
+ -->
526
+ @let currentStep = schema().steps?.[activeIndex()];
527
+ @if (currentStep?.description) {
528
+ <p class="ngx-stepper-desc">{{ currentStep!.description }}</p>
524
529
  }
530
+ <ngx-json-form
531
+ [schema]="schema()"
532
+ [stepFields]="currentStep?.fields ?? []"
533
+ (formChange)="formChange.emit($event)"
534
+ (formSubmit)="onSubmit($event)"
535
+ />
525
536
 
526
537
  <!-- Controls -->
527
538
  <div class="ngx-stepper-actions">
@@ -592,18 +603,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImpo
592
603
  }
593
604
  </ol>
594
605
 
595
- <!-- Step body -->
596
- @if (activeStep(); as step) {
597
- @if (step.description) {
598
- <p class="ngx-stepper-desc">{{ step.description }}</p>
599
- }
600
- <ngx-json-form
601
- [schema]="schema()"
602
- [stepFields]="step.fields"
603
- (formChange)="formChange.emit($event)"
604
- (formSubmit)="onSubmit($event)"
605
- />
606
+ <!--
607
+ Step body resolve the active step from the schema INPUT (not
608
+ from formService.activeStep()) so the inner <ngx-json-form>
609
+ always renders. formService.activeStep() only becomes non-null
610
+ AFTER the inner form calls register(), which only happens once
611
+ the inner form is in the DOM; gating on activeStep() created a
612
+ chicken-and-egg that left the body permanently blank.
613
+ -->
614
+ @let currentStep = schema().steps?.[activeIndex()];
615
+ @if (currentStep?.description) {
616
+ <p class="ngx-stepper-desc">{{ currentStep!.description }}</p>
606
617
  }
618
+ <ngx-json-form
619
+ [schema]="schema()"
620
+ [stepFields]="currentStep?.fields ?? []"
621
+ (formChange)="formChange.emit($event)"
622
+ (formSubmit)="onSubmit($event)"
623
+ />
607
624
 
608
625
  <!-- Controls -->
609
626
  <div class="ngx-stepper-actions">
@@ -1 +1 @@
1
- {"version":3,"file":"ngx-json-forms-primeng.mjs","sources":["../../../../packages/primeng/src/lib/ngx-form-engine-primeng.component.ts","../../../../packages/primeng/src/lib/ngx-form-engine-primeng.component.html","../../../../packages/primeng/src/lib/ngx-json-form-stepper.component.ts","../../../../packages/primeng/src/ngx-json-forms-primeng.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n inject,\n input,\n output,\n signal,\n Type,\n} from '@angular/core';\nimport { FormArray, FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';\nimport { NgComponentOutlet, NgOptimizedImage, NgTemplateOutlet } from '@angular/common';\nimport { Subscription } from 'rxjs';\n\nimport { InputTextModule } from 'primeng/inputtext';\nimport { InputGroupModule } from 'primeng/inputgroup';\nimport { InputGroupAddonModule } from 'primeng/inputgroupaddon';\nimport { FloatLabelModule } from 'primeng/floatlabel';\nimport { SelectModule } from 'primeng/select';\nimport { MultiSelectModule } from 'primeng/multiselect';\nimport { CascadeSelectModule } from 'primeng/cascadeselect';\nimport { AutoCompleteModule } from 'primeng/autocomplete';\nimport { FileUploadModule } from 'primeng/fileupload';\nimport { ButtonModule } from 'primeng/button';\nimport { DialogModule } from 'primeng/dialog';\nimport { DividerModule } from 'primeng/divider';\nimport { PasswordModule } from 'primeng/password';\nimport { DatePickerModule } from 'primeng/datepicker';\nimport { CheckboxModule } from 'primeng/checkbox';\nimport { ToggleSwitchModule } from 'primeng/toggleswitch';\nimport { TextareaModule } from 'primeng/textarea';\nimport { SliderModule } from 'primeng/slider';\nimport { RatingModule } from 'primeng/rating';\nimport { ColorPickerModule } from 'primeng/colorpicker';\nimport { RadioButtonModule } from 'primeng/radiobutton';\nimport { KeyFilterModule } from 'primeng/keyfilter';\nimport { EditorModule } from 'primeng/editor';\n\nimport {\n FieldRegistry,\n FormEngineEvent,\n FormEngineEventType,\n FormEngineService,\n FormField,\n FormSchema,\n ImageUploadService,\n} from '@ngx-json-forms/core';\n\n@Component({\n selector: 'ngx-json-form',\n templateUrl: './ngx-form-engine-primeng.component.html',\n styleUrl: './ngx-form-engine-primeng.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [\n ReactiveFormsModule,\n NgTemplateOutlet,\n NgComponentOutlet,\n NgOptimizedImage,\n // PrimeNG\n InputTextModule,\n InputGroupModule,\n InputGroupAddonModule,\n FloatLabelModule,\n SelectModule,\n MultiSelectModule,\n CascadeSelectModule,\n AutoCompleteModule,\n FileUploadModule,\n ButtonModule,\n DialogModule,\n DividerModule,\n PasswordModule,\n DatePickerModule,\n CheckboxModule,\n ToggleSwitchModule,\n TextareaModule,\n SliderModule,\n RatingModule,\n ColorPickerModule,\n RadioButtonModule,\n KeyFilterModule,\n EditorModule,\n ],\n})\nexport class NgxJsonFormComponent {\n // ─── Inputs / Outputs ────────────────────────────────────────────────────\n\n readonly formTitle = input<string>('');\n readonly fieldsInput = input<FormField[]>([]);\n /** Optional schema input — supersedes `fieldsInput` when provided. */\n readonly schema = input<FormSchema | null>(null);\n /** Only render fields in the given step indices (used by the stepper wrapper). */\n readonly stepFields = input<FormField[] | null>(null);\n\n readonly formSubmit = output<FormEngineEvent>();\n readonly formChange = output<FormEngineEvent>();\n\n // ─── Services ────────────────────────────────────────────────────────────\n\n protected readonly formService = inject(FormEngineService);\n protected readonly uploadService = inject(ImageUploadService);\n protected readonly fieldRegistry = inject(FieldRegistry);\n\n // ─── Internal State ──────────────────────────────────────────────────────\n\n readonly fields = signal<FormField[]>([]);\n readonly formGroup = signal<FormGroup>(new FormGroup({}));\n readonly ready = signal(false);\n\n /** Async-loaded options keyed by formControlName */\n readonly asyncOptions = signal<Record<string, unknown[]>>({});\n\n private readonly formStatusTick = signal(0);\n private readonly focusedMap = signal<Record<string, boolean>>({});\n\n /** Subscriptions for async option re-loads; disposed on every rebuild. */\n private optionLoaderSubs: Subscription[] = [];\n\n // ─── Derived ─────────────────────────────────────────────────────────────\n\n readonly visibleFields = computed(() => {\n this.formStatusTick();\n this.formService.patchTick();\n const values = this.formGroup().getRawValue();\n const source = this.stepFields() ?? this.fields();\n return source.filter((f) => {\n if (f.config.attributes.visible === false) return false;\n return this.formService.evaluateShowWhen(f, values);\n });\n });\n\n /**\n * Track patchTick so .valid (a plain object property) re-reads after every\n * form change. Without this, the submit-button disabled binding stays stuck\n * on the FormGroup's initial (invalid) state.\n */\n readonly formValid = computed(() => {\n this.formService.patchTick();\n this.formStatusTick();\n return this.formGroup().valid;\n });\n\n protected placeholderVisibilityMap: Record<string, ReturnType<typeof computed>> = {};\n\n /**\n * Resolve the placeholder string to render for a field. Safe for nested\n * fields (repeater itemFields, group groupFields) whose formControlName\n * isn't pre-registered in `placeholderVisibilityMap` — those fall back to\n * the raw `field.placeholder` since they don't participate in floatLabel.\n */\n protected placeholderFor(field: FormField): string | null {\n const name = field.formControlName;\n if (!name) return field.placeholder ?? null;\n const sig = this.placeholderVisibilityMap[name];\n if (!sig) return field.placeholder ?? null;\n return sig() ? (field.placeholder ?? null) : null;\n }\n\n readonly errorMap = computed(() => {\n this.formStatusTick();\n this.formService.patchTick();\n const errors: Record<string, string | null> = {};\n const group = this.formGroup();\n if (!group) return errors;\n for (const field of this.fields()) {\n if (!field.formControlName) continue;\n const control = group.get(field.formControlName);\n errors[field.formControlName] = this.formService.resolveError(field, control);\n }\n return errors;\n });\n\n // ─── Lifecycle ───────────────────────────────────────────────────────────\n\n constructor() {\n effect(() => {\n this.ready.set(false);\n\n const schemaIn = this.schema();\n const incoming: FormField[] = schemaIn?.fields\n ? schemaIn.fields\n : schemaIn?.steps\n ? schemaIn.steps.flatMap((s) => s.fields)\n : this.fieldsInput();\n\n if (!incoming.length) return;\n\n const sorted = [...incoming].sort((a, b) => {\n const oa = a.layout?.order ?? Number.MAX_SAFE_INTEGER;\n const ob = b.layout?.order ?? Number.MAX_SAFE_INTEGER;\n return oa - ob;\n });\n\n this.fields.set(sorted);\n this.buildForm(sorted, schemaIn ?? undefined);\n });\n\n effect(() => {\n this.formService.patchTick();\n if (!this.ready()) return;\n this.fields.set(this.formService.fields());\n this.uploadService.syncPreviews(this.fields(), this.formGroup());\n });\n }\n\n // ─── Form Builder ────────────────────────────────────────────────────────\n\n private buildForm(fields: FormField[], schema?: FormSchema): void {\n // Tear down anything tied to the previous form group before we rebuild.\n this.disposeOptionLoaderSubs();\n this.placeholderVisibilityMap = {};\n\n const group = this.formService.buildFormGroup(fields);\n this.formGroup.set(group);\n\n // Register synchronously so prior subs are disposed BEFORE we add new\n // computed-field listeners below — otherwise register() would wipe them.\n this.formService.register(group, fields, schema);\n\n for (const field of fields) {\n if (!field.formControlName) continue;\n this.placeholderVisibilityMap[field.formControlName] = computed(() => {\n if (!field.floatLabel) return true;\n const control = this.formGroup()?.get(field.formControlName!);\n if (!control) return false;\n const v = control.value;\n const hasValue =\n v !== null && v !== undefined && v !== '' && (!Array.isArray(v) || v.length > 0);\n return this.focusedMap()[field.formControlName!] === true && !hasValue;\n });\n }\n\n if (schema?.crossFieldValidators?.length) {\n this.formService.applyCrossFieldValidators(group, schema.crossFieldValidators);\n }\n this.formService.setupComputedFields(group, fields);\n\n // Bootstrap async options for select-like fields\n for (const f of fields) {\n const a = f.config.attributes;\n if (a.optionsLoader && f.formControlName) {\n void this.loadAsyncOptions(f);\n for (const dep of a.optionsDependsOn ?? []) {\n const depCtrl = group.get(dep);\n if (!depCtrl) continue;\n this.optionLoaderSubs.push(\n depCtrl.valueChanges.subscribe(() => void this.loadAsyncOptions(f))\n );\n }\n }\n }\n\n queueMicrotask(() => {\n this.ready.set(true);\n this.uploadService.syncPreviews(this.fields(), this.formGroup());\n });\n }\n\n private disposeOptionLoaderSubs(): void {\n for (const s of this.optionLoaderSubs) s.unsubscribe();\n this.optionLoaderSubs = [];\n }\n\n private async loadAsyncOptions(field: FormField): Promise<void> {\n const a = field.config.attributes;\n if (!a.optionsLoader || !field.formControlName) return;\n const formValue = this.formGroup().getRawValue();\n const context: Record<string, unknown> = {};\n for (const dep of a.optionsDependsOn ?? []) context[dep] = formValue[dep];\n\n this.formService.updateFieldAttributes(field.formControlName, { loading: true });\n const opts = await this.formService.resolveDependentOptions(a.optionsLoader, context, formValue);\n this.asyncOptions.update((m) => ({ ...m, [field.formControlName!]: opts }));\n this.formService.updateFieldAttributes(field.formControlName, { loading: false, options: opts });\n }\n\n // ─── Field Registry resolver (used by custom inputType) ──────────────────\n\n protected customRenderer(field: FormField): Type<unknown> | undefined {\n return this.fieldRegistry.getRenderer(field.config.attributes.inputType);\n }\n\n protected customRendererInputs(field: FormField): Record<string, unknown> {\n return { field, formGroup: this.formGroup() };\n }\n\n // ─── Date helpers ────────────────────────────────────────────────────────\n\n protected minDateFor(field: FormField): Date | undefined {\n const a = field.config.attributes;\n if (a.minDate) return a.minDate;\n if (a.minToday) {\n const d = new Date();\n d.setDate(d.getDate() + (a.minOffsetDays ?? 0));\n return d;\n }\n return undefined;\n }\n\n protected maxDateFor(field: FormField): Date | undefined {\n const a = field.config.attributes;\n if (a.maxDate) return a.maxDate;\n if (a.maxToday) {\n const d = new Date();\n d.setDate(d.getDate() + (a.maxOffsetDays ?? 0));\n return d;\n }\n return undefined;\n }\n\n // ─── Effective options resolver ──────────────────────────────────────────\n\n protected optionsFor(field: FormField): unknown[] {\n const a = field.config.attributes;\n if (field.formControlName && this.asyncOptions()[field.formControlName]) {\n return this.asyncOptions()[field.formControlName];\n }\n return (a.options as unknown[]) ?? [];\n }\n\n // ─── Repeater helpers ────────────────────────────────────────────────────\n\n protected getArray(name: string): FormArray | null {\n const c = this.formGroup().get(name);\n return c instanceof FormArray ? c : null;\n }\n\n protected addRepeaterRow(field: FormField): void {\n if (!field.formControlName) return;\n const arr = this.getArray(field.formControlName);\n if (!arr) return;\n if (field.config.attributes.maxRows && arr.length >= field.config.attributes.maxRows) return;\n this.formService.addArrayItem(field.formControlName);\n this.triggerTick();\n }\n\n protected removeRepeaterRow(field: FormField, i: number): void {\n if (!field.formControlName) return;\n const arr = this.getArray(field.formControlName);\n if (!arr) return;\n if (field.config.attributes.minRows && arr.length <= field.config.attributes.minRows) return;\n this.formService.removeArrayItem(field.formControlName, i);\n this.triggerTick();\n }\n\n protected rowGroup(field: FormField, i: number): FormGroup {\n return this.getArray(field.formControlName!)?.at(i) as FormGroup;\n }\n\n /**\n * DOM id for a field's input element. Scoped by row index when the field\n * lives inside a repeater so the same `formControlName` across rows\n * doesn't produce duplicate ids (HTML spec violation + breaks\n * <label for>, aria-describedby, and document.querySelector lookups).\n */\n protected inputId(field: FormField, suffix?: number | string): string {\n const base = (field.formControlName ?? '') + 'Id';\n return suffix !== undefined && suffix !== null ? `${base}_${suffix}` : base;\n }\n\n /**\n * Resolve the validation message for a single field inside a repeater row.\n * Mirrors errorMap() but for FormGroup rows that aren't tracked in the\n * top-level fields signal.\n */\n protected resolveRowError(row: FormGroup, sub: FormField): string | null {\n this.formService.patchTick();\n if (!sub.formControlName) return null;\n const ctrl = row.get(sub.formControlName);\n return this.formService.resolveError(sub, ctrl);\n }\n\n // ─── Events ──────────────────────────────────────────────────────────────\n\n /** Central event handler. Accepts `unknown` because PrimeNG emits custom event objects. */\n async onEvent(field: FormField, event: unknown, eventType?: FormEngineEventType): Promise<void> {\n this.triggerTick();\n\n const rawType = eventType ?? ((event as Event)?.type as FormEngineEventType);\n let type = rawType;\n\n if (type === 'focus')\n this.focusedMap.update((m) => ({ ...m, [field.formControlName!]: true }));\n if (type === 'blur')\n this.focusedMap.update((m) => ({ ...m, [field.formControlName!]: false }));\n\n if (type === 'uploadHandler') {\n await this.uploadService.handleUpload(\n field,\n event as { files: File[] },\n this.formGroup(),\n this.formService,\n () => this.emitChange(field, 'uploadHandler', event)\n );\n return;\n }\n\n if (type === 'inputKeydown' && field.config.attributes.inputType === 'autocomplete') {\n const ke = event as KeyboardEvent;\n if (ke.key === 'Enter') {\n const inputValue = (ke.target as HTMLInputElement).value?.trim();\n if (inputValue) {\n const tag = {\n [field.config.attributes.optionLabel!]: inputValue,\n [field.config.attributes.optionValue!]: inputValue,\n };\n const existing = [...((field.config.attributes.suggestions as unknown[]) ?? []), tag];\n this.formService.updateFieldAttributes(field.formControlName!, { suggestions: existing });\n this.formGroup().get(field.formControlName!)?.setValue(existing);\n type = 'add';\n }\n }\n }\n\n if (type === 'unselect' && field.config.attributes.inputType === 'autocomplete') {\n const evtValue = (event as { value: unknown }).value;\n const remaining = ((field.config.attributes.suggestions as unknown[]) ?? []).filter(\n (v) => evtValue !== v\n );\n this.formService.updateFieldAttributes(field.formControlName!, { suggestions: remaining });\n this.formGroup().get(field.formControlName!)?.setValue(remaining);\n }\n\n const allowed = field.config.attributes.acceptedEvents ?? [];\n if (!allowed.includes(type)) return;\n\n const payload = this.buildPayload(field, type, event);\n\n if (type === 'click') {\n const role = field.config.attributes.buttonRole;\n if (role === 'reset') {\n this.formService.reset();\n this.formChange.emit(payload);\n return;\n }\n if (role === 'cancel' || role === 'custom') {\n this.formChange.emit(payload);\n return;\n }\n if (!this.formValid()) this.formGroup().markAllAsTouched();\n this.formSubmit.emit({ ...payload, values: this.formService.buildSubmitPayload() });\n } else {\n this.formChange.emit(payload);\n }\n }\n\n removeImage(field: FormField, image: string): void {\n this.uploadService.removeImage(\n field,\n image,\n this.formGroup(),\n this.formService,\n () => this.emitChange(field, 'uploadHandler', new Event('remove'))\n );\n }\n\n // ─── Helpers ─────────────────────────────────────────────────────────────\n\n private buildPayload(field: FormField, type: FormEngineEventType, originalEvent: unknown): FormEngineEvent {\n return {\n field,\n values: this.formGroup().getRawValue(),\n valid: this.formValid(),\n type,\n originalEvent,\n };\n }\n\n private emitChange(field: FormField, type: FormEngineEventType, event: unknown): void {\n this.formChange.emit(this.buildPayload(field, type, event));\n }\n\n private triggerTick(): void {\n this.formStatusTick.update((v) => v + 1);\n }\n\n protected getControl(name: string): FormControl {\n return this.formGroup().get(name) as FormControl;\n }\n}\n","@if (formTitle().length) {\n <div class=\"ngx-form-title\">{{ formTitle() }}</div>\n}\n\n@if (ready()) {\n <form [formGroup]=\"formGroup()\" class=\"ngx-form-grid\">\n @for (field of visibleFields(); track field.formControlName ?? $index) {\n <div\n [class]=\"\n 'ngx-col-' +\n (field.layout?.columnSpan ?? 12) +\n ' ' +\n (field.layout?.wrapperClass ?? '')\n \"\n [style]=\"field.layout?.wrapperStyle ?? {}\"\n [style.display]=\"field.config.attributes.isHidden ? 'none' : 'block'\"\n >\n <!-- Float Label wrapper -->\n @if (field.floatLabel) {\n <p-floatlabel [variant]=\"field.floatVariant ?? 'on'\">\n <div class=\"ngx-field-inner\">\n <ng-container\n [ngTemplateOutlet]=\"fieldTpl\"\n [ngTemplateOutletContext]=\"{ $implicit: field, formGroup: formGroup() }\"\n />\n </div>\n <label\n [attr.for]=\"field.formControlName + 'Id'\"\n [attr.id]=\"field.formControlName + 'Label'\"\n >\n @if (field.labelIconPos === 'left') {\n <i [class]=\"field.labelIcon\"></i>\n }\n {{ field.label }}\n @if (field.labelIconPos === 'right') {\n <i [class]=\"field.labelIcon\"></i>\n }\n @if (field.validations?.rules?.required) {\n <span class=\"ngx-required\">*</span>\n }\n </label>\n </p-floatlabel>\n }\n\n <!-- Toggle card layout -->\n @else if (\n field.config.attributes.cardLayout &&\n field.config.attributes.inputType === 'toggle'\n ) {\n <div\n class=\"ngx-toggle-card\"\n [style.--toggle-color]=\"field.config.attributes.cardIconColor\"\n >\n <div\n class=\"ngx-toggle-card-icon\"\n [style.background]=\"\n field.config.attributes.cardIconBg ??\n 'var(--p-primary-50, #eff6ff)'\n \"\n [style.color]=\"\n field.config.attributes.cardIconColor ??\n 'var(--p-primary-500, #3b82f6)'\n \"\n >\n <i [class]=\"field.config.attributes.cardIcon ?? 'pi pi-bell'\"></i>\n </div>\n <div class=\"ngx-toggle-card-body\">\n <span class=\"ngx-toggle-card-label\">\n {{ field.label }}\n @if (field.validations?.rules?.required) {\n <span class=\"ngx-required\">*</span>\n }\n </span>\n @if (field.config.attributes.info?.length) {\n <span\n class=\"ngx-toggle-card-desc\"\n [innerHTML]=\"field.config.attributes.info\"\n ></span>\n }\n </div>\n <p-toggleswitch\n [formControlName]=\"field.formControlName!\"\n [inputId]=\"field.formControlName + 'Id'\"\n (onChange)=\"onEvent(field, $event, 'change')\"\n />\n </div>\n <!--\n Always reserve one line of space for the error so the row height\n doesn't change when validation fires (otherwise sibling fields\n jump down when the error appears).\n -->\n @if (field.validations?.rules) {\n <small\n class=\"ngx-error\"\n [class.ngx-error--placeholder]=\"!errorMap()[field.formControlName!]\"\n [attr.id]=\"field.formControlName + 'Err'\"\n >{{ errorMap()[field.formControlName!] || ' ' }}</small>\n }\n }\n\n <!-- Normal label wrapper -->\n @else {\n @if (field.label && field.label.length) {\n <label\n class=\"ngx-field-label\"\n [attr.for]=\"field.formControlName + 'Id'\"\n [attr.id]=\"field.formControlName + 'Label'\"\n >\n @if (field.labelIconPos === 'left') {\n <i [class]=\"field.labelIcon\"></i>\n }\n {{ field.label }}\n @if (field.labelIconPos === 'right') {\n <i [class]=\"field.labelIcon\"></i>\n }\n @if (field.validations?.rules?.required) {\n <span class=\"ngx-required\">*</span>\n }\n </label>\n }\n <div class=\"ngx-field-inner\">\n <ng-container\n [ngTemplateOutlet]=\"fieldTpl\"\n [ngTemplateOutletContext]=\"{ $implicit: field, formGroup: formGroup() }\"\n />\n </div>\n\n <!--\n Validation error — always reserve one line of space (placeholder\n class makes it invisible when there's no error) so triggering a\n required/pattern message doesn't push the row below it down.\n -->\n @if (field.validations?.rules) {\n <small\n class=\"ngx-error\"\n [class.ngx-error--placeholder]=\"!errorMap()[field.formControlName!]\"\n [attr.id]=\"field.formControlName + 'Err'\"\n >{{ errorMap()[field.formControlName!] || ' ' }}</small>\n }\n\n <!-- Info / hint -->\n @if (field.config.attributes.info?.length) {\n <small\n class=\"ngx-hint\"\n [attr.id]=\"field.formControlName + 'Hint'\"\n [innerHTML]=\"field.config.attributes.info\"\n ></small>\n }\n }\n </div>\n }\n </form>\n}\n\n<!-- ─── Field Renderer Template ──────────────────────────────────────────── -->\n<!--\n `formGroup` is passed in via the template context so each rendering site\n binds the right group: the root FormGroup for top-level fields, the row's\n FormGroup for repeater rows. Hard-coding `formGroup()` here would override\n row-level bindings and route nested formControlName lookups to the root,\n which is the bug we're fixing.\n\n Known issue: during initial CD passes Angular logs NG01050 spam because\n the FormGroup directive on this ng-container materialises after children\n formControlName directives query their parent ControlContainer. Bindings\n recover and form values flow correctly afterwards. Cleaner fix would be\n to avoid the ngTemplateOutlet + context + nested formGroup combination\n altogether (e.g. inline the @switch at each call site).\n-->\n<ng-template #fieldTpl let-field let-fg=\"formGroup\" let-idSuffix=\"idSuffix\">\n <ng-container [formGroup]=\"fg\">\n @switch (field.config.attributes.inputType) {\n <!-- ── Custom field (registry) ── -->\n @case (customRenderer(field) ? field.config.attributes.inputType : '__never__') {\n <ng-container\n *ngComponentOutlet=\"customRenderer(field)!; inputs: customRendererInputs(field)\"\n />\n }\n\n <!-- ── Group (nested FormGroup) ── -->\n @case ('group') {\n <fieldset\n class=\"ngx-field-group\"\n [attr.formGroupName]=\"field.formControlName\"\n >\n @for (sub of field.config.attributes.groupFields ?? []; track sub.formControlName ?? $index) {\n <div class=\"ngx-field-group-row\">\n <ng-container\n [ngTemplateOutlet]=\"fieldTpl\"\n [ngTemplateOutletContext]=\"{ $implicit: sub, formGroup: formGroup() }\"\n />\n </div>\n }\n </fieldset>\n }\n\n <!-- ── Repeater (FormArray) ── -->\n @case ('repeater') {\n <div class=\"ngx-repeater\">\n @for (row of getArray(field.formControlName!)?.controls ?? []; track $index) {\n @let rowIndex = $index;\n <div class=\"ngx-repeater-row\" [formGroup]=\"$any(row)\">\n <div class=\"ngx-repeater-row-fields\">\n @for (sub of field.config.attributes.itemFields ?? []; track sub.formControlName ?? $index) {\n <div\n [class]=\"\n 'ngx-col-' + (sub.layout?.columnSpan ?? 12)\n \"\n >\n @if (sub.label) {\n <label\n class=\"ngx-field-label\"\n [attr.for]=\"inputId(sub, rowIndex)\"\n >\n {{ sub.label }}\n @if (sub.validations?.rules?.required) {\n <span class=\"ngx-required\">*</span>\n }\n </label>\n }\n <ng-container\n [ngTemplateOutlet]=\"fieldTpl\"\n [ngTemplateOutletContext]=\"{ $implicit: sub, formGroup: $any(row), idSuffix: rowIndex }\"\n />\n @if (sub.validations?.rules && sub.formControlName) {\n <small\n class=\"ngx-error\"\n [class.ngx-error--placeholder]=\"!resolveRowError($any(row), sub)\"\n >{{ resolveRowError($any(row), sub) || ' ' }}</small>\n }\n </div>\n }\n </div>\n <button\n type=\"button\"\n class=\"ngx-repeater-remove\"\n pButton\n [icon]=\"'pi pi-trash'\"\n [rounded]=\"true\"\n [text]=\"true\"\n (click)=\"removeRepeaterRow(field, $index)\"\n ></button>\n </div>\n }\n <button\n pButton\n type=\"button\"\n class=\"ngx-repeater-add\"\n [icon]=\"'pi pi-plus'\"\n [label]=\"field.config.attributes.addLabel ?? 'Add row'\"\n [text]=\"true\"\n (click)=\"addRepeaterRow(field)\"\n ></button>\n </div>\n }\n\n <!-- ── Dependent / Cascading Dropdown ── -->\n @case ('dependentDropdown') {\n <p-cascadeselect\n [id]=\"inputId(field, idSuffix)\"\n [inputId]=\"inputId(field, idSuffix)\"\n [formControlName]=\"field.formControlName!\"\n [options]=\"$any(optionsFor(field))\"\n [optionLabel]=\"field.config.attributes.optionLabel ?? 'label'\"\n [optionValue]=\"field.config.attributes.optionValue ?? 'value'\"\n [optionGroupLabel]=\"field.config.attributes.optionGroupLabel ?? 'label'\"\n [optionGroupChildren]=\"\n $any(field.config.attributes.optionGroupChildren ?? ['children'])\n \"\n [placeholder]=\"field.placeholder ?? ''\"\n appendTo=\"body\"\n (onChange)=\"onEvent(field, $event, 'change')\"\n (onShow)=\"onEvent(field, $event, 'show')\"\n (onHide)=\"onEvent(field, $event, 'hide')\"\n />\n }\n\n <!-- ── Editor (rich text) ── -->\n @case ('editor') {\n <p-editor\n [formControlName]=\"field.formControlName!\"\n [style]=\"{ height: (field.config.attributes['height'] ?? '180px') }\"\n (onTextChange)=\"onEvent(field, $event, 'change')\"\n ></p-editor>\n }\n\n <!-- ── Confirm password ── -->\n @case ('confirmPassword') {\n <p-password\n [inputId]=\"inputId(field, idSuffix)\"\n [formControlName]=\"field.formControlName!\"\n [feedback]=\"false\"\n [toggleMask]=\"field.config.attributes.toggleMask ?? true\"\n [placeholder]=\"field.placeholder ?? ''\"\n appendTo=\"body\"\n (onBlur)=\"onEvent(field, $event, 'blur')\"\n />\n }\n\n <!-- ── File Upload ── -->\n @case ('fileUpload') {\n <div>\n <div\n [class]=\"field.config.attributes.isInline ? 'ngx-file-inline' : ''\"\n >\n <p-fileUpload\n mode=\"basic\"\n customUpload\n [id]=\"inputId(field, idSuffix)\"\n [multiple]=\"field.config.attributes.multiple\"\n [chooseIcon]=\"field.config.attributes.chooseIcon ?? 'pi pi-upload'\"\n [accept]=\"field.config.attributes.accept ?? 'image/*'\"\n [maxFileSize]=\"field.config.attributes.maxFileSize ?? 1000000\"\n [auto]=\"true\"\n [chooseLabel]=\"field.config.attributes.chooseLabel ?? 'Upload'\"\n (uploadHandler)=\"onEvent(field, $event, 'uploadHandler')\"\n />\n\n @if (uploadService.imagePreviews()[field.formControlName!]?.length) {\n <div class=\"ngx-image-list\">\n @for (\n image of uploadService.imagePreviews()[field.formControlName!];\n let i = $index;\n track i\n ) {\n <div class=\"ngx-image-card\">\n <i\n class=\"pi pi-times ngx-image-remove\"\n (click)=\"removeImage(field, image)\"\n ></i>\n <div class=\"ngx-image-wrapper\">\n @if (!uploadService.isBase64(image)) {\n <img\n fill\n sizes=\"100\"\n [ngSrc]=\"image\"\n (load)=\"uploadService.onLoad(image)\"\n (error)=\"uploadService.onLoad(image)\"\n [class.loading]=\"uploadService.isLoading(image)\"\n [class.loaded]=\"!uploadService.isLoading(image)\"\n class=\"ngx-preview-img\"\n alt=\"preview\"\n />\n } @else {\n <img\n fill\n sizes=\"100\"\n [src]=\"image\"\n (load)=\"uploadService.onLoad(image)\"\n (error)=\"uploadService.onLoad(image)\"\n [class.loading]=\"uploadService.isLoading(image)\"\n [class.loaded]=\"!uploadService.isLoading(image)\"\n class=\"ngx-preview-img\"\n alt=\"preview\"\n />\n }\n @if (uploadService.isLoading(image)) {\n <div class=\"ngx-img-skeleton\"></div>\n }\n </div>\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n\n <!-- ── Static Text ── -->\n @case ('staticText') {\n <span\n (click)=\"onEvent(field, $event, 'staticTextClick')\"\n [innerHTML]=\"field.config.attributes.value\"\n ></span>\n }\n\n <!-- ── Divider ── -->\n @case ('divider') {\n <p-divider\n [layout]=\"field.config.attributes.dividerLayout\"\n [type]=\"field.config.attributes.dividerType\"\n [align]=\"field.config.attributes.dividerAlign\"\n >\n @if (field.config.attributes.value) {\n <span [innerHTML]=\"field.config.attributes.value\"></span>\n }\n </p-divider>\n }\n\n <!-- ── Button ── -->\n @case ('button') {\n <div class=\"ngx-btn-wrap\">\n <button\n pButton\n type=\"button\"\n [id]=\"inputId(field, idSuffix)\"\n [label]=\"field.btnLabel ?? ''\"\n [icon]=\"field.config.attributes.icon ?? ''\"\n [iconPos]=\"field.config.attributes.iconPosition ?? 'left'\"\n [tabindex]=\"field.tabIndex ?? 0\"\n [disabled]=\"\n field.config.attributes.buttonRole === 'submit' ||\n field.config.attributes.type === 'submit'\n ? !formValid()\n : !!field.config.attributes.disabled\n \"\n [class.p-button-outlined]=\"\n field.config.attributes.variant === 'secondary'\n \"\n [class.p-button-text]=\"field.config.attributes.text === true\"\n [class.p-button-rounded]=\"field.config.attributes.rounded === true\"\n [class.p-button-sm]=\"field.config.attributes.size === 'sm'\"\n [class.p-button-lg]=\"field.config.attributes.size === 'lg'\"\n (click)=\"onEvent(field, $event)\"\n ></button>\n </div>\n }\n\n <!-- ── Everything else inside p-inputgroup ── -->\n @default {\n <p-inputgroup>\n @if (\n field.config.attributes.fieldPos === 'left' &&\n field.config.attributes.fieldIcon\n ) {\n <p-inputgroup-addon>\n <i [class]=\"field.config.attributes.fieldIcon\">\n {{ field.config.attributes.fieldIconText ?? '' }}\n </i>\n </p-inputgroup-addon>\n }\n\n @switch (field.config.attributes.inputType) {\n <!-- text / email / number / url -->\n @case ('text') {\n <input\n pInputText\n [id]=\"inputId(field, idSuffix)\"\n [formControlName]=\"field.formControlName!\"\n [type]=\"field.config.attributes.type ?? 'text'\"\n [tabindex]=\"field.tabIndex ?? 0\"\n [attr.placeholder]=\"placeholderFor(field)\"\n [attr.aria-describedby]=\"\n (errorMap()[field.formControlName!] ? field.formControlName + 'Err ' : '') +\n (field.config.attributes.info ? field.formControlName + 'Hint' : '')\n \"\n [pKeyFilter]=\"field.config.attributes.keyfilter\"\n (change)=\"onEvent(field, $event)\"\n (input)=\"onEvent(field, $event)\"\n (focus)=\"onEvent(field, $event)\"\n (blur)=\"onEvent(field, $event)\"\n (keyup)=\"onEvent(field, $event)\"\n (keydown)=\"onEvent(field, $event)\"\n (keypress)=\"onEvent(field, $event)\"\n />\n }\n\n <!-- password -->\n @case ('password') {\n <p-password\n [inputId]=\"inputId(field, idSuffix)\"\n [formControlName]=\"field.formControlName!\"\n [feedback]=\"field.config.attributes.feedback\"\n [toggleMask]=\"field.config.attributes.toggleMask\"\n [placeholder]=\"field.config.attributes.placeholder ?? ''\"\n appendTo=\"body\"\n (onBlur)=\"onEvent(field, $event, 'blur')\"\n (onFocus)=\"onEvent(field, $event, 'focus')\"\n >\n @if (field.config.attributes.templateHeader) {\n <ng-container\n [ngTemplateOutlet]=\"field.config.attributes.templateHeader\"\n />\n }\n @if (field.config.attributes.templateFooter) {\n <ng-container\n [ngTemplateOutlet]=\"field.config.attributes.templateFooter\"\n />\n }\n </p-password>\n }\n\n <!-- textarea -->\n @case ('textarea') {\n <textarea\n pTextarea\n [id]=\"inputId(field, idSuffix)\"\n [formControlName]=\"field.formControlName!\"\n [rows]=\"field.config.attributes.rows ?? 3\"\n [cols]=\"field.config.attributes.cols ?? 30\"\n [autoResize]=\"field.config.attributes.autoResize\"\n [placeholder]=\"field.config.attributes.placeholder ?? ''\"\n (change)=\"onEvent(field, $event)\"\n (input)=\"onEvent(field, $event)\"\n (focus)=\"onEvent(field, $event)\"\n (blur)=\"onEvent(field, $event)\"\n >\n </textarea>\n }\n\n <!-- select -->\n @case ('select') {\n <p-select\n [id]=\"inputId(field, idSuffix)\"\n [inputId]=\"inputId(field, idSuffix)\"\n [attr.aria-labelledby]=\"field.formControlName + 'Label'\"\n [formControlName]=\"field.formControlName!\"\n [options]=\"$any(optionsFor(field))\"\n [optionLabel]=\"field.config.attributes.optionLabel\"\n [optionValue]=\"field.config.attributes.optionValue\"\n [placeholder]=\"placeholderFor(field) ?? ''\"\n [showClear]=\"field.config.attributes.showClear\"\n [filter]=\"field.config.attributes.filter\"\n [filterBy]=\"field.config.attributes.filterBy\"\n [filterPlaceholder]=\"field.config.attributes.filterPlaceholder\"\n [loading]=\"field.config.attributes.loading\"\n [virtualScroll]=\"field.config.attributes.virtualScroll\"\n [virtualScrollItemSize]=\"\n field.config.attributes.virtualScrollItemSize\n \"\n [lazy]=\"field.config.attributes.lazy\"\n [emptyMessage]=\"field.config.attributes.emptyMessage\"\n appendTo=\"body\"\n (onChange)=\"onEvent(field, $event, 'change')\"\n (onFocus)=\"onEvent(field, $event, 'focus')\"\n (onBlur)=\"onEvent(field, $event, 'blur')\"\n (onShow)=\"onEvent(field, $event, 'show')\"\n (onHide)=\"onEvent(field, $event, 'hide')\"\n (onClear)=\"onEvent(field, $event, 'clear')\"\n (onLazyLoad)=\"onEvent(field, $event, 'lazyLoad')\"\n >\n @if (\n field.config.attributes.isTemplate &&\n field.config.attributes.template\n ) {\n <ng-container\n [ngTemplateOutlet]=\"field.config.attributes.template\"\n />\n }\n </p-select>\n }\n\n <!-- multiSelect -->\n @case ('multiSelect') {\n <p-multiselect\n [id]=\"inputId(field, idSuffix)\"\n [inputId]=\"inputId(field, idSuffix)\"\n [formControlName]=\"field.formControlName!\"\n [options]=\"$any(optionsFor(field))\"\n [optionLabel]=\"field.config.attributes.optionLabel\"\n [optionValue]=\"field.config.attributes.optionValue\"\n [placeholder]=\"field.config.attributes.placeholder ?? ''\"\n [filter]=\"field.config.attributes.filter\"\n [showClear]=\"field.config.attributes.showClear\"\n [selectionLimit]=\"field.config.attributes.selectionLimit\"\n [display]=\"field.config.attributes.display\"\n [loading]=\"field.config.attributes.loading\"\n [virtualScroll]=\"field.config.attributes.virtualScroll\"\n [virtualScrollItemSize]=\"\n field.config.attributes.virtualScrollItemSize\n \"\n [scrollHeight]=\"field.config.attributes.scrollHeight\"\n appendTo=\"body\"\n (onChange)=\"onEvent(field, $event, 'change')\"\n (onFocus)=\"onEvent(field, $event, 'focus')\"\n (onBlur)=\"onEvent(field, $event, 'blur')\"\n (onClear)=\"onEvent(field, $event, 'clear')\"\n (onHide)=\"onEvent(field, $event, 'hide')\"\n (onRemove)=\"onEvent(field, $event, 'remove')\"\n (onSelectAll)=\"onEvent(field, $event, 'select')\"\n >\n </p-multiselect>\n }\n\n <!-- autocomplete -->\n @case ('autocomplete') {\n <p-autocomplete\n [id]=\"inputId(field, idSuffix)\"\n [inputId]=\"inputId(field, idSuffix)\"\n [formControlName]=\"field.formControlName!\"\n [placeholder]=\"field.config.attributes.placeholder ?? ''\"\n [suggestions]=\"field.config.attributes.suggestions\"\n [optionLabel]=\"field.config.attributes.optionLabel\"\n [multiple]=\"field.config.attributes.multiple\"\n [forceSelection]=\"field.config.attributes.forceSelection\"\n [dropdown]=\"field.config.attributes.dropdown\"\n [showClear]=\"field.config.attributes.showClear\"\n [completeOnFocus]=\"field.config.attributes.completeOnFocus\"\n [minLength]=\"field.config.attributes.minLength ?? 1\"\n [delay]=\"field.config.attributes.delay ?? 300\"\n [virtualScroll]=\"field.config.attributes.virtualScroll\"\n [virtualScrollItemSize]=\"\n field.config.attributes.virtualScrollItemSize\n \"\n [scrollHeight]=\"field.config.attributes.scrollHeight\"\n appendTo=\"body\"\n (completeMethod)=\"onEvent(field, $event, 'complete')\"\n (onSelect)=\"onEvent(field, $event, 'select')\"\n (onUnselect)=\"onEvent(field, $event, 'unselect')\"\n (onAdd)=\"onEvent(field, $event, 'add')\"\n (onFocus)=\"onEvent(field, $event, 'focus')\"\n (onBlur)=\"onEvent(field, $event, 'blur')\"\n (onClear)=\"onEvent(field, $event, 'clear')\"\n (onInputKeydown)=\"onEvent(field, $event, 'inputKeydown')\"\n >\n </p-autocomplete>\n }\n\n <!-- toggle -->\n @case ('toggle') {\n <p-toggleswitch\n [formControlName]=\"field.formControlName!\"\n [inputId]=\"inputId(field, idSuffix)\"\n [attr.aria-labelledby]=\"field.formControlName + 'Label'\"\n (onChange)=\"onEvent(field, $event, 'change')\"\n />\n }\n\n <!-- checkbox -->\n @case ('checkbox') {\n <p-checkbox\n [inputId]=\"inputId(field, idSuffix)\"\n [formControlName]=\"field.formControlName!\"\n [name]=\"field.config.attributes.name ?? field.formControlName!\"\n [value]=\"field.config.attributes.value\"\n (onChange)=\"onEvent(field, $event, 'change')\"\n />\n }\n\n <!-- radio -->\n @case ('radio') {\n @for (opt of $any(optionsFor(field)); track $index) {\n <div class=\"ngx-radio-item\">\n <p-radiobutton\n [inputId]=\"field.formControlName + '_' + $index\"\n [formControlName]=\"field.formControlName!\"\n [name]=\"field.formControlName!\"\n [value]=\"\n opt[field.config.attributes.optionValue ?? 'value']\n \"\n (onClick)=\"onEvent(field, $event, 'change')\"\n />\n <label [for]=\"field.formControlName + '_' + $index\">\n {{ opt[field.config.attributes.optionLabel ?? 'label'] }}\n </label>\n </div>\n }\n }\n\n <!-- datePicker / time / month / year -->\n @case ('datePicker') {\n <p-datepicker\n [inputId]=\"inputId(field, idSuffix)\"\n [formControlName]=\"field.formControlName!\"\n [placeholder]=\"field.config.attributes.placeholder ?? ''\"\n [showIcon]=\"field.config.attributes.showIcon\"\n [minDate]=\"minDateFor(field)!\"\n [maxDate]=\"maxDateFor(field)!\"\n [selectionMode]=\"$any(field.config.attributes.selectionMode)\"\n [readonlyInput]=\"field.config.attributes.readonlyInput\"\n [showButtonBar]=\"field.config.attributes.showButtonBar\"\n [showTime]=\"field.config.attributes.showTime\"\n [hourFormat]=\"field.config.attributes.hourFormat\"\n [timeOnly]=\"field.config.attributes.timeOnly\"\n [view]=\"$any(field.config.attributes.view)\"\n [dateFormat]=\"field.config.attributes.dateFormat\"\n [numberOfMonths]=\"field.config.attributes.numberOfMonths ?? 1\"\n [showClear]=\"field.config.attributes.showClear\"\n appendTo=\"body\"\n (onSelect)=\"onEvent(field, $event, 'select')\"\n (onBlur)=\"onEvent(field, $event, 'blur')\"\n (onFocus)=\"onEvent(field, $event, 'focus')\"\n (onClear)=\"onEvent(field, $event, 'clear')\"\n >\n </p-datepicker>\n }\n\n @case ('time') {\n <p-datepicker\n [inputId]=\"inputId(field, idSuffix)\"\n [formControlName]=\"field.formControlName!\"\n [placeholder]=\"field.config.attributes.placeholder ?? ''\"\n [showIcon]=\"true\"\n [iconDisplay]=\"'input'\"\n [timeOnly]=\"true\"\n [showTime]=\"true\"\n [hourFormat]=\"field.config.attributes.hourFormat ?? '24'\"\n appendTo=\"body\"\n (onSelect)=\"onEvent(field, $event, 'select')\"\n />\n }\n\n @case ('month') {\n <p-datepicker\n [inputId]=\"inputId(field, idSuffix)\"\n [formControlName]=\"field.formControlName!\"\n [placeholder]=\"field.config.attributes.placeholder ?? ''\"\n [showIcon]=\"true\"\n [view]=\"'month'\"\n [dateFormat]=\"field.config.attributes.dateFormat ?? 'mm/yy'\"\n [readonlyInput]=\"true\"\n appendTo=\"body\"\n (onSelect)=\"onEvent(field, $event, 'select')\"\n />\n }\n\n @case ('year') {\n <p-datepicker\n [inputId]=\"inputId(field, idSuffix)\"\n [formControlName]=\"field.formControlName!\"\n [placeholder]=\"field.config.attributes.placeholder ?? ''\"\n [showIcon]=\"true\"\n [view]=\"'year'\"\n [dateFormat]=\"field.config.attributes.dateFormat ?? 'yy'\"\n [readonlyInput]=\"true\"\n appendTo=\"body\"\n (onSelect)=\"onEvent(field, $event, 'select')\"\n />\n }\n\n <!-- slider -->\n @case ('slider') {\n <p-slider\n [formControlName]=\"field.formControlName!\"\n [min]=\"field.config.attributes.min ?? 0\"\n [max]=\"field.config.attributes.max ?? 100\"\n [step]=\"field.config.attributes.step ?? 1\"\n [range]=\"field.config.attributes.range\"\n [orientation]=\"\n field.config.attributes.orientation ?? 'horizontal'\n \"\n (onChange)=\"onEvent(field, $event, 'change')\"\n />\n }\n\n <!-- rating -->\n @case ('rating') {\n <p-rating\n [formControlName]=\"field.formControlName!\"\n [stars]=\"field.config.attributes.stars ?? 5\"\n (onRate)=\"onEvent(field, $event, 'change')\"\n />\n }\n\n <!-- colorPicker -->\n @case ('colorPicker') {\n <p-colorpicker\n [formControlName]=\"field.formControlName!\"\n [inline]=\"field.config.attributes.inline\"\n (onChange)=\"onEvent(field, $event, 'change')\"\n />\n }\n }\n\n @if (\n field.config.attributes.fieldPos === 'right' &&\n field.config.attributes.fieldIcon\n ) {\n <p-inputgroup-addon>\n <i [class]=\"field.config.attributes.fieldIcon\">\n {{ field.config.attributes.fieldIconText ?? '' }}\n </i>\n </p-inputgroup-addon>\n }\n </p-inputgroup>\n }\n }\n </ng-container>\n</ng-template>\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n inject,\n input,\n output,\n} from '@angular/core';\nimport { NgClass } from '@angular/common';\nimport { ButtonModule } from 'primeng/button';\n\nimport {\n FormEngineEvent,\n FormEngineService,\n FormSchema,\n} from '@ngx-json-forms/core';\n\nimport { NgxJsonFormComponent } from './ngx-form-engine-primeng.component';\n\n/**\n * Wizard-style wrapper that drives `<ngx-json-form>` step-by-step using the\n * `FormSchema.steps` definition. Renders a header strip with step indicators,\n * the current step's fields, and Back / Next / Submit controls.\n */\n@Component({\n selector: 'ngx-json-form-stepper',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [NgxJsonFormComponent, ButtonModule, NgClass],\n styleUrl: './ngx-json-form-stepper.component.scss',\n template: `\n @if (schema().steps?.length) {\n <div class=\"ngx-stepper\">\n <!-- Step indicators -->\n <ol class=\"ngx-stepper-bar\">\n @for (step of schema().steps; track step.id) {\n <li\n class=\"ngx-stepper-item\"\n [ngClass]=\"{\n active: $index === activeIndex(),\n done: $index < activeIndex()\n }\"\n (click)=\"jumpTo($index)\"\n >\n <span class=\"ngx-stepper-num\">\n @if ($index < activeIndex()) {\n <i class=\"pi pi-check\"></i>\n } @else {\n {{ $index + 1 }}\n }\n </span>\n <span class=\"ngx-stepper-label\">\n @if (step.icon) {\n <i [class]=\"step.icon\"></i>\n }\n {{ step.title }}\n </span>\n </li>\n }\n </ol>\n\n <!-- Step body -->\n @if (activeStep(); as step) {\n @if (step.description) {\n <p class=\"ngx-stepper-desc\">{{ step.description }}</p>\n }\n <ngx-json-form\n [schema]=\"schema()\"\n [stepFields]=\"step.fields\"\n (formChange)=\"formChange.emit($event)\"\n (formSubmit)=\"onSubmit($event)\"\n />\n }\n\n <!-- Controls -->\n <div class=\"ngx-stepper-actions\">\n <button\n pButton\n type=\"button\"\n class=\"p-button-text\"\n label=\"Back\"\n icon=\"pi pi-arrow-left\"\n [disabled]=\"activeIndex() === 0\"\n (click)=\"back()\"\n ></button>\n @if (!isLast()) {\n <button\n pButton\n type=\"button\"\n label=\"Next\"\n icon=\"pi pi-arrow-right\"\n iconPos=\"right\"\n (click)=\"next()\"\n ></button>\n } @else {\n <button\n pButton\n type=\"button\"\n [label]=\"submitLabel()\"\n icon=\"pi pi-check\"\n iconPos=\"right\"\n [disabled]=\"!formService.formValid()\"\n (click)=\"submit()\"\n ></button>\n }\n </div>\n </div>\n }\n `,\n})\nexport class NgxJsonFormStepperComponent {\n readonly schema = input.required<FormSchema>();\n readonly submitLabel = input<string>('Submit');\n\n readonly formSubmit = output<FormEngineEvent>();\n readonly formChange = output<FormEngineEvent>();\n\n protected readonly formService = inject(FormEngineService);\n\n readonly activeIndex = computed(() => this.formService.activeStepIndex());\n readonly activeStep = computed(() => this.formService.activeStep());\n\n readonly isLast = computed(() => {\n const steps = this.schema().steps ?? [];\n return this.activeIndex() === steps.length - 1;\n });\n\n constructor() {\n // Reset the wizard whenever the schema input changes\n effect(() => {\n this.schema();\n this.formService.goToStep(0);\n });\n }\n\n protected back(): void {\n this.formService.prevStep();\n }\n\n protected next(): void {\n this.formService.nextStep();\n }\n\n protected jumpTo(i: number): void {\n if (i <= this.activeIndex()) this.formService.goToStep(i);\n }\n\n protected submit(): void {\n if (!this.formService.markAllAsTouchedAndValidate()) return;\n const values = this.formService.buildSubmitPayload();\n this.formSubmit.emit({\n field: { config: { attributes: { inputType: 'button', buttonRole: 'submit' } } } as never,\n values,\n valid: true,\n type: 'submit',\n });\n }\n\n /** Pass-through when the inner form emits formSubmit (e.g. via an inline button) */\n protected onSubmit(e: FormEngineEvent): void {\n this.formSubmit.emit(e);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1"],"mappings":"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"}
1
+ {"version":3,"file":"ngx-json-forms-primeng.mjs","sources":["../../../../packages/primeng/src/lib/ngx-form-engine-primeng.component.ts","../../../../packages/primeng/src/lib/ngx-form-engine-primeng.component.html","../../../../packages/primeng/src/lib/ngx-json-form-stepper.component.ts","../../../../packages/primeng/src/ngx-json-forms-primeng.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n inject,\n input,\n output,\n signal,\n Type,\n} from '@angular/core';\nimport { FormArray, FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';\nimport { NgComponentOutlet, NgOptimizedImage, NgTemplateOutlet } from '@angular/common';\nimport { Subscription } from 'rxjs';\n\nimport { InputTextModule } from 'primeng/inputtext';\nimport { InputGroupModule } from 'primeng/inputgroup';\nimport { InputGroupAddonModule } from 'primeng/inputgroupaddon';\nimport { FloatLabelModule } from 'primeng/floatlabel';\nimport { SelectModule } from 'primeng/select';\nimport { MultiSelectModule } from 'primeng/multiselect';\nimport { CascadeSelectModule } from 'primeng/cascadeselect';\nimport { AutoCompleteModule } from 'primeng/autocomplete';\nimport { FileUploadModule } from 'primeng/fileupload';\nimport { ButtonModule } from 'primeng/button';\nimport { DialogModule } from 'primeng/dialog';\nimport { DividerModule } from 'primeng/divider';\nimport { PasswordModule } from 'primeng/password';\nimport { DatePickerModule } from 'primeng/datepicker';\nimport { CheckboxModule } from 'primeng/checkbox';\nimport { ToggleSwitchModule } from 'primeng/toggleswitch';\nimport { TextareaModule } from 'primeng/textarea';\nimport { SliderModule } from 'primeng/slider';\nimport { RatingModule } from 'primeng/rating';\nimport { ColorPickerModule } from 'primeng/colorpicker';\nimport { RadioButtonModule } from 'primeng/radiobutton';\nimport { KeyFilterModule } from 'primeng/keyfilter';\nimport { EditorModule } from 'primeng/editor';\n\nimport {\n FieldRegistry,\n FormEngineEvent,\n FormEngineEventType,\n FormEngineService,\n FormField,\n FormSchema,\n ImageUploadService,\n} from '@ngx-json-forms/core';\n\n@Component({\n selector: 'ngx-json-form',\n templateUrl: './ngx-form-engine-primeng.component.html',\n styleUrl: './ngx-form-engine-primeng.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [\n ReactiveFormsModule,\n NgTemplateOutlet,\n NgComponentOutlet,\n NgOptimizedImage,\n // PrimeNG\n InputTextModule,\n InputGroupModule,\n InputGroupAddonModule,\n FloatLabelModule,\n SelectModule,\n MultiSelectModule,\n CascadeSelectModule,\n AutoCompleteModule,\n FileUploadModule,\n ButtonModule,\n DialogModule,\n DividerModule,\n PasswordModule,\n DatePickerModule,\n CheckboxModule,\n ToggleSwitchModule,\n TextareaModule,\n SliderModule,\n RatingModule,\n ColorPickerModule,\n RadioButtonModule,\n KeyFilterModule,\n EditorModule,\n ],\n})\nexport class NgxJsonFormComponent {\n // ─── Inputs / Outputs ────────────────────────────────────────────────────\n\n readonly formTitle = input<string>('');\n readonly fieldsInput = input<FormField[]>([]);\n /** Optional schema input — supersedes `fieldsInput` when provided. */\n readonly schema = input<FormSchema | null>(null);\n /** Only render fields in the given step indices (used by the stepper wrapper). */\n readonly stepFields = input<FormField[] | null>(null);\n\n readonly formSubmit = output<FormEngineEvent>();\n readonly formChange = output<FormEngineEvent>();\n\n // ─── Services ────────────────────────────────────────────────────────────\n\n protected readonly formService = inject(FormEngineService);\n protected readonly uploadService = inject(ImageUploadService);\n protected readonly fieldRegistry = inject(FieldRegistry);\n\n // ─── Internal State ──────────────────────────────────────────────────────\n\n readonly fields = signal<FormField[]>([]);\n readonly formGroup = signal<FormGroup>(new FormGroup({}));\n readonly ready = signal(false);\n\n /** Async-loaded options keyed by formControlName */\n readonly asyncOptions = signal<Record<string, unknown[]>>({});\n\n private readonly formStatusTick = signal(0);\n private readonly focusedMap = signal<Record<string, boolean>>({});\n\n /** Subscriptions for async option re-loads; disposed on every rebuild. */\n private optionLoaderSubs: Subscription[] = [];\n\n // ─── Derived ─────────────────────────────────────────────────────────────\n\n readonly visibleFields = computed(() => {\n this.formStatusTick();\n this.formService.patchTick();\n const values = this.formGroup().getRawValue();\n const source = this.stepFields() ?? this.fields();\n return source.filter((f) => {\n if (f.config.attributes.visible === false) return false;\n return this.formService.evaluateShowWhen(f, values);\n });\n });\n\n /**\n * Track patchTick so .valid (a plain object property) re-reads after every\n * form change. Without this, the submit-button disabled binding stays stuck\n * on the FormGroup's initial (invalid) state.\n */\n readonly formValid = computed(() => {\n this.formService.patchTick();\n this.formStatusTick();\n return this.formGroup().valid;\n });\n\n protected placeholderVisibilityMap: Record<string, ReturnType<typeof computed>> = {};\n\n /**\n * Resolve the placeholder string to render for a field. Safe for nested\n * fields (repeater itemFields, group groupFields) whose formControlName\n * isn't pre-registered in `placeholderVisibilityMap` — those fall back to\n * the raw `field.placeholder` since they don't participate in floatLabel.\n */\n protected placeholderFor(field: FormField): string | null {\n const name = field.formControlName;\n if (!name) return field.placeholder ?? null;\n const sig = this.placeholderVisibilityMap[name];\n if (!sig) return field.placeholder ?? null;\n return sig() ? (field.placeholder ?? null) : null;\n }\n\n readonly errorMap = computed(() => {\n this.formStatusTick();\n this.formService.patchTick();\n const errors: Record<string, string | null> = {};\n const group = this.formGroup();\n if (!group) return errors;\n for (const field of this.fields()) {\n if (!field.formControlName) continue;\n const control = group.get(field.formControlName);\n errors[field.formControlName] = this.formService.resolveError(field, control);\n }\n return errors;\n });\n\n // ─── Lifecycle ───────────────────────────────────────────────────────────\n\n constructor() {\n effect(() => {\n this.ready.set(false);\n\n const schemaIn = this.schema();\n const incoming: FormField[] = schemaIn?.fields\n ? schemaIn.fields\n : schemaIn?.steps\n ? schemaIn.steps.flatMap((s) => s.fields)\n : this.fieldsInput();\n\n if (!incoming.length) return;\n\n const sorted = [...incoming].sort((a, b) => {\n const oa = a.layout?.order ?? Number.MAX_SAFE_INTEGER;\n const ob = b.layout?.order ?? Number.MAX_SAFE_INTEGER;\n return oa - ob;\n });\n\n this.fields.set(sorted);\n this.buildForm(sorted, schemaIn ?? undefined);\n });\n\n effect(() => {\n this.formService.patchTick();\n if (!this.ready()) return;\n this.fields.set(this.formService.fields());\n this.uploadService.syncPreviews(this.fields(), this.formGroup());\n });\n }\n\n // ─── Form Builder ────────────────────────────────────────────────────────\n\n private buildForm(fields: FormField[], schema?: FormSchema): void {\n // Tear down anything tied to the previous form group before we rebuild.\n this.disposeOptionLoaderSubs();\n this.placeholderVisibilityMap = {};\n\n const group = this.formService.buildFormGroup(fields);\n this.formGroup.set(group);\n\n // Register synchronously so prior subs are disposed BEFORE we add new\n // computed-field listeners below — otherwise register() would wipe them.\n this.formService.register(group, fields, schema);\n\n for (const field of fields) {\n if (!field.formControlName) continue;\n this.placeholderVisibilityMap[field.formControlName] = computed(() => {\n if (!field.floatLabel) return true;\n const control = this.formGroup()?.get(field.formControlName!);\n if (!control) return false;\n const v = control.value;\n const hasValue =\n v !== null && v !== undefined && v !== '' && (!Array.isArray(v) || v.length > 0);\n return this.focusedMap()[field.formControlName!] === true && !hasValue;\n });\n }\n\n if (schema?.crossFieldValidators?.length) {\n this.formService.applyCrossFieldValidators(group, schema.crossFieldValidators);\n }\n this.formService.setupComputedFields(group, fields);\n\n // Bootstrap async options for select-like fields\n for (const f of fields) {\n const a = f.config.attributes;\n if (a.optionsLoader && f.formControlName) {\n void this.loadAsyncOptions(f);\n for (const dep of a.optionsDependsOn ?? []) {\n const depCtrl = group.get(dep);\n if (!depCtrl) continue;\n this.optionLoaderSubs.push(\n depCtrl.valueChanges.subscribe(() => void this.loadAsyncOptions(f))\n );\n }\n }\n }\n\n queueMicrotask(() => {\n this.ready.set(true);\n this.uploadService.syncPreviews(this.fields(), this.formGroup());\n });\n }\n\n private disposeOptionLoaderSubs(): void {\n for (const s of this.optionLoaderSubs) s.unsubscribe();\n this.optionLoaderSubs = [];\n }\n\n private async loadAsyncOptions(field: FormField): Promise<void> {\n const a = field.config.attributes;\n if (!a.optionsLoader || !field.formControlName) return;\n const formValue = this.formGroup().getRawValue();\n const context: Record<string, unknown> = {};\n for (const dep of a.optionsDependsOn ?? []) context[dep] = formValue[dep];\n\n this.formService.updateFieldAttributes(field.formControlName, { loading: true });\n const opts = await this.formService.resolveDependentOptions(a.optionsLoader, context, formValue);\n this.asyncOptions.update((m) => ({ ...m, [field.formControlName!]: opts }));\n this.formService.updateFieldAttributes(field.formControlName, { loading: false, options: opts });\n }\n\n // ─── Field Registry resolver (used by custom inputType) ──────────────────\n\n protected customRenderer(field: FormField): Type<unknown> | undefined {\n return this.fieldRegistry.getRenderer(field.config.attributes.inputType);\n }\n\n protected customRendererInputs(field: FormField): Record<string, unknown> {\n return { field, formGroup: this.formGroup() };\n }\n\n // ─── Date helpers ────────────────────────────────────────────────────────\n\n protected minDateFor(field: FormField): Date | undefined {\n const a = field.config.attributes;\n if (a.minDate) return a.minDate;\n if (a.minToday) {\n const d = new Date();\n d.setDate(d.getDate() + (a.minOffsetDays ?? 0));\n return d;\n }\n return undefined;\n }\n\n protected maxDateFor(field: FormField): Date | undefined {\n const a = field.config.attributes;\n if (a.maxDate) return a.maxDate;\n if (a.maxToday) {\n const d = new Date();\n d.setDate(d.getDate() + (a.maxOffsetDays ?? 0));\n return d;\n }\n return undefined;\n }\n\n // ─── Effective options resolver ──────────────────────────────────────────\n\n protected optionsFor(field: FormField): unknown[] {\n const a = field.config.attributes;\n if (field.formControlName && this.asyncOptions()[field.formControlName]) {\n return this.asyncOptions()[field.formControlName];\n }\n return (a.options as unknown[]) ?? [];\n }\n\n // ─── Repeater helpers ────────────────────────────────────────────────────\n\n protected getArray(name: string): FormArray | null {\n const c = this.formGroup().get(name);\n return c instanceof FormArray ? c : null;\n }\n\n protected addRepeaterRow(field: FormField): void {\n if (!field.formControlName) return;\n const arr = this.getArray(field.formControlName);\n if (!arr) return;\n if (field.config.attributes.maxRows && arr.length >= field.config.attributes.maxRows) return;\n this.formService.addArrayItem(field.formControlName);\n this.triggerTick();\n }\n\n protected removeRepeaterRow(field: FormField, i: number): void {\n if (!field.formControlName) return;\n const arr = this.getArray(field.formControlName);\n if (!arr) return;\n if (field.config.attributes.minRows && arr.length <= field.config.attributes.minRows) return;\n this.formService.removeArrayItem(field.formControlName, i);\n this.triggerTick();\n }\n\n protected rowGroup(field: FormField, i: number): FormGroup {\n return this.getArray(field.formControlName!)?.at(i) as FormGroup;\n }\n\n /**\n * DOM id for a field's input element. Scoped by row index when the field\n * lives inside a repeater so the same `formControlName` across rows\n * doesn't produce duplicate ids (HTML spec violation + breaks\n * <label for>, aria-describedby, and document.querySelector lookups).\n */\n protected inputId(field: FormField, suffix?: number | string): string {\n const base = (field.formControlName ?? '') + 'Id';\n return suffix !== undefined && suffix !== null ? `${base}_${suffix}` : base;\n }\n\n /**\n * Resolve the validation message for a single field inside a repeater row.\n * Mirrors errorMap() but for FormGroup rows that aren't tracked in the\n * top-level fields signal.\n */\n protected resolveRowError(row: FormGroup, sub: FormField): string | null {\n this.formService.patchTick();\n if (!sub.formControlName) return null;\n const ctrl = row.get(sub.formControlName);\n return this.formService.resolveError(sub, ctrl);\n }\n\n // ─── Events ──────────────────────────────────────────────────────────────\n\n /** Central event handler. Accepts `unknown` because PrimeNG emits custom event objects. */\n async onEvent(field: FormField, event: unknown, eventType?: FormEngineEventType): Promise<void> {\n this.triggerTick();\n\n const rawType = eventType ?? ((event as Event)?.type as FormEngineEventType);\n let type = rawType;\n\n if (type === 'focus')\n this.focusedMap.update((m) => ({ ...m, [field.formControlName!]: true }));\n if (type === 'blur')\n this.focusedMap.update((m) => ({ ...m, [field.formControlName!]: false }));\n\n if (type === 'uploadHandler') {\n await this.uploadService.handleUpload(\n field,\n event as { files: File[] },\n this.formGroup(),\n this.formService,\n () => this.emitChange(field, 'uploadHandler', event)\n );\n return;\n }\n\n if (type === 'inputKeydown' && field.config.attributes.inputType === 'autocomplete') {\n const ke = event as KeyboardEvent;\n if (ke.key === 'Enter') {\n const inputValue = (ke.target as HTMLInputElement).value?.trim();\n if (inputValue) {\n const tag = {\n [field.config.attributes.optionLabel!]: inputValue,\n [field.config.attributes.optionValue!]: inputValue,\n };\n const existing = [...((field.config.attributes.suggestions as unknown[]) ?? []), tag];\n this.formService.updateFieldAttributes(field.formControlName!, { suggestions: existing });\n this.formGroup().get(field.formControlName!)?.setValue(existing);\n type = 'add';\n }\n }\n }\n\n if (type === 'unselect' && field.config.attributes.inputType === 'autocomplete') {\n const evtValue = (event as { value: unknown }).value;\n const remaining = ((field.config.attributes.suggestions as unknown[]) ?? []).filter(\n (v) => evtValue !== v\n );\n this.formService.updateFieldAttributes(field.formControlName!, { suggestions: remaining });\n this.formGroup().get(field.formControlName!)?.setValue(remaining);\n }\n\n // A button with buttonRole === 'submit' / 'reset' / 'cancel' / 'custom'\n // should fire its action whether or not 'click' was explicitly listed\n // in acceptedEvents — leaving it off is the most common cause of\n // \"my submit button does nothing\" support tickets. (Added 1.1.0.)\n const isButtonClick = type === 'click' && field.config.attributes.inputType === 'button';\n const allowed = field.config.attributes.acceptedEvents ?? [];\n if (!isButtonClick && !allowed.includes(type)) return;\n\n const payload = this.buildPayload(field, type, event);\n\n if (type === 'click') {\n const role = field.config.attributes.buttonRole;\n if (role === 'reset') {\n this.formService.reset();\n this.formChange.emit(payload);\n return;\n }\n if (role === 'cancel' || role === 'custom') {\n this.formChange.emit(payload);\n return;\n }\n if (!this.formValid()) this.formGroup().markAllAsTouched();\n this.formSubmit.emit({ ...payload, values: this.formService.buildSubmitPayload() });\n } else {\n this.formChange.emit(payload);\n }\n }\n\n removeImage(field: FormField, image: string): void {\n this.uploadService.removeImage(\n field,\n image,\n this.formGroup(),\n this.formService,\n () => this.emitChange(field, 'uploadHandler', new Event('remove'))\n );\n }\n\n // ─── Helpers ─────────────────────────────────────────────────────────────\n\n private buildPayload(field: FormField, type: FormEngineEventType, originalEvent: unknown): FormEngineEvent {\n return {\n field,\n values: this.formGroup().getRawValue(),\n valid: this.formValid(),\n type,\n originalEvent,\n };\n }\n\n private emitChange(field: FormField, type: FormEngineEventType, event: unknown): void {\n this.formChange.emit(this.buildPayload(field, type, event));\n }\n\n private triggerTick(): void {\n this.formStatusTick.update((v) => v + 1);\n }\n\n protected getControl(name: string): FormControl {\n return this.formGroup().get(name) as FormControl;\n }\n}\n","@if (formTitle().length) {\n <div class=\"ngx-form-title\">{{ formTitle() }}</div>\n}\n\n@if (ready()) {\n <form [formGroup]=\"formGroup()\" class=\"ngx-form-grid\">\n @for (field of visibleFields(); track field.formControlName ?? $index) {\n <div\n [class]=\"\n 'ngx-col-' +\n (field.layout?.columnSpan ?? 12) +\n ' ' +\n (field.layout?.wrapperClass ?? '')\n \"\n [style]=\"field.layout?.wrapperStyle ?? {}\"\n [style.display]=\"field.config.attributes.isHidden ? 'none' : 'block'\"\n >\n <!-- Float Label wrapper -->\n @if (field.floatLabel) {\n <p-floatlabel [variant]=\"field.floatVariant ?? 'on'\">\n <div class=\"ngx-field-inner\">\n <ng-container\n [ngTemplateOutlet]=\"fieldTpl\"\n [ngTemplateOutletContext]=\"{ $implicit: field, formGroup: formGroup() }\"\n />\n </div>\n <label\n [attr.for]=\"field.formControlName + 'Id'\"\n [attr.id]=\"field.formControlName + 'Label'\"\n >\n @if (field.labelIconPos === 'left') {\n <i [class]=\"field.labelIcon\"></i>\n }\n {{ field.label }}\n @if (field.labelIconPos === 'right') {\n <i [class]=\"field.labelIcon\"></i>\n }\n @if (field.validations?.rules?.required) {\n <span class=\"ngx-required\">*</span>\n }\n </label>\n </p-floatlabel>\n }\n\n <!-- Toggle card layout -->\n @else if (\n field.config.attributes.cardLayout &&\n field.config.attributes.inputType === 'toggle'\n ) {\n <div\n class=\"ngx-toggle-card\"\n [style.--toggle-color]=\"field.config.attributes.cardIconColor\"\n >\n <div\n class=\"ngx-toggle-card-icon\"\n [style.background]=\"\n field.config.attributes.cardIconBg ??\n 'var(--p-primary-50, #eff6ff)'\n \"\n [style.color]=\"\n field.config.attributes.cardIconColor ??\n 'var(--p-primary-500, #3b82f6)'\n \"\n >\n <i [class]=\"field.config.attributes.cardIcon ?? 'pi pi-bell'\"></i>\n </div>\n <div class=\"ngx-toggle-card-body\">\n <span class=\"ngx-toggle-card-label\">\n {{ field.label }}\n @if (field.validations?.rules?.required) {\n <span class=\"ngx-required\">*</span>\n }\n </span>\n @if (field.config.attributes.info?.length) {\n <span\n class=\"ngx-toggle-card-desc\"\n [innerHTML]=\"field.config.attributes.info\"\n ></span>\n }\n </div>\n <p-toggleswitch\n [formControlName]=\"field.formControlName!\"\n [inputId]=\"field.formControlName + 'Id'\"\n (onChange)=\"onEvent(field, $event, 'change')\"\n />\n </div>\n <!--\n Always reserve one line of space for the error so the row height\n doesn't change when validation fires (otherwise sibling fields\n jump down when the error appears).\n -->\n @if (field.validations?.rules) {\n <small\n class=\"ngx-error\"\n [class.ngx-error--placeholder]=\"!errorMap()[field.formControlName!]\"\n [attr.id]=\"field.formControlName + 'Err'\"\n >{{ errorMap()[field.formControlName!] || ' ' }}</small>\n }\n }\n\n <!-- Normal label wrapper -->\n @else {\n @if (field.label && field.label.length) {\n <label\n class=\"ngx-field-label\"\n [attr.for]=\"field.formControlName + 'Id'\"\n [attr.id]=\"field.formControlName + 'Label'\"\n >\n @if (field.labelIconPos === 'left') {\n <i [class]=\"field.labelIcon\"></i>\n }\n {{ field.label }}\n @if (field.labelIconPos === 'right') {\n <i [class]=\"field.labelIcon\"></i>\n }\n @if (field.validations?.rules?.required) {\n <span class=\"ngx-required\">*</span>\n }\n </label>\n }\n <div class=\"ngx-field-inner\">\n <ng-container\n [ngTemplateOutlet]=\"fieldTpl\"\n [ngTemplateOutletContext]=\"{ $implicit: field, formGroup: formGroup() }\"\n />\n </div>\n\n <!--\n Validation error — always reserve one line of space (placeholder\n class makes it invisible when there's no error) so triggering a\n required/pattern message doesn't push the row below it down.\n -->\n @if (field.validations?.rules) {\n <small\n class=\"ngx-error\"\n [class.ngx-error--placeholder]=\"!errorMap()[field.formControlName!]\"\n [attr.id]=\"field.formControlName + 'Err'\"\n >{{ errorMap()[field.formControlName!] || ' ' }}</small>\n }\n\n <!-- Info / hint -->\n @if (field.config.attributes.info?.length) {\n <small\n class=\"ngx-hint\"\n [attr.id]=\"field.formControlName + 'Hint'\"\n [innerHTML]=\"field.config.attributes.info\"\n ></small>\n }\n }\n </div>\n }\n </form>\n}\n\n<!-- ─── Field Renderer Template ──────────────────────────────────────────── -->\n<!--\n `formGroup` is passed in via the template context so each rendering site\n binds the right group: the root FormGroup for top-level fields, the row's\n FormGroup for repeater rows. Hard-coding `formGroup()` here would override\n row-level bindings and route nested formControlName lookups to the root,\n which is the bug we're fixing.\n\n Known issue: during initial CD passes Angular logs NG01050 spam because\n the FormGroup directive on this ng-container materialises after children\n formControlName directives query their parent ControlContainer. Bindings\n recover and form values flow correctly afterwards. Cleaner fix would be\n to avoid the ngTemplateOutlet + context + nested formGroup combination\n altogether (e.g. inline the @switch at each call site).\n-->\n<ng-template #fieldTpl let-field let-fg=\"formGroup\" let-idSuffix=\"idSuffix\">\n <ng-container [formGroup]=\"fg\">\n @switch (field.config.attributes.inputType) {\n <!-- ── Custom field (registry) ── -->\n @case (customRenderer(field) ? field.config.attributes.inputType : '__never__') {\n <ng-container\n *ngComponentOutlet=\"customRenderer(field)!; inputs: customRendererInputs(field)\"\n />\n }\n\n <!-- ── Group (nested FormGroup) ── -->\n @case ('group') {\n <fieldset\n class=\"ngx-field-group\"\n [attr.formGroupName]=\"field.formControlName\"\n >\n @for (sub of field.config.attributes.groupFields ?? []; track sub.formControlName ?? $index) {\n <div class=\"ngx-field-group-row\">\n <ng-container\n [ngTemplateOutlet]=\"fieldTpl\"\n [ngTemplateOutletContext]=\"{ $implicit: sub, formGroup: formGroup() }\"\n />\n </div>\n }\n </fieldset>\n }\n\n <!-- ── Repeater (FormArray) ── -->\n @case ('repeater') {\n <div class=\"ngx-repeater\">\n @for (row of getArray(field.formControlName!)?.controls ?? []; track $index) {\n @let rowIndex = $index;\n <div class=\"ngx-repeater-row\" [formGroup]=\"$any(row)\">\n <div class=\"ngx-repeater-row-fields\">\n @for (sub of field.config.attributes.itemFields ?? []; track sub.formControlName ?? $index) {\n <div\n [class]=\"\n 'ngx-col-' + (sub.layout?.columnSpan ?? 12)\n \"\n >\n @if (sub.label) {\n <label\n class=\"ngx-field-label\"\n [attr.for]=\"inputId(sub, rowIndex)\"\n >\n {{ sub.label }}\n @if (sub.validations?.rules?.required) {\n <span class=\"ngx-required\">*</span>\n }\n </label>\n }\n <ng-container\n [ngTemplateOutlet]=\"fieldTpl\"\n [ngTemplateOutletContext]=\"{ $implicit: sub, formGroup: $any(row), idSuffix: rowIndex }\"\n />\n @if (sub.validations?.rules && sub.formControlName) {\n <small\n class=\"ngx-error\"\n [class.ngx-error--placeholder]=\"!resolveRowError($any(row), sub)\"\n >{{ resolveRowError($any(row), sub) || ' ' }}</small>\n }\n </div>\n }\n </div>\n <button\n type=\"button\"\n class=\"ngx-repeater-remove\"\n pButton\n [icon]=\"'pi pi-trash'\"\n [rounded]=\"true\"\n [text]=\"true\"\n (click)=\"removeRepeaterRow(field, $index)\"\n ></button>\n </div>\n }\n <button\n pButton\n type=\"button\"\n class=\"ngx-repeater-add\"\n [icon]=\"'pi pi-plus'\"\n [label]=\"field.config.attributes.addLabel ?? 'Add row'\"\n [text]=\"true\"\n (click)=\"addRepeaterRow(field)\"\n ></button>\n </div>\n }\n\n <!-- ── Dependent / Cascading Dropdown ── -->\n @case ('dependentDropdown') {\n <p-cascadeselect\n [id]=\"inputId(field, idSuffix)\"\n [inputId]=\"inputId(field, idSuffix)\"\n [formControlName]=\"field.formControlName!\"\n [options]=\"$any(optionsFor(field))\"\n [optionLabel]=\"field.config.attributes.optionLabel ?? 'label'\"\n [optionValue]=\"field.config.attributes.optionValue ?? 'value'\"\n [optionGroupLabel]=\"field.config.attributes.optionGroupLabel ?? 'label'\"\n [optionGroupChildren]=\"\n $any(field.config.attributes.optionGroupChildren ?? ['children'])\n \"\n [placeholder]=\"field.placeholder ?? ''\"\n appendTo=\"body\"\n (onChange)=\"onEvent(field, $event, 'change')\"\n (onShow)=\"onEvent(field, $event, 'show')\"\n (onHide)=\"onEvent(field, $event, 'hide')\"\n />\n }\n\n <!-- ── Editor (rich text) ── -->\n @case ('editor') {\n <p-editor\n [formControlName]=\"field.formControlName!\"\n [style]=\"{ height: (field.config.attributes['height'] ?? '180px') }\"\n (onTextChange)=\"onEvent(field, $event, 'change')\"\n ></p-editor>\n }\n\n <!-- ── Confirm password ── -->\n @case ('confirmPassword') {\n <p-password\n [inputId]=\"inputId(field, idSuffix)\"\n [formControlName]=\"field.formControlName!\"\n [feedback]=\"false\"\n [toggleMask]=\"field.config.attributes.toggleMask ?? true\"\n [placeholder]=\"field.placeholder ?? ''\"\n appendTo=\"body\"\n (onBlur)=\"onEvent(field, $event, 'blur')\"\n />\n }\n\n <!-- ── File Upload ── -->\n @case ('fileUpload') {\n <div>\n <div\n [class]=\"field.config.attributes.isInline ? 'ngx-file-inline' : ''\"\n >\n <p-fileUpload\n mode=\"basic\"\n customUpload\n [id]=\"inputId(field, idSuffix)\"\n [multiple]=\"field.config.attributes.multiple\"\n [chooseIcon]=\"field.config.attributes.chooseIcon ?? 'pi pi-upload'\"\n [accept]=\"field.config.attributes.accept ?? 'image/*'\"\n [maxFileSize]=\"field.config.attributes.maxFileSize ?? 1000000\"\n [auto]=\"true\"\n [chooseLabel]=\"field.config.attributes.chooseLabel ?? 'Upload'\"\n (uploadHandler)=\"onEvent(field, $event, 'uploadHandler')\"\n />\n\n @if (uploadService.imagePreviews()[field.formControlName!]?.length) {\n <div class=\"ngx-image-list\">\n @for (\n image of uploadService.imagePreviews()[field.formControlName!];\n let i = $index;\n track i\n ) {\n <div class=\"ngx-image-card\">\n <i\n class=\"pi pi-times ngx-image-remove\"\n (click)=\"removeImage(field, image)\"\n ></i>\n <div class=\"ngx-image-wrapper\">\n @if (!uploadService.isBase64(image)) {\n <img\n fill\n sizes=\"100\"\n [ngSrc]=\"image\"\n (load)=\"uploadService.onLoad(image)\"\n (error)=\"uploadService.onLoad(image)\"\n [class.loading]=\"uploadService.isLoading(image)\"\n [class.loaded]=\"!uploadService.isLoading(image)\"\n class=\"ngx-preview-img\"\n alt=\"preview\"\n />\n } @else {\n <img\n fill\n sizes=\"100\"\n [src]=\"image\"\n (load)=\"uploadService.onLoad(image)\"\n (error)=\"uploadService.onLoad(image)\"\n [class.loading]=\"uploadService.isLoading(image)\"\n [class.loaded]=\"!uploadService.isLoading(image)\"\n class=\"ngx-preview-img\"\n alt=\"preview\"\n />\n }\n @if (uploadService.isLoading(image)) {\n <div class=\"ngx-img-skeleton\"></div>\n }\n </div>\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n\n <!-- ── Static Text ── -->\n @case ('staticText') {\n <span\n (click)=\"onEvent(field, $event, 'staticTextClick')\"\n [innerHTML]=\"field.config.attributes.value\"\n ></span>\n }\n\n <!-- ── Divider ── -->\n @case ('divider') {\n <p-divider\n [layout]=\"field.config.attributes.dividerLayout\"\n [type]=\"field.config.attributes.dividerType\"\n [align]=\"field.config.attributes.dividerAlign\"\n >\n @if (field.config.attributes.value) {\n <span [innerHTML]=\"field.config.attributes.value\"></span>\n }\n </p-divider>\n }\n\n <!-- ── Button ── -->\n @case ('button') {\n <div class=\"ngx-btn-wrap\">\n <button\n pButton\n type=\"button\"\n [id]=\"inputId(field, idSuffix)\"\n [label]=\"field.btnLabel ?? ''\"\n [icon]=\"field.config.attributes.icon ?? ''\"\n [iconPos]=\"field.config.attributes.iconPosition ?? 'left'\"\n [tabindex]=\"field.tabIndex ?? 0\"\n [disabled]=\"\n field.config.attributes.buttonRole === 'submit' ||\n field.config.attributes.type === 'submit'\n ? !formValid()\n : !!field.config.attributes.disabled\n \"\n [class.p-button-outlined]=\"\n field.config.attributes.variant === 'secondary'\n \"\n [class.p-button-text]=\"field.config.attributes.text === true\"\n [class.p-button-rounded]=\"field.config.attributes.rounded === true\"\n [class.p-button-sm]=\"field.config.attributes.size === 'sm'\"\n [class.p-button-lg]=\"field.config.attributes.size === 'lg'\"\n (click)=\"onEvent(field, $event)\"\n ></button>\n </div>\n }\n\n <!-- ── Everything else inside p-inputgroup ── -->\n @default {\n <p-inputgroup>\n @if (\n field.config.attributes.fieldPos === 'left' &&\n field.config.attributes.fieldIcon\n ) {\n <p-inputgroup-addon>\n <i [class]=\"field.config.attributes.fieldIcon\">\n {{ field.config.attributes.fieldIconText ?? '' }}\n </i>\n </p-inputgroup-addon>\n }\n\n @switch (field.config.attributes.inputType) {\n <!-- text / email / number / url -->\n @case ('text') {\n <input\n pInputText\n [id]=\"inputId(field, idSuffix)\"\n [formControlName]=\"field.formControlName!\"\n [type]=\"field.config.attributes.type ?? 'text'\"\n [tabindex]=\"field.tabIndex ?? 0\"\n [attr.placeholder]=\"placeholderFor(field)\"\n [attr.aria-describedby]=\"\n (errorMap()[field.formControlName!] ? field.formControlName + 'Err ' : '') +\n (field.config.attributes.info ? field.formControlName + 'Hint' : '')\n \"\n [pKeyFilter]=\"field.config.attributes.keyfilter\"\n (change)=\"onEvent(field, $event)\"\n (input)=\"onEvent(field, $event)\"\n (focus)=\"onEvent(field, $event)\"\n (blur)=\"onEvent(field, $event)\"\n (keyup)=\"onEvent(field, $event)\"\n (keydown)=\"onEvent(field, $event)\"\n (keypress)=\"onEvent(field, $event)\"\n />\n }\n\n <!-- password -->\n @case ('password') {\n <p-password\n [inputId]=\"inputId(field, idSuffix)\"\n [formControlName]=\"field.formControlName!\"\n [feedback]=\"field.config.attributes.feedback\"\n [toggleMask]=\"field.config.attributes.toggleMask\"\n [placeholder]=\"field.config.attributes.placeholder ?? ''\"\n appendTo=\"body\"\n (onBlur)=\"onEvent(field, $event, 'blur')\"\n (onFocus)=\"onEvent(field, $event, 'focus')\"\n >\n @if (field.config.attributes.templateHeader) {\n <ng-container\n [ngTemplateOutlet]=\"field.config.attributes.templateHeader\"\n />\n }\n @if (field.config.attributes.templateFooter) {\n <ng-container\n [ngTemplateOutlet]=\"field.config.attributes.templateFooter\"\n />\n }\n </p-password>\n }\n\n <!-- textarea -->\n @case ('textarea') {\n <textarea\n pTextarea\n [id]=\"inputId(field, idSuffix)\"\n [formControlName]=\"field.formControlName!\"\n [rows]=\"field.config.attributes.rows ?? 3\"\n [cols]=\"field.config.attributes.cols ?? 30\"\n [autoResize]=\"field.config.attributes.autoResize\"\n [placeholder]=\"field.config.attributes.placeholder ?? ''\"\n (change)=\"onEvent(field, $event)\"\n (input)=\"onEvent(field, $event)\"\n (focus)=\"onEvent(field, $event)\"\n (blur)=\"onEvent(field, $event)\"\n >\n </textarea>\n }\n\n <!-- select -->\n @case ('select') {\n <p-select\n [id]=\"inputId(field, idSuffix)\"\n [inputId]=\"inputId(field, idSuffix)\"\n [attr.aria-labelledby]=\"field.formControlName + 'Label'\"\n [formControlName]=\"field.formControlName!\"\n [options]=\"$any(optionsFor(field))\"\n [optionLabel]=\"field.config.attributes.optionLabel\"\n [optionValue]=\"field.config.attributes.optionValue\"\n [placeholder]=\"placeholderFor(field) ?? ''\"\n [showClear]=\"field.config.attributes.showClear\"\n [filter]=\"field.config.attributes.filter\"\n [filterBy]=\"field.config.attributes.filterBy\"\n [filterPlaceholder]=\"field.config.attributes.filterPlaceholder\"\n [loading]=\"field.config.attributes.loading\"\n [virtualScroll]=\"field.config.attributes.virtualScroll\"\n [virtualScrollItemSize]=\"\n field.config.attributes.virtualScrollItemSize\n \"\n [lazy]=\"field.config.attributes.lazy\"\n [emptyMessage]=\"field.config.attributes.emptyMessage\"\n appendTo=\"body\"\n (onChange)=\"onEvent(field, $event, 'change')\"\n (onFocus)=\"onEvent(field, $event, 'focus')\"\n (onBlur)=\"onEvent(field, $event, 'blur')\"\n (onShow)=\"onEvent(field, $event, 'show')\"\n (onHide)=\"onEvent(field, $event, 'hide')\"\n (onClear)=\"onEvent(field, $event, 'clear')\"\n (onLazyLoad)=\"onEvent(field, $event, 'lazyLoad')\"\n >\n @if (\n field.config.attributes.isTemplate &&\n field.config.attributes.template\n ) {\n <ng-container\n [ngTemplateOutlet]=\"field.config.attributes.template\"\n />\n }\n </p-select>\n }\n\n <!-- multiSelect -->\n @case ('multiSelect') {\n <p-multiselect\n [id]=\"inputId(field, idSuffix)\"\n [inputId]=\"inputId(field, idSuffix)\"\n [formControlName]=\"field.formControlName!\"\n [options]=\"$any(optionsFor(field))\"\n [optionLabel]=\"field.config.attributes.optionLabel\"\n [optionValue]=\"field.config.attributes.optionValue\"\n [placeholder]=\"field.config.attributes.placeholder ?? ''\"\n [filter]=\"field.config.attributes.filter\"\n [showClear]=\"field.config.attributes.showClear\"\n [selectionLimit]=\"field.config.attributes.selectionLimit\"\n [display]=\"field.config.attributes.display\"\n [loading]=\"field.config.attributes.loading\"\n [virtualScroll]=\"field.config.attributes.virtualScroll\"\n [virtualScrollItemSize]=\"\n field.config.attributes.virtualScrollItemSize\n \"\n [scrollHeight]=\"field.config.attributes.scrollHeight\"\n appendTo=\"body\"\n (onChange)=\"onEvent(field, $event, 'change')\"\n (onFocus)=\"onEvent(field, $event, 'focus')\"\n (onBlur)=\"onEvent(field, $event, 'blur')\"\n (onClear)=\"onEvent(field, $event, 'clear')\"\n (onHide)=\"onEvent(field, $event, 'hide')\"\n (onRemove)=\"onEvent(field, $event, 'remove')\"\n (onSelectAll)=\"onEvent(field, $event, 'select')\"\n >\n </p-multiselect>\n }\n\n <!-- autocomplete -->\n @case ('autocomplete') {\n <p-autocomplete\n [id]=\"inputId(field, idSuffix)\"\n [inputId]=\"inputId(field, idSuffix)\"\n [formControlName]=\"field.formControlName!\"\n [placeholder]=\"field.config.attributes.placeholder ?? ''\"\n [suggestions]=\"field.config.attributes.suggestions\"\n [optionLabel]=\"field.config.attributes.optionLabel\"\n [multiple]=\"field.config.attributes.multiple\"\n [forceSelection]=\"field.config.attributes.forceSelection\"\n [dropdown]=\"field.config.attributes.dropdown\"\n [showClear]=\"field.config.attributes.showClear\"\n [completeOnFocus]=\"field.config.attributes.completeOnFocus\"\n [minLength]=\"field.config.attributes.minLength ?? 1\"\n [delay]=\"field.config.attributes.delay ?? 300\"\n [virtualScroll]=\"field.config.attributes.virtualScroll\"\n [virtualScrollItemSize]=\"\n field.config.attributes.virtualScrollItemSize\n \"\n [scrollHeight]=\"field.config.attributes.scrollHeight\"\n appendTo=\"body\"\n (completeMethod)=\"onEvent(field, $event, 'complete')\"\n (onSelect)=\"onEvent(field, $event, 'select')\"\n (onUnselect)=\"onEvent(field, $event, 'unselect')\"\n (onAdd)=\"onEvent(field, $event, 'add')\"\n (onFocus)=\"onEvent(field, $event, 'focus')\"\n (onBlur)=\"onEvent(field, $event, 'blur')\"\n (onClear)=\"onEvent(field, $event, 'clear')\"\n (onInputKeydown)=\"onEvent(field, $event, 'inputKeydown')\"\n >\n </p-autocomplete>\n }\n\n <!-- toggle -->\n @case ('toggle') {\n <p-toggleswitch\n [formControlName]=\"field.formControlName!\"\n [inputId]=\"inputId(field, idSuffix)\"\n [attr.aria-labelledby]=\"field.formControlName + 'Label'\"\n (onChange)=\"onEvent(field, $event, 'change')\"\n />\n }\n\n <!-- checkbox -->\n @case ('checkbox') {\n <p-checkbox\n [inputId]=\"inputId(field, idSuffix)\"\n [formControlName]=\"field.formControlName!\"\n [name]=\"field.config.attributes.name ?? field.formControlName!\"\n [value]=\"field.config.attributes.value\"\n (onChange)=\"onEvent(field, $event, 'change')\"\n />\n }\n\n <!-- radio -->\n @case ('radio') {\n @for (opt of $any(optionsFor(field)); track $index) {\n <div class=\"ngx-radio-item\">\n <p-radiobutton\n [inputId]=\"field.formControlName + '_' + $index\"\n [formControlName]=\"field.formControlName!\"\n [name]=\"field.formControlName!\"\n [value]=\"\n opt[field.config.attributes.optionValue ?? 'value']\n \"\n (onClick)=\"onEvent(field, $event, 'change')\"\n />\n <label [for]=\"field.formControlName + '_' + $index\">\n {{ opt[field.config.attributes.optionLabel ?? 'label'] }}\n </label>\n </div>\n }\n }\n\n <!-- datePicker / time / month / year -->\n @case ('datePicker') {\n <p-datepicker\n [inputId]=\"inputId(field, idSuffix)\"\n [formControlName]=\"field.formControlName!\"\n [placeholder]=\"field.config.attributes.placeholder ?? ''\"\n [showIcon]=\"field.config.attributes.showIcon\"\n [minDate]=\"minDateFor(field)!\"\n [maxDate]=\"maxDateFor(field)!\"\n [selectionMode]=\"$any(field.config.attributes.selectionMode)\"\n [readonlyInput]=\"field.config.attributes.readonlyInput\"\n [showButtonBar]=\"field.config.attributes.showButtonBar\"\n [showTime]=\"field.config.attributes.showTime\"\n [hourFormat]=\"field.config.attributes.hourFormat\"\n [timeOnly]=\"field.config.attributes.timeOnly\"\n [view]=\"$any(field.config.attributes.view)\"\n [dateFormat]=\"field.config.attributes.dateFormat\"\n [numberOfMonths]=\"field.config.attributes.numberOfMonths ?? 1\"\n [showClear]=\"field.config.attributes.showClear\"\n appendTo=\"body\"\n (onSelect)=\"onEvent(field, $event, 'select')\"\n (onBlur)=\"onEvent(field, $event, 'blur')\"\n (onFocus)=\"onEvent(field, $event, 'focus')\"\n (onClear)=\"onEvent(field, $event, 'clear')\"\n >\n </p-datepicker>\n }\n\n @case ('time') {\n <p-datepicker\n [inputId]=\"inputId(field, idSuffix)\"\n [formControlName]=\"field.formControlName!\"\n [placeholder]=\"field.config.attributes.placeholder ?? ''\"\n [showIcon]=\"true\"\n [iconDisplay]=\"'input'\"\n [timeOnly]=\"true\"\n [showTime]=\"true\"\n [hourFormat]=\"field.config.attributes.hourFormat ?? '24'\"\n appendTo=\"body\"\n (onSelect)=\"onEvent(field, $event, 'select')\"\n />\n }\n\n @case ('month') {\n <p-datepicker\n [inputId]=\"inputId(field, idSuffix)\"\n [formControlName]=\"field.formControlName!\"\n [placeholder]=\"field.config.attributes.placeholder ?? ''\"\n [showIcon]=\"true\"\n [view]=\"'month'\"\n [dateFormat]=\"field.config.attributes.dateFormat ?? 'mm/yy'\"\n [readonlyInput]=\"true\"\n appendTo=\"body\"\n (onSelect)=\"onEvent(field, $event, 'select')\"\n />\n }\n\n @case ('year') {\n <p-datepicker\n [inputId]=\"inputId(field, idSuffix)\"\n [formControlName]=\"field.formControlName!\"\n [placeholder]=\"field.config.attributes.placeholder ?? ''\"\n [showIcon]=\"true\"\n [view]=\"'year'\"\n [dateFormat]=\"field.config.attributes.dateFormat ?? 'yy'\"\n [readonlyInput]=\"true\"\n appendTo=\"body\"\n (onSelect)=\"onEvent(field, $event, 'select')\"\n />\n }\n\n <!-- slider -->\n @case ('slider') {\n <p-slider\n [formControlName]=\"field.formControlName!\"\n [min]=\"field.config.attributes.min ?? 0\"\n [max]=\"field.config.attributes.max ?? 100\"\n [step]=\"field.config.attributes.step ?? 1\"\n [range]=\"field.config.attributes.range\"\n [orientation]=\"\n field.config.attributes.orientation ?? 'horizontal'\n \"\n (onChange)=\"onEvent(field, $event, 'change')\"\n />\n }\n\n <!-- rating -->\n @case ('rating') {\n <p-rating\n [formControlName]=\"field.formControlName!\"\n [stars]=\"field.config.attributes.stars ?? 5\"\n (onRate)=\"onEvent(field, $event, 'change')\"\n />\n }\n\n <!-- colorPicker -->\n @case ('colorPicker') {\n <p-colorpicker\n [formControlName]=\"field.formControlName!\"\n [inline]=\"field.config.attributes.inline\"\n (onChange)=\"onEvent(field, $event, 'change')\"\n />\n }\n }\n\n @if (\n field.config.attributes.fieldPos === 'right' &&\n field.config.attributes.fieldIcon\n ) {\n <p-inputgroup-addon>\n <i [class]=\"field.config.attributes.fieldIcon\">\n {{ field.config.attributes.fieldIconText ?? '' }}\n </i>\n </p-inputgroup-addon>\n }\n </p-inputgroup>\n }\n }\n </ng-container>\n</ng-template>\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n inject,\n input,\n output,\n} from '@angular/core';\nimport { NgClass } from '@angular/common';\nimport { ButtonModule } from 'primeng/button';\n\nimport {\n FormEngineEvent,\n FormEngineService,\n FormSchema,\n} from '@ngx-json-forms/core';\n\nimport { NgxJsonFormComponent } from './ngx-form-engine-primeng.component';\n\n/**\n * Wizard-style wrapper that drives `<ngx-json-form>` step-by-step using the\n * `FormSchema.steps` definition. Renders a header strip with step indicators,\n * the current step's fields, and Back / Next / Submit controls.\n */\n@Component({\n selector: 'ngx-json-form-stepper',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [NgxJsonFormComponent, ButtonModule, NgClass],\n styleUrl: './ngx-json-form-stepper.component.scss',\n template: `\n @if (schema().steps?.length) {\n <div class=\"ngx-stepper\">\n <!-- Step indicators -->\n <ol class=\"ngx-stepper-bar\">\n @for (step of schema().steps; track step.id) {\n <li\n class=\"ngx-stepper-item\"\n [ngClass]=\"{\n active: $index === activeIndex(),\n done: $index < activeIndex()\n }\"\n (click)=\"jumpTo($index)\"\n >\n <span class=\"ngx-stepper-num\">\n @if ($index < activeIndex()) {\n <i class=\"pi pi-check\"></i>\n } @else {\n {{ $index + 1 }}\n }\n </span>\n <span class=\"ngx-stepper-label\">\n @if (step.icon) {\n <i [class]=\"step.icon\"></i>\n }\n {{ step.title }}\n </span>\n </li>\n }\n </ol>\n\n <!--\n Step body — resolve the active step from the schema INPUT (not\n from formService.activeStep()) so the inner <ngx-json-form>\n always renders. formService.activeStep() only becomes non-null\n AFTER the inner form calls register(), which only happens once\n the inner form is in the DOM; gating on activeStep() created a\n chicken-and-egg that left the body permanently blank.\n -->\n @let currentStep = schema().steps?.[activeIndex()];\n @if (currentStep?.description) {\n <p class=\"ngx-stepper-desc\">{{ currentStep!.description }}</p>\n }\n <ngx-json-form\n [schema]=\"schema()\"\n [stepFields]=\"currentStep?.fields ?? []\"\n (formChange)=\"formChange.emit($event)\"\n (formSubmit)=\"onSubmit($event)\"\n />\n\n <!-- Controls -->\n <div class=\"ngx-stepper-actions\">\n <button\n pButton\n type=\"button\"\n class=\"p-button-text\"\n label=\"Back\"\n icon=\"pi pi-arrow-left\"\n [disabled]=\"activeIndex() === 0\"\n (click)=\"back()\"\n ></button>\n @if (!isLast()) {\n <button\n pButton\n type=\"button\"\n label=\"Next\"\n icon=\"pi pi-arrow-right\"\n iconPos=\"right\"\n (click)=\"next()\"\n ></button>\n } @else {\n <button\n pButton\n type=\"button\"\n [label]=\"submitLabel()\"\n icon=\"pi pi-check\"\n iconPos=\"right\"\n [disabled]=\"!formService.formValid()\"\n (click)=\"submit()\"\n ></button>\n }\n </div>\n </div>\n }\n `,\n})\nexport class NgxJsonFormStepperComponent {\n readonly schema = input.required<FormSchema>();\n readonly submitLabel = input<string>('Submit');\n\n readonly formSubmit = output<FormEngineEvent>();\n readonly formChange = output<FormEngineEvent>();\n\n protected readonly formService = inject(FormEngineService);\n\n readonly activeIndex = computed(() => this.formService.activeStepIndex());\n readonly activeStep = computed(() => this.formService.activeStep());\n\n readonly isLast = computed(() => {\n const steps = this.schema().steps ?? [];\n return this.activeIndex() === steps.length - 1;\n });\n\n constructor() {\n // Reset the wizard whenever the schema input changes\n effect(() => {\n this.schema();\n this.formService.goToStep(0);\n });\n }\n\n protected back(): void {\n this.formService.prevStep();\n }\n\n protected next(): void {\n this.formService.nextStep();\n }\n\n protected jumpTo(i: number): void {\n if (i <= this.activeIndex()) this.formService.goToStep(i);\n }\n\n protected submit(): void {\n if (!this.formService.markAllAsTouchedAndValidate()) return;\n const values = this.formService.buildSubmitPayload();\n this.formSubmit.emit({\n field: { config: { attributes: { inputType: 'button', buttonRole: 'submit' } } } as never,\n values,\n valid: true,\n type: 'submit',\n });\n }\n\n /** Pass-through when the inner form emits formSubmit (e.g. via an inline button) */\n protected onSubmit(e: FormEngineEvent): void {\n this.formSubmit.emit(e);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ngx-json-forms/primeng",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "description": "PrimeNG adapter for ngx-json-forms — renders JSON-defined forms using PrimeNG components.",
5
5
  "keywords": [
6
6
  "angular",
@@ -22,7 +22,7 @@
22
22
  "@angular/common": ">=19.0.0",
23
23
  "@angular/core": ">=19.0.0",
24
24
  "@angular/forms": ">=19.0.0",
25
- "@ngx-json-forms/core": "^1.0.1",
25
+ "@ngx-json-forms/core": "^1.1.0",
26
26
  "primeng": ">=19.0.0",
27
27
  "rxjs": "~7.8.0"
28
28
  },