{"version":3,"file":"ng-forge-dynamic-forms-primeng.mjs","mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAmDc;;AAGH;;AAEU;;;;AAIf;;QAGF;;;;AAZiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA1CT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACqCO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8CE;;AACA;;AACA;;AAEnB;AACE;AACA;;gBAQiB;AACjB;AACA;AAAU;AACV;AACA;;;IAIF;AACE;;;;AAGE;;;IAKJ;QAEE;;;;AAGE;;;;AAMF;;;AAKA;;;;AA9FS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAlCF;AACT;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BC;;AAEF;;;ACSa;;;;;;;;AAMH;;AAEU;;;;AAIf;;AAEF;;;;AAdiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAVlB;;;;AAlCS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACGV;AACF;;;;;;ACyLc;;;;AAMH;;AAET,IAKS;;IAGQ;AAEE;;AACA;;IAGA;;AAEA;;;;AAIf;;AAEF;AACA;AACE;;AACK;AACL;;AAEF;AACE;;AAEF;;;AAGiB;;;AA1CA;AAxHjB;AACE;AACA;AACD;AACD;gFAME;;AAEE;AACA;AACA;oBAEA;;AAEE;AACE;AACA;;;;;;AAOC;;;;AAIR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAlCF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGC;AACE;AACA;AACD;AACD;4IAME;;AAEE;AACA;AACA;;;AAIE;AACE;AACA;;;;;;AAOC;;;;AAIR;AACF;;;;;;;;AC9CW;;;;AAIH;;AAEC;AAEN;;AAEF;IAKiB;;;;;AAKjB;;;;AAIA;;;AAGI;AACE;AACA;;;AAEF;;AAEJ;;AAGF;AACE;AACE;AACA;AACE;;AAEJ;AAEA;AACE;AACA;;;AAIE;;AAEJ;;;AApDiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AArDT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACiEO;;;;;;;;;;;;;;;;AAiBR;;;;AAKT;AACE;;AAEE;AACA;AACD;;;AAKD;;;AAjCS;;;;;;;;;;;;;;;;;;AA9BV;;;;;AAtBC;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;ACqBU;;;;AAIH;;;AAJU;;;;;;;;;;;;;AAnBlB;;;;AAjBS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QC6FS;;AACA;;AACA;;gBAOA;AACjB;AACA;;;IAIF;;;IAKA;;;;AAOE;;;;AAnES;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAHV;;;;AA9CQ;AACT;AACA;;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CC;;AAEF;;;ACfa;;;;AAIH;;AAEU;;AAEA;;;;AAIf;;QAGF;;;;AAfiB;;;;;;;;;;;;;;;;;;;;;;;AAVlB;;;;AA3BS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACyCE;;AAGH;;AACA;;;AAJU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA1CT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACsBE;;AAGH;;AAEA;;AAEA;;;AAGP;;AACA;;;AAXiB;;;;;;;;;;;;;;;;AAHlB;;;;AApBQ;AACT;AACA;;AAEA;;;;;;;;;;;;;;;;AAgBC;;AAEF;;;;;;;;;;ACQkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgDE;;YAKA;;AACA;;AAEnB;AACE;AACA;;;AAKA;;;;AAhES;;;;;;;;;;;;;;;;;;;;;;;;AA1BF;AACT;AACA;AACA;;;;;;;;;;;;;;;;;;;;AAoBC;;AAEF;;;ACUa;;AAGH;;AAEU;;AAEA;;;AAPA;;;;;;;;;;;;;;;;;;;;;;;AAVlB;;;;AA3BS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACoCE;;AAGH;;AAEU;;;;AAIf;;AAEF;;;;AAXiB;;;;;;;;;;;;;;;;;;;;;;;;;;AApCT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACLL;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;ACXI;AACJ;AACA;AACA;;;AAKE;AACE;AACA;;;AAKA;;;AAKA;;QAIF;AACA;;AAGI;;AACA;AACF;;;;AAKE;AACA;;;;AAKJ;AACF;AACF;;;ACtCA;;;AAIA;AACE;AACA;;AAOK;AACL;;AAEE;AACA;;AAEA;AACA;AACE;AACD;AACD;AACD;AACD;;AAEE;AACA;AACA;AACA;AACD;AACD;;AAEE;AACA;AACA;AACA;AACD;AACD;;AAEE;AACA;AACA;AACD;AACD;;AAEE;AACA;AACA;AACD;AACD;;AAEE;AACA;AACA;AACD;AACD;;AAEE;AACA;AACA;AACD;AACD;;AAEE;AACA;AACA;AACD;AACD;;AAEE;AACA;AACA;AACD;AACD;;AAEE;AACA;AACA;AACD;AACD;;AAEE;AACA;AACA;AACD;AACD;;AAEE;AACA;AACA;AACD;AACD;;AAEE;AACA;AACA;AACD;AACD;;AAEE;AACA;AACA;AACA;AACA;AACD;AACD;;AAEE;AACA;AACA;AACA;AACD;AACD;;AAEE;AACA;AACA;AACA;AACD;AACD;;AAEE;AACA;AACA;AACA;AACD;AACD;;AAEE;AACA;AACA;AACA;AACD;AACD;;AAEE;AACA;AACA;AACA;AACD;;;;AC1HG;;;;AAOA;;AAE8B;AAChC;;AAGF;AACF;AAEA;AAEA;AACE;AACA;AACA;AACE;AACE;;;;AAKN;AACE;AACA;AACA;;AAIE;AACE;;QAKF;AACE;;;;;;AAkBF;AACA;;;AAGC;;AAEL;;;;;ICnFW;;AAEU;;;;AAEA;;;AAPR;;;;AATF;AACT;AACA;AACA;AACA;AACE;AACD;;AAEF;;;;;;;;;;IC6CoB;;;;;AAIA;AACjB;;;;AAGiB;;;;;;AAZR;;;;;;;;;;;;;;;;;;;;;;;;;;AAlBV;;;;AA7BS","names":[],"ignoreList":[],"sources":["../../../../packages/dynamic-forms-primeng/src/lib/fields/checkbox/prime-checkbox.component.ts","../../../../packages/dynamic-forms-primeng/src/lib/fields/datepicker/prime-datepicker-control.component.ts","../../../../packages/dynamic-forms-primeng/src/lib/fields/datepicker/prime-datepicker.component.ts","../../../../packages/dynamic-forms-primeng/src/lib/addons/preset-actions.ts","../../../../packages/dynamic-forms-primeng/src/lib/fields/input/prime-input.component.ts","../../../../packages/dynamic-forms-primeng/src/lib/fields/multi-checkbox/prime-multi-checkbox.component.ts","../../../../packages/dynamic-forms-primeng/src/lib/fields/radio/prime-radio-group.component.ts","../../../../packages/dynamic-forms-primeng/src/lib/fields/radio/prime-radio.component.ts","../../../../packages/dynamic-forms-primeng/src/lib/fields/select/prime-select-control.component.ts","../../../../packages/dynamic-forms-primeng/src/lib/fields/select/prime-select.component.ts","../../../../packages/dynamic-forms-primeng/src/lib/fields/slider/prime-slider.component.ts","../../../../packages/dynamic-forms-primeng/src/lib/fields/button/prime-button.component.ts","../../../../packages/dynamic-forms-primeng/src/lib/fields/textarea/prime-textarea-control.component.ts","../../../../packages/dynamic-forms-primeng/src/lib/fields/textarea/prime-textarea.component.ts","../../../../packages/dynamic-forms-primeng/src/lib/fields/toggle/prime-toggle.component.ts","../../../../packages/dynamic-forms-primeng/src/lib/types/types.ts","../../../../packages/dynamic-forms-primeng/src/lib/fields/button/prime-button.mapper.ts","../../../../packages/dynamic-forms-primeng/src/lib/config/primeng-field-config.ts","../../../../packages/dynamic-forms-primeng/src/lib/providers/primeng-providers.ts","../../../../packages/dynamic-forms-primeng/src/lib/addons/prime-icon-addon.component.ts","../../../../packages/dynamic-forms-primeng/src/lib/addons/prime-button-addon.component.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';\nimport { FormField } from '@angular/forms/signals';\nimport { Checkbox } from 'primeng/checkbox';\nimport { DynamicTextPipe } from '@ng-forge/dynamic-forms/integration';\nimport { NgForgeControl, injectNgForgeField, NgForgeFieldHost } from '@ng-forge/dynamic-forms/integration';\nimport { PrimeCheckboxProps } from './prime-checkbox.type';\nimport { AsyncPipe } from '@angular/common';\n\n@Component({\n  selector: 'df-prime-checkbox',\n  imports: [Checkbox, DynamicTextPipe, AsyncPipe, FormField, NgForgeControl],\n  styleUrl: '../../styles/_form-field.scss',\n  hostDirectives: [NgForgeFieldHost],\n  template: `\n    @let f = ngf.field(); @let checkboxId = ngf.key() + '-checkbox';\n\n    <div class=\"flex items-center\">\n      <p-checkbox\n        ngForgeControl=\"input[type='checkbox']\"\n        [formField]=\"f\"\n        [inputId]=\"checkboxId\"\n        [binary]=\"props()?.binary ?? true\"\n        [trueValue]=\"props()?.trueValue ?? true\"\n        [falseValue]=\"props()?.falseValue ?? false\"\n        [styleClass]=\"checkboxClasses()\"\n        [tabindex]=\"ngf.tabIndex() ?? 0\"\n      />\n      @if (ngf.label(); as labelText) {\n        <label [for]=\"checkboxId\" class=\"ml-2\">{{ labelText | dynamicText | async }}</label>\n      }\n    </div>\n\n    @if (ngf.errorsToDisplay()[0]; as error) {\n      <small class=\"p-error\" [id]=\"ngf.errorId()\" role=\"alert\">{{ error.message }}</small>\n    } @else if (props()?.hint; as hint) {\n      <small class=\"p-hint\" [id]=\"ngf.hintId()\" [attr.hidden]=\"f().hidden() || null\">{{ hint | dynamicText | async }}</small>\n    }\n  `,\n  styles: [\n    `\n      :host {\n        display: block;\n      }\n\n      :host([hidden]) {\n        display: none !important;\n      }\n    `,\n  ],\n  changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport default class PrimeCheckboxFieldComponent {\n  protected readonly ngf = injectNgForgeField<boolean>();\n\n  readonly props = input<PrimeCheckboxProps>();\n\n  protected readonly checkboxClasses = computed(() => {\n    const classes: string[] = [];\n    const styleClass = this.props()?.styleClass;\n    if (styleClass) {\n      classes.push(styleClass);\n    }\n    // Note: p-invalid is handled by [invalid] input binding, not manual class\n    return classes.join(' ');\n  });\n}\n","import { ChangeDetectionStrategy, Component, computed, ElementRef, inject, input, model } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { FormValueControl } from '@angular/forms/signals';\nimport { NgForgeField, setupMetaTracking, InputMeta } from '@ng-forge/dynamic-forms/integration';\nimport { DatePicker } from 'primeng/datepicker';\n\n/**\n * PrimeNG DatePicker wrapper implementing FormValueControl. Value is stored\n * as an ISO date string. Rendered inside `df-prime-datepicker` — picks up\n * meta + aria from the ambient parent NgForgeField (selector: `'input'`).\n */\n@Component({\n  selector: 'df-prime-datepicker-control',\n  imports: [DatePicker, FormsModule],\n  template: `\n    <p-datepicker\n      [inputId]=\"inputId()\"\n      [ngModel]=\"dateValue()\"\n      (ngModelChange)=\"onModelChange($event)\"\n      (onSelect)=\"onSelect($event)\"\n      (onClear)=\"onClear()\"\n      [placeholder]=\"placeholder()\"\n      [disabled]=\"disabled()\"\n      [readonlyInput]=\"readonly()\"\n      [invalid]=\"ariaInvalid()\"\n      [dateFormat]=\"dateFormat()\"\n      [inline]=\"inline()\"\n      [showIcon]=\"showIcon()\"\n      [showButtonBar]=\"showButtonBar()\"\n      [selectionMode]=\"selectionMode()\"\n      [touchUI]=\"touchUI()\"\n      [view]=\"view()\"\n      [minDate]=\"minDate()\"\n      [maxDate]=\"maxDate()\"\n      [defaultDate]=\"defaultDate()\"\n      [styleClass]=\"styleClass()\"\n      [attr.tabindex]=\"tabIndex()\"\n      [attr.aria-invalid]=\"ariaInvalid()\"\n      [attr.aria-required]=\"ariaRequired()\"\n      [attr.aria-describedby]=\"ariaDescribedBy()\"\n      (onBlur)=\"onBlur()\"\n    />\n  `,\n  changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class PrimeDatepickerControlComponent implements FormValueControl<string | null> {\n  private readonly elementRef = inject(ElementRef<HTMLElement>);\n  private readonly parentField = inject(NgForgeField, { optional: true });\n\n  // ─────────────────────────────────────────────────────────────────────────────\n  // FormValueControl implementation\n  // ─────────────────────────────────────────────────────────────────────────────\n\n  /** The value of the datepicker as ISO string - required by FormValueControl */\n  readonly value = model<string | null>(null);\n\n  /** Tracks whether the field has been touched - used by FormField directive */\n  readonly touched = model<boolean>(false);\n\n  /** Whether the field is disabled */\n  readonly disabled = input<boolean>(false);\n\n  /** Whether the field is readonly */\n  readonly readonly = input<boolean>(false);\n\n  /** Whether the field is invalid (from FormField directive) */\n  readonly invalid = input<boolean>(false);\n\n  /** Whether the field is required (from FormField directive) */\n  readonly required = input<boolean>(false);\n\n  // ─────────────────────────────────────────────────────────────────────────────\n  // PrimeNG DatePicker-specific props\n  // ─────────────────────────────────────────────────────────────────────────────\n\n  readonly inputId = input<string>('');\n  readonly placeholder = input<string>('');\n  readonly dateFormat = input<string>('mm/dd/yy');\n  readonly inline = input<boolean>(false);\n  readonly showIcon = input<boolean>(true);\n  readonly showButtonBar = input<boolean>(false);\n  readonly selectionMode = input<'single' | 'multiple' | 'range'>('single');\n  readonly touchUI = input<boolean>(false);\n  readonly view = input<'date' | 'month' | 'year'>('date');\n  readonly minDate = input<Date | null>(null);\n  readonly maxDate = input<Date | null>(null);\n  readonly defaultDate = input<Date | null>(null);\n  readonly styleClass = input<string>('');\n  readonly tabIndex = input<number | undefined>(undefined);\n\n  // Meta + aria read from the ambient parent NgForgeField.\n  protected readonly meta = computed<InputMeta | undefined>(() => this.parentField?.meta() as InputMeta | undefined);\n  protected readonly ariaInvalid = computed<boolean>(() => this.parentField?.ariaInvalid() ?? false);\n  protected readonly ariaRequired = computed<true | null>(() => this.parentField?.ariaRequired() ?? null);\n  protected readonly ariaDescribedBy = computed<string | null>(() => this.parentField?.ariaDescribedBy() ?? null);\n\n  constructor() {\n    this.parentField?.markClaimed();\n    setupMetaTracking(this.elementRef, this.meta, { selector: 'input' });\n  }\n\n  // ─────────────────────────────────────────────────────────────────────────────\n  // Date conversion\n  // ─────────────────────────────────────────────────────────────────────────────\n\n  /** Converts the string value to Date for PrimeNG's ngModel */\n  protected readonly dateValue = computed(() => {\n    const val = this.value();\n    if (!val) return null;\n    const date = new Date(val);\n    return isNaN(date.getTime()) ? null : date;\n  });\n\n  /** Handles ngModel changes (from typing or calendar selection) */\n  onModelChange(date: Date | null): void {\n    if (date instanceof Date && !isNaN(date.getTime())) {\n      this.value.set(date.toISOString());\n    } else {\n      this.value.set(null);\n    }\n  }\n\n  /** Handles date selection from DatePicker calendar - converts Date to ISO string */\n  onSelect(event: Date): void {\n    // onSelect is redundant with onModelChange but kept for explicit calendar selection handling\n    if (event instanceof Date && !isNaN(event.getTime())) {\n      this.value.set(event.toISOString());\n    } else {\n      this.value.set(null);\n    }\n  }\n\n  /** Handles clear action from DatePicker */\n  onClear(): void {\n    this.value.set(null);\n  }\n\n  /** Marks the field as touched when datepicker loses focus */\n  onBlur(): void {\n    this.touched.set(true);\n    this.parentField?.field()().markAsTouched();\n  }\n}\n","import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';\nimport { FormField } from '@angular/forms/signals';\nimport { DynamicTextPipe } from '@ng-forge/dynamic-forms/integration';\nimport { injectNgForgeField, NgForgeFieldHost } from '@ng-forge/dynamic-forms/integration';\nimport { PrimeDatepickerProps } from './prime-datepicker.type';\nimport { AsyncPipe } from '@angular/common';\nimport { PrimeDatepickerControlComponent } from './prime-datepicker-control.component';\n\n@Component({\n  selector: 'df-prime-datepicker',\n  imports: [PrimeDatepickerControlComponent, FormField, DynamicTextPipe, AsyncPipe],\n  styleUrl: '../../styles/_form-field.scss',\n  hostDirectives: [NgForgeFieldHost],\n  template: `\n    <div class=\"df-prime-field\">\n      @if (ngf.label()) {\n        <label [for]=\"ngf.key() + '-datepicker'\" class=\"df-prime-label\">{{ ngf.label() | dynamicText | async }}</label>\n      }\n\n      <df-prime-datepicker-control\n        [formField]=\"ngf.field()\"\n        [inputId]=\"ngf.key() + '-datepicker'\"\n        [placeholder]=\"(ngf.placeholder() | dynamicText | async) ?? ''\"\n        [tabIndex]=\"ngf.tabIndex()\"\n        [dateFormat]=\"props()?.dateFormat || 'mm/dd/yy'\"\n        [inline]=\"props()?.inline ?? false\"\n        [showIcon]=\"props()?.showIcon ?? true\"\n        [showButtonBar]=\"props()?.showButtonBar ?? false\"\n        [selectionMode]=\"props()?.selectionMode || 'single'\"\n        [touchUI]=\"props()?.touchUI ?? false\"\n        [view]=\"props()?.view || 'date'\"\n        [minDate]=\"minDate()\"\n        [maxDate]=\"maxDate()\"\n        [defaultDate]=\"startAt()\"\n        [styleClass]=\"datepickerClasses()\"\n      />\n\n      @if (ngf.errorsToDisplay()[0]; as error) {\n        <small class=\"p-error\" [id]=\"ngf.errorId()\" role=\"alert\">{{ error.message }}</small>\n      } @else if (props()?.hint; as hint) {\n        <small class=\"df-prime-hint\" [id]=\"ngf.hintId()\">{{ hint | dynamicText | async }}</small>\n      }\n    </div>\n  `,\n  changeDetection: ChangeDetectionStrategy.OnPush,\n  styles: [\n    `\n      :host([hidden]) {\n        display: none !important;\n      }\n    `,\n  ],\n})\nexport default class PrimeDatepickerFieldComponent {\n  protected readonly ngf = injectNgForgeField<string>();\n\n  readonly minDate = input<Date | null>(null);\n  readonly maxDate = input<Date | null>(null);\n  readonly startAt = input<Date | null>(null);\n  readonly props = input<PrimeDatepickerProps>();\n\n  protected readonly datepickerClasses = computed(() => {\n    const classes: string[] = [];\n    const styleClass = this.props()?.styleClass;\n    if (styleClass) {\n      classes.push(styleClass);\n    }\n    return classes.join(' ');\n  });\n}\n","import type { AddonActionContext, AddonActionPreset } from '@ng-forge/dynamic-forms';\nimport type { PresetCollaborators } from '@ng-forge/dynamic-forms/integration';\nimport { runPresetAction } from '@ng-forge/dynamic-forms/integration';\n\nexport type { PresetCollaborators };\n\n/** PrimeNG adapter binding for the shared preset runner. */\nexport function runPrimePresetAction(\n  preset: AddonActionPreset,\n  ctx: AddonActionContext,\n  collaborators: PresetCollaborators,\n): Promise<void> {\n  return runPresetAction(preset, ctx, collaborators, 'PrimeNG', 'prime-input');\n}\n","import { ChangeDetectionStrategy, Component, computed, forwardRef, inject, input, signal } from '@angular/core';\nimport { FormField } from '@angular/forms/signals';\nimport { AddonActionContext, AddonActionPreset, DynamicFormLogger } from '@ng-forge/dynamic-forms';\nimport { DfAddonSlot } from '@ng-forge/dynamic-forms/integration';\nimport { WrapperFieldInputs } from '@ng-forge/dynamic-forms/integration';\nimport { DynamicTextPipe, FIELD_SIGNAL_CONTEXT } from '@ng-forge/dynamic-forms/integration';\nimport {\n  ADDON_PRESET_HANDLER,\n  AddonPresetHandler,\n  injectNgForgeAddons,\n  injectNgForgeField,\n  NgForgeAddons,\n  NgForgeControl,\n  NgForgeFieldHost,\n} from '@ng-forge/dynamic-forms/integration';\nimport { AsyncPipe } from '@angular/common';\nimport { InputGroupModule } from 'primeng/inputgroup';\nimport { InputGroupAddonModule } from 'primeng/inputgroupaddon';\nimport { InputText } from 'primeng/inputtext';\nimport { runPrimePresetAction } from '../../addons/preset-actions';\nimport { PRIMENG_CONFIG } from '../../models/primeng-config.token';\nimport { PRIME_INPUT_TYPE_OVERRIDE } from '../../tokens/input-type-override.token';\nimport { PrimeInputAddon, PrimeInputProps } from './prime-input.type';\n\n@Component({\n  selector: 'df-prime-input',\n  imports: [InputText, InputGroupModule, InputGroupAddonModule, DfAddonSlot, DynamicTextPipe, AsyncPipe, FormField, NgForgeControl],\n  styleUrl: '../../styles/_form-field.scss',\n  hostDirectives: [NgForgeFieldHost, NgForgeAddons],\n  template: `\n    <div class=\"df-prime-field\">\n      @if (ngf.label()) {\n        <label [for]=\"inputId()\" class=\"df-prime-label\">{{ ngf.label() | dynamicText | async }}</label>\n      }\n      @if (ngfa.hasAddons()) {\n        <p-inputgroup>\n          @for (a of ngfa.prefixAddons(); track $index) {\n            <p-inputgroup-addon>\n              <df-addon-slot [addon]=\"a\" [fieldInputs]=\"fieldInputs()\" [hidden]=\"ngfa.hiddenSignalCache().get(a)\" />\n            </p-inputgroup-addon>\n          }\n          <input\n            pInputText\n            ngForgeControl\n            [id]=\"inputId()\"\n            [formField]=\"ngf.field()\"\n            [type]=\"type()\"\n            [placeholder]=\"(ngf.placeholder() | dynamicText | async) ?? ''\"\n            [attr.tabindex]=\"ngf.tabIndex()\"\n            [class]=\"inputClasses()\"\n          />\n          @for (a of ngfa.suffixAddons(); track $index) {\n            <p-inputgroup-addon>\n              <df-addon-slot [addon]=\"a\" [fieldInputs]=\"fieldInputs()\" [hidden]=\"ngfa.hiddenSignalCache().get(a)\" />\n            </p-inputgroup-addon>\n          }\n        </p-inputgroup>\n      } @else {\n        <input\n          pInputText\n          ngForgeControl\n          [id]=\"inputId()\"\n          [formField]=\"ngf.field()\"\n          [type]=\"type()\"\n          [placeholder]=\"(ngf.placeholder() | dynamicText | async) ?? ''\"\n          [attr.tabindex]=\"ngf.tabIndex()\"\n          [class]=\"inputClasses()\"\n        />\n      }\n      @if (ngf.errorsToDisplay()[0]; as error) {\n        <small class=\"p-error\" [id]=\"ngf.errorId()\" role=\"alert\">{{ error.message }}</small>\n      } @else if (props()?.hint; as hint) {\n        <small class=\"df-prime-hint\" [id]=\"ngf.hintId()\">{{ hint | dynamicText | async }}</small>\n      }\n    </div>\n  `,\n  changeDetection: ChangeDetectionStrategy.OnPush,\n  providers: [\n    {\n      provide: PRIME_INPUT_TYPE_OVERRIDE,\n      useFactory: () => signal<string | undefined>(undefined),\n    },\n    {\n      // Adapter-specific preset semantics for `prime-button` addons (clear /\n      // reset / paste / copy / toggle-password-visibility). The directive\n      // (`NgForgeAddonAction`) delegates here when an addon configures a\n      // `preset`. Per-prime-input-instance so the `typeOverride` signal is\n      // scoped to one field.\n      provide: ADDON_PRESET_HANDLER,\n      useFactory: (): AddonPresetHandler => {\n        const typeOverride = inject(PRIME_INPUT_TYPE_OVERRIDE);\n        const fsc = inject(FIELD_SIGNAL_CONTEXT, { optional: true });\n        const logger = inject(DynamicFormLogger);\n        // forwardRef for baselineType only — host.props()?.type gates toggle-password-visibility.\n        const host = inject(forwardRef(() => PrimeInputFieldComponent));\n        return {\n          run: (preset: string, ctx: AddonActionContext) => {\n            const fieldKey = ctx.field.key;\n            return runPrimePresetAction(preset as AddonActionPreset, ctx, {\n              typeOverride,\n              fieldValueSetter: ctx.setValue,\n              fieldDefaultValueGetter:\n                fsc && fieldKey ? () => (fsc.defaultValues() as Record<string, unknown> | undefined)?.[fieldKey] : undefined,\n              baselineType: () => host.props()?.type,\n              logger,\n            });\n          },\n        };\n      },\n    },\n  ],\n  styles: [\n    `\n      :host([hidden]) {\n        display: none !important;\n      }\n      /* Make p-inputgroup-addon inherit the input's theme tokens so it\n         matches the input surface in any PrimeNG theme (light/dark/custom).\n         PrimeNG's default tokens for inputgroup-addon don't always track the\n         input's surface — explicit binding via input-text vars keeps them\n         visually unified. */\n      /* PrimeNG ships its inputgroup CSS via runtime style injection (requires\n         providePrimeNG()). When the host app doesn't wire that — like an\n         embedded live-example renderer — fall back to layout primitives so\n         the input group still flexes horizontally and the addon containers\n         have their own chrome. Uses PrimeNG's dedicated inputgroup-addon\n         tokens; idempotent if PrimeNG's runtime CSS later loads on top. */\n      :host ::ng-deep p-inputgroup {\n        display: flex;\n        align-items: stretch;\n        width: 100%;\n      }\n      :host ::ng-deep p-inputgroup > input,\n      :host ::ng-deep p-inputgroup > .p-inputtext {\n        flex: 1 1 auto;\n        width: 1%;\n      }\n      /* Per-side padding on the addon containers (independent knobs). The\n         vertical axis still inherits PrimeNG's --p-inputgroup-addon-padding\n         when defined. */\n      :host {\n        --df-prime-addon-prefix-outer-padding: 0.75rem;\n        --df-prime-addon-prefix-inner-padding: 0.75rem;\n        --df-prime-addon-suffix-inner-padding: 0.75rem;\n        --df-prime-addon-suffix-outer-padding: 0.75rem;\n      }\n      /* Border + background fallbacks chain: prefer PrimeNG's addon tokens\n         (loaded when providePrimeNG() runs); fall back to the input-text\n         tokens; fall back to a tinted currentColor that always resolves so\n         the chrome stays visible even when PrimeNG's runtime CSS isn't\n         present in this sub-app's shadow root (multi-demo pages can race\n         the style injection — one shadow root wins, the other ends up\n         without the inputgroup-addon stylesheet). */\n      :host {\n        --df-prime-addon-fallback-border-color: color-mix(in srgb, currentColor 20%, transparent);\n        --df-prime-addon-fallback-background: color-mix(in srgb, currentColor 4%, transparent);\n      }\n      :host ::ng-deep p-inputgroup-addon {\n        display: inline-flex;\n        align-items: center;\n        justify-content: center;\n        background: var(--p-inputgroup-addon-background, var(--p-content-background, var(--df-prime-addon-fallback-background)));\n        color: var(--p-inputgroup-addon-color, var(--p-inputtext-color, currentColor));\n        border: 1px solid\n          var(--p-inputgroup-addon-border-color, var(--p-inputtext-border-color, var(--df-prime-addon-fallback-border-color)));\n      }\n      :host ::ng-deep p-inputgroup > p-inputgroup-addon:first-child {\n        padding-left: var(--df-prime-addon-prefix-outer-padding);\n        padding-right: var(--df-prime-addon-prefix-inner-padding);\n      }\n      :host ::ng-deep p-inputgroup > p-inputgroup-addon:last-child {\n        padding-left: var(--df-prime-addon-suffix-inner-padding);\n        padding-right: var(--df-prime-addon-suffix-outer-padding);\n      }\n      /* Flatten the inner p-button so it doesn't paint chrome over the addon\n         container; hover/active tints use currentColor (PrimeNG's\n         --p-content-hover-background goes near-white on dark themes). */\n      :host ::ng-deep p-inputgroup-addon df-prime-button-addon {\n        --p-button-secondary-background: transparent;\n        --p-button-secondary-border-color: transparent;\n        --p-button-secondary-color: var(--p-inputtext-color);\n        --p-button-secondary-hover-background: color-mix(in srgb, currentColor 8%, transparent);\n        --p-button-secondary-hover-border-color: transparent;\n        --p-button-secondary-hover-color: var(--p-inputtext-color);\n        --p-button-secondary-active-background: color-mix(in srgb, currentColor 16%, transparent);\n        --p-button-secondary-active-border-color: transparent;\n      }\n      :host ::ng-deep p-inputgroup-addon df-prime-button-addon .p-button {\n        box-shadow: none;\n      }\n      :host ::ng-deep p-inputgroup-addon df-prime-button-addon .p-button:focus-visible {\n        /* 2px outward outline for WCAG 2.4.7 / 2.4.11 — matches Bootstrap (+2). */\n        outline: 2px solid var(--p-focus-ring-color, currentColor);\n        outline-offset: 2px;\n      }\n    `,\n  ],\n})\nexport default class PrimeInputFieldComponent {\n  private readonly primeNGConfig = inject(PRIMENG_CONFIG, { optional: true });\n\n  protected readonly ngf = injectNgForgeField<string>();\n  protected readonly ngfa = injectNgForgeAddons<PrimeInputAddon>();\n\n  readonly props = input<PrimeInputProps>();\n\n  /**\n   * Wrapper-style host bag pushed by `DfFieldOutlet`. Declared at the\n   * component level so `setInputIfDeclared` (which uses\n   * `reflectComponentType`) can write it.\n   */\n  readonly fieldInputs = input<WrapperFieldInputs | undefined>();\n\n  /** Per-instance type override populated by `toggle-password-visibility` preset. */\n  private readonly typeOverride = inject(PRIME_INPUT_TYPE_OVERRIDE);\n\n  protected readonly size = computed(() => this.props()?.size ?? this.primeNGConfig?.size);\n  protected readonly variant = computed(() => this.props()?.variant ?? this.primeNGConfig?.variant);\n\n  /** Override (set by `toggle-password-visibility` preset) wins over `props().type`. */\n  protected readonly type = computed(() => this.typeOverride() ?? this.props()?.type ?? 'text');\n\n  protected readonly inputClasses = computed(() => {\n    const classes: string[] = [];\n    const styleClass = this.props()?.styleClass;\n    if (styleClass) {\n      classes.push(styleClass);\n    }\n    const size = this.size();\n    if (size === 'small') {\n      classes.push('p-inputtext-sm');\n    } else if (size === 'large') {\n      classes.push('p-inputtext-lg');\n    }\n    if (this.variant() === 'filled') {\n      classes.push('p-filled');\n    }\n    return classes.join(' ');\n  });\n\n  protected readonly inputId = computed(() => `${this.ngf.key()}-input`);\n}\n","import { ChangeDetectionStrategy, Component, computed, input, linkedSignal } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { Checkbox, CheckboxChangeEvent } from 'primeng/checkbox';\nimport { FieldOption, ValueType } from '@ng-forge/dynamic-forms';\nimport { DynamicTextPipe } from '@ng-forge/dynamic-forms/integration';\nimport { injectNgForgeField, NgForgeFieldHost, isEqual, NgForgeControl } from '@ng-forge/dynamic-forms/integration';\nimport { explicitEffect } from 'ngxtension/explicit-effect';\nimport { PrimeMultiCheckboxProps } from './prime-multi-checkbox.type';\nimport { AsyncPipe } from '@angular/common';\n\n@Component({\n  selector: 'df-prime-multi-checkbox',\n  imports: [Checkbox, FormsModule, DynamicTextPipe, AsyncPipe, NgForgeControl],\n  styleUrl: '../../styles/_form-field.scss',\n  hostDirectives: [NgForgeFieldHost],\n  template: `\n    @let f = ngf.field();\n    @let checked = checkedValuesMap();\n    @let isInvalid = ngf.errorsToDisplay().length > 0;\n    @if (ngf.label(); as label) {\n      <div class=\"checkbox-group-label\">{{ label | dynamicText | async }}</div>\n    }\n\n    <div class=\"checkbox-group\" [class]=\"props()?.styleClass\" [attr.aria-describedby]=\"ngf.ariaDescribedBy()\">\n      @for (option of options(); track option.value) {\n        <div class=\"checkbox-option\">\n          <p-checkbox\n            ngForgeControl=\"input[type='checkbox']\"\n            [inputId]=\"ngf.key() + '-' + option.value\"\n            [binary]=\"true\"\n            [ngModel]=\"checked['' + option.value] || false\"\n            (onChange)=\"onCheckboxChange(option, $event)\"\n            [disabled]=\"f().disabled() || option.disabled || false\"\n            [invalid]=\"isInvalid\"\n          />\n          <label [for]=\"ngf.key() + '-' + option.value\" class=\"ml-2\">{{ option.label | dynamicText | async }}</label>\n        </div>\n      }\n    </div>\n    @if (ngf.errorsToDisplay()[0]; as error) {\n      <small class=\"p-error\" [id]=\"ngf.errorId()\" role=\"alert\">{{ error.message }}</small>\n    } @else if (props()?.hint; as hint) {\n      <small class=\"p-hint\" [id]=\"ngf.hintId()\">{{ hint | dynamicText | async }}</small>\n    }\n  `,\n  styles: [\n    `\n      :host {\n        display: block;\n      }\n\n      :host([hidden]) {\n        display: none !important;\n      }\n\n      .checkbox-option {\n        display: flex;\n        align-items: center;\n        gap: 0.5rem;\n      }\n    `,\n  ],\n  changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport default class PrimeMultiCheckboxFieldComponent {\n  protected readonly ngf = injectNgForgeField<ValueType[]>();\n\n  readonly options = input<FieldOption<ValueType>[]>([]);\n  readonly props = input<PrimeMultiCheckboxProps>();\n\n  protected valueViewModel = linkedSignal<FieldOption<ValueType>[]>(\n    () => {\n      const currentValues = this.ngf.field()().value();\n      return this.options().filter((option) => currentValues.includes(option.value));\n    },\n    { equal: isEqual },\n  );\n\n  /** Computed map of checked option values for O(1) lookup in template */\n  protected readonly checkedValuesMap = computed(() => {\n    const map: Record<string, boolean> = {};\n    for (const opt of this.valueViewModel()) {\n      map[String(opt.value)] = true;\n    }\n    return map;\n  });\n\n  protected onCheckboxChange(option: FieldOption<ValueType>, event: CheckboxChangeEvent): void {\n    const checked = event.checked;\n    this.valueViewModel.update((currentOptions: FieldOption<ValueType>[]) => {\n      if (checked) {\n        return currentOptions.some((opt: FieldOption<ValueType>) => opt.value === option.value)\n          ? currentOptions\n          : [...currentOptions, option];\n      } else {\n        return currentOptions.filter((opt: FieldOption<ValueType>) => opt.value !== option.value);\n      }\n    });\n  }\n\n  constructor() {\n    explicitEffect([this.valueViewModel], ([selectedOptions]: [FieldOption<ValueType>[]]) => {\n      const selectedValues = selectedOptions.map((option: FieldOption<ValueType>) => option.value);\n      if (!isEqual(selectedValues, this.ngf.field()().value())) {\n        this.ngf.field()().value.set(selectedValues);\n      }\n    });\n\n    explicitEffect([this.options], ([options]) => {\n      const values = options.map((option) => option.value);\n      const uniqueValues = new Set(values);\n\n      if (values.length !== uniqueValues.size) {\n        const duplicates = values.filter((value, index) => values.indexOf(value) !== index);\n        throw new Error(`Duplicate option values detected in prime-multi-checkbox: ${duplicates.join(', ')}`);\n      }\n    });\n  }\n}\n","import { ChangeDetectionStrategy, Component, computed, ElementRef, inject, input, model } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport type { FormValueControl } from '@angular/forms/signals';\nimport { FieldMeta, FieldOption, ValueType } from '@ng-forge/dynamic-forms';\nimport { DynamicTextPipe } from '@ng-forge/dynamic-forms/integration';\nimport { NgForgeField, setupMetaTracking } from '@ng-forge/dynamic-forms/integration';\nimport { AsyncPipe } from '@angular/common';\nimport { RadioButton } from 'primeng/radiobutton';\n\nexport interface PrimeRadioGroupProps {\n  /** Custom CSS class for the radio buttons */\n  styleClass?: string;\n}\n\n/**\n * PrimeNG radio group implementing FormValueControl. Rendered inside\n * `df-prime-radio` — picks up meta + aria from the ambient parent NgForgeField\n * via `setupMetaTracking` (selector: `'input[type=\"radio\"]'`).\n */\n@Component({\n  selector: 'df-prime-radio-group',\n  imports: [RadioButton, FormsModule, DynamicTextPipe, AsyncPipe],\n  host: {\n    '[attr.aria-invalid]': 'parentField?.ariaInvalid() || null',\n    '[attr.aria-required]': 'parentField?.ariaRequired()',\n    '[attr.aria-describedby]': 'parentField?.ariaDescribedBy()',\n  },\n  template: `\n    <div class=\"radio-group\">\n      @for (option of options(); track option.value; let i = $index) {\n        <div class=\"radio-option\">\n          <p-radiobutton\n            [name]=\"name()\"\n            [value]=\"option.value\"\n            [ngModel]=\"value()\"\n            (ngModelChange)=\"value.set($event)\"\n            (onBlur)=\"onBlur()\"\n            [disabled]=\"disabled() || option.disabled || false\"\n            [inputId]=\"name() + '_' + i\"\n            [styleClass]=\"properties()?.styleClass\"\n          />\n          <label [for]=\"name() + '_' + i\" class=\"radio-option-label\">{{ option.label | dynamicText | async }}</label>\n        </div>\n      }\n    </div>\n  `,\n  styles: [\n    `\n      :host {\n        display: block;\n      }\n\n      .radio-group {\n        display: flex;\n        flex-direction: column;\n        gap: 0.75rem;\n      }\n\n      .radio-option {\n        display: flex;\n        align-items: center;\n        gap: 0.5rem;\n      }\n\n      .radio-option-label {\n        cursor: pointer;\n        user-select: none;\n      }\n    `,\n  ],\n  changeDetection: ChangeDetectionStrategy.OnPush,\n})\n// Note: FormValueControl is from @angular/forms/signals and provides the contract for\n// components that expose a `value` model for use with [formField]. This is the same\n// pattern used by the Bootstrap radio group adapter (BsRadioGroupComponent).\nexport class PrimeRadioGroupComponent implements FormValueControl<ValueType | undefined> {\n  private readonly elementRef = inject(ElementRef<HTMLElement>);\n  protected readonly parentField = inject(NgForgeField, { optional: true });\n\n  // Value model - FormField directive binds form value to this\n  readonly value = model<ValueType | undefined>(undefined);\n\n  /** Tracks whether the field has been touched - used by Field directive */\n  readonly touched = model<boolean>(false);\n\n  // Optional FormValueControl properties - Field directive will bind these\n  readonly disabled = input<boolean>(false);\n  readonly readonly = input<boolean>(false);\n  readonly invalid = input<boolean>(false);\n  readonly name = input<string>('');\n\n  // Component-specific inputs\n  readonly options = input.required<FieldOption<ValueType>[]>();\n  readonly properties = input<PrimeRadioGroupProps>();\n\n  // Meta reads from the ambient parent NgForgeField.\n  protected readonly meta = computed<FieldMeta | undefined>(() => this.parentField?.meta());\n\n  constructor() {\n    this.parentField?.markClaimed();\n    setupMetaTracking(this.elementRef, this.meta, {\n      selector: 'input[type=\"radio\"]',\n      dependents: [this.options],\n    });\n  }\n\n  /** Marks the field as touched when a radio button loses focus */\n  protected onBlur(): void {\n    this.touched.set(true);\n  }\n}\n","import { ChangeDetectionStrategy, Component, input } from '@angular/core';\nimport { FormField } from '@angular/forms/signals';\nimport { FieldOption, ValueType } from '@ng-forge/dynamic-forms';\nimport { DynamicTextPipe } from '@ng-forge/dynamic-forms/integration';\nimport { injectNgForgeField, NgForgeFieldHost } from '@ng-forge/dynamic-forms/integration';\nimport { PrimeRadioProps } from './prime-radio.type';\nimport { AsyncPipe } from '@angular/common';\nimport { PrimeRadioGroupComponent } from './prime-radio-group.component';\n\n@Component({\n  selector: 'df-prime-radio',\n  imports: [PrimeRadioGroupComponent, FormField, DynamicTextPipe, AsyncPipe],\n  styleUrl: '../../styles/_form-field.scss',\n  hostDirectives: [NgForgeFieldHost],\n  template: `\n    @let f = ngf.field();\n    @if (ngf.label()) {\n      <div class=\"radio-label\">{{ ngf.label() | dynamicText | async }}</div>\n    }\n\n    <df-prime-radio-group [formField]=\"f\" [options]=\"options()\" [properties]=\"props()\" />\n\n    @if (ngf.errorsToDisplay()[0]; as error) {\n      <small class=\"p-error\" [id]=\"ngf.errorId()\" role=\"alert\">{{ error.message }}</small>\n    } @else if (props()?.hint; as hint) {\n      <small class=\"p-hint\" [id]=\"ngf.hintId()\" [attr.hidden]=\"f().hidden() || null\">{{ hint | dynamicText | async }}</small>\n    }\n  `,\n  styles: [\n    `\n      :host {\n        display: block;\n      }\n\n      :host([hidden]) {\n        display: none !important;\n      }\n\n      .radio-label {\n        margin-bottom: 0.5rem;\n        font-weight: 500;\n      }\n    `,\n  ],\n  changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport default class PrimeRadioFieldComponent {\n  protected readonly ngf = injectNgForgeField<ValueType>();\n\n  readonly options = input<FieldOption<ValueType>[]>([]);\n  readonly props = input<PrimeRadioProps>();\n}\n","import { ChangeDetectionStrategy, Component, computed, inject, input, model } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { FormValueControl } from '@angular/forms/signals';\nimport { FieldOption, ValueType } from '@ng-forge/dynamic-forms';\nimport { NgForgeField, NgForgeHostControl } from '@ng-forge/dynamic-forms/integration';\nimport { Select, SelectChangeEvent } from 'primeng/select';\nimport { MultiSelect, MultiSelectChangeEvent } from 'primeng/multiselect';\n\n/**\n * PrimeNG Select/MultiSelect wrapper implementing FormValueControl. Rendered\n * inside `df-prime-select` — `NgForgeHostControl` claims the ambient parent\n * NgForgeField for meta + aria. Standalone use lands `aria-invalid=\"false\"`\n * with no `aria-required` / `aria-describedby`.\n */\n@Component({\n  selector: 'df-prime-select-control',\n  imports: [Select, MultiSelect, FormsModule],\n  hostDirectives: [NgForgeHostControl],\n  template: `\n    @if (multiple()) {\n      <p-multiSelect\n        [inputId]=\"inputId()\"\n        [ngModel]=\"multiValue()\"\n        (onChange)=\"onMultiSelectChange($event)\"\n        [options]=\"options()\"\n        optionLabel=\"label\"\n        optionValue=\"value\"\n        [placeholder]=\"placeholder()\"\n        [disabled]=\"disabled()\"\n        [invalid]=\"ariaInvalid()\"\n        [filter]=\"filter()\"\n        [showClear]=\"showClear()\"\n        [styleClass]=\"styleClass()\"\n        [attr.aria-invalid]=\"ariaInvalid()\"\n        [attr.aria-required]=\"ariaRequired()\"\n        [attr.aria-describedby]=\"ariaDescribedBy()\"\n        (onBlur)=\"onBlur()\"\n        (onHide)=\"onBlur()\"\n      />\n    } @else {\n      <p-select\n        [inputId]=\"inputId()\"\n        [ngModel]=\"value()\"\n        (onChange)=\"onSelectChange($event)\"\n        [options]=\"options()\"\n        optionLabel=\"label\"\n        optionValue=\"value\"\n        [placeholder]=\"placeholder()\"\n        [disabled]=\"disabled()\"\n        [invalid]=\"ariaInvalid()\"\n        [filter]=\"filter()\"\n        [showClear]=\"showClear()\"\n        [styleClass]=\"styleClass()\"\n        [attr.aria-invalid]=\"ariaInvalid()\"\n        [attr.aria-required]=\"ariaRequired()\"\n        [attr.aria-describedby]=\"ariaDescribedBy()\"\n        (onBlur)=\"onBlur()\"\n        (onHide)=\"onBlur()\"\n      />\n    }\n  `,\n  changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class PrimeSelectControlComponent implements FormValueControl<ValueType> {\n  // Ambient parent NgForgeField — feeds aria fallback for inner <p-select> bindings.\n  private readonly parentField = inject(NgForgeField, { optional: true });\n\n  // ─────────────────────────────────────────────────────────────────────────────\n  // FormValueControl implementation\n  // ─────────────────────────────────────────────────────────────────────────────\n\n  /** The value of the select - required by FormValueControl */\n  readonly value = model<ValueType>(undefined as unknown as ValueType);\n\n  /** Tracks whether the field has been touched - used by FormField directive */\n  readonly touched = model<boolean>(false);\n\n  /** Whether the field is disabled */\n  readonly disabled = input<boolean>(false);\n\n  /** Whether the field is readonly */\n  readonly readonly = input<boolean>(false);\n\n  /** Whether the field is invalid (from FormField directive) */\n  readonly invalid = input<boolean>(false);\n\n  /** Whether the field is required (from FormField directive) */\n  readonly required = input<boolean>(false);\n\n  // ─────────────────────────────────────────────────────────────────────────────\n  // PrimeNG Select-specific props\n  // ─────────────────────────────────────────────────────────────────────────────\n\n  readonly inputId = input<string>('');\n  readonly placeholder = input<string>('');\n  readonly options = input<FieldOption<ValueType>[]>([]);\n  readonly multiple = input<boolean>(false);\n  readonly filter = input<boolean>(false);\n  readonly showClear = input<boolean>(false);\n  readonly styleClass = input<string>('');\n\n  // Aria signals read from the ambient parent NgForgeField. Standalone use\n  // (no parent) lands `false` / `null`.\n  protected readonly ariaInvalid = computed<boolean>(() => this.parentField?.ariaInvalid() ?? false);\n  protected readonly ariaRequired = computed<true | null>(() => this.parentField?.ariaRequired() ?? null);\n  protected readonly ariaDescribedBy = computed<string | null>(() => this.parentField?.ariaDescribedBy() ?? null);\n\n  // ─────────────────────────────────────────────────────────────────────────────\n  // Multi-select value handling\n  // ─────────────────────────────────────────────────────────────────────────────\n\n  /** Computed to cast value as array for multi-select */\n  protected readonly multiValue = computed(() => {\n    const val = this.value();\n    return Array.isArray(val) ? val : [];\n  });\n\n  /** Handles single select change event */\n  onSelectChange(event: SelectChangeEvent): void {\n    this.value.set(event.value);\n  }\n\n  /** Handles multi select change event */\n  onMultiSelectChange(event: MultiSelectChangeEvent): void {\n    // Store as array for multi-select - cast to ValueType since that's what the field expects\n    this.value.set(event.value as unknown as ValueType);\n  }\n\n  /** Marks the field as touched when select loses focus */\n  onBlur(): void {\n    this.touched.set(true);\n    this.parentField?.field()().markAsTouched();\n  }\n}\n","import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';\nimport { FormField } from '@angular/forms/signals';\nimport { FieldOption, ValueType } from '@ng-forge/dynamic-forms';\nimport { DynamicTextPipe } from '@ng-forge/dynamic-forms/integration';\nimport { injectNgForgeField, NgForgeFieldHost } from '@ng-forge/dynamic-forms/integration';\nimport { AsyncPipe } from '@angular/common';\nimport { PrimeSelectProps } from './prime-select.type';\nimport { PrimeSelectControlComponent } from './prime-select-control.component';\n\n@Component({\n  selector: 'df-prime-select',\n  imports: [FormField, PrimeSelectControlComponent, DynamicTextPipe, AsyncPipe],\n  styleUrl: '../../styles/_form-field.scss',\n  hostDirectives: [NgForgeFieldHost],\n  template: `\n    <div class=\"df-prime-field\">\n      @if (ngf.label(); as label) {\n        <label [for]=\"ngf.key() + '-select'\" class=\"df-prime-label\">{{ label | dynamicText | async }}</label>\n      }\n\n      <df-prime-select-control\n        [formField]=\"ngf.field()\"\n        [inputId]=\"ngf.key() + '-select'\"\n        [options]=\"options()\"\n        [placeholder]=\"(ngf.placeholder() | dynamicText | async) ?? ''\"\n        [multiple]=\"isMultiple()\"\n        [filter]=\"props()?.filter ?? false\"\n        [showClear]=\"props()?.showClear ?? false\"\n        [styleClass]=\"selectClasses()\"\n      />\n\n      @if (ngf.errorsToDisplay()[0]; as error) {\n        <small class=\"p-error\" [id]=\"ngf.errorId()\" role=\"alert\">{{ error.message }}</small>\n      } @else if (props()?.hint; as hint) {\n        <small class=\"df-prime-hint\" [id]=\"ngf.hintId()\">{{ hint | dynamicText | async }}</small>\n      }\n    </div>\n  `,\n  changeDetection: ChangeDetectionStrategy.OnPush,\n  styles: [\n    `\n      :host([hidden]) {\n        display: none !important;\n      }\n    `,\n  ],\n})\nexport default class PrimeSelectFieldComponent {\n  protected readonly ngf = injectNgForgeField<ValueType>();\n\n  readonly options = input<FieldOption<ValueType>[]>([]);\n  readonly props = input<PrimeSelectProps>();\n\n  protected readonly isMultiple = computed(() => this.props()?.multiple ?? false);\n\n  protected readonly selectClasses = computed(() => {\n    const classes: string[] = [];\n    const styleClass = this.props()?.styleClass;\n    if (styleClass) {\n      classes.push(styleClass);\n    }\n    // Note: p-invalid is handled by [invalid] input binding, not manual class\n    return classes.join(' ');\n  });\n}\n","import { ChangeDetectionStrategy, Component, input } from '@angular/core';\nimport { FormField } from '@angular/forms/signals';\nimport { DynamicTextPipe } from '@ng-forge/dynamic-forms/integration';\nimport { NgForgeControl, injectNgForgeField, NgForgeFieldHost } from '@ng-forge/dynamic-forms/integration';\nimport { PrimeSliderProps } from './prime-slider.type';\nimport { AsyncPipe } from '@angular/common';\nimport { Slider } from 'primeng/slider';\n\n@Component({\n  selector: 'df-prime-slider',\n  imports: [Slider, FormField, DynamicTextPipe, AsyncPipe, NgForgeControl],\n  styleUrl: '../../styles/_form-field.scss',\n  hostDirectives: [NgForgeFieldHost],\n  template: `\n    @let f = ngf.field();\n    @let inputId = ngf.key() + '-input';\n\n    <div class=\"df-prime-field\">\n      @if (ngf.label(); as label) {\n        <label [for]=\"inputId\" class=\"df-prime-label\">{{ label | dynamicText | async }}</label>\n      }\n\n      <p-slider\n        ngForgeControl\n        [id]=\"inputId\"\n        [formField]=\"f\"\n        [min]=\"f().min?.() ?? props()?.min ?? 0\"\n        [max]=\"f().max?.() ?? props()?.max ?? 100\"\n        [step]=\"step() ?? props()?.step ?? 1\"\n        [range]=\"props()?.range || false\"\n        [orientation]=\"props()?.orientation || 'horizontal'\"\n        [attr.tabindex]=\"ngf.tabIndex()\"\n        [styleClass]=\"props()?.styleClass ?? ''\"\n      />\n\n      @if (ngf.errorsToDisplay()[0]; as error) {\n        <small class=\"p-error\" [id]=\"ngf.errorId()\" role=\"alert\">{{ error.message }}</small>\n      } @else if (props()?.hint; as hint) {\n        <small class=\"p-hint\" [id]=\"ngf.hintId()\">{{ hint | dynamicText | async }}</small>\n      }\n    </div>\n  `,\n  changeDetection: ChangeDetectionStrategy.OnPush,\n  styles: [\n    `\n      :host([hidden]) {\n        display: none !important;\n      }\n    `,\n  ],\n})\nexport default class PrimeSliderFieldComponent {\n  protected readonly ngf = injectNgForgeField<number>();\n\n  readonly step = input<number>();\n  readonly props = input<PrimeSliderProps>();\n}\n","import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';\nimport { AsyncPipe } from '@angular/common';\nimport { ButtonDirective } from 'primeng/button';\nimport { FormEvent } from '@ng-forge/dynamic-forms';\nimport { DynamicTextPipe } from '@ng-forge/dynamic-forms/integration';\nimport { injectNgForgeAction, NgForgeActionHost } from '@ng-forge/dynamic-forms/integration';\nimport { PrimeButtonProps } from './prime-button.type';\n\n@Component({\n  selector: 'df-prime-button',\n  imports: [ButtonDirective, DynamicTextPipe, AsyncPipe],\n  hostDirectives: [NgForgeActionHost],\n  template: `\n    <button\n      pButton\n      [type]=\"buttonType()\"\n      [severity]=\"props()?.severity || 'primary'\"\n      [text]=\"props()?.text || false\"\n      [outlined]=\"props()?.outlined || false\"\n      [raised]=\"props()?.raised || false\"\n      [rounded]=\"props()?.rounded || false\"\n      [disabled]=\"action.disabled()\"\n      [attr.tabindex]=\"action.tabIndex()\"\n      [attr.data-testid]=\"buttonTestId()\"\n      (click)=\"onClick()\"\n    >\n      {{ action.label() | dynamicText | async }}\n    </button>\n  `,\n  changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport default class PrimeButtonFieldComponent<TEvent extends FormEvent> {\n  protected readonly action = injectNgForgeAction<TEvent>();\n\n  readonly props = input<PrimeButtonProps>();\n\n  readonly buttonType = computed(() => this.props()?.type ?? 'button');\n\n  readonly buttonTestId = computed(() => `${this.buttonType()}-${this.action.key()}`);\n\n  onClick(): void {\n    if (this.buttonType() === 'submit') return;\n    this.action.dispatch();\n  }\n}\n","import { ChangeDetectionStrategy, Component, computed, ElementRef, inject, input, model } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { FormValueControl } from '@angular/forms/signals';\nimport { NgForgeField, setupMetaTracking, TextareaMeta } from '@ng-forge/dynamic-forms/integration';\nimport { TextareaModule } from 'primeng/textarea';\n\n/**\n * PrimeNG textarea wrapper implementing FormValueControl. Rendered inside\n * `df-prime-textarea` — picks up meta + aria from the ambient parent\n * NgForgeField via `setupMetaTracking` (selector: `'textarea'`).\n */\n@Component({\n  selector: 'df-prime-textarea-control',\n  imports: [TextareaModule, FormsModule],\n  template: `\n    <textarea\n      pInputTextarea\n      [id]=\"inputId()\"\n      [ngModel]=\"value()\"\n      (ngModelChange)=\"value.set($event)\"\n      [placeholder]=\"placeholder()\"\n      [attr.minlength]=\"minLength()\"\n      [attr.maxlength]=\"maxLength()\"\n      [attr.tabindex]=\"tabIndex()\"\n      [autoResize]=\"autoResize()\"\n      [disabled]=\"disabled()\"\n      [readonly]=\"readonly()\"\n      [invalid]=\"ariaInvalid()\"\n      [class]=\"styleClass()\"\n      [attr.aria-invalid]=\"ariaInvalid()\"\n      [attr.aria-required]=\"ariaRequired()\"\n      [attr.aria-describedby]=\"ariaDescribedBy()\"\n      (blur)=\"onBlur()\"\n    ></textarea>\n  `,\n  changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class PrimeTextareaControlComponent implements FormValueControl<string> {\n  private readonly elementRef = inject(ElementRef<HTMLElement>);\n  private readonly parentField = inject(NgForgeField, { optional: true });\n\n  // ─────────────────────────────────────────────────────────────────────────────\n  // FormValueControl implementation\n  // ─────────────────────────────────────────────────────────────────────────────\n\n  /** The value of the textarea - required by FormValueControl */\n  readonly value = model<string>('');\n\n  /** Tracks whether the field has been touched - used by Field directive */\n  readonly touched = model<boolean>(false);\n\n  /** Whether the field is disabled */\n  readonly disabled = input<boolean>(false);\n\n  /** Whether the field is readonly */\n  readonly readonly = input<boolean>(false);\n\n  /** Whether the field is invalid (from Field directive) */\n  readonly invalid = input<boolean>(false);\n\n  /** Whether the field is required (from Field directive) */\n  readonly required = input<boolean>(false);\n\n  // ─────────────────────────────────────────────────────────────────────────────\n  // PrimeNG-specific props\n  // ─────────────────────────────────────────────────────────────────────────────\n\n  /** Id forwarded onto the inner <textarea> so the parent `<label [for]>` resolves correctly. */\n  readonly inputId = input<string>('');\n  readonly placeholder = input<string>('');\n  readonly rows = input<number>(4);\n  readonly cols = input<number | undefined>(undefined);\n  // Length-validator → DOM wiring uses Signal Forms's setInputOnDirectives to copy\n  // FieldState.maxLength/minLength onto these camelCase-named inputs automatically.\n  // The match must be exact-case — renaming these to lowercase would silently break the\n  // wiring. The Ionic adapter takes the alternate strategy (direct template binding)\n  // because <ion-input> / <ion-textarea> use lowercase property names we cannot rename.\n  // See packages/dynamic-forms-ionic/src/lib/fields/input/ionic-input.component.ts.\n  readonly maxLength = input<number | undefined>(undefined);\n  readonly minLength = input<number | undefined>(undefined);\n  readonly tabIndex = input<number | undefined>(undefined);\n  readonly autoResize = input<boolean>(false);\n  readonly styleClass = input<string>('');\n\n  // Meta + aria-describedby read from the ambient parent NgForgeField.\n  protected readonly meta = computed<TextareaMeta | undefined>(() => this.parentField?.meta() as TextareaMeta | undefined);\n  protected readonly ariaDescribedBy = computed<string | null>(() => this.parentField?.ariaDescribedBy() ?? null);\n\n  // Aria signals read from the ambient parent NgForgeField — matches the\n  // pattern in prime-datepicker-control / prime-select-control. Standalone\n  // use (no parent) lands false / null.\n  protected readonly ariaInvalid = computed<boolean>(() => this.parentField?.ariaInvalid() ?? false);\n  protected readonly ariaRequired = computed<true | null>(() => this.parentField?.ariaRequired() ?? null);\n\n  constructor() {\n    this.parentField?.markClaimed();\n    setupMetaTracking(this.elementRef, this.meta, { selector: 'textarea' });\n  }\n\n  /** Marks the field as touched when textarea loses focus */\n  onBlur(): void {\n    this.touched.set(true);\n    this.parentField?.field()().markAsTouched();\n  }\n}\n","import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';\nimport { FormField } from '@angular/forms/signals';\nimport { DynamicTextPipe } from '@ng-forge/dynamic-forms/integration';\nimport { injectNgForgeField, NgForgeFieldHost } from '@ng-forge/dynamic-forms/integration';\nimport { PrimeTextareaProps } from './prime-textarea.type';\nimport { AsyncPipe } from '@angular/common';\nimport { PrimeTextareaControlComponent } from './prime-textarea-control.component';\n\n@Component({\n  selector: 'df-prime-textarea',\n  imports: [DynamicTextPipe, AsyncPipe, FormField, PrimeTextareaControlComponent],\n  styleUrl: '../../styles/_form-field.scss',\n  hostDirectives: [NgForgeFieldHost],\n  template: `\n    <div class=\"df-prime-field\">\n      @if (ngf.label()) {\n        <label [for]=\"inputId()\" class=\"df-prime-label\">{{ ngf.label() | dynamicText | async }}</label>\n      }\n\n      <df-prime-textarea-control\n        [inputId]=\"inputId()\"\n        [formField]=\"ngf.field()\"\n        [placeholder]=\"(ngf.placeholder() | dynamicText | async) ?? ''\"\n        [rows]=\"props()?.rows || 4\"\n        [cols]=\"props()?.cols\"\n        [tabIndex]=\"ngf.tabIndex()\"\n        [autoResize]=\"props()?.autoResize ?? false\"\n        [styleClass]=\"textareaClasses()\"\n      />\n\n      @if (ngf.errorsToDisplay()[0]; as error) {\n        <small class=\"p-error\" [id]=\"ngf.errorId()\" role=\"alert\">{{ error.message }}</small>\n      } @else if (props()?.hint; as hint) {\n        <small class=\"df-prime-hint\" [id]=\"ngf.hintId()\">{{ hint | dynamicText | async }}</small>\n      }\n    </div>\n  `,\n  changeDetection: ChangeDetectionStrategy.OnPush,\n  styles: [\n    `\n      :host([hidden]) {\n        display: none !important;\n      }\n    `,\n  ],\n})\nexport default class PrimeTextareaFieldComponent {\n  protected readonly ngf = injectNgForgeField<string>();\n\n  readonly props = input<PrimeTextareaProps>();\n\n  protected readonly textareaClasses = computed(() => this.props()?.styleClass ?? '');\n\n  protected readonly inputId = computed(() => `${this.ngf.key()}-textarea`);\n}\n","import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';\nimport { FormField } from '@angular/forms/signals';\nimport { DynamicTextPipe } from '@ng-forge/dynamic-forms/integration';\nimport { NgForgeControl, injectNgForgeField, NgForgeFieldHost } from '@ng-forge/dynamic-forms/integration';\nimport { PrimeToggleProps } from './prime-toggle.type';\nimport { AsyncPipe } from '@angular/common';\nimport { ToggleSwitch } from 'primeng/toggleswitch';\n\n@Component({\n  selector: 'df-prime-toggle',\n  imports: [ToggleSwitch, DynamicTextPipe, AsyncPipe, FormField, NgForgeControl],\n  styleUrl: '../../styles/_form-field.scss',\n  hostDirectives: [NgForgeFieldHost],\n  template: `\n    <div class=\"df-prime-field\">\n      @if (ngf.label()) {\n        <label [for]=\"ngf.key() + '-toggle'\" class=\"df-prime-label\">{{ ngf.label() | dynamicText | async }}</label>\n      }\n\n      <p-toggleSwitch\n        ngForgeControl=\"input[type='checkbox']\"\n        [inputId]=\"ngf.key() + '-toggle'\"\n        [formField]=\"ngf.field()\"\n        [tabindex]=\"ngf.tabIndex() ?? 0\"\n        [trueValue]=\"true\"\n        [falseValue]=\"false\"\n        [styleClass]=\"toggleClasses()\"\n      />\n\n      @if (ngf.errorsToDisplay()[0]; as error) {\n        <small class=\"p-error\" [id]=\"ngf.errorId()\" role=\"alert\">{{ error.message }}</small>\n      } @else if (props()?.hint; as hint) {\n        <small class=\"p-hint\" [id]=\"ngf.hintId()\">{{ hint | dynamicText | async }}</small>\n      }\n    </div>\n  `,\n  changeDetection: ChangeDetectionStrategy.OnPush,\n  styles: [\n    `\n      :host([hidden]) {\n        display: none !important;\n      }\n    `,\n  ],\n})\nexport default class PrimeToggleFieldComponent {\n  protected readonly ngf = injectNgForgeField<boolean>();\n\n  readonly props = input<PrimeToggleProps>();\n\n  protected readonly toggleClasses = computed(() => {\n    const classes: string[] = [];\n    const styleClass = this.props()?.styleClass;\n    if (styleClass) {\n      classes.push(styleClass);\n    }\n    return classes.join(' ');\n  });\n}\n","/**\n * All PrimeNG field types supported by the dynamic form library.\n * These constants are used to identify field types in the configuration.\n */\nexport const PrimeField = {\n  Input: 'input',\n  Select: 'select',\n  Checkbox: 'checkbox',\n  Button: 'button',\n  Submit: 'submit',\n  Next: 'next',\n  Previous: 'previous',\n  AddArrayItem: 'add-array-item',\n  PrependArrayItem: 'prepend-array-item',\n  InsertArrayItem: 'insert-array-item',\n  RemoveArrayItem: 'remove-array-item',\n  PopArrayItem: 'pop-array-item',\n  ShiftArrayItem: 'shift-array-item',\n  Textarea: 'textarea',\n  Radio: 'radio',\n  MultiCheckbox: 'multi-checkbox',\n  Datepicker: 'datepicker',\n  Slider: 'slider',\n  Toggle: 'toggle',\n} as const;\n\nexport type PrimeFieldType = (typeof PrimeField)[keyof typeof PrimeField];\n","import { computed, inject, isSignal, Signal } from '@angular/core';\nimport { FieldDef } from '@ng-forge/dynamic-forms';\nimport { ARRAY_CONTEXT, buildBaseInputs, DEFAULT_PROPS, injectNonFieldLogicResolver } from '@ng-forge/dynamic-forms/integration';\n\n/**\n * Generic button mapper for custom events or basic buttons.\n * For specific button types (submit, next, prev, add/remove array items),\n * use the dedicated field types and their specific mappers.\n *\n * @param fieldDef The button field definition\n * @returns Signal containing Record of input names to values for ngComponentOutlet\n */\nexport function buttonFieldMapper(fieldDef: FieldDef<Record<string, unknown>>): Signal<Record<string, unknown>> {\n  const defaultProps = inject(DEFAULT_PROPS);\n  const arrayContext = inject(ARRAY_CONTEXT, { optional: true });\n  const resolveLogic = injectNonFieldLogicResolver(fieldDef);\n\n  return computed(() => {\n    const baseInputs = buildBaseInputs(fieldDef, defaultProps());\n\n    const inputs: Record<string, unknown> = {\n      ...baseInputs,\n      ...resolveLogic(),\n    };\n\n    // Add event binding for button events\n    if ('event' in fieldDef && fieldDef.event !== undefined) {\n      inputs['event'] = fieldDef.event;\n    }\n\n    // Add eventArgs binding if provided\n    if ('eventArgs' in fieldDef && fieldDef.eventArgs !== undefined) {\n      inputs['eventArgs'] = fieldDef.eventArgs;\n    }\n\n    // Add eventContext for token resolution (supports $template, $arrayKey, $index, etc.)\n    const template = 'template' in fieldDef ? fieldDef.template : undefined;\n    if (template || arrayContext) {\n      // Read signal value if index is a signal (supports differential updates)\n      const getIndex = () => {\n        if (!arrayContext) return -1;\n        return isSignal(arrayContext.index) ? arrayContext.index() : arrayContext.index;\n      };\n\n      inputs['eventContext'] = {\n        key: fieldDef.key,\n        index: getIndex(),\n        arrayKey: arrayContext?.arrayKey ?? '',\n        formValue: arrayContext?.formValue ?? {},\n        template,\n      };\n    }\n\n    return inputs;\n  });\n}\n","import { FieldTypeDefinition } from '@ng-forge/dynamic-forms/integration';\nimport {\n  addArrayItemButtonMapper,\n  checkboxFieldMapper,\n  datepickerFieldMapper,\n  insertArrayItemButtonMapper,\n  optionsFieldMapper,\n  popArrayItemButtonMapper,\n  prependArrayItemButtonMapper,\n  removeArrayItemButtonMapper,\n  shiftArrayItemButtonMapper,\n  valueFieldMapper,\n} from '@ng-forge/dynamic-forms/integration';\nimport { PrimeField } from '../types/types';\nimport { buttonFieldMapper } from '../fields/button/prime-button.mapper';\nimport { nextButtonFieldMapper, previousButtonFieldMapper, submitButtonFieldMapper } from '../fields/button/prime-specific-button.mapper';\n\nconst VALUE_FIELD_TYPES_BASE = {\n  renderReadyWhen: ['field'],\n} as const;\n\nconst BUTTON_FIELD_TYPES_BASE = {\n  renderReadyWhen: [],\n  valueHandling: 'exclude',\n} as const;\n\n/**\n * PrimeNG field type definitions\n * Follows the FieldTypeDefinition interface for proper registry integration\n */\nexport const PRIMENG_FIELD_TYPES: FieldTypeDefinition[] = [\n  {\n    name: PrimeField.Input,\n    loadComponent: () => import('../fields/input/prime-input.component'),\n    mapper: valueFieldMapper,\n    propsToMeta: ['type'],\n    scope: ['text-input', 'numeric'],\n    addons: {\n      slots: ['prefix', 'suffix'],\n    },\n    ...VALUE_FIELD_TYPES_BASE,\n  },\n  {\n    name: PrimeField.Select,\n    loadComponent: () => import('../fields/select/prime-select.component'),\n    mapper: optionsFieldMapper,\n    scope: 'single-select',\n    ...VALUE_FIELD_TYPES_BASE,\n  },\n  {\n    name: PrimeField.Checkbox,\n    loadComponent: () => import('../fields/checkbox/prime-checkbox.component'),\n    mapper: checkboxFieldMapper,\n    scope: 'boolean',\n    ...VALUE_FIELD_TYPES_BASE,\n  },\n  {\n    name: PrimeField.Button,\n    loadComponent: () => import('../fields/button/prime-button.component'),\n    mapper: buttonFieldMapper,\n    ...BUTTON_FIELD_TYPES_BASE,\n  },\n  {\n    name: PrimeField.Submit,\n    loadComponent: () => import('../fields/button/prime-button.component'),\n    mapper: submitButtonFieldMapper,\n    ...BUTTON_FIELD_TYPES_BASE,\n  },\n  {\n    name: PrimeField.Next,\n    loadComponent: () => import('../fields/button/prime-button.component'),\n    mapper: nextButtonFieldMapper,\n    ...BUTTON_FIELD_TYPES_BASE,\n  },\n  {\n    name: PrimeField.Previous,\n    loadComponent: () => import('../fields/button/prime-button.component'),\n    mapper: previousButtonFieldMapper,\n    ...BUTTON_FIELD_TYPES_BASE,\n  },\n  {\n    name: PrimeField.AddArrayItem,\n    loadComponent: () => import('../fields/button/prime-button.component'),\n    mapper: addArrayItemButtonMapper,\n    ...BUTTON_FIELD_TYPES_BASE,\n  },\n  {\n    name: PrimeField.PrependArrayItem,\n    loadComponent: () => import('../fields/button/prime-button.component'),\n    mapper: prependArrayItemButtonMapper,\n    ...BUTTON_FIELD_TYPES_BASE,\n  },\n  {\n    name: PrimeField.InsertArrayItem,\n    loadComponent: () => import('../fields/button/prime-button.component'),\n    mapper: insertArrayItemButtonMapper,\n    ...BUTTON_FIELD_TYPES_BASE,\n  },\n  {\n    name: PrimeField.RemoveArrayItem,\n    loadComponent: () => import('../fields/button/prime-button.component'),\n    mapper: removeArrayItemButtonMapper,\n    ...BUTTON_FIELD_TYPES_BASE,\n  },\n  {\n    name: PrimeField.PopArrayItem,\n    loadComponent: () => import('../fields/button/prime-button.component'),\n    mapper: popArrayItemButtonMapper,\n    ...BUTTON_FIELD_TYPES_BASE,\n  },\n  {\n    name: PrimeField.ShiftArrayItem,\n    loadComponent: () => import('../fields/button/prime-button.component'),\n    mapper: shiftArrayItemButtonMapper,\n    ...BUTTON_FIELD_TYPES_BASE,\n  },\n  {\n    name: PrimeField.Textarea,\n    loadComponent: () => import('../fields/textarea/prime-textarea.component'),\n    mapper: valueFieldMapper,\n    propsToMeta: ['rows', 'cols'],\n    scope: 'text-input',\n    ...VALUE_FIELD_TYPES_BASE,\n  },\n  {\n    name: PrimeField.Radio,\n    loadComponent: () => import('../fields/radio/prime-radio.component'),\n    mapper: optionsFieldMapper,\n    scope: 'single-select',\n    ...VALUE_FIELD_TYPES_BASE,\n  },\n  {\n    name: PrimeField.MultiCheckbox,\n    loadComponent: () => import('../fields/multi-checkbox/prime-multi-checkbox.component'),\n    mapper: optionsFieldMapper,\n    scope: 'multi-select',\n    ...VALUE_FIELD_TYPES_BASE,\n  },\n  {\n    name: PrimeField.Datepicker,\n    loadComponent: () => import('../fields/datepicker/prime-datepicker.component'),\n    mapper: datepickerFieldMapper,\n    scope: 'date',\n    ...VALUE_FIELD_TYPES_BASE,\n  },\n  {\n    name: PrimeField.Slider,\n    loadComponent: () => import('../fields/slider/prime-slider.component'),\n    mapper: valueFieldMapper,\n    scope: 'numeric',\n    ...VALUE_FIELD_TYPES_BASE,\n  },\n  {\n    name: PrimeField.Toggle,\n    loadComponent: () => import('../fields/toggle/prime-toggle.component'),\n    mapper: checkboxFieldMapper,\n    scope: 'boolean',\n    ...VALUE_FIELD_TYPES_BASE,\n  },\n];\n","import type { Provider } from '@angular/core';\nimport { DynamicFormError, type AddonTypeDefinition } from '@ng-forge/dynamic-forms';\nimport { ADDON_TYPE_DEFINITIONS, type FieldTypeDefinition } from '@ng-forge/dynamic-forms/integration';\nimport { PRIMENG_FIELD_TYPES } from '../config/primeng-field-config';\nimport { PrimeNGConfig } from '../models/primeng-config';\nimport { PRIMENG_CONFIG } from '../models/primeng-config.token';\nimport type { PrimeButtonAddon, PrimeIconAddon } from '../types/addons';\n\n/** Field type definitions for PrimeNG components. */\nexport type PrimeNGFieldTypes = FieldTypeDefinition[];\n\ntype PrimeNGConfigFeature = {\n  ɵkind: 'primeng-config';\n  ɵproviders: Provider[];\n};\n\n/**\n * Default `withPrimeNGFields()` shape — field defs + the auto-included\n * addons feature so `prime-icon` / `prime-button` work out of the box.\n */\ntype PrimeNGFieldsWithAddons = [...PrimeNGFieldTypes, PrimeNGAddonsFeature];\n\ntype PrimeNGFieldsWithConfig = [...PrimeNGFieldTypes, PrimeNGAddonsFeature, PrimeNGConfigFeature];\n\n/**\n * Provides PrimeNG field type definitions for the dynamic form system,\n * with PrimeNG-shipped addon types (`prime-icon`, `prime-button`) auto-included\n * so addons work out of the box.\n *\n * @param config - Optional global configuration for PrimeNG form fields\n * @returns Tuple of field type definitions, the addons feature, and\n *   optionally a config feature.\n */\nexport function withPrimeNGFields(): PrimeNGFieldsWithAddons;\nexport function withPrimeNGFields(config: PrimeNGConfig): PrimeNGFieldsWithConfig;\nexport function withPrimeNGFields(config: PrimeNGConfig | undefined): PrimeNGFieldsWithAddons | PrimeNGFieldsWithConfig;\nexport function withPrimeNGFields(config?: PrimeNGConfig): PrimeNGFieldsWithAddons | PrimeNGFieldsWithConfig {\n  // Always include the addons feature — prime-icon / prime-button are part of\n  // the canonical PrimeNG surface.\n  const base: unknown[] = [...PRIMENG_FIELD_TYPES, withPrimeNGAddons()];\n\n  if (config) {\n    base.push({\n      ɵkind: 'primeng-config',\n      ɵproviders: [{ provide: PRIMENG_CONFIG, useValue: config }],\n    } satisfies PrimeNGConfigFeature);\n    return base as PrimeNGFieldsWithConfig;\n  }\n\n  return base as PrimeNGFieldsWithAddons;\n}\n\n/* -- PrimeNG addon types ----------------------------------------------- */\n\nconst PI_ICON_KIND: AddonTypeDefinition<PrimeIconAddon> = {\n  type: 'prime-icon',\n  loadComponent: () => import('../addons/prime-icon-addon.component').then((m) => m.PrimeIconAddonComponent),\n  validate: (addon, fieldKey) => {\n    if (typeof addon.icon !== 'string' || addon.icon.length === 0) {\n      throw new DynamicFormError(`Addon type 'prime-icon' requires a non-empty 'icon' string (field: '${fieldKey}').`);\n    }\n  },\n};\n\nconst PI_BUTTON_KIND: AddonTypeDefinition<PrimeButtonAddon> = {\n  type: 'prime-button',\n  loadComponent: () => import('../addons/prime-button-addon.component').then((m) => m.PrimeButtonAddonComponent),\n  validate: (addon, fieldKey) => {\n    // Exactly one of preset / actionRef / action — validator drops the addon\n    // (with warning) if the rule is violated.\n    const set = [addon.preset, addon.actionRef, addon.action].filter((v) => v !== undefined);\n    if (set.length > 1) {\n      throw new DynamicFormError(\n        `Addon type 'prime-button' on field '${fieldKey}' has more than one of preset/actionRef/action — exactly one allowed.`,\n      );\n    }\n    // Icon-only buttons require ariaLabel for screen readers.\n    if (addon.icon && !addon.label && !addon.ariaLabel) {\n      throw new DynamicFormError(`Addon type 'prime-button' on field '${fieldKey}' is icon-only — provide 'ariaLabel' for accessibility.`);\n    }\n  },\n};\n\n/**\n * Feature type discriminant for the PrimeNG addons feature. Matches core's\n * `'addons'` type so providers flow through the standard addon-type pipeline\n * in `provideDynamicForm`.\n */\ntype PrimeNGAddonsFeature = {\n  ɵkind: 'addons';\n  ɵproviders: Provider[];\n};\n\n/** Register PrimeNG-shipped addon types (`prime-icon`, `prime-button`) standalone. */\nexport function withPrimeNGAddons(): PrimeNGAddonsFeature {\n  return {\n    ɵkind: 'addons',\n    ɵproviders: [\n      { provide: ADDON_TYPE_DEFINITIONS, useValue: PI_ICON_KIND, multi: true },\n      { provide: ADDON_TYPE_DEFINITIONS, useValue: PI_BUTTON_KIND, multi: true },\n    ],\n  };\n}\n","import { AsyncPipe } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';\nimport { WrapperFieldInputs } from '@ng-forge/dynamic-forms/integration';\nimport { DynamicTextPipe } from '@ng-forge/dynamic-forms/integration';\nimport type { PrimeIconAddon } from '../types/addons';\n\n/** Renderer for the `prime-icon` addon type. */\n@Component({\n  selector: 'df-prime-icon-addon',\n  imports: [AsyncPipe, DynamicTextPipe],\n  template: `<i [class]=\"iconClass()\" [attr.aria-label]=\"(ariaLabel() | dynamicText | async) ?? null\"></i>`,\n  host: {\n    '[attr.aria-hidden]': 'hasAriaLabel() ? null : \"true\"',\n  },\n  changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class PrimeIconAddonComponent {\n  readonly addon = input.required<PrimeIconAddon>();\n  /** Accepted for contract uniformity — `NgComponentOutlet` setInput is strict; every type must declare it. */\n  readonly fieldInputs = input<WrapperFieldInputs | undefined>();\n\n  protected readonly iconClass = computed(() => `pi pi-${this.addon().icon}`);\n  protected readonly ariaLabel = computed(() => this.addon().ariaLabel);\n  protected readonly hasAriaLabel = computed(() => this.addon().ariaLabel !== undefined);\n}\n","import { AsyncPipe } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, computed } from '@angular/core';\nimport { DynamicTextPipe } from '@ng-forge/dynamic-forms/integration';\nimport { injectNgForgeAddonAction, NgForgeAddonAction } from '@ng-forge/dynamic-forms/integration';\nimport { ButtonModule } from 'primeng/button';\nimport type { PrimeButtonAddon } from '../types/addons';\n\n/** Renderer for the `prime-button` addon type. */\n@Component({\n  selector: 'df-prime-button-addon',\n  imports: [ButtonModule, DynamicTextPipe, AsyncPipe],\n  hostDirectives: [NgForgeAddonAction],\n  template: `\n    @if (isIconOnly()) {\n      <p-button\n        [icon]=\"iconClass()\"\n        [severity]=\"addon().severity ?? 'secondary'\"\n        [loading]=\"action.loading()\"\n        [disabled]=\"action.disabled() || action.loading()\"\n        [attr.aria-label]=\"(ariaLabel() | dynamicText | async) ?? null\"\n        [attr.aria-busy]=\"action.loading() || null\"\n        (onClick)=\"action.dispatch()\"\n      />\n    } @else {\n      <p-button\n        [icon]=\"iconClass()\"\n        [label]=\"(label() | dynamicText | async) ?? ''\"\n        [severity]=\"addon().severity ?? 'secondary'\"\n        [loading]=\"action.loading()\"\n        [disabled]=\"action.disabled() || action.loading()\"\n        [attr.aria-label]=\"(ariaLabel() | dynamicText | async) ?? null\"\n        [attr.aria-busy]=\"action.loading() || null\"\n        (onClick)=\"action.dispatch()\"\n      />\n    }\n    @if (action.loading()) {\n      <span class=\"df-prime-sr-only\" role=\"status\">Loading…</span>\n    }\n  `,\n  styles: [\n    `\n      .df-prime-sr-only {\n        position: absolute;\n        width: 1px;\n        height: 1px;\n        padding: 0;\n        margin: -1px;\n        overflow: hidden;\n        clip: rect(0, 0, 0, 0);\n        white-space: nowrap;\n        border: 0;\n      }\n    `,\n  ],\n  changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class PrimeButtonAddonComponent {\n  protected readonly action = injectNgForgeAddonAction<PrimeButtonAddon>();\n\n  /** Re-exposed for template binding — same signal stored on the directive. */\n  protected readonly addon = this.action.addon;\n\n  protected readonly label = computed(() => this.addon().label);\n  protected readonly ariaLabel = computed(() => this.addon().ariaLabel);\n  protected readonly isIconOnly = computed(() => {\n    const a = this.addon();\n    return !!a.icon && !a.label;\n  });\n  protected readonly iconClass = computed(() => {\n    const icon = this.addon().icon;\n    return icon ? `pi pi-${icon}` : '';\n  });\n}\n"]}