@ng-forge/dynamic-forms 1.1.0-next.2 → 1.1.0-next.4

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 (26) hide show
  1. package/README.md +4 -1
  2. package/fesm2022/{ng-forge-dynamic-forms-array-field.component-CftX-bCB.mjs → ng-forge-dynamic-forms-array-field.component-DCHrAcfd.mjs} +2 -2
  3. package/fesm2022/{ng-forge-dynamic-forms-array-field.component-CftX-bCB.mjs.map → ng-forge-dynamic-forms-array-field.component-DCHrAcfd.mjs.map} +1 -1
  4. package/fesm2022/{ng-forge-dynamic-forms-bootstrap-derivation-orchestrator-CFSJLZPZ.mjs → ng-forge-dynamic-forms-bootstrap-derivation-orchestrator-DWIWQjjZ.mjs} +2 -2
  5. package/fesm2022/{ng-forge-dynamic-forms-bootstrap-derivation-orchestrator-CFSJLZPZ.mjs.map → ng-forge-dynamic-forms-bootstrap-derivation-orchestrator-DWIWQjjZ.mjs.map} +1 -1
  6. package/fesm2022/{ng-forge-dynamic-forms-container-field.component-B_bQ-f2g.mjs → ng-forge-dynamic-forms-container-field.component-CSYhRBe6.mjs} +2 -2
  7. package/fesm2022/{ng-forge-dynamic-forms-container-field.component-B_bQ-f2g.mjs.map → ng-forge-dynamic-forms-container-field.component-CSYhRBe6.mjs.map} +1 -1
  8. package/fesm2022/{ng-forge-dynamic-forms-group-field.component-Bl9WRPvF.mjs → ng-forge-dynamic-forms-group-field.component-DqhHzVsN.mjs} +2 -2
  9. package/fesm2022/{ng-forge-dynamic-forms-group-field.component-Bl9WRPvF.mjs.map → ng-forge-dynamic-forms-group-field.component-DqhHzVsN.mjs.map} +1 -1
  10. package/fesm2022/ng-forge-dynamic-forms-integration.mjs +17 -67
  11. package/fesm2022/ng-forge-dynamic-forms-integration.mjs.map +1 -1
  12. package/fesm2022/ng-forge-dynamic-forms-internal.mjs +65 -45
  13. package/fesm2022/ng-forge-dynamic-forms-internal.mjs.map +1 -1
  14. package/fesm2022/{ng-forge-dynamic-forms-ng-forge-dynamic-forms-fMB33l2f.mjs → ng-forge-dynamic-forms-ng-forge-dynamic-forms-BYyZ_cuA.mjs} +49 -135
  15. package/fesm2022/ng-forge-dynamic-forms-ng-forge-dynamic-forms-BYyZ_cuA.mjs.map +1 -0
  16. package/fesm2022/{ng-forge-dynamic-forms-page-field.component-C9bQkVjQ.mjs → ng-forge-dynamic-forms-page-field.component-Vvk3fYZp.mjs} +2 -2
  17. package/fesm2022/{ng-forge-dynamic-forms-page-field.component-C9bQkVjQ.mjs.map → ng-forge-dynamic-forms-page-field.component-Vvk3fYZp.mjs.map} +1 -1
  18. package/fesm2022/ng-forge-dynamic-forms-testing.mjs +84 -0
  19. package/fesm2022/ng-forge-dynamic-forms-testing.mjs.map +1 -0
  20. package/fesm2022/ng-forge-dynamic-forms.mjs +1 -1
  21. package/package.json +5 -1
  22. package/types/ng-forge-dynamic-forms-integration.d.ts +6 -54
  23. package/types/ng-forge-dynamic-forms-internal.d.ts +53 -13
  24. package/types/ng-forge-dynamic-forms-testing.d.ts +58 -0
  25. package/types/ng-forge-dynamic-forms.d.ts +1 -1
  26. package/fesm2022/ng-forge-dynamic-forms-ng-forge-dynamic-forms-fMB33l2f.mjs.map +0 -1
@@ -1,6 +1,6 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { inject, DestroyRef, Injector, EnvironmentInjector, input, computed, ChangeDetectionStrategy, Component } from '@angular/core';
3
- import { i as injectFieldRegistry, c as createFieldResolutionPipe, D as DfFieldOutlet } from './ng-forge-dynamic-forms-ng-forge-dynamic-forms-fMB33l2f.mjs';
3
+ import { i as injectFieldRegistry, c as createFieldResolutionPipe, D as DfFieldOutlet } from './ng-forge-dynamic-forms-ng-forge-dynamic-forms-BYyZ_cuA.mjs';
4
4
  import { outputFromObservable } from '@angular/core/rxjs-interop';
5
5
  import { explicitEffect } from 'ngxtension/explicit-effect';
6
6
  import { EventBus, DynamicFormLogger, validatePageNesting, derivedFromDeferred } from '@ng-forge/dynamic-forms/internal';
@@ -94,4 +94,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
94
94
  }], ctorParameters: () => [], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], pageIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageIndex", required: true }] }], isVisible: [{ type: i0.Input, args: [{ isSignal: true, alias: "isVisible", required: true }] }], nextPage: [{ type: i0.Output, args: ["nextPage"] }], previousPage: [{ type: i0.Output, args: ["previousPage"] }], pageChange: [{ type: i0.Output, args: ["pageChange"] }] } });
95
95
 
96
96
  export { PageFieldComponent as default };
97
- //# sourceMappingURL=ng-forge-dynamic-forms-page-field.component-C9bQkVjQ.mjs.map
97
+ //# sourceMappingURL=ng-forge-dynamic-forms-page-field.component-Vvk3fYZp.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ng-forge-dynamic-forms-page-field.component-C9bQkVjQ.mjs","mappings":";;;;;;;;AAsCc;YAKK;;AAEA;AACE;AACF;AACA;;;;;AAQjB;;;;;;YAQS;;AAEA;;AAEA;;;;YAQA;AACA;AACA;YAMQ;AACf;AACE;;;;;AAKe;AAGf;AACA;;;AAGA;AACE;;;;AAOH;YAQH;;;;;AAWE;;;;;AAQA;;;AA/FiB;;;;;;AAdlB;;;;AARS;;;;;;;AAWR;AACA;AACA;AACA;AACA;AACA;AACA;AACA","names":[],"ignoreList":[],"sources":["../../../../packages/dynamic-forms/src/lib/fields/page/page-field.component.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, computed, DestroyRef, EnvironmentInjector, inject, Injector, input } from '@angular/core';\nimport { DfFieldOutlet } from '../../directives/df-field-outlet/df-field-outlet.directive';\nimport { outputFromObservable } from '@angular/core/rxjs-interop';\nimport { explicitEffect } from 'ngxtension/explicit-effect';\nimport { derivedFromDeferred } from '@ng-forge/dynamic-forms/internal';\nimport { createFieldResolutionPipe, ResolvedField } from '../../utils/resolve-field/resolve-field';\nimport { computeContainerHostClasses, setupContainerInitEffect } from '../../utils/container-utils/container-utils';\nimport { PageField, validatePageNesting } from '@ng-forge/dynamic-forms/internal';\nimport { injectFieldRegistry } from '../../utils/inject-field-registry/inject-field-registry';\nimport { EventBus } from '@ng-forge/dynamic-forms/internal';\nimport { NextPageEvent, PageChangeEvent, PreviousPageEvent } from '../../events/constants';\nimport { FieldDef } from '@ng-forge/dynamic-forms/internal';\nimport { DynamicFormLogger } from '@ng-forge/dynamic-forms/internal';\n\n/** Renders a single page in multi-page (wizard) forms. */\n@Component({\n selector: 'section[page-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: './page-field.component.scss',\n host: {\n '[class]': 'hostClasses()',\n '[class.disabled]': 'disabled()',\n '[class.df-page-visible]': 'isVisible()',\n '[class.df-page-hidden]': '!isVisible()',\n '[attr.aria-hidden]': '!isVisible()',\n '[attr.data-page-index]': 'pageIndex()',\n '[id]': '`${key()}`',\n '[attr.data-testid]': 'key()',\n },\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport default class PageFieldComponent {\n // ─────────────────────────────────────────────────────────────────────────────\n // Dependencies\n // ─────────────────────────────────────────────────────────────────────────────\n\n private readonly destroyRef = inject(DestroyRef);\n private readonly fieldRegistry = injectFieldRegistry();\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 // Inputs\n // ─────────────────────────────────────────────────────────────────────────────\n\n field = input.required<PageField>();\n key = input.required<string>();\n className = input<string>();\n pageIndex = input.required<number>();\n isVisible = input.required<boolean>();\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Computed Signals\n // ─────────────────────────────────────────────────────────────────────────────\n\n readonly hostClasses = computed(() => computeContainerHostClasses('page-field', this.className()));\n\n readonly disabled = computed(() => this.field().disabled || false);\n\n readonly isValid = computed(() => validatePageNesting(this.field()));\n\n private readonly rawFieldRegistry = computed(() => this.fieldRegistry.raw);\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Outputs\n // ─────────────────────────────────────────────────────────────────────────────\n\n readonly nextPage = outputFromObservable(this.eventBus.on<NextPageEvent>('next-page'));\n readonly previousPage = outputFromObservable(this.eventBus.on<PreviousPageEvent>('previous-page'));\n readonly pageChange = outputFromObservable(this.eventBus.on<PageChangeEvent>('page-change'));\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Field Resolution\n // ─────────────────────────────────────────────────────────────────────────────\n\n private readonly fieldsSource = computed(() => {\n if (!this.isValid()) {\n return [];\n }\n return this.field().fields || [];\n });\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.injector,\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 page '${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, 'page', () => this.field().key, this.injector);\n\n explicitEffect([this.isValid, this.field], ([valid, pageField]) => {\n if (!valid) {\n this.logger.error(\n `Invalid configuration: Page '${pageField.key}' contains nested page fields. ` +\n `Pages cannot contain other pages. Consider using groups or rows for nested structure.`,\n pageField,\n );\n }\n });\n }\n}\n"]}
1
+ {"version":3,"file":"ng-forge-dynamic-forms-page-field.component-Vvk3fYZp.mjs","mappings":";;;;;;;;AAsCc;YAKK;;AAEA;AACE;AACF;AACA;;;;;AAQjB;;;;;;YAQS;;AAEA;;AAEA;;;;YAQA;AACA;AACA;YAMQ;AACf;AACE;;;;;AAKe;AAGf;AACA;;;AAGA;AACE;;;;AAOH;YAQH;;;;;AAWE;;;;;AAQA;;;AA/FiB;;;;;;AAdlB;;;;AARS;;;;;;;AAWR;AACA;AACA;AACA;AACA;AACA;AACA;AACA","names":[],"ignoreList":[],"sources":["../../../../packages/dynamic-forms/src/lib/fields/page/page-field.component.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, computed, DestroyRef, EnvironmentInjector, inject, Injector, input } from '@angular/core';\nimport { DfFieldOutlet } from '../../directives/df-field-outlet/df-field-outlet.directive';\nimport { outputFromObservable } from '@angular/core/rxjs-interop';\nimport { explicitEffect } from 'ngxtension/explicit-effect';\nimport { derivedFromDeferred } from '@ng-forge/dynamic-forms/internal';\nimport { createFieldResolutionPipe, ResolvedField } from '../../utils/resolve-field/resolve-field';\nimport { computeContainerHostClasses, setupContainerInitEffect } from '../../utils/container-utils/container-utils';\nimport { PageField, validatePageNesting } from '@ng-forge/dynamic-forms/internal';\nimport { injectFieldRegistry } from '../../utils/inject-field-registry/inject-field-registry';\nimport { EventBus } from '@ng-forge/dynamic-forms/internal';\nimport { NextPageEvent, PageChangeEvent, PreviousPageEvent } from '../../events/constants';\nimport { FieldDef } from '@ng-forge/dynamic-forms/internal';\nimport { DynamicFormLogger } from '@ng-forge/dynamic-forms/internal';\n\n/** Renders a single page in multi-page (wizard) forms. */\n@Component({\n selector: 'section[page-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: './page-field.component.scss',\n host: {\n '[class]': 'hostClasses()',\n '[class.disabled]': 'disabled()',\n '[class.df-page-visible]': 'isVisible()',\n '[class.df-page-hidden]': '!isVisible()',\n '[attr.aria-hidden]': '!isVisible()',\n '[attr.data-page-index]': 'pageIndex()',\n '[id]': '`${key()}`',\n '[attr.data-testid]': 'key()',\n },\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport default class PageFieldComponent {\n // ─────────────────────────────────────────────────────────────────────────────\n // Dependencies\n // ─────────────────────────────────────────────────────────────────────────────\n\n private readonly destroyRef = inject(DestroyRef);\n private readonly fieldRegistry = injectFieldRegistry();\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 // Inputs\n // ─────────────────────────────────────────────────────────────────────────────\n\n field = input.required<PageField>();\n key = input.required<string>();\n className = input<string>();\n pageIndex = input.required<number>();\n isVisible = input.required<boolean>();\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Computed Signals\n // ─────────────────────────────────────────────────────────────────────────────\n\n readonly hostClasses = computed(() => computeContainerHostClasses('page-field', this.className()));\n\n readonly disabled = computed(() => this.field().disabled || false);\n\n readonly isValid = computed(() => validatePageNesting(this.field()));\n\n private readonly rawFieldRegistry = computed(() => this.fieldRegistry.raw);\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Outputs\n // ─────────────────────────────────────────────────────────────────────────────\n\n readonly nextPage = outputFromObservable(this.eventBus.on<NextPageEvent>('next-page'));\n readonly previousPage = outputFromObservable(this.eventBus.on<PreviousPageEvent>('previous-page'));\n readonly pageChange = outputFromObservable(this.eventBus.on<PageChangeEvent>('page-change'));\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Field Resolution\n // ─────────────────────────────────────────────────────────────────────────────\n\n private readonly fieldsSource = computed(() => {\n if (!this.isValid()) {\n return [];\n }\n return this.field().fields || [];\n });\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.injector,\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 page '${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, 'page', () => this.field().key, this.injector);\n\n explicitEffect([this.isValid, this.field], ([valid, pageField]) => {\n if (!valid) {\n this.logger.error(\n `Invalid configuration: Page '${pageField.key}' contains nested page fields. ` +\n `Pages cannot contain other pages. Consider using groups or rows for nested structure.`,\n pageField,\n );\n }\n });\n }\n}\n"]}
@@ -0,0 +1,84 @@
1
+ import { signal, EnvironmentInjector, runInInjectionContext } from '@angular/core';
2
+ import { getTestBed, TestBed } from '@angular/core/testing';
3
+ import { form, schema } from '@angular/forms/signals';
4
+ import { DynamicFormError, DynamicFormLogger, EventBus, DEFAULT_VALIDATION_MESSAGES } from '@ng-forge/dynamic-forms/internal';
5
+
6
+ const fixtureLogger = {
7
+ debug: (message, ...args) => console.debug('[Dynamic Forms]', message, ...args),
8
+ info: (message, ...args) => console.info('[Dynamic Forms]', message, ...args),
9
+ warn: (message, ...args) => console.warn('[Dynamic Forms]', message, ...args),
10
+ error: (message, ...args) => console.error('[Dynamic Forms]', message, ...args),
11
+ };
12
+ function assertTestEnvironmentInitialized() {
13
+ if (getTestBed().platform)
14
+ return;
15
+ throw new DynamicFormError('The Angular test environment was never initialized for the @angular/core/testing instance this fixture resolved. ' +
16
+ 'Under Vitest this means your specs use a Vite-transformed copy of @angular/core/testing while the fixtures load the native one. ' +
17
+ 'Fix: either remove @angular/* from server.deps.inline so everything resolves natively, or inline the whole Angular graph:\n' +
18
+ "test: { server: { deps: { inline: [/@angular\\//, /@ng-forge/, 'ngxtension'] } } }\n" +
19
+ "and keep import '@angular/compiler' in your test setup so the inlined bundles JIT-link.\n" +
20
+ 'On Jest or Karma this instead means initTestEnvironment was never called; add it to your test setup file (e.g. getTestBed().initTestEnvironment(...)).');
21
+ }
22
+ function createNgForgeFieldFixture(component, options) {
23
+ assertTestEnvironmentInitialized();
24
+ TestBed.configureTestingModule({
25
+ imports: [component],
26
+ providers: [{ provide: DynamicFormLogger, useValue: fixtureLogger }, ...(options.providers ?? [])],
27
+ });
28
+ const key = options.key;
29
+ const rootValue = signal({ [key]: options.value }, /* @ts-ignore */
30
+ ...(ngDevMode ? [{ debugName: "rootValue" }] : /* istanbul ignore next */ []));
31
+ const injector = TestBed.inject(EnvironmentInjector);
32
+ const schemaCallback = options.schema;
33
+ const root = runInInjectionContext(injector, () => {
34
+ if (!schemaCallback)
35
+ return form(rootValue);
36
+ return form(rootValue, schema((path) => {
37
+ schemaCallback(path[key]);
38
+ }));
39
+ });
40
+ const field = root[key];
41
+ if (options.touched)
42
+ field().markAsTouched();
43
+ const fixture = TestBed.createComponent(component);
44
+ fixture.componentRef.setInput('field', field);
45
+ fixture.componentRef.setInput('key', key);
46
+ if (options.inputs) {
47
+ for (const [name, value] of Object.entries(options.inputs)) {
48
+ fixture.componentRef.setInput(name, value);
49
+ }
50
+ }
51
+ return { fixture, field, rootValue };
52
+ }
53
+ function createNgForgeActionFixture(component, options) {
54
+ assertTestEnvironmentInitialized();
55
+ TestBed.configureTestingModule({
56
+ imports: [component],
57
+ providers: [EventBus, { provide: DynamicFormLogger, useValue: fixtureLogger }, ...(options.providers ?? [])],
58
+ });
59
+ const fixture = TestBed.createComponent(component);
60
+ fixture.componentRef.setInput('key', options.key);
61
+ fixture.componentRef.setInput('label', options.label);
62
+ if (options.event)
63
+ fixture.componentRef.setInput('event', options.event);
64
+ if (options.eventArgs)
65
+ fixture.componentRef.setInput('eventArgs', options.eventArgs);
66
+ if (options.disabled !== undefined)
67
+ fixture.componentRef.setInput('disabled', options.disabled);
68
+ if (options.hidden !== undefined)
69
+ fixture.componentRef.setInput('hidden', options.hidden);
70
+ if (options.inputs) {
71
+ for (const [name, value] of Object.entries(options.inputs)) {
72
+ fixture.componentRef.setInput(name, value);
73
+ }
74
+ }
75
+ return { fixture, eventBus: TestBed.inject(EventBus) };
76
+ }
77
+ function provideTestValidationMessages(messages) {
78
+ return { provide: DEFAULT_VALIDATION_MESSAGES, useValue: signal(messages) };
79
+ }
80
+
81
+
82
+
83
+ export { createNgForgeActionFixture, createNgForgeFieldFixture, provideTestValidationMessages };
84
+ //# sourceMappingURL=ng-forge-dynamic-forms-testing.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ng-forge-dynamic-forms-testing.mjs","mappings":";;;;;AAWA;AACE;AACA;AACA;AACA;;AAyBF;;;;;;;;AAQM;AAEN;AAOM;AAIJ;;;;AAIC;AAED;AACA;;;AAGA;AACA;AACE;AAAqB;;AAIjB;;AAGN;AAEA;;AAEqB;;;;AAKrB;AACE;;;;AAKF;AACF;AAuBM;AAIJ;;;;AAIC;;;;;;;;AAOD;;AACA;;AACA;AACE;;;;AAKF;AACF;AAGM;AACJ;AACF","names":[],"ignoreList":[],"sources":["../../../../packages/dynamic-forms/testing/src/create-field-fixture.ts"],"sourcesContent":["import { EnvironmentInjector, Provider, runInInjectionContext, signal, type Type, type WritableSignal } from '@angular/core';\nimport { ComponentFixture, getTestBed, TestBed } from '@angular/core/testing';\nimport { type FieldTree, form, schema, type SchemaPath } from '@angular/forms/signals';\nimport { type FormEvent, type FormEventConstructor } from '@ng-forge/dynamic-forms';\nimport { EventBus, DynamicFormError, DynamicFormLogger, type Logger } from '@ng-forge/dynamic-forms/internal';\nimport { DEFAULT_VALIDATION_MESSAGES, type DynamicText, type ValidationMessages } from '@ng-forge/dynamic-forms/internal';\n\n/** Structural copy of integration's EventArgs; importing it would cycle the entrypoints. */\ntype EventArgs = readonly (string | number | boolean | null | undefined)[];\n\n/** Default logger so fixtures work without provideDynamicForm(); override via options.providers. */\nconst fixtureLogger: Logger = {\n debug: (message, ...args) => console.debug('[Dynamic Forms]', message, ...args),\n info: (message, ...args) => console.info('[Dynamic Forms]', message, ...args),\n warn: (message, ...args) => console.warn('[Dynamic Forms]', message, ...args),\n error: (message, ...args) => console.error('[Dynamic Forms]', message, ...args),\n};\n\nexport interface CreateNgForgeFieldFixtureOptions<TValue = unknown> {\n /** Field key. Becomes the only property on the wrapping form. */\n readonly key: string;\n /** Initial value for the field. */\n readonly value?: TValue;\n /** Optional schema callback that receives the field's `SchemaPath`. Use it to attach validators (`required`, `minLength`, etc.). */\n readonly schema?: (fieldPath: SchemaPath<TValue>) => void;\n /** Mark the field as touched after creation (useful for invalid-state assertions). */\n readonly touched?: boolean;\n /** Extra inputs to set on the component before `detectChanges()`. */\n readonly inputs?: Record<string, unknown>;\n /** Extra TestBed providers. */\n readonly providers?: readonly Provider[];\n}\n\nexport interface NgForgeFieldFixture<C, TValue = unknown> {\n readonly fixture: ComponentFixture<C>;\n readonly field: FieldTree<TValue>;\n readonly rootValue: WritableSignal<Record<string, TValue>>;\n}\n\n/** Guards against a second, uninitialized @angular/core/testing instance (Vitest externalization). */\nfunction assertTestEnvironmentInitialized(): void {\n if (getTestBed().platform) return;\n throw new DynamicFormError(\n 'The Angular test environment was never initialized for the @angular/core/testing instance this fixture resolved. ' +\n 'Under Vitest this means your specs use a Vite-transformed copy of @angular/core/testing while the fixtures load the native one. ' +\n 'Fix: either remove @angular/* from server.deps.inline so everything resolves natively, or inline the whole Angular graph:\\n' +\n \"test: { server: { deps: { inline: [/@angular\\\\//, /@ng-forge/, 'ngxtension'] } } }\\n\" +\n \"and keep import '@angular/compiler' in your test setup so the inlined bundles JIT-link.\\n\" +\n 'On Jest or Karma this instead means initTestEnvironment was never called; add it to your test setup file (e.g. getTestBed().initTestEnvironment(...)).',\n );\n}\n\n/**\n * Builds a `ComponentFixture` for an `NgForgeField`-composing component with\n * `field` + `key` bound BEFORE `detectChanges()` — sidesteps the NG0950 that\n * Shell's required `key` and Field's required `field` would otherwise throw.\n */\nexport function createNgForgeFieldFixture<C, TValue = unknown>(\n component: Type<C>,\n options: CreateNgForgeFieldFixtureOptions<TValue>,\n): NgForgeFieldFixture<C, TValue> {\n assertTestEnvironmentInitialized();\n TestBed.configureTestingModule({\n imports: [component],\n providers: [{ provide: DynamicFormLogger, useValue: fixtureLogger }, ...(options.providers ?? [])],\n });\n\n const key = options.key;\n const rootValue = signal<Record<string, TValue>>({ [key]: options.value as TValue });\n\n const injector = TestBed.inject(EnvironmentInjector);\n const schemaCallback = options.schema;\n const root = runInInjectionContext(injector, () => {\n if (!schemaCallback) return form(rootValue);\n return form(\n rootValue,\n schema<Record<string, TValue>>((path) => {\n schemaCallback(path[key] as SchemaPath<TValue>);\n }),\n );\n });\n\n const field = (root as unknown as Record<string, FieldTree<TValue>>)[key];\n\n if (options.touched) field().markAsTouched();\n\n const fixture = TestBed.createComponent(component);\n fixture.componentRef.setInput('field', field);\n fixture.componentRef.setInput('key', key);\n if (options.inputs) {\n for (const [name, value] of Object.entries(options.inputs)) {\n fixture.componentRef.setInput(name, value);\n }\n }\n\n return { fixture, field, rootValue };\n}\n\nexport interface CreateNgForgeActionFixtureOptions<TEvent extends FormEvent = FormEvent> {\n readonly key: string;\n readonly label: DynamicText;\n readonly event?: FormEventConstructor<TEvent>;\n readonly eventArgs?: EventArgs;\n readonly disabled?: boolean;\n readonly hidden?: boolean;\n readonly inputs?: Record<string, unknown>;\n readonly providers?: readonly Provider[];\n}\n\nexport interface NgForgeActionFixture<C> {\n readonly fixture: ComponentFixture<C>;\n readonly eventBus: EventBus;\n}\n\n/**\n * Builds a `ComponentFixture` for an `NgForgeAction`-composing component with\n * `key` + `label` bound and `EventBus` provided. The caller calls\n * `detectChanges()`; the harness handles the NG0950-avoidance bindings.\n */\nexport function createNgForgeActionFixture<C, TEvent extends FormEvent = FormEvent>(\n component: Type<C>,\n options: CreateNgForgeActionFixtureOptions<TEvent>,\n): NgForgeActionFixture<C> {\n assertTestEnvironmentInitialized();\n TestBed.configureTestingModule({\n imports: [component],\n providers: [EventBus, { provide: DynamicFormLogger, useValue: fixtureLogger }, ...(options.providers ?? [])],\n });\n\n const fixture = TestBed.createComponent(component);\n fixture.componentRef.setInput('key', options.key);\n fixture.componentRef.setInput('label', options.label);\n if (options.event) fixture.componentRef.setInput('event', options.event);\n if (options.eventArgs) fixture.componentRef.setInput('eventArgs', options.eventArgs);\n if (options.disabled !== undefined) fixture.componentRef.setInput('disabled', options.disabled);\n if (options.hidden !== undefined) fixture.componentRef.setInput('hidden', options.hidden);\n if (options.inputs) {\n for (const [name, value] of Object.entries(options.inputs)) {\n fixture.componentRef.setInput(name, value);\n }\n }\n\n return { fixture, eventBus: TestBed.inject(EventBus) };\n}\n\n/** Provider for `DEFAULT_VALIDATION_MESSAGES` in field tests — supply the default-messages map and the directive resolves it from DI. */\nexport function provideTestValidationMessages(messages: ValidationMessages): Provider {\n return { provide: DEFAULT_VALIDATION_MESSAGES, useValue: signal(messages) };\n}\n"]}
@@ -1,3 +1,3 @@
1
- export { o as AppendArrayItemEvent, B as BUILT_IN_FIELDS, p as ComponentAddonComponent, q as ConsoleLogger, s as DfTemplate, u as DynamicForm, E as EventDispatcher, v as FormClearEvent, w as FormResetEvent, x as FormSubmitEvent, I as InsertArrayItemEvent, M as MoveArrayItemEvent, N as NextPageEvent, y as PageChangeEvent, z as PopArrayItemEvent, G as PrependArrayItemEvent, H as PreviousPageEvent, R as RemoveAtIndexEvent, S as ShiftArrayItemEvent, T as TemplateAddonComponent, J as TextAddonComponent, K as arrayEvent, L as createWrappers, O as isWrappersBundle, Q as provideDynamicForm, U as sanitizeFormConfig, V as withAddonActions, W as withCustomAddon, X as withEventFormValue, Y as withLegacyStatusClasses, Z as withLoggerConfig, _ as withValidationExecutionDefaults, $ as withValueExclusionDefaults, a0 as wrapperProps } from './ng-forge-dynamic-forms-ng-forge-dynamic-forms-fMB33l2f.mjs';
1
+ export { o as AppendArrayItemEvent, B as BUILT_IN_FIELDS, p as ComponentAddonComponent, q as ConsoleLogger, s as DfTemplate, u as DynamicForm, E as EventDispatcher, v as FormClearEvent, w as FormResetEvent, x as FormSubmitEvent, I as InsertArrayItemEvent, M as MoveArrayItemEvent, N as NextPageEvent, y as PageChangeEvent, z as PopArrayItemEvent, G as PrependArrayItemEvent, H as PreviousPageEvent, R as RemoveAtIndexEvent, S as ShiftArrayItemEvent, T as TemplateAddonComponent, J as TextAddonComponent, K as arrayEvent, L as createWrappers, O as isWrappersBundle, Q as provideDynamicForm, U as sanitizeFormConfig, V as withAddonActions, W as withCustomAddon, X as withEventFormValue, Y as withLegacyStatusClasses, Z as withLoggerConfig, _ as withValidationExecutionDefaults, $ as withValueExclusionDefaults, a0 as wrapperProps } from './ng-forge-dynamic-forms-ng-forge-dynamic-forms-BYyZ_cuA.mjs';
2
2
  export { DF_FIELD_TEMPLATES, DynamicFormError, DynamicFormLogger, NoopLogger, hasFormValue, isArrayField, isContainerField, isDisplayOnlyField, isFieldBoundContext, isFormStateCondition, isGroupField, isHiddenField, isLeafField, isPageField, isRowField, isSimplifiedArrayField, isValueBearingField, isWrapperTypeDefinition, resolveDynamicValue } from '@ng-forge/dynamic-forms/internal';
3
3
  //# sourceMappingURL=ng-forge-dynamic-forms.mjs.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ng-forge/dynamic-forms",
3
- "version": "1.1.0-next.2",
3
+ "version": "1.1.0-next.4",
4
4
  "description": "Type-safe, signal-powered dynamic forms for Angular. Build complex forms from configuration with full TypeScript inference.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -67,6 +67,10 @@
67
67
  "./schema": {
68
68
  "types": "./types/ng-forge-dynamic-forms-schema.d.ts",
69
69
  "default": "./fesm2022/ng-forge-dynamic-forms-schema.mjs"
70
+ },
71
+ "./testing": {
72
+ "types": "./types/ng-forge-dynamic-forms-testing.d.ts",
73
+ "default": "./fesm2022/ng-forge-dynamic-forms-testing.mjs"
70
74
  }
71
75
  },
72
76
  "ngForgeSchematicDeps": {
@@ -1,11 +1,11 @@
1
1
  import { FormEvent, FormEventConstructor, FormSubmitEvent, NextPageEvent, PreviousPageEvent, FieldWithValidation, ArrayItemContext, BaseAddon, DynamicValue } from '@ng-forge/dynamic-forms';
2
2
  export { BUILT_IN_FIELDS, FieldWrapper, InferWrapperRegistry, WrapperRegistration, WrapperTypeDefinition, WrappersBundle, createWrappers, isWrappersBundle, wrapperProps } from '@ng-forge/dynamic-forms';
3
- import { FieldDef, StateLogicConfig, BaseCheckedField, FieldMeta, BaseValueField, FieldOption, ArrayAllowedChildren, NonFieldLogicConfig, LogicConfig, ValidationMessages, DynamicText, AnyAddon, AddonActionHandler, WrapperFieldInputs, AddonActionContext, EventBus } from '@ng-forge/dynamic-forms/internal';
3
+ import { FieldDef, StateLogicConfig, BaseCheckedField, FieldMeta, BaseValueField, FieldOption, ArrayAllowedChildren, NonFieldLogicConfig, LogicConfig, ValidationMessages, DynamicText, AnyAddon, AddonActionHandler, WrapperFieldInputs, AddonActionContext } from '@ng-forge/dynamic-forms/internal';
4
4
  export { ADDON_ACTION_REGISTRY, ADDON_TYPE_COMPONENT_CACHE, ADDON_TYPE_DEFINITIONS, ADDON_TYPE_REGISTRY, ARRAY_CONTEXT, AddonActionHandler, AddonShapeValidator, AddonTypeDefinition, AddonTypeSchema, ArrayContext, ArrayFieldTree, CheckedFieldComponent, DEFAULT_PROPS, DEFAULT_VALIDATION_MESSAGES, DEFAULT_WRAPPERS, DfAddonSlot, DynamicTextPipe, EventBus, FIELD_REGISTRY, FIELD_SIGNAL_CONTEXT, FORM_OPTIONS, FieldAddonSupport, FieldAddonSupportEntry, FieldScope, FieldSignalContext, FieldStateContext, FieldStateInfo, FieldTypeDefinition, FormFieldStateMap, GROUP_CONTEXT, HttpResourceRequest, INITIALIZATION_TIMEOUT_MS, MapperFn, NonFieldLogicConfig, NonFieldLogicContext, NonFieldLogicType, PresetCollaborators, ReadonlyFieldTree, RootFormRegistryService, ValueFieldComponent, ValueHandlingMode, WrapperFieldInputs, applyMetaToElement, applyValidator, applyValidators, arrayFieldMapper, baseFieldMapper, buildBaseInputs, containerFieldMapper, dynamicTextToObservable, getArrayLength, groupFieldMapper, injectAddonTypeRegistry, injectFieldSignalContext, injectFieldsSupportingAddons, interpolateParams, isCheckedField, isEqual, isValueField, pageFieldMapper, resolveDynamicValue, resolveNonFieldDisabled, resolveNonFieldHidden, resolveTokens, rowFieldMapper, runPresetAction, textFieldMapper, toReadonlyFieldTree, withPreviousValue, writeToFieldValue } from '@ng-forge/dynamic-forms/internal';
5
5
  import * as i0 from '@angular/core';
6
- import { Signal, Injector, ElementRef, InjectionToken, Provider, WritableSignal, Type } from '@angular/core';
7
- import { FieldTree, SchemaPath } from '@angular/forms/signals';
8
- import { ComponentFixture } from '@angular/core/testing';
6
+ import { Signal, Injector, ElementRef, InjectionToken } from '@angular/core';
7
+ import { FieldTree } from '@angular/forms/signals';
8
+ export { CreateNgForgeActionFixtureOptions, CreateNgForgeFieldFixtureOptions, NgForgeActionFixture, NgForgeFieldFixture, createNgForgeActionFixture, createNgForgeFieldFixture, provideTestValidationMessages } from '@ng-forge/dynamic-forms/testing';
9
9
 
10
10
  /**
11
11
  * Event arguments that can contain static values or tokens to be resolved at runtime.
@@ -906,53 +906,5 @@ declare class NgForgeActionHost {
906
906
  static ɵdir: i0.ɵɵDirectiveDeclaration<NgForgeActionHost, never, never, {}, {}, never, never, true, [{ directive: typeof NgForgeFieldShell; inputs: { "key": "key"; "className": "className"; }; outputs: {}; }, { directive: typeof NgForgeAction; inputs: { "label": "label"; "disabled": "disabled"; "hidden": "hidden"; "tabIndex": "tabIndex"; "event": "event"; "eventArgs": "eventArgs"; "eventContext": "eventContext"; "props": "props"; }; outputs: {}; }]>;
907
907
  }
908
908
 
909
- interface CreateNgForgeFieldFixtureOptions<TValue = unknown> {
910
- /** Field key. Becomes the only property on the wrapping form. */
911
- readonly key: string;
912
- /** Initial value for the field. */
913
- readonly value?: TValue;
914
- /** Optional schema callback that receives the field's `SchemaPath`. Use it to attach validators (`required`, `minLength`, etc.). */
915
- readonly schema?: (fieldPath: SchemaPath<TValue>) => void;
916
- /** Mark the field as touched after creation (useful for invalid-state assertions). */
917
- readonly touched?: boolean;
918
- /** Extra inputs to set on the component before `detectChanges()`. */
919
- readonly inputs?: Record<string, unknown>;
920
- /** Extra TestBed providers. */
921
- readonly providers?: readonly Provider[];
922
- }
923
- interface NgForgeFieldFixture<C, TValue = unknown> {
924
- readonly fixture: ComponentFixture<C>;
925
- readonly field: FieldTree<TValue>;
926
- readonly rootValue: WritableSignal<Record<string, TValue>>;
927
- }
928
- /**
929
- * Builds a `ComponentFixture` for an `NgForgeField`-composing component with
930
- * `field` + `key` bound BEFORE `detectChanges()` — sidesteps the NG0950 that
931
- * Shell's required `key` and Field's required `field` would otherwise throw.
932
- */
933
- declare function createNgForgeFieldFixture<C, TValue = unknown>(component: Type<C>, options: CreateNgForgeFieldFixtureOptions<TValue>): NgForgeFieldFixture<C, TValue>;
934
- interface CreateNgForgeActionFixtureOptions<TEvent extends FormEvent = FormEvent> {
935
- readonly key: string;
936
- readonly label: DynamicText;
937
- readonly event?: FormEventConstructor<TEvent>;
938
- readonly eventArgs?: EventArgs;
939
- readonly disabled?: boolean;
940
- readonly hidden?: boolean;
941
- readonly inputs?: Record<string, unknown>;
942
- readonly providers?: readonly Provider[];
943
- }
944
- interface NgForgeActionFixture<C> {
945
- readonly fixture: ComponentFixture<C>;
946
- readonly eventBus: EventBus;
947
- }
948
- /**
949
- * Builds a `ComponentFixture` for an `NgForgeAction`-composing component with
950
- * `key` + `label` bound and `EventBus` provided. The caller calls
951
- * `detectChanges()`; the harness handles the NG0950-avoidance bindings.
952
- */
953
- declare function createNgForgeActionFixture<C, TEvent extends FormEvent = FormEvent>(component: Type<C>, options: CreateNgForgeActionFixtureOptions<TEvent>): NgForgeActionFixture<C>;
954
- /** Provider for `DEFAULT_VALIDATION_MESSAGES` in field tests — supply the default-messages map and the directive resolves it from DI. */
955
- declare function provideTestValidationMessages(messages: ValidationMessages): Provider;
956
-
957
- 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, injectNonFieldLogicResolver, insertArrayItemButtonMapper, nextButtonFieldMapper, optionsFieldMapper, popArrayItemButtonMapper, prependArrayItemButtonMapper, previousButtonFieldMapper, provideTestValidationMessages, removeArrayItemButtonMapper, resolveArrayButtonContext, resolveArrayButtonEventArgs, resolveValueFieldContext, setupMetaTracking, shiftArrayItemButtonMapper, shouldShowErrors, submitButtonFieldMapper, valueFieldMapper };
958
- export type { AddonPresetHandler, ArrayButtonContext, ArrayButtonEventContext, Autocapitalize, AutocompleteValue, BaseArrayAddButtonField, BaseArrayRemoveButtonField, BaseInsertArrayItemButtonField, BaseNavigationButtonField, ButtonField, CheckboxField, CreateNgForgeActionFixtureOptions, CreateNgForgeFieldFixtureOptions, DatepickerField, DatepickerProps, EnterKeyHint, EventArg, EventArgs, FieldWithOptions, HtmlInputType, InferInputValue, InputField, InputMeta, InputMode, InputProps, InputType, MetaTrackingOptions, MultiCheckboxField, NgForgeActionFixture, NgForgeFieldFixture, NumericInputType, RadioField, ResolvedError, SelectField, SelectProps, SliderField, StringInputType, TextareaField, TextareaMeta, TextareaProps, TextareaWrap, ToggleField, TypedNgForgeAddonAction, TypedNgForgeAddons, TypedNgForgeField, ValueFieldContext };
909
+ 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, createResolvedErrorsSignal, datepickerFieldMapper, injectNgForgeAction, injectNgForgeAddonAction, injectNgForgeAddons, injectNgForgeField, injectNonFieldLogicResolver, insertArrayItemButtonMapper, nextButtonFieldMapper, optionsFieldMapper, popArrayItemButtonMapper, prependArrayItemButtonMapper, previousButtonFieldMapper, removeArrayItemButtonMapper, resolveArrayButtonContext, resolveArrayButtonEventArgs, resolveValueFieldContext, setupMetaTracking, shiftArrayItemButtonMapper, shouldShowErrors, submitButtonFieldMapper, valueFieldMapper };
910
+ export type { AddonPresetHandler, ArrayButtonContext, ArrayButtonEventContext, Autocapitalize, AutocompleteValue, BaseArrayAddButtonField, BaseArrayRemoveButtonField, BaseInsertArrayItemButtonField, BaseNavigationButtonField, ButtonField, CheckboxField, DatepickerField, DatepickerProps, EnterKeyHint, EventArg, EventArgs, FieldWithOptions, HtmlInputType, InferInputValue, InputField, InputMeta, InputMode, InputProps, InputType, MetaTrackingOptions, MultiCheckboxField, NumericInputType, RadioField, ResolvedError, SelectField, SelectProps, SliderField, StringInputType, TextareaField, TextareaMeta, TextareaProps, TextareaWrap, ToggleField, TypedNgForgeAddonAction, TypedNgForgeAddons, TypedNgForgeField, ValueFieldContext };
@@ -1459,15 +1459,22 @@ interface SchemaDefinition {
1459
1459
  * This replaces our custom ValidationError interface
1460
1460
  */
1461
1461
  type ValidationError = ValidationError$1;
1462
+ /**
1463
+ * Resolves a validation message from the validation error, so error params
1464
+ * (e.g. maxLength, min) can be passed to an i18n layer natively.
1465
+ */
1466
+ type ValidationMessageResolver = (error: ValidationError) => DynamicText;
1467
+ /** A validation message: static or reactive text, or a function of the validation error. */
1468
+ type ValidationMessage = DynamicText | ValidationMessageResolver;
1462
1469
  interface ValidationMessages {
1463
- required?: DynamicText;
1464
- email?: DynamicText;
1465
- min?: DynamicText;
1466
- max?: DynamicText;
1467
- minLength?: DynamicText;
1468
- maxLength?: DynamicText;
1469
- pattern?: DynamicText;
1470
- [key: string]: DynamicText | undefined;
1470
+ required?: ValidationMessage;
1471
+ email?: ValidationMessage;
1472
+ min?: ValidationMessage;
1473
+ max?: ValidationMessage;
1474
+ minLength?: ValidationMessage;
1475
+ maxLength?: ValidationMessage;
1476
+ pattern?: ValidationMessage;
1477
+ [key: string]: ValidationMessage | undefined;
1471
1478
  }
1472
1479
 
1473
1480
  /**
@@ -2344,8 +2351,17 @@ declare function isResourceBasedValidator(config: ValidatorConfig): boolean;
2344
2351
  * @param config The validator configuration to check
2345
2352
  * @param context Optional context providing function scope lookup
2346
2353
  * @returns true if the when condition references other fields
2354
+ * @deprecated No longer used for validator routing; `when` conditions are applied natively
2355
+ * via Angular's validator `when` config. Use {@link requiresTreeValidation} for routing.
2347
2356
  */
2348
2357
  declare function hasCrossFieldWhenCondition(config: ValidatorConfig, context?: CrossFieldDetectionContext): boolean;
2358
+ /**
2359
+ * True only when the validator must be evaluated by the root validateTree:
2360
+ * a cross-field dynamic-value/validation EXPRESSION. A `when` condition alone
2361
+ * never requires tree validation; it is applied natively via Angular's
2362
+ * validator `when` config (built-ins) or whenLogic gating (custom/async/http).
2363
+ */
2364
+ declare function requiresTreeValidation(config: ValidatorConfig): boolean;
2349
2365
  /**
2350
2366
  * Detects if a StateLogicConfig has a cross-field condition.
2351
2367
  *
@@ -2645,8 +2661,13 @@ declare class FieldContextRegistryService {
2645
2661
  /**
2646
2662
  * Resolves external data signals to their current values.
2647
2663
  *
2648
- * @param reactive - If true, reads signals reactively (creates dependencies).
2649
- * If false, reads signals with untracked() (no dependencies).
2664
+ * Always reads reactively. Unlike the field value and form value (which are
2665
+ * read untracked to break the validator -> state -> valid -> validator cycle),
2666
+ * externalData is one-directional external input that validation output can
2667
+ * never feed back into, so tracking it cannot cause a cycle. Reading it
2668
+ * reactively is what lets dynamic values and validators bound to externalData
2669
+ * update when it changes.
2670
+ *
2650
2671
  * @returns Record of resolved external data values, or undefined if no external data.
2651
2672
  */
2652
2673
  private resolveExternalData;
@@ -3440,6 +3461,21 @@ declare function dynamicTextToObservable(value: DynamicText | undefined, injecto
3440
3461
  /** Normalises a {@link DynamicValue} into a `Signal<T>`. */
3441
3462
  declare function resolveDynamicValue<T>(value: DynamicValue<T> | undefined, fallback: T, injector?: Injector): Signal<T>;
3442
3463
 
3464
+ /**
3465
+ * Generates CSS class string for responsive grid layout based on field column configuration.
3466
+ *
3467
+ * @param fieldDef - Field definition containing column configuration
3468
+ * @returns CSS class string for grid layout, empty if no valid column configuration
3469
+ */
3470
+ declare function getGridClassString(fieldDef: FieldDef<unknown>): string;
3471
+ /**
3472
+ * Builds a combined className string from a field definition.
3473
+ *
3474
+ * @param fieldDef - Field definition containing className and col properties
3475
+ * @returns Combined class string, or undefined if no classes
3476
+ */
3477
+ declare function buildClassName(fieldDef: FieldDef<unknown>): string | undefined;
3478
+
3443
3479
  /**
3444
3480
  * Injection token for configuring the initialization timeout in milliseconds.
3445
3481
  * Defaults to 10 seconds. When the timeout is reached, a warning is logged
@@ -3478,9 +3514,13 @@ declare function interpolateParams(message: string, error: ValidationError): str
3478
3514
  /**
3479
3515
  * Performs a deep equality comparison between two values.
3480
3516
  *
3517
+ * Symbol-keyed properties are intentionally ignored: form values carry
3518
+ * enumerable symbol metadata stamped by Angular Signal Forms, and comparing it
3519
+ * would make structurally equal values compare unequal. Only string keys count.
3520
+ *
3481
3521
  * @param a - First value
3482
3522
  * @param b - Second value
3483
- * @returns true if values are deeply equal
3523
+ * @returns true if values are deeply equal by their string-keyed properties
3484
3524
  */
3485
3525
  declare function isEqual(a: unknown, b: unknown): boolean;
3486
3526
  /**
@@ -3558,5 +3598,5 @@ declare function assertNever(value: never): never;
3558
3598
  */
3559
3599
  declare function withPreviousValue<T>(input: Resource<T>): Resource<T>;
3560
3600
 
3561
- export { ADDON_ACTION_HANDLERS, ADDON_ACTION_REGISTRY, ADDON_TYPE_COMPONENT_CACHE, ADDON_TYPE_DEFINITIONS, ADDON_TYPE_REGISTRY, ARRAY_CONTEXT, AsyncConditionFunctionCacheService, ComponentInitializedEvent, DEFAULT_PROPS, DEFAULT_VALIDATION_MESSAGES, DEFAULT_WRAPPERS, DEPRECATION_WARNING_TRACKER, DF_FIELD_TEMPLATES, DfAddonSlot, DynamicFormError, DynamicFormLogger, DynamicTextPipe, DynamicValueFunctionCacheService, EMIT_FORM_VALUE_ON_EVENTS, EXTERNAL_DATA, EventBus, ExpressionParser, ExpressionParserError, FIELD_REGISTRY, FIELD_SIGNAL_CONTEXT, FORM_ID_PREFIX, FORM_OPTIONS, FieldContextRegistryService, FunctionRegistryService, GROUP_CONTEXT, HTTP_CONDITION_CACHE, HttpConditionCache, HttpConditionFunctionCacheService, INITIALIZATION_TIMEOUT_MS, LogicFunctionCacheService, NoopLogger, READONLY_FIELD_TREE_CACHE, RootFormRegistryService, TokenType, WRAPPER_AUTO_ASSOCIATIONS, WRAPPER_COMPONENT_CACHE, WRAPPER_REGISTRY, applyMetaToElement, applyValidator, applyValidators, arrayFieldMapper, assertNever, baseFieldMapper, buildBaseInputs, compareValues, containerFieldMapper, createAddonActionRegistry, createDebouncedLogicFunction, createDefaultDerivationLogConfig, createDynamicValueFunction, createFormFieldStateMap, createInitializationTracker, createLogicFunction, createWarningTracker, deepMergeDefaults, derivedFromDeferred, detectFormMode, dynamicTextToObservable, evaluateCondition, evaluateNonFieldDisabled, evaluateNonFieldHidden, extractExpressionDependencies, extractStringDependencies, getArrayLength, getChangedKeys, getFieldValueHandling, getNestedValue, groupFieldMapper, hasChildFields, hasCrossFieldWhenCondition, hasFormValue, hasNestedProperty, hasTargetProperty, injectAddonTypeRegistry, injectFieldSignalContext, injectFieldsSupportingAddons, injectNonFieldEvaluationContext, interpolateParams, isArrayField, isCheckedField, isContainerField, isCrossFieldBuiltInValidator, isCrossFieldExpression, isCrossFieldSchema, isCrossFieldStateLogic, isCrossFieldValidator, isDerivationLogicConfig, isDisplayOnlyField, isEqual, isFieldBoundContext, isFormStateCondition, isFunctionHttpValidator, isGenericContainerField, isGroupField, isHiddenField, isLeafField, isNonPagedForm, isPageField, isPagedForm, isResourceBasedValidator, isRowField, isSimplifiedArrayField, isStateLogicConfig, isValidNonPagedForm, isValidPagedForm, isValueBearingField, isValueField, isWrapperTypeDefinition, keyBy, mapValues, memoize, normalizeFieldsArray, omit, pageFieldMapper, readFieldStateInfo, resolveDynamicValue, resolveHttpRequest, resolveNextButtonDisabled, resolveNonFieldDisabled, resolveNonFieldHidden, resolveSubmitButtonDisabled, resolveTokens, rowFieldMapper, runPresetAction, setupInitializationTracking, shouldLog, textFieldMapper, toReadonlyFieldTree, toReadonlyFieldTreeCached, validatePageNesting, withPreviousValue, writeToFieldValue };
3562
- export type { ASTNode, AddonActionContext, AddonActionHandler, AddonActionPreset, AddonShapeValidator, AddonSlot, AddonTypeDefinition, AddonTypeRegistryRef, AddonTypeSchema, AndCondition, AnyAddon, ArrayAllowedChildren, ArrayButtonConfig, ArrayComponent, ArrayContext, ArrayField, ArrayFieldTree, ArrayItemDefinition, ArrayItemTemplate, ArrayLiteralNode, ArrowFunctionNode, AsyncCondition, AsyncConditionFunction, AsyncCustomValidator, AsyncDerivationFunction, AsyncValidatorConfig, AvailableFieldTypes, BaseAddon, BaseCheckedField, BaseValidatorConfig, BaseValueField, BinaryOpNode, BuiltInValidatorConfig, ButtonLogicContext, CallExpressionNode, CheckedFieldComponent, CommonAddonActionPreset, CommonAddonSlot, ComparisonOperator, ComponentAddon, ComputedMemberAccessNode, ConditionalExpression, ConditionalNode, ContainerAllowedChildren, ContainerComponent, ContainerField, ContainerFieldTypes, ContainerLogicConfig, CrossFieldDetectionContext, CssWrapper, CustomCondition, CustomFnConfig, CustomFunction, CustomFunctionOptions, CustomFunctionScope, CustomValidator, CustomValidatorConfig, DeclarativeHttpValidatorConfig, DerivationLogConfig, DerivationLogLevel, DerivationLogicConfig, DerivedFromDeferredOptions, DynamicFormActionRegistry, DynamicFormAddonActionPresetRegistry, DynamicFormAddonRegistry, DynamicFormAddonSlotRegistry, DynamicFormFieldRegistry, DynamicText, DynamicValue, EvaluationContext, ExtractField, FieldAddonSupport, FieldAddonSupportEntry, FieldBoundAddonActionContext, FieldComponent, FieldDef, FieldMeta, FieldOption, FieldPathAccess, FieldRegistryContainers, FieldRegistryLeaves, FieldRegistryWrappers, FieldScope, FieldSignalContext, FieldStateContext, FieldStateInfo, FieldTreeRecord, FieldTypeDefinition, FieldValueCondition, FieldWithValidation, FieldWrapper, FormConfig, FormEvent, FormEventConstructor, FormFieldStateMap, FormMode, FormModeDetectionResult, FormOptions, FormStateCondition, FunctionHttpValidatorConfig, GroupAllowedChildren, GroupComponent, GroupContext, GroupField, HiddenField, HiddenScalar, HiddenValue, HttpCondition, HttpCustomValidator, HttpRequestConfig, HttpResourceRequest, HttpValidationResponseMapping, IdentifierNode, InferFormModel, InferFormValue, InitializationTrackingOptions, JavascriptCondition, LazyComponentLoader, LeafFieldTypes, LiteralNode, Logger, LogicConfig, LogicTrigger, MapperFn, MemberAccessNode, MemoizeOptions, NarrowField, NarrowFields, NextButtonOptions, NonFieldLogicConfig, NonFieldLogicContext, NonFieldLogicType, ObjectLiteralNode, OrCondition, OrphanAddonActionContext, PageAllowedChildren, PageField, PresetCollaborators, Prettify, ReadonlyFieldTree, RegisteredActionRef, RegisteredFieldTypes, RegisteredWrapperTypes, RenderReadyInput, ResolvedValidationExecutionConfig, ResolvedValueExclusionConfig, RowAllowedChildren, RowComponent, RowField, RowWrapper, SchemaApplicationConfig, SchemaDefinition, SimplifiedArrayField, StateLogicConfig, StateLogicType, SubmissionActionResult, SubmissionConfig, SubmitButtonOptions, TemplateAddon, TextAddon, TextElementType, TextField, TextProps, Token, TokenContext, UnaryOpNode, ValidationError, ValidationExecutionConfig, ValidationMessages, ValidatorConfig, ValueExclusionConfig, ValueFieldComponent, ValueHandlingMode, ValueType, WarningTracker, WithInputSignals, WrapperAutoAssociations, WrapperConfig, WrapperFieldInputs, WrapperTypeDefinition };
3601
+ export { ADDON_ACTION_HANDLERS, ADDON_ACTION_REGISTRY, ADDON_TYPE_COMPONENT_CACHE, ADDON_TYPE_DEFINITIONS, ADDON_TYPE_REGISTRY, ARRAY_CONTEXT, AsyncConditionFunctionCacheService, ComponentInitializedEvent, DEFAULT_PROPS, DEFAULT_VALIDATION_MESSAGES, DEFAULT_WRAPPERS, DEPRECATION_WARNING_TRACKER, DF_FIELD_TEMPLATES, DfAddonSlot, DynamicFormError, DynamicFormLogger, DynamicTextPipe, DynamicValueFunctionCacheService, EMIT_FORM_VALUE_ON_EVENTS, EXTERNAL_DATA, EventBus, ExpressionParser, ExpressionParserError, FIELD_REGISTRY, FIELD_SIGNAL_CONTEXT, FORM_ID_PREFIX, FORM_OPTIONS, FieldContextRegistryService, FunctionRegistryService, GROUP_CONTEXT, HTTP_CONDITION_CACHE, HttpConditionCache, HttpConditionFunctionCacheService, INITIALIZATION_TIMEOUT_MS, LogicFunctionCacheService, NoopLogger, READONLY_FIELD_TREE_CACHE, RootFormRegistryService, TokenType, WRAPPER_AUTO_ASSOCIATIONS, WRAPPER_COMPONENT_CACHE, WRAPPER_REGISTRY, applyMetaToElement, applyValidator, applyValidators, arrayFieldMapper, assertNever, baseFieldMapper, buildBaseInputs, buildClassName, compareValues, containerFieldMapper, createAddonActionRegistry, createDebouncedLogicFunction, createDefaultDerivationLogConfig, createDynamicValueFunction, createFormFieldStateMap, createInitializationTracker, createLogicFunction, createWarningTracker, deepMergeDefaults, derivedFromDeferred, detectFormMode, dynamicTextToObservable, evaluateCondition, evaluateNonFieldDisabled, evaluateNonFieldHidden, extractExpressionDependencies, extractStringDependencies, getArrayLength, getChangedKeys, getFieldValueHandling, getGridClassString, getNestedValue, groupFieldMapper, hasChildFields, hasCrossFieldWhenCondition, hasFormValue, hasNestedProperty, hasTargetProperty, injectAddonTypeRegistry, injectFieldSignalContext, injectFieldsSupportingAddons, injectNonFieldEvaluationContext, interpolateParams, isArrayField, isCheckedField, isContainerField, isCrossFieldBuiltInValidator, isCrossFieldExpression, isCrossFieldSchema, isCrossFieldStateLogic, isCrossFieldValidator, isDerivationLogicConfig, isDisplayOnlyField, isEqual, isFieldBoundContext, isFormStateCondition, isFunctionHttpValidator, isGenericContainerField, isGroupField, isHiddenField, isLeafField, isNonPagedForm, isPageField, isPagedForm, isResourceBasedValidator, isRowField, isSimplifiedArrayField, isStateLogicConfig, isValidNonPagedForm, isValidPagedForm, isValueBearingField, isValueField, isWrapperTypeDefinition, keyBy, mapValues, memoize, normalizeFieldsArray, omit, pageFieldMapper, readFieldStateInfo, requiresTreeValidation, resolveDynamicValue, resolveHttpRequest, resolveNextButtonDisabled, resolveNonFieldDisabled, resolveNonFieldHidden, resolveSubmitButtonDisabled, resolveTokens, rowFieldMapper, runPresetAction, setupInitializationTracking, shouldLog, textFieldMapper, toReadonlyFieldTree, toReadonlyFieldTreeCached, validatePageNesting, withPreviousValue, writeToFieldValue };
3602
+ export type { ASTNode, AddonActionContext, AddonActionHandler, AddonActionPreset, AddonShapeValidator, AddonSlot, AddonTypeDefinition, AddonTypeRegistryRef, AddonTypeSchema, AndCondition, AnyAddon, ArrayAllowedChildren, ArrayButtonConfig, ArrayComponent, ArrayContext, ArrayField, ArrayFieldTree, ArrayItemDefinition, ArrayItemTemplate, ArrayLiteralNode, ArrowFunctionNode, AsyncCondition, AsyncConditionFunction, AsyncCustomValidator, AsyncDerivationFunction, AsyncValidatorConfig, AvailableFieldTypes, BaseAddon, BaseCheckedField, BaseValidatorConfig, BaseValueField, BinaryOpNode, BuiltInValidatorConfig, ButtonLogicContext, CallExpressionNode, CheckedFieldComponent, CommonAddonActionPreset, CommonAddonSlot, ComparisonOperator, ComponentAddon, ComputedMemberAccessNode, ConditionalExpression, ConditionalNode, ContainerAllowedChildren, ContainerComponent, ContainerField, ContainerFieldTypes, ContainerLogicConfig, CrossFieldDetectionContext, CssWrapper, CustomCondition, CustomFnConfig, CustomFunction, CustomFunctionOptions, CustomFunctionScope, CustomValidator, CustomValidatorConfig, DeclarativeHttpValidatorConfig, DerivationLogConfig, DerivationLogLevel, DerivationLogicConfig, DerivedFromDeferredOptions, DynamicFormActionRegistry, DynamicFormAddonActionPresetRegistry, DynamicFormAddonRegistry, DynamicFormAddonSlotRegistry, DynamicFormFieldRegistry, DynamicText, DynamicValue, EvaluationContext, ExtractField, FieldAddonSupport, FieldAddonSupportEntry, FieldBoundAddonActionContext, FieldComponent, FieldDef, FieldMeta, FieldOption, FieldPathAccess, FieldRegistryContainers, FieldRegistryLeaves, FieldRegistryWrappers, FieldScope, FieldSignalContext, FieldStateContext, FieldStateInfo, FieldTreeRecord, FieldTypeDefinition, FieldValueCondition, FieldWithValidation, FieldWrapper, FormConfig, FormEvent, FormEventConstructor, FormFieldStateMap, FormMode, FormModeDetectionResult, FormOptions, FormStateCondition, FunctionHttpValidatorConfig, GroupAllowedChildren, GroupComponent, GroupContext, GroupField, HiddenField, HiddenScalar, HiddenValue, HttpCondition, HttpCustomValidator, HttpRequestConfig, HttpResourceRequest, HttpValidationResponseMapping, IdentifierNode, InferFormModel, InferFormValue, InitializationTrackingOptions, JavascriptCondition, LazyComponentLoader, LeafFieldTypes, LiteralNode, Logger, LogicConfig, LogicTrigger, MapperFn, MemberAccessNode, MemoizeOptions, NarrowField, NarrowFields, NextButtonOptions, NonFieldLogicConfig, NonFieldLogicContext, NonFieldLogicType, ObjectLiteralNode, OrCondition, OrphanAddonActionContext, PageAllowedChildren, PageField, PresetCollaborators, Prettify, ReadonlyFieldTree, RegisteredActionRef, RegisteredFieldTypes, RegisteredWrapperTypes, RenderReadyInput, ResolvedValidationExecutionConfig, ResolvedValueExclusionConfig, RowAllowedChildren, RowComponent, RowField, RowWrapper, SchemaApplicationConfig, SchemaDefinition, SimplifiedArrayField, StateLogicConfig, StateLogicType, SubmissionActionResult, SubmissionConfig, SubmitButtonOptions, TemplateAddon, TextAddon, TextElementType, TextField, TextProps, Token, TokenContext, UnaryOpNode, ValidationError, ValidationExecutionConfig, ValidationMessage, ValidationMessageResolver, ValidationMessages, ValidatorConfig, ValueExclusionConfig, ValueFieldComponent, ValueHandlingMode, ValueType, WarningTracker, WithInputSignals, WrapperAutoAssociations, WrapperConfig, WrapperFieldInputs, WrapperTypeDefinition };
@@ -0,0 +1,58 @@
1
+ import { Provider, WritableSignal, Type } from '@angular/core';
2
+ import { ComponentFixture } from '@angular/core/testing';
3
+ import { SchemaPath, FieldTree } from '@angular/forms/signals';
4
+ import { FormEvent, FormEventConstructor } from '@ng-forge/dynamic-forms';
5
+ import { DynamicText, EventBus, ValidationMessages } from '@ng-forge/dynamic-forms/internal';
6
+
7
+ /** Structural copy of integration's EventArgs; importing it would cycle the entrypoints. */
8
+ type EventArgs = readonly (string | number | boolean | null | undefined)[];
9
+ interface CreateNgForgeFieldFixtureOptions<TValue = unknown> {
10
+ /** Field key. Becomes the only property on the wrapping form. */
11
+ readonly key: string;
12
+ /** Initial value for the field. */
13
+ readonly value?: TValue;
14
+ /** Optional schema callback that receives the field's `SchemaPath`. Use it to attach validators (`required`, `minLength`, etc.). */
15
+ readonly schema?: (fieldPath: SchemaPath<TValue>) => void;
16
+ /** Mark the field as touched after creation (useful for invalid-state assertions). */
17
+ readonly touched?: boolean;
18
+ /** Extra inputs to set on the component before `detectChanges()`. */
19
+ readonly inputs?: Record<string, unknown>;
20
+ /** Extra TestBed providers. */
21
+ readonly providers?: readonly Provider[];
22
+ }
23
+ interface NgForgeFieldFixture<C, TValue = unknown> {
24
+ readonly fixture: ComponentFixture<C>;
25
+ readonly field: FieldTree<TValue>;
26
+ readonly rootValue: WritableSignal<Record<string, TValue>>;
27
+ }
28
+ /**
29
+ * Builds a `ComponentFixture` for an `NgForgeField`-composing component with
30
+ * `field` + `key` bound BEFORE `detectChanges()` — sidesteps the NG0950 that
31
+ * Shell's required `key` and Field's required `field` would otherwise throw.
32
+ */
33
+ declare function createNgForgeFieldFixture<C, TValue = unknown>(component: Type<C>, options: CreateNgForgeFieldFixtureOptions<TValue>): NgForgeFieldFixture<C, TValue>;
34
+ interface CreateNgForgeActionFixtureOptions<TEvent extends FormEvent = FormEvent> {
35
+ readonly key: string;
36
+ readonly label: DynamicText;
37
+ readonly event?: FormEventConstructor<TEvent>;
38
+ readonly eventArgs?: EventArgs;
39
+ readonly disabled?: boolean;
40
+ readonly hidden?: boolean;
41
+ readonly inputs?: Record<string, unknown>;
42
+ readonly providers?: readonly Provider[];
43
+ }
44
+ interface NgForgeActionFixture<C> {
45
+ readonly fixture: ComponentFixture<C>;
46
+ readonly eventBus: EventBus;
47
+ }
48
+ /**
49
+ * Builds a `ComponentFixture` for an `NgForgeAction`-composing component with
50
+ * `key` + `label` bound and `EventBus` provided. The caller calls
51
+ * `detectChanges()`; the harness handles the NG0950-avoidance bindings.
52
+ */
53
+ declare function createNgForgeActionFixture<C, TEvent extends FormEvent = FormEvent>(component: Type<C>, options: CreateNgForgeActionFixtureOptions<TEvent>): NgForgeActionFixture<C>;
54
+ /** Provider for `DEFAULT_VALIDATION_MESSAGES` in field tests — supply the default-messages map and the directive resolves it from DI. */
55
+ declare function provideTestValidationMessages(messages: ValidationMessages): Provider;
56
+
57
+ export { createNgForgeActionFixture, createNgForgeFieldFixture, provideTestValidationMessages };
58
+ export type { CreateNgForgeActionFixtureOptions, CreateNgForgeFieldFixtureOptions, NgForgeActionFixture, NgForgeFieldFixture };
@@ -3,7 +3,7 @@ import * as _angular_core from '@angular/core';
3
3
  import { Type, Injector, Signal, EnvironmentInjector, WritableSignal, Provider, EnvironmentProviders, TemplateRef } from '@angular/core';
4
4
  import * as _ng_forge_dynamic_forms_internal from '@ng-forge/dynamic-forms/internal';
5
5
  import { FieldDef, FormEvent, RegisteredFieldTypes, InferFormModel, FormConfig, FormOptions, EventBus, LazyComponentLoader, WrapperTypeDefinition, FieldTypeDefinition, InferFormValue as InferFormValue$1, DerivationLogLevel, Logger, ValueExclusionConfig, ValidationExecutionConfig, TextAddon, WrapperFieldInputs, TemplateAddon, ComponentAddon, BaseAddon, AddonTypeDefinition, AddonActionHandler, ArrayItemDefinition } from '@ng-forge/dynamic-forms/internal';
6
- export { AddonActionContext, AddonActionPreset, AddonSlot, AddonTypeDefinition, AnyAddon, ArrayAllowedChildren, ArrayButtonConfig, ArrayField, ArrayItemTemplate, AsyncCondition, AsyncConditionFunction, AsyncCustomValidator, AsyncDerivationFunction, AsyncValidatorConfig, AvailableFieldTypes, BaseAddon, BaseCheckedField, BaseValidatorConfig, BaseValueField, BuiltInValidatorConfig, CheckedFieldComponent, CommonAddonActionPreset, CommonAddonSlot, ComponentAddon, ConditionalExpression, ContainerAllowedChildren, ContainerField, ContainerFieldTypes, CssWrapper, CustomFnConfig, CustomFunction, CustomValidator, CustomValidatorConfig, DF_FIELD_TEMPLATES, DeclarativeHttpValidatorConfig, DynamicFormActionRegistry, DynamicFormAddonActionPresetRegistry, DynamicFormAddonRegistry, DynamicFormAddonSlotRegistry, DynamicFormError, DynamicFormFieldRegistry, DynamicFormLogger, DynamicText, DynamicValue, EvaluationContext, ExtractField, FieldBoundAddonActionContext, FieldComponent, FieldDef, FieldMeta, FieldOption, FieldPathAccess, FieldRegistryContainers, FieldRegistryLeaves, FieldRegistryWrappers, FieldWithValidation, FieldWrapper, FormConfig, FormEvent, FormEventConstructor, FormMode, FormModeDetectionResult, FormOptions, FormStateCondition, GroupAllowedChildren, GroupField, HiddenField, HiddenScalar, HiddenValue, HttpCondition, HttpCustomValidator, HttpRequestConfig, HttpValidationResponseMapping, InferFormValue, LeafFieldTypes, Logger, LogicConfig, NarrowField, NarrowFields, NextButtonOptions, NoopLogger, OrphanAddonActionContext, PageAllowedChildren, PageField, RegisteredActionRef, RegisteredFieldTypes, ResolvedValidationExecutionConfig, ResolvedValueExclusionConfig, RowAllowedChildren, RowField, SchemaApplicationConfig, SchemaDefinition, SimplifiedArrayField, StateLogicConfig, SubmissionActionResult, SubmissionConfig, SubmitButtonOptions, TemplateAddon, TextAddon, TextElementType, TextField, TextProps, TokenContext, ValidationError, ValidationExecutionConfig, ValidationMessages, ValidatorConfig, ValueExclusionConfig, ValueFieldComponent, ValueType, WithInputSignals, WrapperConfig, WrapperTypeDefinition, hasFormValue, isArrayField, isContainerField, isDisplayOnlyField, isFieldBoundContext, isFormStateCondition, isGroupField, isHiddenField, isLeafField, isPageField, isRowField, isSimplifiedArrayField, isValueBearingField, isWrapperTypeDefinition, resolveDynamicValue } from '@ng-forge/dynamic-forms/internal';
6
+ export { AddonActionContext, AddonActionPreset, AddonSlot, AddonTypeDefinition, AnyAddon, ArrayAllowedChildren, ArrayButtonConfig, ArrayField, ArrayItemTemplate, AsyncCondition, AsyncConditionFunction, AsyncCustomValidator, AsyncDerivationFunction, AsyncValidatorConfig, AvailableFieldTypes, BaseAddon, BaseCheckedField, BaseValidatorConfig, BaseValueField, BuiltInValidatorConfig, CheckedFieldComponent, CommonAddonActionPreset, CommonAddonSlot, ComponentAddon, ConditionalExpression, ContainerAllowedChildren, ContainerField, ContainerFieldTypes, CssWrapper, CustomFnConfig, CustomFunction, CustomValidator, CustomValidatorConfig, DF_FIELD_TEMPLATES, DeclarativeHttpValidatorConfig, DynamicFormActionRegistry, DynamicFormAddonActionPresetRegistry, DynamicFormAddonRegistry, DynamicFormAddonSlotRegistry, DynamicFormError, DynamicFormFieldRegistry, DynamicFormLogger, DynamicText, DynamicValue, EvaluationContext, ExtractField, FieldBoundAddonActionContext, FieldComponent, FieldDef, FieldMeta, FieldOption, FieldPathAccess, FieldRegistryContainers, FieldRegistryLeaves, FieldRegistryWrappers, FieldWithValidation, FieldWrapper, FormConfig, FormEvent, FormEventConstructor, FormMode, FormModeDetectionResult, FormOptions, FormStateCondition, GroupAllowedChildren, GroupField, HiddenField, HiddenScalar, HiddenValue, HttpCondition, HttpCustomValidator, HttpRequestConfig, HttpValidationResponseMapping, InferFormValue, LeafFieldTypes, Logger, LogicConfig, NarrowField, NarrowFields, NextButtonOptions, NoopLogger, OrphanAddonActionContext, PageAllowedChildren, PageField, RegisteredActionRef, RegisteredFieldTypes, ResolvedValidationExecutionConfig, ResolvedValueExclusionConfig, RowAllowedChildren, RowField, SchemaApplicationConfig, SchemaDefinition, SimplifiedArrayField, StateLogicConfig, SubmissionActionResult, SubmissionConfig, SubmitButtonOptions, TemplateAddon, TextAddon, TextElementType, TextField, TextProps, TokenContext, ValidationError, ValidationExecutionConfig, ValidationMessage, ValidationMessageResolver, ValidationMessages, ValidatorConfig, ValueExclusionConfig, ValueFieldComponent, ValueType, WithInputSignals, WrapperConfig, WrapperTypeDefinition, hasFormValue, isArrayField, isContainerField, isDisplayOnlyField, isFieldBoundContext, isFormStateCondition, isGroupField, isHiddenField, isLeafField, isPageField, isRowField, isSimplifiedArrayField, isValueBearingField, isWrapperTypeDefinition, resolveDynamicValue } from '@ng-forge/dynamic-forms/internal';
7
7
  import * as _angular_forms_signals from '@angular/forms/signals';
8
8
  import { FieldTree } from '@angular/forms/signals';
9
9
  import * as _angular_forms from '@angular/forms';