@ng-forge/dynamic-forms 0.9.0-next.11 → 0.9.0-next.13

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.
Files changed (33) hide show
  1. package/fesm2022/{ng-forge-dynamic-forms-array-field.component-DJ-LiLm_.mjs → ng-forge-dynamic-forms-array-field.component-Ckpe0rW7.mjs} +158 -73
  2. package/fesm2022/ng-forge-dynamic-forms-array-field.component-Ckpe0rW7.mjs.map +1 -0
  3. package/fesm2022/{ng-forge-dynamic-forms-container-field.component-Pcxg5PQu.mjs → ng-forge-dynamic-forms-container-field.component-BD7Lpcts.mjs} +12 -8
  4. package/fesm2022/ng-forge-dynamic-forms-container-field.component-BD7Lpcts.mjs.map +1 -0
  5. package/fesm2022/{ng-forge-dynamic-forms-container-utils-a4RstR2Z.mjs → ng-forge-dynamic-forms-container-utils-CeHyhb2v.mjs} +2 -2
  6. package/fesm2022/{ng-forge-dynamic-forms-container-utils-a4RstR2Z.mjs.map → ng-forge-dynamic-forms-container-utils-CeHyhb2v.mjs.map} +1 -1
  7. package/fesm2022/{ng-forge-dynamic-forms-css-wrapper.component-CJACCIEK.mjs → ng-forge-dynamic-forms-css-wrapper.component-DkyuJH6T.mjs} +5 -5
  8. package/fesm2022/{ng-forge-dynamic-forms-css-wrapper.component-CJACCIEK.mjs.map → ng-forge-dynamic-forms-css-wrapper.component-DkyuJH6T.mjs.map} +1 -1
  9. package/fesm2022/{ng-forge-dynamic-forms-emit-initialization-Bjf_I0D_.mjs → ng-forge-dynamic-forms-emit-initialization-u4H5jr35.mjs} +2 -2
  10. package/fesm2022/{ng-forge-dynamic-forms-emit-initialization-Bjf_I0D_.mjs.map → ng-forge-dynamic-forms-emit-initialization-u4H5jr35.mjs.map} +1 -1
  11. package/fesm2022/{ng-forge-dynamic-forms-group-field.component-fzKwPrQr.mjs → ng-forge-dynamic-forms-group-field.component-C9xUHrXp.mjs} +15 -11
  12. package/fesm2022/ng-forge-dynamic-forms-group-field.component-C9xUHrXp.mjs.map +1 -0
  13. package/fesm2022/ng-forge-dynamic-forms-integration.mjs +334 -27
  14. package/fesm2022/ng-forge-dynamic-forms-integration.mjs.map +1 -1
  15. package/fesm2022/{ng-forge-dynamic-forms-ng-forge-dynamic-forms-o3rJX4vG.mjs → ng-forge-dynamic-forms-ng-forge-dynamic-forms-BbgkzKuI.mjs} +1941 -407
  16. package/fesm2022/ng-forge-dynamic-forms-ng-forge-dynamic-forms-BbgkzKuI.mjs.map +1 -0
  17. package/fesm2022/ng-forge-dynamic-forms-page-field.component-BwNIx3R1.mjs +114 -0
  18. package/fesm2022/ng-forge-dynamic-forms-page-field.component-BwNIx3R1.mjs.map +1 -0
  19. package/fesm2022/ng-forge-dynamic-forms-row-wrapper.component-CFtnatYj.mjs +34 -0
  20. package/fesm2022/{ng-forge-dynamic-forms-row-wrapper.component-BIvEUoia.mjs.map → ng-forge-dynamic-forms-row-wrapper.component-CFtnatYj.mjs.map} +1 -1
  21. package/fesm2022/{ng-forge-dynamic-forms-text-field.component-B9SK8Vun.mjs → ng-forge-dynamic-forms-text-field.component-CpgtswdO.mjs} +5 -5
  22. package/fesm2022/{ng-forge-dynamic-forms-text-field.component-B9SK8Vun.mjs.map → ng-forge-dynamic-forms-text-field.component-CpgtswdO.mjs.map} +1 -1
  23. package/fesm2022/ng-forge-dynamic-forms.mjs +1 -1
  24. package/package.json +1 -1
  25. package/types/ng-forge-dynamic-forms-integration.d.ts +241 -37
  26. package/types/ng-forge-dynamic-forms.d.ts +2320 -1160
  27. package/fesm2022/ng-forge-dynamic-forms-array-field.component-DJ-LiLm_.mjs.map +0 -1
  28. package/fesm2022/ng-forge-dynamic-forms-container-field.component-Pcxg5PQu.mjs.map +0 -1
  29. package/fesm2022/ng-forge-dynamic-forms-group-field.component-fzKwPrQr.mjs.map +0 -1
  30. package/fesm2022/ng-forge-dynamic-forms-ng-forge-dynamic-forms-o3rJX4vG.mjs.map +0 -1
  31. package/fesm2022/ng-forge-dynamic-forms-page-field.component-BX4R9GGa.mjs +0 -110
  32. package/fesm2022/ng-forge-dynamic-forms-page-field.component-BX4R9GGa.mjs.map +0 -1
  33. package/fesm2022/ng-forge-dynamic-forms-row-wrapper.component-BIvEUoia.mjs +0 -34
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ng-forge-dynamic-forms-group-field.component-C9xUHrXp.mjs","sources":["../../../../packages/dynamic-forms/src/lib/fields/group/group-field.component.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n EnvironmentInjector,\n inject,\n Injector,\n input,\n linkedSignal,\n runInInjectionContext,\n untracked,\n} from '@angular/core';\nimport { DfFieldOutlet } from '../../directives/df-field-outlet/df-field-outlet.directive';\nimport { outputFromObservable, toObservable } from '@angular/core/rxjs-interop';\nimport { explicitEffect } from 'ngxtension/explicit-effect';\nimport { derivedFromDeferred } from '../../utils/derived-from-deferred/derived-from-deferred';\nimport { createFieldResolutionPipe, ResolvedField } from '../../utils/resolve-field/resolve-field';\nimport { computeContainerHostClasses, setupContainerInitEffect } from '../../utils/container-utils/container-utils';\nimport { CONTAINER_FIELD_PROCESSORS } from '../../utils/container-utils/container-field-processors';\nimport { isEqual } from '../../utils/object-utils';\nimport { DynamicFormLogger } from '../../providers/features/logger/logger.token';\nimport { GroupField } from '../../definitions/default/group-field';\nimport { injectFieldRegistry } from '../../utils/inject-field-registry/inject-field-registry';\nimport { FieldTree, form } from '@angular/forms/signals';\nimport { FieldDef } from '../../definitions/base/field-def';\nimport { FieldSignalContext, GroupContext } from '../../mappers/types';\nimport { FIELD_SIGNAL_CONTEXT, GROUP_CONTEXT, injectFieldSignalContext } from '../../models/field-signal-context.token';\nimport { createSchemaFromFields } from '../../core/schema-builder';\nimport { EventBus } from '../../events/event.bus';\nimport { SubmitEvent } from '../../events/constants/submit.event';\n\n/**\n * Container component for rendering nested form groups.\n *\n * Creates a scoped form context with its own validation state.\n * Child fields receive a FIELD_SIGNAL_CONTEXT scoped to this group's form instance.\n * Group values are nested under the group's key in the parent form.\n */\n@Component({\n selector: 'fieldset[group-field]',\n imports: [DfFieldOutlet],\n template: `\n @for (field of resolvedFields(); track field.key) {\n @if (!field.hidden()) {\n <ng-container *dfFieldOutlet=\"field; environmentInjector: environmentInjector\" />\n }\n }\n `,\n styleUrl: './group-field.component.scss',\n host: {\n '[class]': 'hostClasses()',\n role: 'group',\n '[class.disabled]': 'disabled()',\n '[class.df-container-hidden]': 'hidden()',\n '[attr.aria-hidden]': 'hidden() || null',\n // The group element's own id is the plain `key()` — only its DESCENDANTS\n // compose scoped ids via GROUP_CONTEXT (e.g. children of an `address`\n // group render as `address_street`). The group selector is `#address`.\n '[id]': '`${key()}`',\n '[attr.data-testid]': 'key()',\n },\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport default class GroupFieldComponent<TModel extends Record<string, unknown> = Record<string, unknown>> {\n // ─────────────────────────────────────────────────────────────────────────────\n // Dependencies\n // ─────────────────────────────────────────────────────────────────────────────\n\n private readonly destroyRef = inject(DestroyRef);\n private readonly fieldRegistry = injectFieldRegistry();\n private readonly parentFieldSignalContext = injectFieldSignalContext<TModel>();\n private readonly parentGroupContext = inject(GROUP_CONTEXT, { optional: true });\n private readonly injector = inject(Injector);\n protected readonly environmentInjector = inject(EnvironmentInjector);\n private readonly eventBus = inject(EventBus);\n private readonly logger = inject(DynamicFormLogger);\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Memoized Functions\n // ─────────────────────────────────────────────────────────────────────────────\n\n private readonly fieldProcessors = inject(CONTAINER_FIELD_PROCESSORS);\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Inputs\n // ─────────────────────────────────────────────────────────────────────────────\n\n field = input.required<GroupField>();\n key = input.required<string>();\n className = input<string>();\n hidden = input(false);\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Computed Signals\n // ─────────────────────────────────────────────────────────────────────────────\n\n readonly hostClasses = computed(() => computeContainerHostClasses('group', this.className()));\n\n private readonly rawFieldRegistry = computed(() => this.fieldRegistry.raw);\n\n private readonly formSetup = computed(() => {\n const groupField = this.field();\n const registry = this.rawFieldRegistry();\n\n if (groupField.fields && groupField.fields.length > 0) {\n const flattenedFields = this.fieldProcessors.memoizedFlattenFields(groupField.fields, registry);\n const flattenedFieldsForRendering = this.fieldProcessors.memoizedFlattenFieldsForRendering(groupField.fields, registry);\n const fieldsById = this.fieldProcessors.memoizedKeyBy(flattenedFields);\n const defaultValues = this.fieldProcessors.memoizedDefaultValues(fieldsById, registry);\n\n return {\n fields: flattenedFieldsForRendering,\n schemaFields: flattenedFields,\n originalFields: groupField.fields,\n defaultValues,\n registry,\n };\n }\n\n return {\n fields: [],\n schemaFields: [],\n originalFields: [],\n defaultValues: {},\n registry,\n };\n });\n\n readonly defaultValues = linkedSignal(() => this.formSetup().defaultValues);\n\n /**\n * Entity computed from parent value, group key, and defaults.\n * Uses deep equality check to prevent unnecessary updates when\n * object spread creates new references with identical values.\n */\n private readonly entity = linkedSignal(\n () => {\n const parentValue = this.parentFieldSignalContext.value();\n const groupKey = this.field().key;\n const defaults = this.defaultValues();\n const groupValue = (parentValue as Record<string, unknown>)?.[groupKey] || {};\n return { ...defaults, ...groupValue };\n },\n {\n debugName: 'GroupFieldComponent.entity',\n equal: isEqual,\n },\n );\n\n private readonly form = computed(() => {\n return runInInjectionContext(this.injector, () => {\n const setup = this.formSetup();\n\n if (setup.schemaFields.length > 0) {\n const schema = createSchemaFromFields(setup.schemaFields, setup.registry);\n return untracked(() => form(this.entity, schema));\n }\n\n return untracked(() => form(this.entity));\n });\n });\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Public State Signals\n // ─────────────────────────────────────────────────────────────────────────────\n\n readonly formValue = computed(() => this.entity());\n readonly valid = computed(() => this.form()().valid());\n readonly invalid = computed(() => this.form()().invalid());\n readonly dirty = computed(() => this.form()().dirty());\n readonly touched = computed(() => this.form()().touched());\n readonly errors = computed(() => this.form()().errors());\n readonly disabled = computed(() => this.form()().disabled());\n\n private readonly nestedFieldTree = computed((): FieldTree<Record<string, unknown>> | undefined => {\n const parentForm = this.parentFieldSignalContext.form as Record<string, FieldTree<Record<string, unknown>>>;\n const groupKey = this.field().key;\n return parentForm[groupKey];\n });\n\n private readonly groupFieldSignalContext: FieldSignalContext<Record<string, unknown>> = (() => {\n const nestedFieldTree = this.nestedFieldTree;\n return {\n injector: this.injector,\n value: this.parentFieldSignalContext.value,\n defaultValues: this.defaultValues,\n get form() {\n return nestedFieldTree() ?? ({} as FieldTree<Record<string, unknown>>);\n },\n };\n })();\n\n /**\n * Group context propagated to descendants — carries the dot-separated path of\n * group ancestors so child fields can scope their DOM IDs (issue #401).\n * Reactive via `computed()`: a nested group composes its path from the parent\n * context signal + its own key, so the chain stays consistent if either changes.\n */\n private readonly groupContext: GroupContext = {\n groupPath: computed(() => {\n const ownKey = this.field().key;\n const parentPath = this.parentGroupContext?.groupPath();\n return parentPath ? `${parentPath}.${ownKey}` : ownKey;\n }),\n };\n\n private readonly groupInjector = Injector.create({\n parent: this.injector,\n providers: [\n { provide: FIELD_SIGNAL_CONTEXT, useValue: this.groupFieldSignalContext },\n { provide: GROUP_CONTEXT, useValue: this.groupContext },\n ],\n });\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Outputs\n // ─────────────────────────────────────────────────────────────────────────────\n\n readonly validityChange = outputFromObservable(toObservable(this.valid));\n readonly dirtyChange = outputFromObservable(toObservable(this.dirty));\n readonly submitted = outputFromObservable(this.eventBus.on<SubmitEvent>('submit'));\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Field Resolution\n // ─────────────────────────────────────────────────────────────────────────────\n\n private readonly fieldsSource = computed(() => this.formSetup().fields);\n\n protected readonly resolvedFields = derivedFromDeferred(\n this.fieldsSource,\n createFieldResolutionPipe(() => ({\n loadTypeComponent: (type: string) => this.fieldRegistry.loadTypeComponent(type),\n registry: this.rawFieldRegistry(),\n injector: this.groupInjector,\n destroyRef: this.destroyRef,\n onError: (fieldDef: FieldDef<unknown>, error: unknown) => {\n const fieldKey = fieldDef.key || '<no key>';\n this.logger.error(\n `Failed to load component for field type '${fieldDef.type}' (key: ${fieldKey}) ` +\n `within group '${this.field().key}'. Ensure the field type is registered in your field registry.`,\n error,\n );\n },\n })),\n { initialValue: [] as ResolvedField[], injector: this.injector },\n );\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Constructor\n // ─────────────────────────────────────────────────────────────────────────────\n\n constructor() {\n this.setupEffects();\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Private Methods\n // ─────────────────────────────────────────────────────────────────────────────\n\n private setupEffects(): void {\n setupContainerInitEffect(this.resolvedFields, this.eventBus, 'group', () => this.field().key, this.injector);\n\n explicitEffect(\n [this.nestedFieldTree, this.field],\n ([tree, field]) => {\n if (!tree) {\n this.logger.warn(\n `Group field \"${field.key}\" not found in parent form. ` + `Ensure the parent form schema includes this group field.`,\n );\n }\n },\n { defer: true },\n );\n }\n}\n\nexport { GroupFieldComponent };\n"],"names":[],"mappings":"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"}
@@ -1,10 +1,11 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, computed, signal, Injector, isDevMode, afterRenderEffect, input, Directive, untracked, ElementRef, EnvironmentInjector, runInInjectionContext } from '@angular/core';
3
- import { FIELD_SIGNAL_CONTEXT, omit, buildBaseInputs, DEFAULT_PROPS, resolveNonFieldHidden, resolveNonFieldDisabled, RootFormRegistryService, ARRAY_CONTEXT, DynamicFormLogger, AppendArrayItemEvent, PrependArrayItemEvent, InsertArrayItemEvent, RemoveAtIndexEvent, PopArrayItemEvent, ShiftArrayItemEvent, FORM_OPTIONS, resolveSubmitButtonDisabled, resolveNextButtonDisabled, NextPageEvent, PreviousPageEvent, dynamicTextToObservable, interpolateParams, isEqual, applyMetaToElement, DEFAULT_VALIDATION_MESSAGES, EventBus, resolveTokens } from '@ng-forge/dynamic-forms';
2
+ import { inject, computed, signal, Injector, isDevMode, afterRenderEffect, input, Directive, untracked, InjectionToken, ElementRef, EnvironmentInjector, runInInjectionContext } from '@angular/core';
3
+ import { injectFieldSignalContext, omit, buildBaseInputs, DEFAULT_PROPS, resolveNonFieldHidden, resolveNonFieldDisabled, RootFormRegistryService, ARRAY_CONTEXT, DynamicFormLogger, AppendArrayItemEvent, PrependArrayItemEvent, InsertArrayItemEvent, RemoveAtIndexEvent, PopArrayItemEvent, ShiftArrayItemEvent, FORM_OPTIONS, resolveSubmitButtonDisabled, resolveNextButtonDisabled, NextPageEvent, PreviousPageEvent, dynamicTextToObservable, interpolateParams, isEqual, applyMetaToElement, DEFAULT_VALIDATION_MESSAGES, EventBus, resolveTokens, resolveDynamicValue, ADDON_ACTION_REGISTRY, writeToFieldValue } from '@ng-forge/dynamic-forms';
4
4
  export { createWrappers, isEqual, isWrappersBundle, resolveNonFieldDisabled, resolveNonFieldHidden, wrapperProps } from '@ng-forge/dynamic-forms';
5
5
  import { toObservable, toSignal } from '@angular/core/rxjs-interop';
6
6
  import { combineLatest, of } from 'rxjs';
7
7
  import { switchMap, map } from 'rxjs/operators';
8
+ import { explicitEffect } from 'ngxtension/explicit-effect';
8
9
  import { TestBed } from '@angular/core/testing';
9
10
  import { form, schema } from '@angular/forms/signals';
10
11
 
@@ -23,7 +24,7 @@ import { form, schema } from '@angular/forms/signals';
23
24
  * @returns The value field context with reactive field tree accessor
24
25
  */
25
26
  function resolveValueFieldContext() {
26
- const context = inject(FIELD_SIGNAL_CONTEXT);
27
+ const context = injectFieldSignalContext();
27
28
  return {
28
29
  getFieldTree: (fieldKey) => {
29
30
  // Access context.form here (inside a function that will be called from a computed)
@@ -110,7 +111,7 @@ function valueFieldMapper(fieldDef) {
110
111
  * @returns Signal containing Record of input names to values for ngComponentOutlet
111
112
  */
112
113
  function checkboxFieldMapper(fieldDef) {
113
- const context = inject(FIELD_SIGNAL_CONTEXT);
114
+ const context = injectFieldSignalContext();
114
115
  const defaultProps = inject(DEFAULT_PROPS);
115
116
  return computed(() => {
116
117
  const omittedFields = omit(fieldDef, ['value']);
@@ -560,7 +561,7 @@ function submitButtonFieldMapper(fieldDef) {
560
561
  // =============================================================================
561
562
  /** Mapper for next page button — preconfigures NextPageEvent. */
562
563
  function nextButtonFieldMapper(fieldDef) {
563
- const fieldSignalContext = inject(FIELD_SIGNAL_CONTEXT);
564
+ const fieldSignalContext = injectFieldSignalContext();
564
565
  const rootFormRegistry = inject(RootFormRegistryService);
565
566
  const defaultProps = inject(DEFAULT_PROPS);
566
567
  const formOptions = inject(FORM_OPTIONS);
@@ -877,10 +878,10 @@ function createAriaDescribedBySignal(errorsToDisplay, errorId, hintId, hasHint)
877
878
  class NgForgeFieldShell {
878
879
  key = input.required(...(ngDevMode ? [{ debugName: "key" }] : /* istanbul ignore next */ []));
879
880
  className = input('', ...(ngDevMode ? [{ debugName: "className" }] : /* istanbul ignore next */ []));
880
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NgForgeFieldShell, deps: [], target: i0.ɵɵFactoryTarget.Directive });
881
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.8", type: NgForgeFieldShell, isStandalone: true, inputs: { key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "id": "key()", "attr.data-testid": "key()", "class": "className()" } }, ngImport: i0 });
881
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NgForgeFieldShell, deps: [], target: i0.ɵɵFactoryTarget.Directive });
882
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.14", type: NgForgeFieldShell, isStandalone: true, inputs: { key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "id": "key()", "attr.data-testid": "key()", "class": "className()" } }, ngImport: i0 });
882
883
  }
883
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NgForgeFieldShell, decorators: [{
884
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NgForgeFieldShell, decorators: [{
884
885
  type: Directive,
885
886
  args: [{
886
887
  host: {
@@ -1010,10 +1011,10 @@ class NgForgeField {
1010
1011
  });
1011
1012
  }
1012
1013
  }
1013
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NgForgeField, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1014
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.8", type: NgForgeField, isStandalone: true, inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, meta: { classPropertyName: "meta", publicName: "meta", isSignal: true, isRequired: false, transformFunction: null }, validationMessages: { classPropertyName: "validationMessages", publicName: "validationMessages", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.hidden": "field()().hidden() || null", "attr.aria-disabled": "field()().disabled() || null" } }, ngImport: i0 });
1014
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NgForgeField, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1015
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.14", type: NgForgeField, isStandalone: true, inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, meta: { classPropertyName: "meta", publicName: "meta", isSignal: true, isRequired: false, transformFunction: null }, validationMessages: { classPropertyName: "validationMessages", publicName: "validationMessages", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.hidden": "field()().hidden() || null", "attr.aria-disabled": "field()().disabled() || null" } }, ngImport: i0 });
1015
1016
  }
1016
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NgForgeField, decorators: [{
1017
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NgForgeField, decorators: [{
1017
1018
  type: Directive,
1018
1019
  args: [{
1019
1020
  host: {
@@ -1124,10 +1125,10 @@ class NgForgeAction {
1124
1125
  : (this.eventContext() ?? { key: this.key() });
1125
1126
  this.eventBus.dispatch(event, ...resolveTokens(args, context));
1126
1127
  }
1127
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NgForgeAction, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1128
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.8", type: NgForgeAction, isStandalone: true, inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, hidden: { classPropertyName: "hidden", publicName: "hidden", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, event: { classPropertyName: "event", publicName: "event", isSignal: true, isRequired: false, transformFunction: null }, eventArgs: { classPropertyName: "eventArgs", publicName: "eventArgs", isSignal: true, isRequired: false, transformFunction: null }, eventContext: { classPropertyName: "eventContext", publicName: "eventContext", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.hidden": "hidden() || null", "attr.aria-disabled": "disabled() || null" } }, ngImport: i0 });
1128
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NgForgeAction, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1129
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.14", type: NgForgeAction, isStandalone: true, inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, hidden: { classPropertyName: "hidden", publicName: "hidden", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, event: { classPropertyName: "event", publicName: "event", isSignal: true, isRequired: false, transformFunction: null }, eventArgs: { classPropertyName: "eventArgs", publicName: "eventArgs", isSignal: true, isRequired: false, transformFunction: null }, eventContext: { classPropertyName: "eventContext", publicName: "eventContext", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.hidden": "hidden() || null", "attr.aria-disabled": "disabled() || null" } }, ngImport: i0 });
1129
1130
  }
1130
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NgForgeAction, decorators: [{
1131
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NgForgeAction, decorators: [{
1131
1132
  type: Directive,
1132
1133
  args: [{
1133
1134
  host: {
@@ -1160,6 +1161,312 @@ function injectNgForgeAction() {
1160
1161
  return inject(NgForgeAction);
1161
1162
  }
1162
1163
 
1164
+ /**
1165
+ * Universal addon-array plumbing: signal-cached `hidden` resolution and
1166
+ * slot bucketing. Used internally by the `NgForgeAddons` host wrapper —
1167
+ * consumers should compose `NgForgeAddons` directly and inject the
1168
+ * directive instance via `injectNgForgeAddons<TAddon>()`.
1169
+ */
1170
+ class NgForgeAddonsBase {
1171
+ /** Capture the host's injector so `toSignal` (inside `resolveDynamicValue`) ties to the host's `DestroyRef`. */
1172
+ hostInjector = inject(Injector);
1173
+ /** Addon array mapped from `FieldDef.addons` by `buildBaseInputs`. */
1174
+ addons = input(undefined, ...(ngDevMode ? [{ debugName: "addons" }] : /* istanbul ignore next */ []));
1175
+ /**
1176
+ * Per-addon `hidden` signal cache. Built via `explicitEffect` rather
1177
+ * than `computed` because `toSignal` (inside `resolveDynamicValue` for
1178
+ * Observable inputs) is disallowed in reactive contexts (NG0602).
1179
+ */
1180
+ _hiddenSignalCache = signal(new Map(), ...(ngDevMode ? [{ debugName: "_hiddenSignalCache" }] : /* istanbul ignore next */ []));
1181
+ hiddenSignalCache = this._hiddenSignalCache.asReadonly();
1182
+ visibleAddons = computed(() => {
1183
+ const list = this.addons() ?? [];
1184
+ const cache = this.hiddenSignalCache();
1185
+ return list.filter((a) => !(cache.get(a)?.() ?? false));
1186
+ }, ...(ngDevMode ? [{ debugName: "visibleAddons" }] : /* istanbul ignore next */ []));
1187
+ hasAddons = computed(() => this.visibleAddons().length > 0, ...(ngDevMode ? [{ debugName: "hasAddons" }] : /* istanbul ignore next */ []));
1188
+ prefixAddons = computed(() => this.visibleAddons().filter((a) => a.slot === 'prefix'), ...(ngDevMode ? [{ debugName: "prefixAddons" }] : /* istanbul ignore next */ []));
1189
+ suffixAddons = computed(() => this.visibleAddons().filter((a) => a.slot === 'suffix'), ...(ngDevMode ? [{ debugName: "suffixAddons" }] : /* istanbul ignore next */ []));
1190
+ /**
1191
+ * Visible addons grouped by their `slot` string. Convenience view for
1192
+ * adapters with non-universal slots (e.g., Ionic `start` / `end`).
1193
+ */
1194
+ addonsBySlot = computed(() => {
1195
+ const map = new Map();
1196
+ for (const a of this.visibleAddons()) {
1197
+ const bucket = map.get(a.slot) ?? [];
1198
+ bucket.push(a);
1199
+ map.set(a.slot, bucket);
1200
+ }
1201
+ return map;
1202
+ }, ...(ngDevMode ? [{ debugName: "addonsBySlot" }] : /* istanbul ignore next */ []));
1203
+ /** Secondary index keyed by `hidden` value identity. Catches the common case
1204
+ * where a FormConfig re-emit produces structurally-different-but-content-
1205
+ * identical addon objects — without this, every re-emit would spawn a new
1206
+ * `toSignal` subscription for each addon's hidden axis. */
1207
+ _hiddenByValue = new WeakMap();
1208
+ constructor() {
1209
+ explicitEffect([this.addons], ([list]) => {
1210
+ const prev = this._hiddenSignalCache();
1211
+ const next = new Map();
1212
+ for (const a of list ?? []) {
1213
+ // Tier 1: reference identity — the cheapest hit when the same addon
1214
+ // object is reused across emissions.
1215
+ let resolved = prev.get(a);
1216
+ if (!resolved) {
1217
+ // Tier 2: hidden-value identity — when `hidden` is an object
1218
+ // (Signal / Observable / function), the same instance can be passed
1219
+ // through multiple new addon objects on FormConfig re-emit.
1220
+ const h = a.hidden;
1221
+ const valueKey = typeof h === 'object' && h !== null ? h : null;
1222
+ resolved = valueKey ? this._hiddenByValue.get(valueKey) : undefined;
1223
+ if (!resolved) {
1224
+ resolved = resolveDynamicValue(a.hidden, false, this.hostInjector);
1225
+ if (valueKey)
1226
+ this._hiddenByValue.set(valueKey, resolved);
1227
+ }
1228
+ }
1229
+ next.set(a, resolved);
1230
+ }
1231
+ this._hiddenSignalCache.set(next);
1232
+ });
1233
+ }
1234
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NgForgeAddonsBase, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1235
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.14", type: NgForgeAddonsBase, isStandalone: true, inputs: { addons: { classPropertyName: "addons", publicName: "addons", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
1236
+ }
1237
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NgForgeAddonsBase, decorators: [{
1238
+ type: Directive,
1239
+ args: [{}]
1240
+ }], ctorParameters: () => [], propDecorators: { addons: [{ type: i0.Input, args: [{ isSignal: true, alias: "addons", required: false }] }] } });
1241
+ /** Forwarded onto `NgForgeAddonsBase` via the `NgForgeAddons` wrapper. */
1242
+ const NG_FORGE_ADDONS_INPUTS = ['addons'];
1243
+ // Compile-time lockstep — drift between the tuple and the declared inputs fails the build.
1244
+ const _NG_FORGE_ADDONS_INPUTS_LOCKSTEP = true;
1245
+ void _NG_FORGE_ADDONS_INPUTS_LOCKSTEP;
1246
+ /**
1247
+ * Host wrapper for `NgForgeAddonsBase`. Consumers compose this directly:
1248
+ *
1249
+ * ```ts
1250
+ * \@Component({
1251
+ * hostDirectives: [NgForgeFieldHost, NgForgeAddons],
1252
+ * template: `
1253
+ * @if (ngfa.hasAddons()) {
1254
+ * <p-inputgroup>
1255
+ * @for (a of ngfa.prefixAddons(); track $index) {
1256
+ * <df-addon-slot [addon]="a" [hidden]="ngfa.hiddenSignalCache().get(a)" />
1257
+ * }
1258
+ * <input ngForgeControl ... />
1259
+ * </p-inputgroup>
1260
+ * }
1261
+ * `,
1262
+ * })
1263
+ * export class MyInputField {
1264
+ * protected readonly ngfa = injectNgForgeAddons<MyInputAddon>();
1265
+ * }
1266
+ * ```
1267
+ *
1268
+ * The wrapper exists so `hostDirectives: [NgForgeAddons]` resolves
1269
+ * cross-package — same constraint that drives `NgForgeFieldHost`.
1270
+ */
1271
+ class NgForgeAddons {
1272
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NgForgeAddons, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1273
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.14", type: NgForgeAddons, isStandalone: true, hostDirectives: [{ directive: NgForgeAddonsBase, inputs: ["addons", "addons"] }], ngImport: i0 });
1274
+ }
1275
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NgForgeAddons, decorators: [{
1276
+ type: Directive,
1277
+ args: [{
1278
+ hostDirectives: [{ directive: NgForgeAddonsBase, inputs: [...NG_FORGE_ADDONS_INPUTS] }],
1279
+ }]
1280
+ }] });
1281
+ /**
1282
+ * Typed inject helper. Always resolves to the underlying
1283
+ * `NgForgeAddonsBase` instance — the wrapper class has no instance
1284
+ * fields of its own.
1285
+ */
1286
+ function injectNgForgeAddons() {
1287
+ return inject(NgForgeAddonsBase);
1288
+ }
1289
+
1290
+ const ADDON_PRESET_HANDLER = new InjectionToken('ADDON_PRESET_HANDLER');
1291
+
1292
+ /**
1293
+ * Universal click-dispatch plumbing for action-style addons (icon buttons,
1294
+ * labelled buttons, etc.): `disabled` / `loading` resolution from
1295
+ * `DynamicValue<boolean>`, action context construction, and the
1296
+ * `preset / actionRef / action` precedence dispatcher.
1297
+ *
1298
+ * Adapter button kinds (e.g., `prime-button`) compose `NgForgeAddonAction`
1299
+ * and read state via `injectNgForgeAddonAction<TAddon>()`. Preset semantics
1300
+ * are adapter-specific — register an `ADDON_PRESET_HANDLER` at the host
1301
+ * field scope to receive preset dispatches.
1302
+ */
1303
+ class NgForgeAddonActionBase {
1304
+ // The action registry is form-scoped. `optional: true` matches the
1305
+ // preset handler so addons rendered outside a form that called
1306
+ // `provideAddonActions(...)` degrade gracefully instead of throwing —
1307
+ // `actionRef` dispatches then log an actionable warning and no-op.
1308
+ actionRegistry = inject(ADDON_ACTION_REGISTRY, { optional: true });
1309
+ presetHandler = inject(ADDON_PRESET_HANDLER, { optional: true });
1310
+ logger = inject(DynamicFormLogger);
1311
+ hostInjector = inject(Injector);
1312
+ addon = input.required(...(ngDevMode ? [{ debugName: "addon" }] : /* istanbul ignore next */ []));
1313
+ fieldInputs = input(undefined, ...(ngDevMode ? [{ debugName: "fieldInputs" }] : /* istanbul ignore next */ []));
1314
+ /**
1315
+ * Per-value caches for `disabled` / `loading` signal resolution. Keyed by
1316
+ * the `DynamicValue` identity so a single `toSignal` subscription is
1317
+ * shared across addon-reference swaps that pass the same Observable.
1318
+ * Mirrors `NgForgeAddonsBase._hiddenByValue` — `resolveDynamicValue`
1319
+ * cannot run inside `computed`/`linkedSignal.computation` because
1320
+ * `toSignal` throws in reactive contexts (NG0602), and re-running it on
1321
+ * every recomputation would leak subscriptions on each cycle.
1322
+ */
1323
+ _disabledByValue = new WeakMap();
1324
+ _loadingByValue = new WeakMap();
1325
+ _resolvedDisabled = signal(undefined, ...(ngDevMode ? [{ debugName: "_resolvedDisabled" }] : /* istanbul ignore next */ []));
1326
+ _resolvedLoading = signal(undefined, ...(ngDevMode ? [{ debugName: "_resolvedLoading" }] : /* istanbul ignore next */ []));
1327
+ disabled = computed(() => this._resolvedDisabled()?.() ?? false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
1328
+ loading = computed(() => this._resolvedLoading()?.() ?? false, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
1329
+ constructor() {
1330
+ explicitEffect([this.addon], ([addon]) => {
1331
+ this._resolvedDisabled.set(this._resolveAxis(addon.disabled, this._disabledByValue));
1332
+ this._resolvedLoading.set(this._resolveAxis(addon.loading, this._loadingByValue));
1333
+ });
1334
+ }
1335
+ _resolveAxis(value, cache) {
1336
+ const valueKey = typeof value === 'object' && value !== null ? value : null;
1337
+ let resolved = valueKey ? cache.get(valueKey) : undefined;
1338
+ if (!resolved) {
1339
+ resolved = resolveDynamicValue(value, false, this.hostInjector);
1340
+ if (valueKey)
1341
+ cache.set(valueKey, resolved);
1342
+ }
1343
+ return resolved;
1344
+ }
1345
+ /**
1346
+ * Resolve the click handler from the addon's three-axis click variant and
1347
+ * invoke it. Precedence on multi-set: `preset > actionRef > action`. The
1348
+ * validator drops multi-set configs at config-init time; this is
1349
+ * defence-in-depth + a logged warning so the misconfiguration is loud.
1350
+ */
1351
+ dispatch() {
1352
+ const addon = this.addon();
1353
+ const ctx = this.buildActionContext();
1354
+ const variantsSet = [addon.preset, addon.actionRef, addon.action].filter((v) => v !== undefined).length;
1355
+ if (variantsSet > 1) {
1356
+ this.logger.warn(`Addon button: more than one of preset/actionRef/action configured — dispatching by precedence (preset > actionRef > action). Ship at most one to silence this.`);
1357
+ }
1358
+ if (addon.preset !== undefined) {
1359
+ if (!this.presetHandler) {
1360
+ this.logger.warn(`Addon button: preset '${addon.preset}' is configured but no ADDON_PRESET_HANDLER is registered in this scope. Did the adapter forget to provide one at the host field?`);
1361
+ return;
1362
+ }
1363
+ void this.presetHandler.run(addon.preset, ctx);
1364
+ return;
1365
+ }
1366
+ if (addon.actionRef !== undefined) {
1367
+ const handler = this.actionRegistry?.get(addon.actionRef);
1368
+ if (handler) {
1369
+ handler(ctx);
1370
+ }
1371
+ else {
1372
+ this.logger.warn(`Addon button: actionRef '${addon.actionRef}' is not registered. ` +
1373
+ (this.actionRegistry
1374
+ ? `Did you call provideAddonActions({ ${addon.actionRef}: ... })?`
1375
+ : `No provideAddonActions(...) registry is reachable in this scope — was the addon rendered outside a form?`));
1376
+ }
1377
+ return;
1378
+ }
1379
+ if (addon.action !== undefined) {
1380
+ addon.action(ctx);
1381
+ return;
1382
+ }
1383
+ // Decorative — no handler configured.
1384
+ }
1385
+ /**
1386
+ * Build an `AddonActionContext` for handlers from the wrapper-style
1387
+ * `fieldInputs` bag. Returns the field-bound variant when a host field
1388
+ * is reachable, or the orphan variant otherwise.
1389
+ *
1390
+ * Resolution order for `setValue`:
1391
+ * 1. `inputs.setValue` from the forwarded bag (preferred — populated by
1392
+ * `buildFieldInputs` in `DfFieldOutlet`).
1393
+ * 2. Fallback reconstructed from `inputs.field` itself: although
1394
+ * `ReadonlyFieldTree.value` is type-narrowed to `Signal<T>`, the
1395
+ * underlying runtime object is the same `WritableSignal<T>` created
1396
+ * by Signal Forms (the read-only wrapping is type-level only, see
1397
+ * `toReadonlyFieldTree`). Casting back at the writer boundary
1398
+ * produces a working setValue for ANY field depth — top-level OR
1399
+ * nested under groups. This avoids the previous FSC-key navigation
1400
+ * that broke for grouped fields, where `inputs.key` is DOM-mangled
1401
+ * (`'user_address_street'`) and `fsc.form[key]` returns undefined.
1402
+ *
1403
+ * The orphan variant fires only when the bag carries no field tree at
1404
+ * all — genuine "rendered outside a field" scenario.
1405
+ */
1406
+ buildActionContext() {
1407
+ const inputs = this.fieldInputs();
1408
+ const key = inputs?.key ?? '';
1409
+ const type = inputs?.type ?? '';
1410
+ const tree = inputs?.field;
1411
+ if (tree) {
1412
+ // `writeToFieldValue` centralises the `Signal → WritableSignal` cast and
1413
+ // warns at runtime if Signal Forms ever stops storing a writable signal
1414
+ // here (the alternative — a silent no-op preset — is much worse).
1415
+ const setValue = inputs?.setValue ?? ((next) => writeToFieldValue(tree.value, next, this.logger));
1416
+ return {
1417
+ field: { key, type },
1418
+ form: tree,
1419
+ value: tree.value() ?? undefined,
1420
+ setValue,
1421
+ };
1422
+ }
1423
+ return {
1424
+ field: { key, type },
1425
+ form: null,
1426
+ value: undefined,
1427
+ };
1428
+ }
1429
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NgForgeAddonActionBase, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1430
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.14", type: NgForgeAddonActionBase, isStandalone: true, inputs: { addon: { classPropertyName: "addon", publicName: "addon", isSignal: true, isRequired: true, transformFunction: null }, fieldInputs: { classPropertyName: "fieldInputs", publicName: "fieldInputs", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
1431
+ }
1432
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NgForgeAddonActionBase, decorators: [{
1433
+ type: Directive,
1434
+ args: [{}]
1435
+ }], ctorParameters: () => [], propDecorators: { addon: [{ type: i0.Input, args: [{ isSignal: true, alias: "addon", required: true }] }], fieldInputs: [{ type: i0.Input, args: [{ isSignal: true, alias: "fieldInputs", required: false }] }] } });
1436
+ /** Forwarded onto `NgForgeAddonActionBase` via the `NgForgeAddonAction` wrapper. */
1437
+ const NG_FORGE_ADDON_ACTION_INPUTS = ['addon', 'fieldInputs'];
1438
+ const _NG_FORGE_ADDON_ACTION_INPUTS_LOCKSTEP = true;
1439
+ void _NG_FORGE_ADDON_ACTION_INPUTS_LOCKSTEP;
1440
+ /**
1441
+ * Host wrapper for `NgForgeAddonActionBase`. Consumers compose this directly:
1442
+ *
1443
+ * ```ts
1444
+ * \@Component({
1445
+ * hostDirectives: [NgForgeAddonAction],
1446
+ * template: `
1447
+ * <p-button [loading]="action.loading()" [disabled]="action.disabled()"
1448
+ * (onClick)="action.dispatch()" />
1449
+ * `,
1450
+ * })
1451
+ * export class MyButtonAddon {
1452
+ * protected readonly action = injectNgForgeAddonAction<MyButtonAddon>();
1453
+ * }
1454
+ * ```
1455
+ */
1456
+ class NgForgeAddonAction {
1457
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NgForgeAddonAction, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1458
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.14", type: NgForgeAddonAction, isStandalone: true, hostDirectives: [{ directive: NgForgeAddonActionBase, inputs: ["addon", "addon", "fieldInputs", "fieldInputs"] }], ngImport: i0 });
1459
+ }
1460
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NgForgeAddonAction, decorators: [{
1461
+ type: Directive,
1462
+ args: [{
1463
+ hostDirectives: [{ directive: NgForgeAddonActionBase, inputs: [...NG_FORGE_ADDON_ACTION_INPUTS] }],
1464
+ }]
1465
+ }] });
1466
+ function injectNgForgeAddonAction() {
1467
+ return inject(NgForgeAddonActionBase);
1468
+ }
1469
+
1163
1470
  /**
1164
1471
  * Marker directive applied to the canonical control element of an
1165
1472
  * `NgForgeField`-using component. Forwards the field's `meta` AND
@@ -1201,10 +1508,10 @@ class NgForgeControl {
1201
1508
  setupMarkerAttrTracking(inject(ElementRef), parent, () => this.target());
1202
1509
  parent.markClaimed();
1203
1510
  }
1204
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NgForgeControl, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1205
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.8", type: NgForgeControl, isStandalone: true, selector: "[ngForgeControl]", inputs: { target: { classPropertyName: "target", publicName: "ngForgeControl", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
1511
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NgForgeControl, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1512
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.14", type: NgForgeControl, isStandalone: true, selector: "[ngForgeControl]", inputs: { target: { classPropertyName: "target", publicName: "ngForgeControl", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
1206
1513
  }
1207
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NgForgeControl, decorators: [{
1514
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NgForgeControl, decorators: [{
1208
1515
  type: Directive,
1209
1516
  args: [{ selector: '[ngForgeControl]' }]
1210
1517
  }], ctorParameters: () => [], propDecorators: { target: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngForgeControl", required: false }] }] } });
@@ -1239,10 +1546,10 @@ class NgForgeHostControl {
1239
1546
  setupMarkerAttrTracking(inject(ElementRef), parent, () => undefined);
1240
1547
  parent.markClaimed();
1241
1548
  }
1242
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NgForgeHostControl, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1243
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.8", type: NgForgeHostControl, isStandalone: true, ngImport: i0 });
1549
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NgForgeHostControl, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1550
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.14", type: NgForgeHostControl, isStandalone: true, ngImport: i0 });
1244
1551
  }
1245
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NgForgeHostControl, decorators: [{
1552
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NgForgeHostControl, decorators: [{
1246
1553
  type: Directive,
1247
1554
  args: [{}]
1248
1555
  }], ctorParameters: () => [] });
@@ -1274,10 +1581,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
1274
1581
  * for the same reason. See https://www.angularspace.com/host-directives-decomposition-unleashed/
1275
1582
  */
1276
1583
  class NgForgeFieldHost {
1277
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NgForgeFieldHost, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1278
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.8", type: NgForgeFieldHost, isStandalone: true, hostDirectives: [{ directive: NgForgeFieldShell, inputs: ["key", "key", "className", "className"] }, { directive: NgForgeField, inputs: ["field", "field", "label", "label", "placeholder", "placeholder", "tabIndex", "tabIndex", "props", "props", "meta", "meta", "validationMessages", "validationMessages"] }], ngImport: i0 });
1584
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NgForgeFieldHost, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1585
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.14", type: NgForgeFieldHost, isStandalone: true, hostDirectives: [{ directive: NgForgeFieldShell, inputs: ["key", "key", "className", "className"] }, { directive: NgForgeField, inputs: ["field", "field", "label", "label", "placeholder", "placeholder", "tabIndex", "tabIndex", "props", "props", "meta", "meta", "validationMessages", "validationMessages"] }], ngImport: i0 });
1279
1586
  }
1280
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NgForgeFieldHost, decorators: [{
1587
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NgForgeFieldHost, decorators: [{
1281
1588
  type: Directive,
1282
1589
  args: [{
1283
1590
  hostDirectives: [
@@ -1303,10 +1610,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
1303
1610
  * ```
1304
1611
  */
1305
1612
  class NgForgeActionHost {
1306
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NgForgeActionHost, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1307
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.8", type: NgForgeActionHost, isStandalone: true, hostDirectives: [{ directive: NgForgeFieldShell, inputs: ["key", "key", "className", "className"] }, { directive: NgForgeAction, inputs: ["label", "label", "disabled", "disabled", "hidden", "hidden", "tabIndex", "tabIndex", "event", "event", "eventArgs", "eventArgs", "eventContext", "eventContext", "props", "props"] }], ngImport: i0 });
1613
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NgForgeActionHost, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1614
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.14", type: NgForgeActionHost, isStandalone: true, hostDirectives: [{ directive: NgForgeFieldShell, inputs: ["key", "key", "className", "className"] }, { directive: NgForgeAction, inputs: ["label", "label", "disabled", "disabled", "hidden", "hidden", "tabIndex", "tabIndex", "event", "event", "eventArgs", "eventArgs", "eventContext", "eventContext", "props", "props"] }], ngImport: i0 });
1308
1615
  }
1309
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NgForgeActionHost, decorators: [{
1616
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NgForgeActionHost, decorators: [{
1310
1617
  type: Directive,
1311
1618
  args: [{
1312
1619
  hostDirectives: [
@@ -1399,5 +1706,5 @@ function provideTestValidationMessages(messages) {
1399
1706
  * Generated bundle index. Do not edit.
1400
1707
  */
1401
1708
 
1402
- export { NG_FORGE_ACTION_INPUTS, NG_FORGE_FIELD_SHELL_INPUTS, NG_FORGE_VALUE_FIELD_INPUTS, NgForgeAction, NgForgeActionHost, NgForgeControl, NgForgeField, NgForgeFieldHost, NgForgeFieldShell, NgForgeHostControl, addArrayItemButtonMapper, buildArrayButtonEventContext, buildValueFieldInputs, buttonFieldMapper, checkboxFieldMapper, createAriaDescribedBySignal, createNgForgeActionFixture, createNgForgeFieldFixture, createResolvedErrorsSignal, datepickerFieldMapper, injectNgForgeAction, injectNgForgeField, insertArrayItemButtonMapper, nextButtonFieldMapper, optionsFieldMapper, popArrayItemButtonMapper, prependArrayItemButtonMapper, previousButtonFieldMapper, provideTestValidationMessages, removeArrayItemButtonMapper, resolveArrayButtonContext, resolveArrayButtonEventArgs, resolveValueFieldContext, setupMetaTracking, shiftArrayItemButtonMapper, shouldShowErrors, submitButtonFieldMapper, valueFieldMapper };
1709
+ export { ADDON_PRESET_HANDLER, NG_FORGE_ACTION_INPUTS, NG_FORGE_ADDONS_INPUTS, NG_FORGE_ADDON_ACTION_INPUTS, NG_FORGE_FIELD_SHELL_INPUTS, NG_FORGE_VALUE_FIELD_INPUTS, NgForgeAction, NgForgeActionHost, NgForgeAddonAction, NgForgeAddonActionBase, NgForgeAddons, NgForgeAddonsBase, NgForgeControl, NgForgeField, NgForgeFieldHost, NgForgeFieldShell, NgForgeHostControl, addArrayItemButtonMapper, buildArrayButtonEventContext, buildValueFieldInputs, buttonFieldMapper, checkboxFieldMapper, createAriaDescribedBySignal, createNgForgeActionFixture, createNgForgeFieldFixture, createResolvedErrorsSignal, datepickerFieldMapper, injectNgForgeAction, injectNgForgeAddonAction, injectNgForgeAddons, injectNgForgeField, insertArrayItemButtonMapper, nextButtonFieldMapper, optionsFieldMapper, popArrayItemButtonMapper, prependArrayItemButtonMapper, previousButtonFieldMapper, provideTestValidationMessages, removeArrayItemButtonMapper, resolveArrayButtonContext, resolveArrayButtonEventArgs, resolveValueFieldContext, setupMetaTracking, shiftArrayItemButtonMapper, shouldShowErrors, submitButtonFieldMapper, valueFieldMapper };
1403
1710
  //# sourceMappingURL=ng-forge-dynamic-forms-integration.mjs.map