@ng-forge/dynamic-forms 1.2.0-next.1 → 1.2.0-next.10

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 (50) hide show
  1. package/README.md +11 -11
  2. package/fesm2022/{ng-forge-dynamic-forms-array-field.component-BVnXnaNw.mjs → ng-forge-dynamic-forms-array-field.component-CSCKq_1K.mjs} +9 -13
  3. package/fesm2022/ng-forge-dynamic-forms-array-field.component-CSCKq_1K.mjs.map +1 -0
  4. package/fesm2022/{ng-forge-dynamic-forms-bootstrap-derivation-orchestrator-CkqvXXs_.mjs → ng-forge-dynamic-forms-bootstrap-derivation-orchestrator-CTOTwzzw.mjs} +29 -7
  5. package/fesm2022/ng-forge-dynamic-forms-bootstrap-derivation-orchestrator-CTOTwzzw.mjs.map +1 -0
  6. package/fesm2022/ng-forge-dynamic-forms-bootstrap-web-mcp-BtjqeJOj.mjs +1054 -0
  7. package/fesm2022/ng-forge-dynamic-forms-bootstrap-web-mcp-BtjqeJOj.mjs.map +1 -0
  8. package/fesm2022/{ng-forge-dynamic-forms-container-field.component-CM1pY9v5.mjs → ng-forge-dynamic-forms-container-field.component-Dc3ROhHL.mjs} +14 -17
  9. package/fesm2022/ng-forge-dynamic-forms-container-field.component-Dc3ROhHL.mjs.map +1 -0
  10. package/fesm2022/{ng-forge-dynamic-forms-css-wrapper.component-D_yRuLpu.mjs → ng-forge-dynamic-forms-css-wrapper.component-BzgX8lAD.mjs} +5 -5
  11. package/fesm2022/ng-forge-dynamic-forms-css-wrapper.component-BzgX8lAD.mjs.map +1 -0
  12. package/fesm2022/ng-forge-dynamic-forms-debounce-C9F4v1Ke.mjs +17 -0
  13. package/fesm2022/ng-forge-dynamic-forms-debounce-C9F4v1Ke.mjs.map +1 -0
  14. package/fesm2022/ng-forge-dynamic-forms-field-errors-wrapper.component-CIKbWqYA.mjs +25 -0
  15. package/fesm2022/ng-forge-dynamic-forms-field-errors-wrapper.component-CIKbWqYA.mjs.map +1 -0
  16. package/fesm2022/ng-forge-dynamic-forms-form-schema.service-Dx5Dlb15.mjs +24 -0
  17. package/fesm2022/ng-forge-dynamic-forms-form-schema.service-Dx5Dlb15.mjs.map +1 -0
  18. package/fesm2022/{ng-forge-dynamic-forms-group-field.component-D4JhDffB.mjs → ng-forge-dynamic-forms-group-field.component-DAC3P9DC.mjs} +9 -13
  19. package/fesm2022/ng-forge-dynamic-forms-group-field.component-DAC3P9DC.mjs.map +1 -0
  20. package/fesm2022/ng-forge-dynamic-forms-integration.mjs +43 -105
  21. package/fesm2022/ng-forge-dynamic-forms-integration.mjs.map +1 -1
  22. package/fesm2022/ng-forge-dynamic-forms-internal.mjs +290 -116
  23. package/fesm2022/ng-forge-dynamic-forms-internal.mjs.map +1 -1
  24. package/fesm2022/{ng-forge-dynamic-forms-ng-forge-dynamic-forms-ZiNaCWHl.mjs → ng-forge-dynamic-forms-ng-forge-dynamic-forms-CXQe_5td.mjs} +1871 -1632
  25. package/fesm2022/ng-forge-dynamic-forms-ng-forge-dynamic-forms-CXQe_5td.mjs.map +1 -0
  26. package/fesm2022/{ng-forge-dynamic-forms-page-field.component-Wbz6S8iH.mjs → ng-forge-dynamic-forms-page-field.component-DPKJcwUO.mjs} +57 -16
  27. package/fesm2022/ng-forge-dynamic-forms-page-field.component-DPKJcwUO.mjs.map +1 -0
  28. package/fesm2022/{ng-forge-dynamic-forms-row-wrapper.component-BBWmqQA_.mjs → ng-forge-dynamic-forms-row-wrapper.component-DMEeKZny.mjs} +5 -5
  29. package/fesm2022/ng-forge-dynamic-forms-row-wrapper.component-DMEeKZny.mjs.map +1 -0
  30. package/fesm2022/ng-forge-dynamic-forms-schema-builder-BvDTzfdM.mjs +570 -0
  31. package/fesm2022/ng-forge-dynamic-forms-schema-builder-BvDTzfdM.mjs.map +1 -0
  32. package/fesm2022/{ng-forge-dynamic-forms-text-field.component-C-f80sbk.mjs → ng-forge-dynamic-forms-text-field.component-BB-jutBq.mjs} +4 -4
  33. package/fesm2022/{ng-forge-dynamic-forms-text-field.component-C-f80sbk.mjs.map → ng-forge-dynamic-forms-text-field.component-BB-jutBq.mjs.map} +1 -1
  34. package/fesm2022/ng-forge-dynamic-forms.mjs +2 -2
  35. package/package.json +2 -2
  36. package/types/ng-forge-dynamic-forms-integration.d.ts +7 -31
  37. package/types/ng-forge-dynamic-forms-internal.d.ts +669 -308
  38. package/types/ng-forge-dynamic-forms.d.ts +287 -33
  39. package/fesm2022/ng-forge-dynamic-forms-array-field.component-BVnXnaNw.mjs.map +0 -1
  40. package/fesm2022/ng-forge-dynamic-forms-bootstrap-derivation-orchestrator-CkqvXXs_.mjs.map +0 -1
  41. package/fesm2022/ng-forge-dynamic-forms-container-field.component-CM1pY9v5.mjs.map +0 -1
  42. package/fesm2022/ng-forge-dynamic-forms-container-utils-BZFz6ztF.mjs +0 -24
  43. package/fesm2022/ng-forge-dynamic-forms-container-utils-BZFz6ztF.mjs.map +0 -1
  44. package/fesm2022/ng-forge-dynamic-forms-css-wrapper.component-D_yRuLpu.mjs.map +0 -1
  45. package/fesm2022/ng-forge-dynamic-forms-emit-initialization-DhHwU6FJ.mjs +0 -17
  46. package/fesm2022/ng-forge-dynamic-forms-emit-initialization-DhHwU6FJ.mjs.map +0 -1
  47. package/fesm2022/ng-forge-dynamic-forms-group-field.component-D4JhDffB.mjs.map +0 -1
  48. package/fesm2022/ng-forge-dynamic-forms-ng-forge-dynamic-forms-ZiNaCWHl.mjs.map +0 -1
  49. package/fesm2022/ng-forge-dynamic-forms-page-field.component-Wbz6S8iH.mjs.map +0 -1
  50. package/fesm2022/ng-forge-dynamic-forms-row-wrapper.component-BBWmqQA_.mjs.map +0 -1
@@ -1,8 +1,8 @@
1
1
  import * as _ng_forge_dynamic_forms_internal from '@ng-forge/dynamic-forms/internal';
2
2
  import * as i0 from '@angular/core';
3
- import { Signal, Type, ResourceRef, ViewContainerRef, InjectionToken, WritableSignal, Injector, TemplateRef, PipeTransform, Resource } from '@angular/core';
3
+ import { Signal, Type, ResourceRef, ViewContainerRef, InjectionToken, WritableSignal, Injector, TemplateRef, PipeTransform, Resource, Provider } from '@angular/core';
4
4
  import { Observable, OperatorFunction } from 'rxjs';
5
- import { FieldContext, TreeValidationResult, ValidationError as ValidationError$1, FieldTree, ReadonlyFieldState, LogicFn, SchemaPath, SchemaPathTree } from '@angular/forms/signals';
5
+ import { FieldContext, ValidationError as ValidationError$1, TreeValidationResult, FieldTree, ReadonlyFieldState, LogicFn, SchemaPath, SchemaPathTree } from '@angular/forms/signals';
6
6
  import { FormSchema } from '@ng-forge/dynamic-forms/schema';
7
7
 
8
8
  type DynamicText = string | Observable<string> | Signal<string>;
@@ -83,6 +83,45 @@ interface FieldMeta {
83
83
  [key: string]: string | number | boolean | undefined;
84
84
  }
85
85
 
86
+ /**
87
+ * Per-field WebMCP exposure policy.
88
+ *
89
+ * WebMCP tools are callable by any agent that reaches the page, so what a field
90
+ * lets an agent read and write is a security decision, not a formatting one.
91
+ * Sensible defaults are derived from the field itself (see below); this
92
+ * overrides them where the author knows better.
93
+ *
94
+ * Defaults, applied when a key is left unset:
95
+ *
96
+ * | Field | `readable` | `writable` |
97
+ * | --- | --- | --- |
98
+ * | `type: 'hidden'` | `false` | `false` |
99
+ * | `props.type === 'password'` | `false` | `true` |
100
+ * | `readonly: true`, or a `derivation` | `true` | `false` |
101
+ * | anything else | `true` | `true` |
102
+ *
103
+ * @experimental
104
+ */
105
+ interface FieldWebMcpOptions {
106
+ /**
107
+ * Whether an agent may read this field's value back in a tool response.
108
+ *
109
+ * A field that is not readable is still reported by name, so the agent knows
110
+ * it exists and whether it currently holds a value — only the value itself is
111
+ * withheld.
112
+ */
113
+ readable?: boolean;
114
+ /** Whether an agent may write this field. A write to a non-writable field is rejected. */
115
+ writable?: boolean;
116
+ }
117
+ /**
118
+ * A field's WebMCP exposure policy. `false` is shorthand for hiding the field
119
+ * from agents entirely (`{ readable: false, writable: false }`).
120
+ *
121
+ * @experimental
122
+ */
123
+ type FieldWebMcpConfig = FieldWebMcpOptions | false;
124
+
86
125
  /**
87
126
  * Base interface for all dynamic form field definitions.
88
127
  *
@@ -168,6 +207,17 @@ interface FieldDef<TProps, TMeta extends FieldMeta = FieldMeta> {
168
207
  skipDefaultWrappers?: boolean;
169
208
  /** Addons rendered inside this field's slots (typically `prefix` / `suffix`). */
170
209
  addons?: ReadonlyArray<AnyAddon>;
210
+ /**
211
+ * What a browser AI agent may read and write on this field, when the form
212
+ * opts in through `options.webMcp`. Ignored otherwise.
213
+ *
214
+ * Defaults are derived from the field (a password input is not readable, a
215
+ * `readonly` or derived field is not writable, a `hidden` field type is
216
+ * neither); `false` hides the field from agents entirely.
217
+ *
218
+ * @experimental
219
+ */
220
+ webMcp?: FieldWebMcpConfig;
171
221
  }
172
222
  type IncludedKeys = 'label' | 'className' | 'hidden' | 'tabIndex';
173
223
  /**
@@ -480,12 +530,242 @@ interface RowField<TFields extends readonly RowAllowedChildren[] = readonly RowA
480
530
  declare function isRowField(field: FieldDef<any>): field is RowField;
481
531
  type RowComponent = FieldComponent<RowField<RowAllowedChildren[]>>;
482
532
 
533
+ /**
534
+ * Custom validator function signature using Angular's public FieldContext API
535
+ *
536
+ * @template TValue The type of value stored in the field being validated
537
+ */
538
+ type CustomValidator<TValue = unknown> = (ctx: FieldContext<TValue>, params?: Record<string, unknown>) => ValidationError$1 | ValidationError$1[] | null;
539
+ /**
540
+ * Async custom validator configuration using Angular's resource-based API
541
+ *
542
+ * @template TValue The type of value stored in the field being validated
543
+ * @template TParams The type of params passed to the resource
544
+ * @template TResult The type of result returned by the resource
545
+ */
546
+ interface AsyncCustomValidator<TValue = unknown, TParams = unknown, TResult = unknown> {
547
+ /**
548
+ * Function that receives field context and returns resource params.
549
+ * Params will be tracked as a signal and trigger resource reload when changed.
550
+ */
551
+ readonly params: (ctx: FieldContext<TValue>, config?: Record<string, unknown>) => TParams;
552
+ /**
553
+ * Function that creates a ResourceRef from the params signal.
554
+ * The resource will be automatically managed by Angular's lifecycle.
555
+ */
556
+ readonly factory: (params: Signal<TParams | undefined>) => ResourceRef<TResult | undefined>;
557
+ /**
558
+ * Optional function to map successful resource result to validation errors.
559
+ * Return null if validation passes, or ValidationError/ValidationError[] if validation fails.
560
+ */
561
+ readonly onSuccess?: (result: TResult, ctx: FieldContext<TValue>) => TreeValidationResult;
562
+ /**
563
+ * Optional error handler for resource errors (network failures, etc.).
564
+ * Return null to ignore the error, or ValidationError to display it to the user.
565
+ */
566
+ readonly onError?: (error: unknown, ctx: FieldContext<TValue>) => ValidationError$1 | ValidationError$1[] | null;
567
+ }
568
+ /** HTTP request configuration for validateHttp API */
569
+ interface HttpResourceRequest {
570
+ url: string;
571
+ method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
572
+ body?: unknown;
573
+ headers?: Record<string, string | string[]>;
574
+ }
575
+ /**
576
+ * HTTP-based validator configuration for Angular's validateHttp API
577
+ *
578
+ * @template TValue The type of value stored in the field being validated
579
+ * @template TResult The type of HTTP response
580
+ */
581
+ interface HttpCustomValidator<TValue = unknown, TResult = unknown> {
582
+ /**
583
+ * Function that returns the HTTP request configuration.
584
+ * Can return:
585
+ * - `undefined` to skip validation (e.g., if field is empty)
586
+ * - `string` for simple GET requests (just the URL)
587
+ * - `HttpResourceRequest` for full control (method, body, headers)
588
+ */
589
+ readonly request: (ctx: FieldContext<TValue>, config?: Record<string, unknown>) => string | HttpResourceRequest | undefined;
590
+ /** REQUIRED function to map successful HTTP response to validation errors. */
591
+ readonly onSuccess: (result: TResult, ctx: FieldContext<TValue>) => TreeValidationResult;
592
+ /**
593
+ * Optional error handler for HTTP errors (network failures, 4xx/5xx status codes).
594
+ * Return null to ignore the error, or ValidationError to display it to the user.
595
+ */
596
+ readonly onError?: (error: unknown, ctx: FieldContext<TValue>) => ValidationError$1 | ValidationError$1[] | null;
597
+ }
598
+
599
+ /** Mapping configuration for interpreting HTTP responses as validation results. */
600
+ interface HttpValidationResponseMapping {
601
+ /** Expression evaluated with scope `{ response }`. Must evaluate to `true` (strict boolean) to be valid. */
602
+ validWhen: string;
603
+ /** Error kind returned when validation fails — maps to field-level `validationMessages` */
604
+ errorKind: string;
605
+ /**
606
+ * Parameters to include in the validation error for message interpolation.
607
+ * Map of parameter names to expressions evaluated against `{ response }`.
608
+ */
609
+ errorParams?: Record<string, string>;
610
+ }
611
+
612
+ /** Base configuration shared by all validators */
613
+ interface BaseValidatorConfig {
614
+ /** Conditional logic for when validator applies */
615
+ when?: ConditionalExpression;
616
+ }
617
+ /** Built-in validator configuration (required, email, min, max, etc.) */
618
+ interface BuiltInValidatorConfig extends BaseValidatorConfig {
619
+ /** Validator type identifier */
620
+ type: 'required' | 'email' | 'min' | 'max' | 'minLength' | 'maxLength' | 'pattern';
621
+ /** Static value for the validator (e.g., min value, pattern) */
622
+ value?: number | string | RegExp;
623
+ /** Dynamic value expression that evaluates to validator parameter */
624
+ expression?: string;
625
+ }
626
+ /**
627
+ * Custom validator configuration using Angular's public FieldContext API.
628
+ * Returns ValidationError | ValidationError[] | null synchronously.
629
+ */
630
+ interface CustomValidatorConfig extends BaseValidatorConfig {
631
+ /** Validator type identifier */
632
+ type: 'custom';
633
+ /** Name of registered validator function (function-based pattern) */
634
+ functionName?: string;
635
+ /**
636
+ * Inline custom validator (code-only authoring).
637
+ * Mutually exclusive with `functionName`. NOT JSON-serializable.
638
+ */
639
+ fn?: CustomValidator;
640
+ /** Optional parameters to pass to validator function */
641
+ params?: Record<string, unknown>;
642
+ /** JavaScript expression to evaluate (expression-based pattern) */
643
+ expression?: string;
644
+ /** Error kind for expression-based validators - links to validationMessages */
645
+ kind?: string;
646
+ /**
647
+ * Parameters to include in error object for message interpolation (expression-based pattern)
648
+ * Map of parameter names to expressions that will be evaluated in the same context as the validation expression
649
+ */
650
+ errorParams?: Record<string, string>;
651
+ }
652
+ /**
653
+ * Shared fields for both branches of {@link AsyncValidatorConfig}.
654
+ *
655
+ * @internal
656
+ */
657
+ interface AsyncValidatorConfigShared extends BaseValidatorConfig {
658
+ /** Validator type identifier. */
659
+ type: 'async';
660
+ /** Optional parameters to pass to validator function */
661
+ params?: Record<string, unknown>;
662
+ }
663
+ /**
664
+ * Async custom validator configuration using Angular's `validateAsync` API.
665
+ * Returns Observable<ValidationError | ValidationError[] | null>.
666
+ */
667
+ type AsyncValidatorConfig = (AsyncValidatorConfigShared & {
668
+ /** Name of registered async validator function */
669
+ functionName: string;
670
+ /** Inline form is forbidden when `functionName` is set */
671
+ fn?: never;
672
+ }) | (AsyncValidatorConfigShared & {
673
+ /** Inline async validator. Mutually exclusive with `functionName`. */
674
+ fn: AsyncCustomValidator;
675
+ /** Registered form is forbidden when `fn` is set */
676
+ functionName?: never;
677
+ });
678
+ /**
679
+ * Shared fields for both branches of {@link FunctionHttpValidatorConfig}.
680
+ *
681
+ * @internal
682
+ */
683
+ interface FunctionHttpValidatorConfigShared extends BaseValidatorConfig {
684
+ /** Validator type identifier. */
685
+ type: 'http';
686
+ /** Optional parameters to pass to HTTP validator */
687
+ params?: Record<string, unknown>;
688
+ }
689
+ /** Function-based HTTP validator configuration. Uses Angular's `validateHttp` API. */
690
+ type FunctionHttpValidatorConfig = (FunctionHttpValidatorConfigShared & {
691
+ /** Name of registered HTTP validator configuration */
692
+ functionName: string;
693
+ /** Inline form is forbidden when `functionName` is set */
694
+ fn?: never;
695
+ }) | (FunctionHttpValidatorConfigShared & {
696
+ /** Inline HTTP validator. Mutually exclusive with `functionName`. */
697
+ fn: HttpCustomValidator;
698
+ /** Registered form is forbidden when `fn` is set */
699
+ functionName?: never;
700
+ });
701
+ /** Declarative HTTP validator configuration — fully JSON-serializable, no function registration required. */
702
+ interface DeclarativeHttpValidatorConfig extends BaseValidatorConfig {
703
+ /** Validator type identifier */
704
+ type: 'http';
705
+ /** HTTP request configuration with expression-based query params and body */
706
+ http: HttpRequestConfig;
707
+ /** Mapping that interprets the HTTP response as a validation result */
708
+ responseMapping: HttpValidationResponseMapping;
709
+ }
710
+ /**
711
+ * Configuration for signal forms validator functions that can be serialized from API.
712
+ * Discriminated union type for type-safe validator configuration.
713
+ */
714
+ type ValidatorConfig = BuiltInValidatorConfig | CustomValidatorConfig | AsyncValidatorConfig | FunctionHttpValidatorConfig | DeclarativeHttpValidatorConfig;
715
+ /** Type guard to distinguish function-based HTTP validators from declarative ones. */
716
+ declare function isFunctionHttpValidator(config: FunctionHttpValidatorConfig | DeclarativeHttpValidatorConfig): config is FunctionHttpValidatorConfig;
717
+
718
+ /**
719
+ * Re-export Angular's ValidationError for consistency
720
+ * This replaces our custom ValidationError interface
721
+ */
722
+ type ValidationError = ValidationError$1;
723
+ /**
724
+ * Resolves a validation message from the validation error, so error params
725
+ * (e.g. maxLength, min) can be passed to an i18n layer natively.
726
+ */
727
+ type ValidationMessageResolver = (error: ValidationError) => DynamicText;
728
+ /** A validation message: static or reactive text, or a function of the validation error. */
729
+ type ValidationMessage = DynamicText | ValidationMessageResolver;
730
+ interface ValidationMessages {
731
+ required?: ValidationMessage;
732
+ email?: ValidationMessage;
733
+ min?: ValidationMessage;
734
+ max?: ValidationMessage;
735
+ minLength?: ValidationMessage;
736
+ maxLength?: ValidationMessage;
737
+ pattern?: ValidationMessage;
738
+ [key: string]: ValidationMessage | undefined;
739
+ }
740
+
741
+ /**
742
+ * Tree-level validation for container fields (`group` / `array`).
743
+ *
744
+ * A validator here runs against the container's own subtree: `ctx.value()` is the group's
745
+ * object or the array's item list. Layout containers (`page`, `row`, `container`) flatten
746
+ * into their parent and have no schema path, so they are excluded.
747
+ */
748
+ interface ContainerValidation {
749
+ /**
750
+ * Marks every descendant required. An inherited default, not a rule on the container —
751
+ * a descendant's own `required` wins, including `false`. Use `minLength` for array size.
752
+ */
753
+ readonly required?: boolean;
754
+ /** Validators applied to the container's own schema path. Gated by `validateWhenHidden`. */
755
+ readonly validators?: ValidatorConfig[];
756
+ /**
757
+ * Messages keyed by error `kind`. Rendered by the `field-errors` wrapper, attached
758
+ * automatically when the container declares `validators`.
759
+ */
760
+ readonly validationMessages?: ValidationMessages;
761
+ }
762
+
483
763
  /**
484
764
  * Group field interface for creating logical field groupings that map to object values
485
765
  * Groups create nested form structures where child field values are collected into an object
486
766
  * This is a programmatic grouping only - users cannot customize this field type
487
767
  */
488
- interface GroupField<TFields extends readonly GroupAllowedChildren[] = readonly GroupAllowedChildren[]> extends FieldDef<never> {
768
+ interface GroupField<TFields extends readonly GroupAllowedChildren[] = readonly GroupAllowedChildren[]> extends FieldDef<never>, ContainerValidation {
489
769
  type: 'group';
490
770
  readonly fields: TFields;
491
771
  /** Groups do not have a label property - they are logical containers only * */
@@ -573,7 +853,7 @@ type ArrayItemTemplate = readonly ArrayAllowedChildren[];
573
853
  */
574
854
  type ArrayItemDefinition = ArrayAllowedChildren | ArrayItemTemplate;
575
855
  /** Array field interface for creating dynamic field collections that map to array values. */
576
- interface ArrayField<TFields extends readonly ArrayItemDefinition[] = readonly ArrayItemDefinition[]> extends FieldDef<never> {
856
+ interface ArrayField<TFields extends readonly ArrayItemDefinition[] = readonly ArrayItemDefinition[]> extends FieldDef<never>, ContainerValidation {
577
857
  type: 'array';
578
858
  /**
579
859
  * Array of item definitions. Each element defines one array item:
@@ -619,7 +899,7 @@ interface ArrayButtonConfig {
619
899
  readonly props?: Record<string, unknown>;
620
900
  }
621
901
  /** Simplified array field interface for common use cases. */
622
- interface SimplifiedArrayField extends FieldDef<never> {
902
+ interface SimplifiedArrayField extends FieldDef<never>, ContainerValidation {
623
903
  type: 'array';
624
904
  /**
625
905
  * Template defining the structure of a single array item.
@@ -795,282 +1075,97 @@ type InferSingleTemplateValueBase<T, D extends number> = T extends {
795
1075
  type: 'number';
796
1076
  };
797
1077
  } ? number : T extends {
798
- type: 'checkbox' | 'toggle';
799
- } ? boolean : T extends {
800
- value: infer V;
801
- } ? [V] extends [null] ? string : Widen<V, Depth[D]> : string;
802
- type InferSingleTemplateValue<T, D extends number> = T extends {
803
- nullable: true;
804
- } ? InferSingleTemplateValueBase<T, D> | null : InferSingleTemplateValueBase<T, D>;
805
- /**
806
- * Infers the value type for an array field.
807
- * Handles four cases:
808
- * 1. Simplified array with template + value → infer item type from value
809
- * 2. Simplified array with array template (no value) → infer object type from template fields
810
- * 3. Simplified array with single-field template (no value) → infer primitive type from template field
811
- * 4. Full-API array with fields → infer from children
812
- */
813
- type InferArrayValue<T, D extends number> = T extends {
814
- template: unknown;
815
- value: readonly (infer Item)[];
816
- } ? Widen<Item>[] : T extends {
817
- template: infer TArr;
818
- } ? TArr extends readonly RegisteredFieldTypes[] ? InferFormValueWithDepth<[...TArr], Depth[D]>[] : InferSingleTemplateValue<TArr, D>[] : T extends {
819
- fields: infer F;
820
- } ? InferContainerChildren<F, Depth[D], unknown>[] : unknown[];
821
- /**
822
- * Recurse into a container's child fields, but only when they form a fixed-length
823
- * tuple — i.e. a config authored with `as const`. A general `RegisteredFieldTypes[]`
824
- * array (notably the base default `InferFormValue<RegisteredFieldTypes[]>` over the
825
- * whole registry) bails to `TFallback`; recursing there would make the type explode
826
- * past TypeScript's union-complexity limit (TS2590) and break consumers of the
827
- * abstract `FormConfig`. `[...F]` re-mutabilises the readonly tuple for the inner
828
- * `InferFormValueWithDepth` constraint.
829
- */
830
- type InferContainerChildren<F, D extends number, TFallback> = F extends readonly RegisteredFieldTypes[] ? number extends F['length'] ? TFallback : InferFormValueWithDepth<[...F], D> : TFallback;
831
- /** Process a single field and determine its contribution to the form value type */
832
- type ProcessField<T, D extends number = 5> = [D] extends [never] ? Record<string, unknown> : T extends {
833
- type: 'page' | 'row';
834
- fields: infer F;
835
- } ? InferContainerChildren<F, Depth[D], never> : T extends {
836
- type: 'group';
837
- key: infer K;
838
- fields: infer F;
839
- } ? K extends string ? {
840
- [P in K]: InferContainerChildren<F, Depth[D], Record<string, unknown>>;
841
- } : never : T extends {
842
- type: 'array';
843
- key: infer K;
844
- } ? K extends string ? {
845
- [P in K]: InferArrayValue<T, D>;
846
- } : never : T extends {
847
- type: 'text';
848
- } ? never : T extends {
849
- type: 'submit' | 'button' | 'next' | 'previous' | 'addArrayItem' | 'add-array-item' | 'prependArrayItem' | 'prepend-array-item' | 'insertArrayItem' | 'insert-array-item' | 'removeArrayItem' | 'remove-array-item' | 'popArrayItem' | 'pop-array-item' | 'shiftArrayItem' | 'shift-array-item';
850
- } ? never : T extends {
851
- key: infer K;
852
- value: infer V;
853
- } ? K extends string ? {
854
- [P in K]: MaybeOptional<T, InferValueType<T, V>>;
855
- } : never : T extends {
856
- key: infer K;
857
- } ? K extends string ? {
858
- [P in K]: MaybeOptional<T, T extends {
859
- nullable: true;
860
- } ? string | null : string>;
861
- } : never : never;
862
- /** Internal helper with depth tracking */
863
- type InferFormValueWithDepth<T extends RegisteredFieldTypes[], D extends number = 5> = UnionToIntersection<ProcessField<T[number], D>>;
864
- /** Helper to extract fields from either fields array or FormConfig */
865
- type ExtractFields<T> = T extends {
866
- fields: infer TFields;
867
- } ? TFields extends readonly RegisteredFieldTypes[] ? TFields : never : T extends readonly RegisteredFieldTypes[] ? T : never;
868
- /**
869
- * Infer form value type from fields array or FormConfig.
870
- * Recursively processes nested structures and merges the results.
871
- * Limited to 5 levels of nesting to prevent infinite type instantiation.
872
- */
873
- type InferFormValue<T> = ExtractFields<T> extends readonly RegisteredFieldTypes[] ? InferFormValueWithDepth<ExtractFields<T> extends RegisteredFieldTypes[] ? ExtractFields<T> : [...ExtractFields<T>], 5> : never;
874
- /**
875
- * Default `TModel` for `DynamicForm` / `FormStateManager` generics.
876
- *
877
- * Equals `InferFormValue<T>` for any concrete config (an object type). Falls back
878
- * to `Record<string, unknown>` only when inference yields a non-record — e.g. an
879
- * empty `fields` array, where `InferFormValue` is `unknown` — so the `TModel
880
- * extends Record<string, unknown>` bound always holds by construction.
881
- *
882
- * Crucially, unlike the older `InferFormValue<T> & Record<string, unknown>`
883
- * default, this does NOT graft an index signature onto the model. That matters at
884
- * the consumer call site: the index signature made `value['anyTypo']` resolve to
885
- * `unknown` instead of erroring, silently defeating the typo-safety the inference
886
- * is meant to provide.
887
- */
888
- type InferFormModel<T, M = InferFormValue<T>> = M extends Record<string, unknown> ? M : Record<string, unknown>;
889
-
890
- /**
891
- * Custom validator function signature using Angular's public FieldContext API
892
- *
893
- * @template TValue The type of value stored in the field being validated
894
- */
895
- type CustomValidator<TValue = unknown> = (ctx: FieldContext<TValue>, params?: Record<string, unknown>) => ValidationError$1 | ValidationError$1[] | null;
896
- /**
897
- * Async custom validator configuration using Angular's resource-based API
898
- *
899
- * @template TValue The type of value stored in the field being validated
900
- * @template TParams The type of params passed to the resource
901
- * @template TResult The type of result returned by the resource
902
- */
903
- interface AsyncCustomValidator<TValue = unknown, TParams = unknown, TResult = unknown> {
904
- /**
905
- * Function that receives field context and returns resource params.
906
- * Params will be tracked as a signal and trigger resource reload when changed.
907
- */
908
- readonly params: (ctx: FieldContext<TValue>, config?: Record<string, unknown>) => TParams;
909
- /**
910
- * Function that creates a ResourceRef from the params signal.
911
- * The resource will be automatically managed by Angular's lifecycle.
912
- */
913
- readonly factory: (params: Signal<TParams | undefined>) => ResourceRef<TResult | undefined>;
914
- /**
915
- * Optional function to map successful resource result to validation errors.
916
- * Return null if validation passes, or ValidationError/ValidationError[] if validation fails.
917
- */
918
- readonly onSuccess?: (result: TResult, ctx: FieldContext<TValue>) => TreeValidationResult;
919
- /**
920
- * Optional error handler for resource errors (network failures, etc.).
921
- * Return null to ignore the error, or ValidationError to display it to the user.
922
- */
923
- readonly onError?: (error: unknown, ctx: FieldContext<TValue>) => ValidationError$1 | ValidationError$1[] | null;
924
- }
925
- /** HTTP request configuration for validateHttp API */
926
- interface HttpResourceRequest {
927
- url: string;
928
- method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
929
- body?: unknown;
930
- headers?: Record<string, string | string[]>;
931
- }
932
- /**
933
- * HTTP-based validator configuration for Angular's validateHttp API
934
- *
935
- * @template TValue The type of value stored in the field being validated
936
- * @template TResult The type of HTTP response
937
- */
938
- interface HttpCustomValidator<TValue = unknown, TResult = unknown> {
939
- /**
940
- * Function that returns the HTTP request configuration.
941
- * Can return:
942
- * - `undefined` to skip validation (e.g., if field is empty)
943
- * - `string` for simple GET requests (just the URL)
944
- * - `HttpResourceRequest` for full control (method, body, headers)
945
- */
946
- readonly request: (ctx: FieldContext<TValue>, config?: Record<string, unknown>) => string | HttpResourceRequest | undefined;
947
- /** REQUIRED function to map successful HTTP response to validation errors. */
948
- readonly onSuccess: (result: TResult, ctx: FieldContext<TValue>) => TreeValidationResult;
949
- /**
950
- * Optional error handler for HTTP errors (network failures, 4xx/5xx status codes).
951
- * Return null to ignore the error, or ValidationError to display it to the user.
952
- */
953
- readonly onError?: (error: unknown, ctx: FieldContext<TValue>) => ValidationError$1 | ValidationError$1[] | null;
954
- }
955
-
956
- /** Mapping configuration for interpreting HTTP responses as validation results. */
957
- interface HttpValidationResponseMapping {
958
- /** Expression evaluated with scope `{ response }`. Must evaluate to `true` (strict boolean) to be valid. */
959
- validWhen: string;
960
- /** Error kind returned when validation fails — maps to field-level `validationMessages` */
961
- errorKind: string;
962
- /**
963
- * Parameters to include in the validation error for message interpolation.
964
- * Map of parameter names to expressions evaluated against `{ response }`.
965
- */
966
- errorParams?: Record<string, string>;
967
- }
968
-
969
- /** Base configuration shared by all validators */
970
- interface BaseValidatorConfig {
971
- /** Conditional logic for when validator applies */
972
- when?: ConditionalExpression;
973
- }
974
- /** Built-in validator configuration (required, email, min, max, etc.) */
975
- interface BuiltInValidatorConfig extends BaseValidatorConfig {
976
- /** Validator type identifier */
977
- type: 'required' | 'email' | 'min' | 'max' | 'minLength' | 'maxLength' | 'pattern';
978
- /** Static value for the validator (e.g., min value, pattern) */
979
- value?: number | string | RegExp;
980
- /** Dynamic value expression that evaluates to validator parameter */
981
- expression?: string;
982
- }
983
- /**
984
- * Custom validator configuration using Angular's public FieldContext API.
985
- * Returns ValidationError | ValidationError[] | null synchronously.
986
- */
987
- interface CustomValidatorConfig extends BaseValidatorConfig {
988
- /** Validator type identifier */
989
- type: 'custom';
990
- /** Name of registered validator function (function-based pattern) */
991
- functionName?: string;
992
- /**
993
- * Inline custom validator (code-only authoring).
994
- * Mutually exclusive with `functionName`. NOT JSON-serializable.
995
- */
996
- fn?: CustomValidator;
997
- /** Optional parameters to pass to validator function */
998
- params?: Record<string, unknown>;
999
- /** JavaScript expression to evaluate (expression-based pattern) */
1000
- expression?: string;
1001
- /** Error kind for expression-based validators - links to validationMessages */
1002
- kind?: string;
1003
- /**
1004
- * Parameters to include in error object for message interpolation (expression-based pattern)
1005
- * Map of parameter names to expressions that will be evaluated in the same context as the validation expression
1006
- */
1007
- errorParams?: Record<string, string>;
1008
- }
1078
+ type: 'checkbox' | 'toggle';
1079
+ } ? boolean : T extends {
1080
+ value: infer V;
1081
+ } ? [V] extends [null] ? string : Widen<V, Depth[D]> : string;
1082
+ type InferSingleTemplateValue<T, D extends number> = T extends {
1083
+ nullable: true;
1084
+ } ? InferSingleTemplateValueBase<T, D> | null : InferSingleTemplateValueBase<T, D>;
1009
1085
  /**
1010
- * Shared fields for both branches of {@link AsyncValidatorConfig}.
1011
- *
1012
- * @internal
1086
+ * Infers the value type for an array field.
1087
+ * Handles four cases:
1088
+ * 1. Simplified array with template + value → infer item type from value
1089
+ * 2. Simplified array with array template (no value) → infer object type from template fields
1090
+ * 3. Simplified array with single-field template (no value) → infer primitive type from template field
1091
+ * 4. Full-API array with fields → infer from children
1013
1092
  */
1014
- interface AsyncValidatorConfigShared extends BaseValidatorConfig {
1015
- /** Validator type identifier. */
1016
- type: 'async';
1017
- /** Optional parameters to pass to validator function */
1018
- params?: Record<string, unknown>;
1019
- }
1093
+ type InferArrayValue<T, D extends number> = T extends {
1094
+ template: unknown;
1095
+ value: readonly (infer Item)[];
1096
+ } ? Widen<Item>[] : T extends {
1097
+ template: infer TArr;
1098
+ } ? TArr extends readonly RegisteredFieldTypes[] ? InferFormValueWithDepth<[...TArr], Depth[D]>[] : InferSingleTemplateValue<TArr, D>[] : T extends {
1099
+ fields: infer F;
1100
+ } ? InferContainerChildren<F, Depth[D], unknown>[] : unknown[];
1020
1101
  /**
1021
- * Async custom validator configuration using Angular's `validateAsync` API.
1022
- * Returns Observable<ValidationError | ValidationError[] | null>.
1102
+ * Recurse into a container's child fields, but only when they form a fixed-length
1103
+ * tuple — i.e. a config authored with `as const`. A general `RegisteredFieldTypes[]`
1104
+ * array (notably the base default `InferFormValue<RegisteredFieldTypes[]>` over the
1105
+ * whole registry) bails to `TFallback`; recursing there would make the type explode
1106
+ * past TypeScript's union-complexity limit (TS2590) and break consumers of the
1107
+ * abstract `FormConfig`. `[...F]` re-mutabilises the readonly tuple for the inner
1108
+ * `InferFormValueWithDepth` constraint.
1023
1109
  */
1024
- type AsyncValidatorConfig = (AsyncValidatorConfigShared & {
1025
- /** Name of registered async validator function */
1026
- functionName: string;
1027
- /** Inline form is forbidden when `functionName` is set */
1028
- fn?: never;
1029
- }) | (AsyncValidatorConfigShared & {
1030
- /** Inline async validator. Mutually exclusive with `functionName`. */
1031
- fn: AsyncCustomValidator;
1032
- /** Registered form is forbidden when `fn` is set */
1033
- functionName?: never;
1034
- });
1110
+ type InferContainerChildren<F, D extends number, TFallback> = F extends readonly RegisteredFieldTypes[] ? number extends F['length'] ? TFallback : InferFormValueWithDepth<[...F], D> : TFallback;
1111
+ /** Process a single field and determine its contribution to the form value type */
1112
+ type ProcessField<T, D extends number = 5> = [D] extends [never] ? Record<string, unknown> : T extends {
1113
+ type: 'page' | 'row';
1114
+ fields: infer F;
1115
+ } ? InferContainerChildren<F, Depth[D], never> : T extends {
1116
+ type: 'group';
1117
+ key: infer K;
1118
+ fields: infer F;
1119
+ } ? K extends string ? {
1120
+ [P in K]: InferContainerChildren<F, Depth[D], Record<string, unknown>>;
1121
+ } : never : T extends {
1122
+ type: 'array';
1123
+ key: infer K;
1124
+ } ? K extends string ? {
1125
+ [P in K]: InferArrayValue<T, D>;
1126
+ } : never : T extends {
1127
+ type: 'text';
1128
+ } ? never : T extends {
1129
+ type: 'submit' | 'button' | 'next' | 'previous' | 'addArrayItem' | 'add-array-item' | 'prependArrayItem' | 'prepend-array-item' | 'insertArrayItem' | 'insert-array-item' | 'removeArrayItem' | 'remove-array-item' | 'popArrayItem' | 'pop-array-item' | 'shiftArrayItem' | 'shift-array-item';
1130
+ } ? never : T extends {
1131
+ key: infer K;
1132
+ value: infer V;
1133
+ } ? K extends string ? {
1134
+ [P in K]: MaybeOptional<T, InferValueType<T, V>>;
1135
+ } : never : T extends {
1136
+ key: infer K;
1137
+ } ? K extends string ? {
1138
+ [P in K]: MaybeOptional<T, T extends {
1139
+ nullable: true;
1140
+ } ? string | null : string>;
1141
+ } : never : never;
1142
+ /** Internal helper with depth tracking */
1143
+ type InferFormValueWithDepth<T extends RegisteredFieldTypes[], D extends number = 5> = UnionToIntersection<ProcessField<T[number], D>>;
1144
+ /** Helper to extract fields from either fields array or FormConfig */
1145
+ type ExtractFields<T> = T extends {
1146
+ fields: infer TFields;
1147
+ } ? TFields extends readonly RegisteredFieldTypes[] ? TFields : never : T extends readonly RegisteredFieldTypes[] ? T : never;
1035
1148
  /**
1036
- * Shared fields for both branches of {@link FunctionHttpValidatorConfig}.
1037
- *
1038
- * @internal
1149
+ * Infer form value type from fields array or FormConfig.
1150
+ * Recursively processes nested structures and merges the results.
1151
+ * Limited to 5 levels of nesting to prevent infinite type instantiation.
1039
1152
  */
1040
- interface FunctionHttpValidatorConfigShared extends BaseValidatorConfig {
1041
- /** Validator type identifier. */
1042
- type: 'http';
1043
- /** Optional parameters to pass to HTTP validator */
1044
- params?: Record<string, unknown>;
1045
- }
1046
- /** Function-based HTTP validator configuration. Uses Angular's `validateHttp` API. */
1047
- type FunctionHttpValidatorConfig = (FunctionHttpValidatorConfigShared & {
1048
- /** Name of registered HTTP validator configuration */
1049
- functionName: string;
1050
- /** Inline form is forbidden when `functionName` is set */
1051
- fn?: never;
1052
- }) | (FunctionHttpValidatorConfigShared & {
1053
- /** Inline HTTP validator. Mutually exclusive with `functionName`. */
1054
- fn: HttpCustomValidator;
1055
- /** Registered form is forbidden when `fn` is set */
1056
- functionName?: never;
1057
- });
1058
- /** Declarative HTTP validator configuration — fully JSON-serializable, no function registration required. */
1059
- interface DeclarativeHttpValidatorConfig extends BaseValidatorConfig {
1060
- /** Validator type identifier */
1061
- type: 'http';
1062
- /** HTTP request configuration with expression-based query params and body */
1063
- http: HttpRequestConfig;
1064
- /** Mapping that interprets the HTTP response as a validation result */
1065
- responseMapping: HttpValidationResponseMapping;
1066
- }
1153
+ type InferFormValue<T> = ExtractFields<T> extends readonly RegisteredFieldTypes[] ? InferFormValueWithDepth<ExtractFields<T> extends RegisteredFieldTypes[] ? ExtractFields<T> : [...ExtractFields<T>], 5> : never;
1067
1154
  /**
1068
- * Configuration for signal forms validator functions that can be serialized from API.
1069
- * Discriminated union type for type-safe validator configuration.
1155
+ * Default `TModel` for `DynamicForm` / `FormStateManager` generics.
1156
+ *
1157
+ * Equals `InferFormValue<T>` for any concrete config (an object type). Falls back
1158
+ * to `Record<string, unknown>` only when inference yields a non-record — e.g. an
1159
+ * empty `fields` array, where `InferFormValue` is `unknown` — so the `TModel
1160
+ * extends Record<string, unknown>` bound always holds by construction.
1161
+ *
1162
+ * Crucially, unlike the older `InferFormValue<T> & Record<string, unknown>`
1163
+ * default, this does NOT graft an index signature onto the model. That matters at
1164
+ * the consumer call site: the index signature made `value['anyTypo']` resolve to
1165
+ * `unknown` instead of erroring, silently defeating the typo-safety the inference
1166
+ * is meant to provide.
1070
1167
  */
1071
- type ValidatorConfig = BuiltInValidatorConfig | CustomValidatorConfig | AsyncValidatorConfig | FunctionHttpValidatorConfig | DeclarativeHttpValidatorConfig;
1072
- /** Type guard to distinguish function-based HTTP validators from declarative ones. */
1073
- declare function isFunctionHttpValidator(config: FunctionHttpValidatorConfig | DeclarativeHttpValidatorConfig): config is FunctionHttpValidatorConfig;
1168
+ type InferFormModel<T, M = InferFormValue<T>> = M extends Record<string, unknown> ? M : Record<string, unknown>;
1074
1169
 
1075
1170
  /** Special form-state conditions for button disabled logic. */
1076
1171
  type FormStateCondition =
@@ -1454,29 +1549,6 @@ interface SchemaDefinition {
1454
1549
  subSchemas?: SchemaApplicationConfig[];
1455
1550
  }
1456
1551
 
1457
- /**
1458
- * Re-export Angular's ValidationError for consistency
1459
- * This replaces our custom ValidationError interface
1460
- */
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;
1469
- interface ValidationMessages {
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;
1478
- }
1479
-
1480
1552
  /**
1481
1553
  * The result type for submission actions.
1482
1554
  * Can be either a Promise or an Observable.
@@ -1584,11 +1656,28 @@ interface FormOptions {
1584
1656
  /** Default disabled behavior for next page buttons. */
1585
1657
  nextButton?: NextButtonOptions;
1586
1658
  /**
1587
- * For paged forms: how many pages on each side of the current page are eagerly
1588
- * mounted (the "preload window"). Pages outside the window render a lightweight
1589
- * placeholder and mount when navigation brings them into range.
1659
+ * For paged forms: which page to start on. Use for deep links and session restore.
1660
+ *
1661
+ * Applied by the orchestrator as it initializes, so it is race-free even when the
1662
+ * config arrives asynchronously. Out-of-range indices clamp to the last page;
1663
+ * negative or non-finite values fall back to `0`. A hidden target resolves to the
1664
+ * nearest visible page.
1665
+ *
1666
+ * The shorthand `initialPage: 4` lands on the page unconditionally, which is what
1667
+ * restore usually wants. Pass `{ index, validate: true }` to run the same validity
1668
+ * gate a forward `GoToPageEvent` uses, which stops on the first invalid page.
1669
+ *
1670
+ * A gated landing resolves once at mount, so supply restored values with the config.
1671
+ *
1672
+ * @default undefined (starts on page 0)
1673
+ */
1674
+ initialPage?: number | InitialPageConfig;
1675
+ /**
1676
+ * For paged forms: how many pages on each side of the current page are mounted
1677
+ * during idle time (the "preload window"). The active page renders directly;
1678
+ * pages outside the window remain lightweight placeholders.
1590
1679
  *
1591
- * `0` mounts only the current page; `1` mounts ±1 for flicker-free sequential
1680
+ * `0` mounts only the current page; `1` preloads ±1 on idle for flicker-free sequential
1592
1681
  * navigation; higher values pre-warm more pages for jump navigation at the cost
1593
1682
  * of more initial DOM + change detection.
1594
1683
  *
@@ -1604,7 +1693,16 @@ interface FormOptions {
1604
1693
  *
1605
1694
  * `true` enables windowing using the global `withFieldWindowing()` defaults;
1606
1695
  * `false` force-disables it even if the global feature is enabled; an object
1607
- * enables it with per-form `eager` / `placeholderHeight` overrides.
1696
+ * enables it with per-form `eager` / `placeholderHeight` / `park` overrides.
1697
+ *
1698
+ * `park` holds scrolled-away fields out of change detection while leaving
1699
+ * their DOM in place, so they stay findable, autofillable and reachable by
1700
+ * assistive tech. It is off unless `withFieldWindowing()` is used, because it
1701
+ * suspends model → DOM updates for a scrolled-away field until it returns.
1702
+ * Set `park: true` to opt in without deferred mounting, `park: false` to opt
1703
+ * out, or `park: { margin }` to change how far outside the viewport stays live.
1704
+ * The margin follows `IntersectionObserver.rootMargin` and accepts one to four
1705
+ * pixel or percentage values; unsupported units fall back to the inherited margin.
1608
1706
  *
1609
1707
  * Overrides the global `withFieldWindowing(...)` default for this form.
1610
1708
  *
@@ -1613,6 +1711,9 @@ interface FormOptions {
1613
1711
  fieldWindowing?: boolean | {
1614
1712
  eager?: number;
1615
1713
  placeholderHeight?: string;
1714
+ park?: boolean | {
1715
+ margin?: string;
1716
+ };
1616
1717
  };
1617
1718
  /**
1618
1719
  * Whether to exclude values of hidden fields from submission output.
@@ -1644,6 +1745,67 @@ interface FormOptions {
1644
1745
  * @default undefined (uses global setting)
1645
1746
  */
1646
1747
  emitFormValueOnEvents?: boolean;
1748
+ /**
1749
+ * Exposes this form to browser AI agents as WebMCP tools.
1750
+ *
1751
+ * Requires the `withExperimentalWebMcp()` feature on `provideDynamicForm(...)`. Registers
1752
+ * `fill_{name}`, which applies a partial patch of values and reports the
1753
+ * form's state back. Submission stays off unless `allowSubmit` is set.
1754
+ *
1755
+ * Experimental: WebMCP is an emerging standard and Angular's underlying APIs
1756
+ * are marked experimental, so this may change outside a major version.
1757
+ *
1758
+ * @example
1759
+ * ```typescript
1760
+ * options: { webMcp: { name: 'invoice', description: 'Create an invoice for a customer.' } }
1761
+ * ```
1762
+ *
1763
+ * @default undefined (form is not exposed to agents)
1764
+ */
1765
+ webMcp?: WebMcpToolOptions;
1766
+ }
1767
+ /** Identifies a form's WebMCP tools to connected AI agents. */
1768
+ interface WebMcpToolOptions {
1769
+ /**
1770
+ * Base name for this form's tools, used as `fill_{name}` and (when submission
1771
+ * is allowed) `submit_{name}`. Must be unique across every form on the page.
1772
+ */
1773
+ name: string;
1774
+ /** What this form is for, and when an agent should reach for it. */
1775
+ description: string;
1776
+ /**
1777
+ * Whether an agent may submit this form directly.
1778
+ *
1779
+ * Off by default. Every registered tool is callable by any agent that reaches
1780
+ * the page, including one acting on injected instructions from elsewhere, so
1781
+ * submission is treated as the consequential step and kept opt-in. With it
1782
+ * off, an agent can still fill the form and a human presses the button.
1783
+ *
1784
+ * Leave it off for anything that spends money, sends a message, or cannot be
1785
+ * undone.
1786
+ *
1787
+ * @default false
1788
+ */
1789
+ allowSubmit?: boolean;
1790
+ /**
1791
+ * How much of the form a tool response hands back to the agent.
1792
+ *
1793
+ * `'changed'` (the default) returns only the values the call itself set, plus
1794
+ * which fields apply, which are still empty, and any validation errors. That
1795
+ * is enough for an agent to orient itself and correct its own work without
1796
+ * being handed every value the form already held — prefilled personal data,
1797
+ * identifiers, anything a user typed before the agent arrived.
1798
+ *
1799
+ * `'all'` returns the whole model, minus fields whose `webMcp.readable` is
1800
+ * off. Choose it deliberately: every registered tool is callable by any agent
1801
+ * that reaches the page, and Chrome's guidance is that even a read-only tool
1802
+ * can reveal user information.
1803
+ *
1804
+ * @see https://developer.chrome.com/docs/ai/webmcp/secure-tools
1805
+ *
1806
+ * @default 'changed'
1807
+ */
1808
+ readback?: 'changed' | 'all';
1647
1809
  }
1648
1810
  /** Options for controlling submit button disabled behavior. */
1649
1811
  interface SubmitButtonOptions {
@@ -1660,6 +1822,18 @@ interface SubmitButtonOptions {
1660
1822
  */
1661
1823
  disableWhileSubmitting?: boolean;
1662
1824
  }
1825
+ /** Which page a paged form starts on, for deep links and session restore. */
1826
+ interface InitialPageConfig {
1827
+ /** Target page index (0-based). */
1828
+ index: number;
1829
+ /**
1830
+ * Whether to apply the forward-jump validity gate, stopping on the first
1831
+ * invalid page instead of landing on the target.
1832
+ *
1833
+ * @default false
1834
+ */
1835
+ validate?: boolean;
1836
+ }
1663
1837
  /** Options for controlling next page button disabled behavior. */
1664
1838
  interface NextButtonOptions {
1665
1839
  /**
@@ -1821,6 +1995,24 @@ interface RowWrapper {
1821
1995
  readonly type: 'row';
1822
1996
  }
1823
1997
 
1998
+ /**
1999
+ * Renders the wrapped field's validation errors, for a leaf or a container.
2000
+ *
2001
+ * On a container it is the only thing that can render the message — a `group` / `array`
2002
+ * has no adapter field component — so it is appended automatically when the container
2003
+ * declares `validators`. On a leaf it is opt-in: adding it takes error rendering over
2004
+ * from the field component, which suppresses its own via `FIELD_ERROR_DISPLAY`.
2005
+ *
2006
+ * To restyle it, register a `WrapperTypeDefinition` with the same
2007
+ * `wrapperName: 'field-errors'` — the later registration wins, so an adapter or an app
2008
+ * can swap in its own component without touching config.
2009
+ */
2010
+ interface FieldErrorsWrapper {
2011
+ readonly type: 'field-errors';
2012
+ /** Messages keyed by error `kind`. Containers forward their own `validationMessages`. */
2013
+ readonly validationMessages?: ValidationMessages;
2014
+ }
2015
+
1824
2016
  /** Container fields registry - augment this interface to add custom container fields */
1825
2017
  interface FieldRegistryContainers {
1826
2018
  page: PageField;
@@ -1838,6 +2030,7 @@ interface FieldRegistryLeaves {
1838
2030
  interface FieldRegistryWrappers {
1839
2031
  css: CssWrapper;
1840
2032
  row: RowWrapper;
2033
+ 'field-errors': FieldErrorsWrapper;
1841
2034
  }
1842
2035
  /**
1843
2036
  * Global interface for dynamic form field definitions with categorization
@@ -1916,6 +2109,12 @@ interface WrapperTypeDefinition<T extends WrapperConfig = WrapperConfig> {
1916
2109
  loadComponent: LazyComponentLoader;
1917
2110
  /** Field types this wrapper should auto-apply to. */
1918
2111
  types?: readonly string[];
2112
+ /**
2113
+ * Declares that this wrapper renders the wrapped field's errors, so the default
2114
+ * `field-errors` wrapper is not appended next to it. Needed here as well as via
2115
+ * `provideFieldErrorDisplay`: the chain resolves before any component exists to ask.
2116
+ */
2117
+ rendersFieldErrors?: boolean;
1919
2118
  }
1920
2119
  /** Type guard for WrapperTypeDefinition. */
1921
2120
  declare function isWrapperTypeDefinition(value: unknown): value is WrapperTypeDefinition;
@@ -1941,9 +2140,11 @@ interface FieldWrapper {
1941
2140
  readonly fieldComponent: Signal<ViewContainerRef>;
1942
2141
  }
1943
2142
  /** Injection token for the wrapper type registry. */
1944
- declare const WRAPPER_REGISTRY: InjectionToken<Map<string, WrapperTypeDefinition<_ng_forge_dynamic_forms_internal.RowWrapper | _ng_forge_dynamic_forms_internal.CssWrapper>>>;
2143
+ declare const WRAPPER_REGISTRY: InjectionToken<Map<string, WrapperTypeDefinition<_ng_forge_dynamic_forms_internal.RowWrapper | _ng_forge_dynamic_forms_internal.CssWrapper | _ng_forge_dynamic_forms_internal.FieldErrorsWrapper>>>;
1945
2144
  /** Component cache for loaded wrapper components. */
1946
2145
  declare const WRAPPER_COMPONENT_CACHE: InjectionToken<Map<string, Type<unknown>>>;
2146
+ /** Pending wrapper loads, shared by preloading and the normal render path. */
2147
+ declare const WRAPPER_COMPONENT_LOAD_CACHE: InjectionToken<Map<string, Promise<Type<unknown> | undefined>>>;
1947
2148
  /**
1948
2149
  * Pre-computed reverse index: `fieldType → WrapperConfig[]` for every
1949
2150
  * registered `WrapperTypeDefinition.types` entry. Built once in the
@@ -2919,8 +3120,122 @@ declare class RootFormRegistryService {
2919
3120
  constructor(formValue: Signal<Record<string, unknown>>, rootForm: Signal<FieldTree<Record<string, unknown>> | undefined>);
2920
3121
  }
2921
3122
 
2922
- declare function applyValidator(config: ValidatorConfig, fieldPath: SchemaPath<any> | SchemaPathTree<any>): void;
2923
- declare function applyValidators(configs: ValidatorConfig[], fieldPath: SchemaPath<any> | SchemaPathTree<any>): void;
3123
+ /** Resolved validation error with interpolated message */
3124
+ interface ResolvedError {
3125
+ kind: string;
3126
+ message: string;
3127
+ }
3128
+ /**
3129
+ * Factory function that creates a signal of resolved validation errors
3130
+ * Handles async resolution of DynamicText validation messages
3131
+ *
3132
+ * @param field - Signal containing the FieldTree, or `undefined` before it
3133
+ * exists (containers resolve their node lazily from the parent tree)
3134
+ * @param validationMessages - Signal containing custom field-level validation messages
3135
+ * @param defaultValidationMessages - Signal containing default validation messages (fallback)
3136
+ * @param injector - Optional injector for DynamicText resolution
3137
+ * @returns Signal<ResolvedError[]> - Reactively resolved error messages
3138
+ */
3139
+ declare function createResolvedErrorsSignal<T>(field: Signal<FieldTree<T> | undefined>, validationMessages: Signal<ValidationMessages | undefined>, defaultValidationMessages?: Signal<ValidationMessages | undefined>, injector?: Injector): Signal<ResolvedError[]>;
3140
+
3141
+ /** A wrapper's claim to render errors, scoped to the one field key it wraps. */
3142
+ interface FieldErrorDisplayClaim {
3143
+ /** Key of the field whose errors this wrapper renders; `undefined` before inputs bind. */
3144
+ readonly claimedKey: Signal<string | undefined>;
3145
+ }
3146
+ /**
3147
+ * Marks that a wrapper is rendering a field's errors, so that field's component stops
3148
+ * rendering its own and the message appears once.
3149
+ *
3150
+ * The claim carries a key because a wrapper's providers reach every descendant: a wrapper
3151
+ * around an `array` would otherwise silence the errors of every input inside it. A field
3152
+ * suppresses its own rendering only when the claimed key is its own.
3153
+ *
3154
+ * Not `multi` — element injectors shadow rather than merge, so a nested claim would hide
3155
+ * the outer one regardless.
3156
+ */
3157
+ declare const FIELD_ERROR_DISPLAY: InjectionToken<FieldErrorDisplayClaim>;
3158
+ /** The error surface a wrapper gets, mirroring what `NgForgeField` exposes to field components. */
3159
+ interface FieldErrors {
3160
+ /** Every resolved error, regardless of whether it should be shown yet. */
3161
+ readonly errors: Signal<ResolvedError[]>;
3162
+ /** Whether errors are ready to show — invalid, touched, and non-empty. */
3163
+ readonly showErrors: Signal<boolean>;
3164
+ /** `errors()` gated by `showErrors()`. This is what a template should render. */
3165
+ readonly errorsToDisplay: Signal<ResolvedError[]>;
3166
+ /** `{key}-error`, for wiring `aria-describedby` on the wrapped control. */
3167
+ readonly errorId: Signal<string>;
3168
+ }
3169
+ interface FieldErrorsOptions {
3170
+ /** The wrapper's `fieldInputs` input. */
3171
+ readonly fieldInputs: Signal<WrapperFieldInputs | undefined>;
3172
+ /** Overrides the messages in `fieldInputs` — containers pass their own. */
3173
+ readonly validationMessages?: Signal<ValidationMessages | undefined>;
3174
+ /** Defaults to the current injection context. */
3175
+ readonly injector?: Injector;
3176
+ }
3177
+ /**
3178
+ * Resolves the wrapped field's errors for a wrapper component, for a leaf or a container.
3179
+ *
3180
+ * A wrapper cannot `inject(NgForgeField)` — the chain is built before the field component
3181
+ * exists — so this reads the same information out of the `fieldInputs` bag it already has.
3182
+ * A leaf carries its own `field`; a container has none, so its node is resolved by key
3183
+ * against the parent tree in `FIELD_SIGNAL_CONTEXT`.
3184
+ *
3185
+ * Must be called in an injection context.
3186
+ */
3187
+ declare function injectFieldErrors(options: FieldErrorsOptions): FieldErrors;
3188
+
3189
+ /** The error to raise, minus the `fieldTree` that {@link rowError} fills in. */
3190
+ interface RowErrorSpec {
3191
+ /** Error kind, matched against `validationMessages`. */
3192
+ readonly kind: string;
3193
+ /**
3194
+ * Message shown for this error. A row-targeted error needs its own, because the
3195
+ * container's `validationMessages` are keyed to the container, not to the child the
3196
+ * error moves to.
3197
+ */
3198
+ readonly message?: string;
3199
+ readonly [param: string]: unknown;
3200
+ }
3201
+ /**
3202
+ * Targets a validation error at one field of one row, from a validator declared on the
3203
+ * array (issue #568).
3204
+ *
3205
+ * A container validator sees the whole item list, which is what makes per-row rules
3206
+ * expressible at all — but one message for the list cannot say which row is wrong.
3207
+ * Returning the result of this helper puts the error on that row's own input, where the
3208
+ * adapter renders it like any other field error.
3209
+ *
3210
+ * ```typescript
3211
+ * const periodOrder: CustomValidator = (ctx) => {
3212
+ * const rows = (ctx.value() ?? []) as { from?: string; to?: string }[];
3213
+ * return rows.flatMap((row, i) =>
3214
+ * row.from && row.to && row.to < row.from
3215
+ * ? [rowError(ctx, i, 'to', { kind: 'periodOrder', message: 'The end must not be before the start.' })]
3216
+ * : [],
3217
+ * );
3218
+ * };
3219
+ * ```
3220
+ *
3221
+ * Returns the error untargeted when the row or field cannot be resolved, so it still
3222
+ * surfaces on the container rather than vanishing.
3223
+ */
3224
+ declare function rowError(ctx: FieldContext<unknown>, index: number, key: string, error: RowErrorSpec): ValidationError$1;
3225
+
3226
+ /**
3227
+ * Computed signal that determines if errors should be displayed.
3228
+ * Based on field's invalid, touched, and error count.
3229
+ *
3230
+ * @param field - Signal containing the FieldTree, or `undefined` before it exists
3231
+ * @returns Signal<boolean> - True if errors should be displayed
3232
+ */
3233
+ declare function shouldShowErrors<T>(field: Signal<FieldTree<T> | undefined>): Signal<boolean>;
3234
+
3235
+ /** `field` = `validate()`; `tree` = `validateTree()`, which re-homes errors carrying a `fieldTree`. */
3236
+ type ValidatorAttachment = 'field' | 'tree';
3237
+ declare function applyValidator(config: ValidatorConfig, fieldPath: SchemaPath<any> | SchemaPathTree<any>, attachment?: ValidatorAttachment): void;
3238
+ declare function applyValidators(configs: ValidatorConfig[], fieldPath: SchemaPath<any> | SchemaPathTree<any>, attachment?: ValidatorAttachment): void;
2924
3239
 
2925
3240
  /**
2926
3241
  * Create a dynamic value function from an expression string.
@@ -2969,7 +3284,7 @@ interface BaseCheckedField<TProps, TMeta extends FieldMeta = FieldMeta, TNullabl
2969
3284
  nullable?: TNullable;
2970
3285
  }
2971
3286
  declare function isCheckedField<TProps, TMeta extends FieldMeta = FieldMeta>(field: FieldDef<TProps, TMeta>): field is BaseCheckedField<TProps, TMeta, boolean>;
2972
- type ExcludedKeys$1 = 'type' | 'conditionals' | 'value' | 'nullable' | 'disabled' | 'readonly' | 'hidden' | 'col' | keyof FieldWithValidation | 'excludeValueIfHidden' | 'excludeValueIfDisabled' | 'excludeValueIfReadonly' | 'validateWhenHidden' | 'wrappers' | 'skipAutoWrappers' | 'skipDefaultWrappers' | 'addons';
3287
+ type ExcludedKeys$1 = 'type' | 'conditionals' | 'value' | 'nullable' | 'disabled' | 'readonly' | 'hidden' | 'col' | keyof FieldWithValidation | 'excludeValueIfHidden' | 'excludeValueIfDisabled' | 'excludeValueIfReadonly' | 'validateWhenHidden' | 'wrappers' | 'skipAutoWrappers' | 'skipDefaultWrappers' | 'addons' | 'webMcp';
2973
3288
  type CheckedFieldComponent<T extends BaseCheckedField<Record<string, unknown> | unknown, FieldMeta, boolean>> = Prettify<WithInputSignals<Omit<T, ExcludedKeys$1>>>;
2974
3289
 
2975
3290
  /**
@@ -2993,7 +3308,7 @@ interface BaseValueField<TProps, TValue, TMeta extends FieldMeta = FieldMeta, TN
2993
3308
  nullable?: TNullable;
2994
3309
  }
2995
3310
  declare function isValueField<TProps, TMeta extends FieldMeta = FieldMeta>(field: FieldDef<TProps, TMeta>): field is BaseValueField<TProps, ValueType, TMeta, boolean>;
2996
- type ExcludedKeys = 'type' | 'conditionals' | 'value' | 'valueType' | 'nullable' | 'disabled' | 'readonly' | 'hidden' | 'col' | 'minValue' | 'maxValue' | 'step' | 'required' | 'email' | 'min' | 'max' | 'minLength' | 'maxLength' | 'pattern' | 'validators' | 'logic' | 'derivation' | 'schemas' | 'excludeValueIfHidden' | 'excludeValueIfDisabled' | 'excludeValueIfReadonly' | 'validateWhenHidden' | 'wrappers' | 'skipAutoWrappers' | 'skipDefaultWrappers' | 'addons';
3311
+ type ExcludedKeys = 'type' | 'conditionals' | 'value' | 'valueType' | 'nullable' | 'disabled' | 'readonly' | 'hidden' | 'col' | 'minValue' | 'maxValue' | 'step' | 'required' | 'email' | 'min' | 'max' | 'minLength' | 'maxLength' | 'pattern' | 'validators' | 'logic' | 'derivation' | 'schemas' | 'excludeValueIfHidden' | 'excludeValueIfDisabled' | 'excludeValueIfReadonly' | 'validateWhenHidden' | 'wrappers' | 'skipAutoWrappers' | 'skipDefaultWrappers' | 'addons' | 'webMcp';
2997
3312
  type ValueFieldComponent<T extends BaseValueField<Record<string, unknown> | unknown, unknown, FieldMeta, boolean>> = Prettify<WithInputSignals<Omit<T, ExcludedKeys>>>;
2998
3313
 
2999
3314
  /** Base interface for all form events in the dynamic form system. */
@@ -3637,6 +3952,11 @@ declare function memoize<TFunc extends (...args: any[]) => any>(fn: TFunc, resol
3637
3952
  * @returns Fields as array
3638
3953
  */
3639
3954
  declare function normalizeFieldsArray<T>(fields: readonly T[] | Record<string, T>): T[];
3955
+ /**
3956
+ * {@link getChangedKeys} restricted to `keys`. Callers that only care about a handful of
3957
+ * paths avoid diffing an entire form value on every change.
3958
+ */
3959
+ declare function getChangedKeysWithin(previous: Record<string, unknown> | null | undefined, current: Record<string, unknown> | null | undefined, keys: ReadonlySet<string>): Set<string>;
3640
3960
  /**
3641
3961
  * Gets the keys that differ between two objects.
3642
3962
  *
@@ -3656,5 +3976,46 @@ declare function assertNever(value: never): never;
3656
3976
  */
3657
3977
  declare function withPreviousValue<T>(input: Resource<T>): Resource<T>;
3658
3978
 
3659
- 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, createFieldValueProxy, createFormFieldStateMap, createFormStateLogicFunction, 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, resolveDynamicValue, resolveHttpRequest, resolveNextButtonDisabled, resolveNonFieldDisabled, resolveNonFieldHidden, resolveSubmitButtonDisabled, resolveTokens, rowFieldMapper, runPresetAction, setupInitializationTracking, shouldLog, textFieldMapper, toReadonlyFieldTree, toReadonlyFieldTreeCached, validatePageNesting, withPreviousValue, writeToFieldValue };
3660
- 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 };
3979
+ /**
3980
+ * Plumbing shared by every `field-errors` wrapper: the slot, the inputs, the resolved
3981
+ * error surface, and the key this wrapper claims. Subclasses supply only a template —
3982
+ * which is the only thing that actually differs between the core default and each
3983
+ * adapter's native markup.
3984
+ *
3985
+ * ```typescript
3986
+ * @Component({
3987
+ * selector: 'df-mat-field-errors',
3988
+ * imports: [MatError],
3989
+ * template: `
3990
+ * <ng-container #fieldComponent></ng-container>
3991
+ * @if (ngf.errorsToDisplay()[0]; as error) {
3992
+ * <mat-error [id]="ngf.errorId()">{{ error.message }}</mat-error>
3993
+ * }
3994
+ * `,
3995
+ * providers: [provideFieldErrorDisplay(() => MatFieldErrorsWrapperComponent)],
3996
+ * })
3997
+ * export default class MatFieldErrorsWrapperComponent extends FieldErrorsWrapperBase {}
3998
+ * ```
3999
+ */
4000
+ declare abstract class FieldErrorsWrapperBase implements FieldWrapper, FieldErrorDisplayClaim {
4001
+ readonly fieldComponent: i0.Signal<ViewContainerRef>;
4002
+ /** Overrides the messages in `fieldInputs`. Containers forward their own. */
4003
+ readonly validationMessages: i0.InputSignal<ValidationMessages | undefined>;
4004
+ readonly fieldInputs: i0.InputSignal<WrapperFieldInputs | undefined>;
4005
+ /** The field whose errors this wrapper renders — see `FieldErrorDisplayClaim`. */
4006
+ readonly claimedKey: i0.Signal<string | undefined>;
4007
+ /** Resolved error surface, mirroring what `injectNgForgeField()` gives a field component. */
4008
+ protected readonly ngf: _ng_forge_dynamic_forms_internal.FieldErrors;
4009
+ static ɵfac: i0.ɵɵFactoryDeclaration<FieldErrorsWrapperBase, never>;
4010
+ static ɵdir: i0.ɵɵDirectiveDeclaration<FieldErrorsWrapperBase, never, never, { "validationMessages": { "alias": "validationMessages"; "required": false; "isSignal": true; }; "fieldInputs": { "alias": "fieldInputs"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
4011
+ }
4012
+ /**
4013
+ * Declares that a wrapper renders the wrapped field's errors, so that field's component
4014
+ * renders none of its own.
4015
+ *
4016
+ * Takes a thunk because the class is still being defined when the decorator evaluates.
4017
+ */
4018
+ declare function provideFieldErrorDisplay(wrapper: () => Type<FieldErrorDisplayClaim>): Provider;
4019
+
4020
+ 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_ERROR_DISPLAY, FIELD_REGISTRY, FIELD_SIGNAL_CONTEXT, FORM_ID_PREFIX, FORM_OPTIONS, FieldContextRegistryService, FieldErrorsWrapperBase, 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_COMPONENT_LOAD_CACHE, WRAPPER_REGISTRY, applyMetaToElement, applyValidator, applyValidators, arrayFieldMapper, assertNever, baseFieldMapper, buildBaseInputs, buildClassName, compareValues, containerFieldMapper, createAddonActionRegistry, createDebouncedLogicFunction, createDefaultDerivationLogConfig, createDynamicValueFunction, createFieldValueProxy, createFormFieldStateMap, createFormStateLogicFunction, createInitializationTracker, createLogicFunction, createResolvedErrorsSignal, createWarningTracker, deepMergeDefaults, derivedFromDeferred, detectFormMode, dynamicTextToObservable, evaluateCondition, evaluateNonFieldDisabled, evaluateNonFieldHidden, extractExpressionDependencies, extractStringDependencies, getArrayLength, getChangedKeys, getChangedKeysWithin, getFieldValueHandling, getGridClassString, getNestedValue, groupFieldMapper, hasChildFields, hasCrossFieldWhenCondition, hasFormValue, hasNestedProperty, hasTargetProperty, injectAddonTypeRegistry, injectFieldErrors, 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, provideFieldErrorDisplay, readFieldStateInfo, resolveDynamicValue, resolveHttpRequest, resolveNextButtonDisabled, resolveNonFieldDisabled, resolveNonFieldHidden, resolveSubmitButtonDisabled, resolveTokens, rowError, rowFieldMapper, runPresetAction, setupInitializationTracking, shouldLog, shouldShowErrors, textFieldMapper, toReadonlyFieldTree, toReadonlyFieldTreeCached, validatePageNesting, withPreviousValue, writeToFieldValue };
4021
+ 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, ContainerValidation, 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, FieldErrorDisplayClaim, FieldErrors, FieldErrorsOptions, FieldErrorsWrapper, FieldMeta, FieldOption, FieldPathAccess, FieldRegistryContainers, FieldRegistryLeaves, FieldRegistryWrappers, FieldScope, FieldSignalContext, FieldStateContext, FieldStateInfo, FieldTreeRecord, FieldTypeDefinition, FieldValueCondition, FieldWebMcpConfig, FieldWebMcpOptions, 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, InitialPageConfig, 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, ResolvedError, ResolvedValidationExecutionConfig, ResolvedValueExclusionConfig, RowAllowedChildren, RowComponent, RowErrorSpec, RowField, RowWrapper, SchemaApplicationConfig, SchemaDefinition, SimplifiedArrayField, StateLogicConfig, StateLogicType, SubmissionActionResult, SubmissionConfig, SubmitButtonOptions, TemplateAddon, TextAddon, TextElementType, TextField, TextProps, Token, TokenContext, UnaryOpNode, ValidationError, ValidationExecutionConfig, ValidationMessage, ValidationMessageResolver, ValidationMessages, ValidatorAttachment, ValidatorConfig, ValueExclusionConfig, ValueFieldComponent, ValueHandlingMode, ValueType, WarningTracker, WebMcpToolOptions, WithInputSignals, WrapperAutoAssociations, WrapperConfig, WrapperFieldInputs, WrapperTypeDefinition };