@ng-forge/dynamic-forms 0.6.0 → 0.6.1

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.
@@ -3,7 +3,7 @@ import { Observable } from 'rxjs';
3
3
  import * as _angular_core from '@angular/core';
4
4
  import { Signal, Injector, WritableSignal, InjectionToken, Type, ResourceRef, Provider, EnvironmentProviders, PipeTransform } from '@angular/core';
5
5
  import * as _angular_forms_signals from '@angular/forms/signals';
6
- import { FieldTree, FieldContext, ValidationError as ValidationError$1, TreeValidationResult, SchemaPath, SchemaPathTree } from '@angular/forms/signals';
6
+ import { FieldTree, FieldContext, TreeValidationResult, ValidationError as ValidationError$1, SchemaPath, SchemaPathTree } from '@angular/forms/signals';
7
7
  import * as _angular_forms from '@angular/forms';
8
8
  import * as _ng_forge_dynamic_forms from '@ng-forge/dynamic-forms';
9
9
  import { FormSchema } from '@ng-forge/dynamic-forms/schema';
@@ -2362,19 +2362,36 @@ type MaybeOptional<T, V> = T extends {
2362
2362
  } ? V : T extends {
2363
2363
  required: true;
2364
2364
  } ? V : V | undefined;
2365
+ /**
2366
+ * Infers the value type from a single template field (for primitive arrays).
2367
+ * Mirrors InferValueType logic: slider → number, input[number] → number, else string.
2368
+ */
2369
+ type InferSingleTemplateValue<T, D extends number> = T extends {
2370
+ type: 'slider';
2371
+ } ? number : T extends {
2372
+ type: 'input';
2373
+ props: {
2374
+ type: 'number';
2375
+ };
2376
+ } ? number : T extends {
2377
+ type: 'checkbox' | 'toggle';
2378
+ } ? boolean : T extends {
2379
+ value: infer V;
2380
+ } ? Widen<V, Depth[D]> : string;
2365
2381
  /**
2366
2382
  * Infers the value type for an array field.
2367
- * Handles three cases:
2383
+ * Handles four cases:
2368
2384
  * 1. Simplified array with template + value → infer item type from value
2369
- * 2. Simplified array with template only → unknown[]
2370
- * 3. Full-API array with fields → infer from children
2385
+ * 2. Simplified array with array template (no value) → infer object type from template fields
2386
+ * 3. Simplified array with single-field template (no value) → infer primitive type from template field
2387
+ * 4. Full-API array with fields → infer from children
2371
2388
  */
2372
2389
  type InferArrayValue<T, D extends number> = T extends {
2373
2390
  template: unknown;
2374
2391
  value: readonly (infer Item)[];
2375
2392
  } ? Widen<Item>[] : T extends {
2376
- template: unknown;
2377
- } ? unknown[] : T extends {
2393
+ template: infer TArr;
2394
+ } ? TArr extends readonly RegisteredFieldTypes[] ? InferFormValueWithDepth<[...TArr], Depth[D]>[] : InferSingleTemplateValue<TArr, D>[] : T extends {
2378
2395
  fields: infer F;
2379
2396
  } ? F extends RegisteredFieldTypes[] ? InferFormValueWithDepth<F, Depth[D]>[] : unknown[] : unknown[];
2380
2397
  /**
@@ -2457,11 +2474,11 @@ type InferFormValue$1<T> = ExtractFields<T> extends readonly RegisteredFieldType
2457
2474
  */
2458
2475
  interface HttpValidationResponseMapping {
2459
2476
  /**
2460
- * Expression evaluated with scope `{ response }`. Truthy = valid (no error).
2477
+ * Expression evaluated with scope `{ response }`. Must evaluate to `true` (strict boolean) to be valid.
2461
2478
  *
2462
2479
  * NOTE: This is the OPPOSITE of the function-based HttpCustomValidator.onSuccess
2463
2480
  * convention, which maps successful HTTP responses to validation errors.
2464
- * Here, truthy means "validation passed".
2481
+ * Here, `=== true` means "validation passed". Non-boolean results are treated as invalid and trigger a warning.
2465
2482
  */
2466
2483
  validWhen: string;
2467
2484
  /** Error kind returned when validation fails — maps to field-level `validationMessages` */
@@ -2963,7 +2980,7 @@ type FormFieldStateMap = Record<string, FieldStateInfo | undefined>;
2963
2980
  */
2964
2981
  type FieldStateContext = FieldStateInfo;
2965
2982
 
2966
- interface EvaluationContext<TValue = unknown> {
2983
+ interface EvaluationContext<TValue = unknown, TFormValue extends Record<string, unknown> = any> {
2967
2984
  /** Current field value */
2968
2985
  fieldValue: TValue;
2969
2986
  /**
@@ -2973,7 +2990,7 @@ interface EvaluationContext<TValue = unknown> {
2973
2990
  * For array item derivations, this is scoped to the current array item.
2974
2991
  * Use `rootFormValue` to access the complete form when inside an array context.
2975
2992
  */
2976
- formValue: Record<string, unknown>;
2993
+ formValue: TFormValue;
2977
2994
  /** Field path for relative references */
2978
2995
  fieldPath: string;
2979
2996
  /** Custom evaluation functions */
@@ -3114,7 +3131,7 @@ interface EvaluationContext<TValue = unknown> {
3114
3131
  * };
3115
3132
  * ```
3116
3133
  */
3117
- type CustomFunction = (context: EvaluationContext) => unknown;
3134
+ type CustomFunction<TFormValue extends Record<string, unknown> = any> = (context: EvaluationContext<unknown, TFormValue>) => unknown;
3118
3135
 
3119
3136
  /**
3120
3137
  * Async function for derivations — returns any value.
@@ -3133,7 +3150,7 @@ type CustomFunction = (context: EvaluationContext) => unknown;
3133
3150
  *
3134
3151
  * @public
3135
3152
  */
3136
- type AsyncDerivationFunction = (context: EvaluationContext) => Promise<unknown> | Observable<unknown>;
3153
+ type AsyncDerivationFunction<TFormValue extends Record<string, unknown> = any> = (context: EvaluationContext<unknown, TFormValue>) => Promise<unknown> | Observable<unknown>;
3137
3154
  /**
3138
3155
  * Async function for conditions — returns boolean.
3139
3156
  *
@@ -3151,7 +3168,7 @@ type AsyncDerivationFunction = (context: EvaluationContext) => Promise<unknown>
3151
3168
  *
3152
3169
  * @public
3153
3170
  */
3154
- type AsyncConditionFunction = (context: EvaluationContext) => Promise<boolean> | Observable<boolean>;
3171
+ type AsyncConditionFunction<TFormValue extends Record<string, unknown> = any> = (context: EvaluationContext<unknown, TFormValue>) => Promise<boolean> | Observable<boolean>;
3155
3172
 
3156
3173
  /**
3157
3174
  * Re-export Angular's ValidationError for consistency
@@ -3416,7 +3433,7 @@ interface FormConfig<TFields extends NarrowFields | RegisteredFieldTypes[] = Reg
3416
3433
  /**
3417
3434
  * Signal forms adapter configuration.
3418
3435
  */
3419
- customFnConfig?: CustomFnConfig;
3436
+ customFnConfig?: CustomFnConfig<TValue extends Record<string, unknown> ? TValue : Record<string, unknown>>;
3420
3437
  /**
3421
3438
  * Form submission configuration.
3422
3439
  *
@@ -3571,7 +3588,7 @@ interface FormConfig<TFields extends NarrowFields | RegisteredFieldTypes[] = Reg
3571
3588
  *
3572
3589
  * @public
3573
3590
  */
3574
- interface CustomFnConfig {
3591
+ interface CustomFnConfig<TFormValue extends Record<string, unknown> = Record<string, unknown>> {
3575
3592
  /**
3576
3593
  * Custom evaluation functions for conditional expressions.
3577
3594
  *
@@ -3589,7 +3606,7 @@ interface CustomFnConfig {
3589
3606
  * }
3590
3607
  * ```
3591
3608
  */
3592
- customFunctions?: Record<string, CustomFunction>;
3609
+ customFunctions?: Record<string, CustomFunction<TFormValue>>;
3593
3610
  /**
3594
3611
  * Custom derivation functions for value derivation logic.
3595
3612
  *
@@ -3657,7 +3674,7 @@ interface CustomFnConfig {
3657
3674
  * }
3658
3675
  * ```
3659
3676
  */
3660
- derivations?: Record<string, CustomFunction>;
3677
+ derivations?: Record<string, CustomFunction<TFormValue>>;
3661
3678
  /**
3662
3679
  * @deprecated Register functions under `derivations` instead. Use `type: 'derivation'`
3663
3680
  * with `targetProperty` in field logic configs. Will be removed in a future minor version.
@@ -3700,7 +3717,7 @@ interface CustomFnConfig {
3700
3717
  * }
3701
3718
  * ```
3702
3719
  */
3703
- propertyDerivations?: Record<string, CustomFunction>;
3720
+ propertyDerivations?: Record<string, CustomFunction<TFormValue>>;
3704
3721
  /**
3705
3722
  * Async derivation functions for asynchronous value derivation logic.
3706
3723
  *
@@ -3730,7 +3747,7 @@ interface CustomFnConfig {
3730
3747
  * }
3731
3748
  * ```
3732
3749
  */
3733
- asyncDerivations?: Record<string, AsyncDerivationFunction>;
3750
+ asyncDerivations?: Record<string, AsyncDerivationFunction<TFormValue>>;
3734
3751
  /**
3735
3752
  * Async condition functions for asynchronous field state logic.
3736
3753
  *
@@ -3754,7 +3771,7 @@ interface CustomFnConfig {
3754
3771
  * }
3755
3772
  * ```
3756
3773
  */
3757
- asyncConditions?: Record<string, AsyncConditionFunction>;
3774
+ asyncConditions?: Record<string, AsyncConditionFunction<TFormValue>>;
3758
3775
  /**
3759
3776
  * Custom validators using Angular's public FieldContext API
3760
3777
  *
@@ -4324,15 +4341,10 @@ declare class DynamicForm<TFields extends RegisteredFieldTypes[] = RegisteredFie
4324
4341
  private injector;
4325
4342
  private eventBus;
4326
4343
  private logger;
4327
- /**
4328
- * Connect input signals to the shared deps holder BEFORE injecting FormStateManager.
4329
- * Field initializers run in declaration order, so this runs after inputs are created
4330
- * but before stateManager is injected. FormStateManager reads from these signals
4331
- * in computeds/effects, which are all lazy and evaluated after construction.
4332
- */
4333
- private readonly _connectStateDeps;
4334
- /** State manager that owns all form state. */
4335
- private stateManager;
4344
+ private dispatcher;
4345
+ /** State manager that owns all form state. Initialized via connectDeps() to guarantee
4346
+ * FORM_STATE_DEPS is populated before FormStateManager is injected. */
4347
+ private readonly stateManager;
4336
4348
  private componentId;
4337
4349
  /** The currently active config used for form rendering */
4338
4350
  activeConfig: Signal<FormConfig<TFields, InferFormValue$1<TFields extends readonly RegisteredFieldTypes[] ? TFields : RegisteredFieldTypes[]>, Record<string, unknown>, unknown> | undefined>;
@@ -4370,7 +4382,7 @@ declare class DynamicForm<TFields extends RegisteredFieldTypes[] = RegisteredFie
4370
4382
  /** Whether any form field has been touched (blurred) */
4371
4383
  touched: Signal<boolean>;
4372
4384
  /** Current validation errors from all fields */
4373
- errors: Signal<_angular_forms_signals.ValidationError.WithField[]>;
4385
+ errors: Signal<_angular_forms_signals.ValidationError.WithFieldTree[]>;
4374
4386
  /** Whether the form is disabled (from options or form state) */
4375
4387
  disabled: Signal<boolean>;
4376
4388
  /** Whether the form is currently submitting */
@@ -4381,6 +4393,13 @@ declare class DynamicForm<TFields extends RegisteredFieldTypes[] = RegisteredFie
4381
4393
  shouldRender: Signal<boolean>;
4382
4394
  /** Resolved fields ready for rendering */
4383
4395
  protected resolvedFields: Signal<ResolvedField[]>;
4396
+ /**
4397
+ * Recursively counts container components that will emit ComponentInitializedEvent.
4398
+ * Includes the dynamic-form component itself (+1).
4399
+ *
4400
+ * Recurses into all container children, including those nested inside array
4401
+ * item templates, to avoid a premature (initialized) emission.
4402
+ */
4384
4403
  private totalComponentsCount;
4385
4404
  initialized$: rxjs.Observable<boolean>;
4386
4405
  /** Emits when form validity changes. */
@@ -4426,11 +4445,176 @@ declare class DynamicForm<TFields extends RegisteredFieldTypes[] = RegisteredFie
4426
4445
  */
4427
4446
  protected onNativeSubmit(event: Event): void;
4428
4447
  private setupEffects;
4448
+ /**
4449
+ * Populates FORM_STATE_DEPS with this component's input signals, then injects
4450
+ * FormStateManager. Must be called as a field initializer (after the input signals
4451
+ * are declared) so that FormStateManager reads populated deps when it is constructed.
4452
+ * inject() is valid here because field initializers run inside the injection context.
4453
+ */
4454
+ private connectDeps;
4429
4455
  private setupEventHandlers;
4430
4456
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<DynamicForm<any, any>, never>;
4431
4457
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<DynamicForm<any, any>, "form[dynamic-form]", never, { "config": { "alias": "dynamic-form"; "required": true; "isSignal": true; }; "formOptions": { "alias": "formOptions"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "validityChange": "validityChange"; "dirtyChange": "dirtyChange"; "submitted": "submitted"; "reset": "reset"; "cleared": "cleared"; "events": "events"; "initialized": "initialized"; "onPageChange": "onPageChange"; "onPageNavigationStateChange": "onPageNavigationStateChange"; }, never, never, true, never>;
4432
4458
  }
4433
4459
 
4460
+ declare class EventBus {
4461
+ private readonly pipeline$;
4462
+ private readonly globalEmitFormValue;
4463
+ private readonly rootFormRegistry;
4464
+ private readonly formOptions;
4465
+ private readonly logger;
4466
+ events$: Observable<FormEvent>;
4467
+ /**
4468
+ * Dispatches a pre-created event instance directly.
4469
+ *
4470
+ * Use this overload with the `arrayEvent()` factory or any other code that
4471
+ * produces a `FormEvent` instance rather than a constructor:
4472
+ *
4473
+ * ```typescript
4474
+ * eventBus.dispatch(arrayEvent('contacts').append(template));
4475
+ * eventBus.dispatch(arrayEvent('contacts').pop());
4476
+ * ```
4477
+ *
4478
+ * @param event - A FormEvent instance to dispatch
4479
+ */
4480
+ dispatch(event: FormEvent): void;
4481
+ /**
4482
+ * Dispatches an event to all subscribers by instantiating the provided constructor.
4483
+ *
4484
+ * Creates an instance of the provided event constructor and broadcasts it
4485
+ * through the event pipeline to all active subscribers.
4486
+ *
4487
+ * If `withEventFormValue()` is enabled globally or `options.emitFormValueOnEvents`
4488
+ * is set to `true` in the form config, the current form value will be attached
4489
+ * to the event's `formValue` property.
4490
+ *
4491
+ * @param eventConstructor - Constructor function for the event to dispatch
4492
+ * @param args - Arguments to pass to the event constructor
4493
+ *
4494
+ * @example
4495
+ * ```typescript
4496
+ * // Dispatch a submit event
4497
+ * eventBus.dispatch(SubmitEvent);
4498
+ *
4499
+ * // Dispatch a custom event with args
4500
+ * eventBus.dispatch(CustomFormEvent, 'arg1', 42);
4501
+ * ```
4502
+ */
4503
+ dispatch<T extends FormEventConstructor>(eventConstructor: T, ...args: ConstructorParameters<T>): void;
4504
+ /**
4505
+ * Dispatches a pre-created event instance directly.
4506
+ * Used internally by EventDispatcher to forward events into the bus.
4507
+ * @internal
4508
+ */
4509
+ emitInstance(event: FormEvent): void;
4510
+ /**
4511
+ * Shared emit path for both dispatch() and emitInstance().
4512
+ * Attaches form value if configured, then pushes to the pipeline.
4513
+ */
4514
+ private emit;
4515
+ /**
4516
+ * Emits an event through the pipeline. Catches any synchronous exception that escapes
4517
+ * RxJS's own error handling so dispatch() callers are never disrupted by a failing subscriber.
4518
+ */
4519
+ private safeEmit;
4520
+ /**
4521
+ * Determines whether form value should be attached to events.
4522
+ *
4523
+ * Precedence rules:
4524
+ * 1. Per-form setting (if defined) takes precedence
4525
+ * 2. Falls back to global setting
4526
+ */
4527
+ private shouldEmitFormValue;
4528
+ /**
4529
+ * Subscribes to events of a specific type.
4530
+ *
4531
+ * @param eventType - The type of event to subscribe to
4532
+ * @returns Observable that emits events of the specified type
4533
+ */
4534
+ on<T extends FormEvent>(eventType: T['type']): Observable<T>;
4535
+ /**
4536
+ * Subscribes to events of multiple types.
4537
+ *
4538
+ * @param eventType - Array of event types to subscribe to
4539
+ * @returns Observable that emits events matching any of the specified types
4540
+ */
4541
+ on<T extends FormEvent>(eventType: Array<T['type']>): Observable<T>;
4542
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<EventBus, never>;
4543
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<EventBus>;
4544
+ }
4545
+
4546
+ /**
4547
+ * Injectable service for dispatching events into a DynamicForm from outside the form.
4548
+ *
4549
+ * ## When to use
4550
+ *
4551
+ * Use `EventDispatcher` when you need to drive form behaviour **from the host component** —
4552
+ * for example, appending array items in response to a field value change, triggering a form
4553
+ * reset from a toolbar button, or reacting to external application state.
4554
+ *
4555
+ * This is the recommended alternative to accessing the form's internals via `viewChild`.
4556
+ *
4557
+ * ## Setup
4558
+ *
4559
+ * Provide `EventDispatcher` at the **host component** level (not root). DynamicForm
4560
+ * automatically detects it and connects its internal event bus to the dispatcher.
4561
+ *
4562
+ * ```typescript
4563
+ * @Component({
4564
+ * providers: [EventDispatcher],
4565
+ * template: `<form [dynamic-form]="config" [(value)]="formValue"></form>`
4566
+ * })
4567
+ * export class MyComponent {
4568
+ * readonly dispatcher = inject(EventDispatcher);
4569
+ * readonly formValue = signal<Record<string, unknown>>({});
4570
+ *
4571
+ * constructor() {
4572
+ * effect(() => {
4573
+ * const category = this.formValue()?.['category'] as string | undefined;
4574
+ * if (category) {
4575
+ * this.dispatcher.dispatch(
4576
+ * arrayEvent('tasks').append([{ key: 'name', type: 'input', label: 'Task', value: category }])
4577
+ * );
4578
+ * }
4579
+ * });
4580
+ * }
4581
+ * }
4582
+ * ```
4583
+ *
4584
+ * ## Multi-form note
4585
+ *
4586
+ * If multiple `DynamicForm` instances exist under the same provider scope, **all forms**
4587
+ * will receive dispatched events. To target a specific form, scope the provider to a
4588
+ * wrapper component that contains only that form.
4589
+ *
4590
+ * ## What events can be dispatched
4591
+ *
4592
+ * Any `FormEvent` instance is accepted — array events, reset/clear events, custom events, etc.
4593
+ * The `arrayEvent()` builder is the recommended way to construct array manipulation events:
4594
+ *
4595
+ * ```typescript
4596
+ * dispatcher.dispatch(arrayEvent('tasks').append(template));
4597
+ * dispatcher.dispatch(arrayEvent('tasks').removeAt(0));
4598
+ * dispatcher.dispatch(new FormResetEvent());
4599
+ * ```
4600
+ */
4601
+ declare class EventDispatcher {
4602
+ private bus;
4603
+ /**
4604
+ * Dispatches a form event into the connected DynamicForm's event bus.
4605
+ * No-op if no form is currently connected.
4606
+ *
4607
+ * @param event - A FormEvent instance. Use the `arrayEvent()` builder for array operations.
4608
+ */
4609
+ dispatch(event: FormEvent): void;
4610
+ /** @internal - Called by DynamicForm on init */
4611
+ connect(bus: EventBus): void;
4612
+ /** @internal - Called by DynamicForm on destroy */
4613
+ disconnect(): void;
4614
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<EventDispatcher, never>;
4615
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<EventDispatcher>;
4616
+ }
4617
+
4434
4618
  /**
4435
4619
  * Base interface for dynamic form features.
4436
4620
  * Features are configuration options that can be passed to provideDynamicForm
@@ -5444,92 +5628,6 @@ declare function arrayEvent(arrayKey: string): {
5444
5628
  removeAt: (index: number) => RemoveAtIndexEvent;
5445
5629
  };
5446
5630
 
5447
- /**
5448
- * Event bus service for form-wide event communication.
5449
- *
5450
- * Provides type-safe event dispatching and subscription for form components
5451
- * to communicate without direct coupling. Uses RxJS observables for reactive
5452
- * event handling and supports both single event type and multiple event type subscriptions.
5453
- *
5454
- * @example
5455
- * ```typescript
5456
- * @Component({
5457
- * providers: [EventBus]
5458
- * })
5459
- * export class MyFormComponent {
5460
- * constructor(private eventBus: EventBus) {
5461
- * // Subscribe to form submission events
5462
- * this.eventBus.on<SubmitEvent>('submit').subscribe(() => {
5463
- * console.log('Form was submitted');
5464
- * });
5465
- *
5466
- * // Subscribe to multiple event types
5467
- * this.eventBus.on<SubmitEvent | FormResetEvent>(['submit', 'form-reset']).subscribe(event => {
5468
- * console.log('Form event:', event.type);
5469
- * });
5470
- * }
5471
- *
5472
- * onSubmit() {
5473
- * // Dispatch a submit event
5474
- * this.eventBus.dispatch(SubmitEvent);
5475
- * }
5476
- * }
5477
- * ```
5478
- */
5479
- declare class EventBus {
5480
- private readonly pipeline$;
5481
- private readonly globalEmitFormValue;
5482
- private readonly rootFormRegistry;
5483
- private readonly formOptions;
5484
- events$: Observable<FormEvent>;
5485
- /**
5486
- * Dispatches an event to all subscribers.
5487
- *
5488
- * Creates an instance of the provided event constructor and broadcasts it
5489
- * through the event pipeline to all active subscribers.
5490
- *
5491
- * If `withEventFormValue()` is enabled globally or `options.emitFormValueOnEvents`
5492
- * is set to `true` in the form config, the current form value will be attached
5493
- * to the event's `formValue` property.
5494
- *
5495
- * @param eventConstructor - Constructor function for the event to dispatch
5496
- *
5497
- * @example
5498
- * ```typescript
5499
- * // Dispatch a submit event
5500
- * eventBus.dispatch(SubmitEvent);
5501
- *
5502
- * // Dispatch a custom event
5503
- * eventBus.dispatch(CustomFormEvent);
5504
- * ```
5505
- */
5506
- dispatch<T extends FormEventConstructor>(eventConstructor: T, ...args: ConstructorParameters<T>): void;
5507
- /**
5508
- * Determines whether form value should be attached to events.
5509
- *
5510
- * Precedence rules:
5511
- * 1. Per-form setting (if defined) takes precedence
5512
- * 2. Falls back to global setting
5513
- */
5514
- private shouldEmitFormValue;
5515
- /**
5516
- * Subscribes to events of a specific type.
5517
- *
5518
- * @param eventType - The type of event to subscribe to
5519
- * @returns Observable that emits events of the specified type
5520
- */
5521
- on<T extends FormEvent>(eventType: T['type']): Observable<T>;
5522
- /**
5523
- * Subscribes to events of multiple types.
5524
- *
5525
- * @param eventType - Array of event types to subscribe to
5526
- * @returns Observable that emits events matching any of the specified types
5527
- */
5528
- on<T extends FormEvent>(eventType: Array<T['type']>): Observable<T>;
5529
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<EventBus, never>;
5530
- static ɵprov: _angular_core.ɵɵInjectableDeclaration<EventBus>;
5531
- }
5532
-
5533
5631
  /**
5534
5632
  * Context for token resolution in event args
5535
5633
  */
@@ -5946,7 +6044,7 @@ declare class GroupFieldComponent<TModel extends Record<string, unknown> = Recor
5946
6044
  readonly invalid: _angular_core.Signal<boolean>;
5947
6045
  readonly dirty: _angular_core.Signal<boolean>;
5948
6046
  readonly touched: _angular_core.Signal<boolean>;
5949
- readonly errors: _angular_core.Signal<_angular_forms_signals.ValidationError.WithField[]>;
6047
+ readonly errors: _angular_core.Signal<_angular_forms_signals.ValidationError.WithFieldTree[]>;
5950
6048
  readonly disabled: _angular_core.Signal<boolean>;
5951
6049
  private readonly nestedFieldTree;
5952
6050
  private readonly groupFieldSignalContext;
@@ -6007,7 +6105,7 @@ declare class ArrayFieldComponent<TModel extends Record<string, unknown> = Recor
6007
6105
  key: _angular_core.InputSignal<string>;
6008
6106
  className: _angular_core.InputSignal<string | undefined>;
6009
6107
  hidden: _angular_core.InputSignal<boolean>;
6010
- readonly hostClasses: _angular_core.Signal<string>;
6108
+ readonly hostClasses: Signal<string>;
6011
6109
  private readonly rawFieldRegistry;
6012
6110
  /**
6013
6111
  * Gets the auto-remove button FieldDef from normalization metadata.
@@ -6052,7 +6150,12 @@ declare class ArrayFieldComponent<TModel extends Record<string, unknown> = Recor
6052
6150
  */
6053
6151
  private readonly itemPositionMap;
6054
6152
  /** Read-only view of resolved items for template consumption. */
6055
- readonly resolvedItems: _angular_core.Signal<ResolvedArrayItem[]>;
6153
+ readonly resolvedItems: Signal<ResolvedArrayItem[]>;
6154
+ /**
6155
+ * Whether the array has reached its configured maxLength.
6156
+ * Exposed as a public signal so add-button components can bind [disabled]="atMaxLength()".
6157
+ */
6158
+ readonly atMaxLength: Signal<boolean>;
6056
6159
  /**
6057
6160
  * Caches the result of appending the auto-remove button to template arrays.
6058
6161
  * Keyed by template array reference — cache hits occur during recreate/resolution
@@ -6191,5 +6294,12 @@ declare class RootFormRegistryService {
6191
6294
  constructor(formValue: Signal<Record<string, unknown>>, rootForm: Signal<FieldTree<Record<string, unknown>> | undefined>);
6192
6295
  }
6193
6296
 
6194
- export { ARRAY_CONTEXT, AppendArrayItemEvent, ArrayFieldComponent, BUILT_IN_FIELDS, ConsoleLogger, DEFAULT_PROPS, DEFAULT_VALIDATION_MESSAGES, DynamicForm, DynamicFormError, DynamicFormLogger, DynamicTextPipe, EventBus, FIELD_REGISTRY, FIELD_SIGNAL_CONTEXT, FORM_OPTIONS, FormClearEvent, FormResetEvent, GroupFieldComponent, InsertArrayItemEvent, NextPageEvent, NoopLogger, PageChangeEvent, PopArrayItemEvent, PrependArrayItemEvent, PreviousPageEvent, RemoveAtIndexEvent, RootFormRegistryService, RowFieldComponent, ShiftArrayItemEvent, SubmitEvent, applyMetaToElement, applyValidator, applyValidators, arrayEvent, arrayFieldMapper, baseFieldMapper, buildBaseInputs, createField, dynamicTextToObservable, evaluateNonFieldDisabled, evaluateNonFieldHidden, field, formConfig, getArrayLength, groupFieldMapper, hasFormValue, interpolateParams, isArrayField, isCheckedField, isContainerField, isDisplayOnlyField, isEqual, isFormStateCondition, isGroupField, isLeafField, isPageField, isPropertyDerivationLogicConfig, isRowField, isSimplifiedArrayField, isValueBearingField, isValueField, omit, pageFieldMapper, provideDynamicForm, resolveNextButtonDisabled, resolveNonFieldDisabled, resolveNonFieldHidden, resolveSubmitButtonDisabled, resolveTokens, rowFieldMapper, textFieldMapper, withEventFormValue, withLoggerConfig, withValueExclusionDefaults };
6297
+ /**
6298
+ * Injection token for configuring the initialization timeout in milliseconds.
6299
+ * Defaults to 10 seconds. When the timeout is reached, a warning is logged
6300
+ * and (initialized) emits true as a best-effort fallback.
6301
+ */
6302
+ declare const INITIALIZATION_TIMEOUT_MS: InjectionToken<number>;
6303
+
6304
+ export { ARRAY_CONTEXT, AppendArrayItemEvent, ArrayFieldComponent, BUILT_IN_FIELDS, ConsoleLogger, DEFAULT_PROPS, DEFAULT_VALIDATION_MESSAGES, DynamicForm, DynamicFormError, DynamicFormLogger, DynamicTextPipe, EventBus, EventDispatcher, FIELD_REGISTRY, FIELD_SIGNAL_CONTEXT, FORM_OPTIONS, FormClearEvent, FormResetEvent, GroupFieldComponent, INITIALIZATION_TIMEOUT_MS, InsertArrayItemEvent, NextPageEvent, NoopLogger, PageChangeEvent, PopArrayItemEvent, PrependArrayItemEvent, PreviousPageEvent, RemoveAtIndexEvent, RootFormRegistryService, RowFieldComponent, ShiftArrayItemEvent, SubmitEvent, applyMetaToElement, applyValidator, applyValidators, arrayEvent, arrayFieldMapper, baseFieldMapper, buildBaseInputs, createField, dynamicTextToObservable, evaluateNonFieldDisabled, evaluateNonFieldHidden, field, formConfig, getArrayLength, groupFieldMapper, hasFormValue, interpolateParams, isArrayField, isCheckedField, isContainerField, isDisplayOnlyField, isEqual, isFormStateCondition, isGroupField, isLeafField, isPageField, isPropertyDerivationLogicConfig, isRowField, isSimplifiedArrayField, isValueBearingField, isValueField, omit, pageFieldMapper, provideDynamicForm, resolveNextButtonDisabled, resolveNonFieldDisabled, resolveNonFieldHidden, resolveSubmitButtonDisabled, resolveTokens, rowFieldMapper, textFieldMapper, withEventFormValue, withLoggerConfig, withValueExclusionDefaults };
6195
6305
  export type { ArrayAllowedChildren, ArrayButtonConfig, ArrayContext, ArrayField, ArrayFieldTree, ArrayItemContext, ArrayItemDefinitionTemplate, ArrayItemTemplate, AsyncCondition, AsyncConditionFunction, AsyncCustomValidator, AsyncDerivationFunction, AsyncValidatorConfig, AvailableFieldTypes, BaseCheckedField, BaseValidatorConfig, BaseValueField, BuiltInValidatorConfig, ButtonLogicContext, CheckedFieldComponent, ConditionalExpression, ContainerFieldTypes, CustomFnConfig, CustomValidator, CustomValidatorConfig, DeclarativeHttpValidatorConfig, DynamicFormFieldRegistry, DynamicText, EvaluationContext, ExtractField, ExtractFieldDefs, ExtractFormValue, FieldComponent, FieldDef, FieldMeta, FieldOption, FieldPathAccess, FieldRegistryContainers, FieldRegistryLeaves, FieldSignalContext, FieldStateContext, FieldStateInfo, FieldTypeDefinition, FieldWithValidation, FormConfig, FormEvent, FormEventConstructor, FormFieldStateMap, FormMode, FormModeDetectionResult, FormOptions, FormStateCondition, GroupAllowedChildren, GroupField, HttpCondition, HttpCustomValidator, HttpRequestConfig, HttpResourceRequest, HttpValidationResponseMapping, HttpValidatorConfig, InferFormValue$1 as InferFormValue, LeafFieldTypes, Logger, LogicConfig, MapperFn, NarrowField, NarrowFields, NextButtonOptions, NonFieldLogicConfig, NonFieldLogicContext, NonFieldLogicType, PageAllowedChildren, PageField, Prettify, PropertyDerivationLogicConfig, RegisteredFieldTypes, ResolvedValueExclusionConfig, RowAllowedChildren, RowField, SchemaApplicationConfig, SchemaDefinition, SimplifiedArrayField, StateLogicConfig, SubmissionActionResult, SubmissionConfig, SubmitButtonOptions, TextElementType, TextField, TextProps, TokenContext, ValidationError, ValidationMessages, ValidatorConfig, ValueExclusionConfig, ValueFieldComponent, ValueHandlingMode, ValueType, WithInputSignals };