@ng-forge/dynamic-forms 0.3.1 → 0.5.0
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.
- package/README.md +5 -1
- package/fesm2022/ng-forge-dynamic-forms-integration.mjs +37 -66
- package/fesm2022/ng-forge-dynamic-forms-integration.mjs.map +1 -1
- package/fesm2022/{ng-forge-dynamic-forms-ng-forge-dynamic-forms-D58rojQc.mjs → ng-forge-dynamic-forms-ng-forge-dynamic-forms-WGww2nXx.mjs} +3572 -346
- package/fesm2022/ng-forge-dynamic-forms-ng-forge-dynamic-forms-WGww2nXx.mjs.map +1 -0
- package/fesm2022/{ng-forge-dynamic-forms-page-field.component-m35XgkkL.mjs → ng-forge-dynamic-forms-page-field.component-CrO9WTDw.mjs} +5 -5
- package/fesm2022/{ng-forge-dynamic-forms-page-field.component-m35XgkkL.mjs.map → ng-forge-dynamic-forms-page-field.component-CrO9WTDw.mjs.map} +1 -1
- package/fesm2022/ng-forge-dynamic-forms-schema.mjs +92 -0
- package/fesm2022/ng-forge-dynamic-forms-schema.mjs.map +1 -0
- package/fesm2022/{ng-forge-dynamic-forms-text-field.component-CfDZFTyf.mjs → ng-forge-dynamic-forms-text-field.component-BcFx_kOz.mjs} +5 -5
- package/fesm2022/{ng-forge-dynamic-forms-text-field.component-CfDZFTyf.mjs.map → ng-forge-dynamic-forms-text-field.component-BcFx_kOz.mjs.map} +1 -1
- package/fesm2022/ng-forge-dynamic-forms.mjs +1 -1
- package/package.json +13 -12
- package/types/ng-forge-dynamic-forms-integration.d.ts +61 -32
- package/types/ng-forge-dynamic-forms-schema.d.ts +178 -0
- package/types/ng-forge-dynamic-forms.d.ts +1173 -240
- package/fesm2022/ng-forge-dynamic-forms-ng-forge-dynamic-forms-D58rojQc.mjs.map +0 -1
- package/fesm2022/ng-forge-dynamic-forms-testing-test-button.harness-0iXHLraC.mjs +0 -31
- package/fesm2022/ng-forge-dynamic-forms-testing-test-button.harness-0iXHLraC.mjs.map +0 -1
- package/fesm2022/ng-forge-dynamic-forms-testing.mjs +0 -971
- package/fesm2022/ng-forge-dynamic-forms-testing.mjs.map +0 -1
- package/types/ng-forge-dynamic-forms-testing.d.ts +0 -597
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import * as rxjs from 'rxjs';
|
|
2
2
|
import { Observable } from 'rxjs';
|
|
3
|
-
import * as _angular_forms from '@angular/forms';
|
|
4
3
|
import * as _angular_forms_signals from '@angular/forms/signals';
|
|
5
|
-
import { ValidationError as ValidationError$1,
|
|
4
|
+
import { FieldTree, FieldContext, ValidationError as ValidationError$1, TreeValidationResult, SchemaPath, SchemaPathTree } from '@angular/forms/signals';
|
|
5
|
+
import * as _angular_forms from '@angular/forms';
|
|
6
6
|
import * as _ng_forge_dynamic_forms from '@ng-forge/dynamic-forms';
|
|
7
7
|
import * as _angular_core from '@angular/core';
|
|
8
|
-
import { Signal,
|
|
8
|
+
import { Signal, Injector, WritableSignal, InjectionToken, Type, ResourceRef, OnDestroy, InputSignal, Provider, EnvironmentProviders, PipeTransform } from '@angular/core';
|
|
9
|
+
import { FormSchema } from '@ng-forge/dynamic-forms/schema';
|
|
9
10
|
|
|
10
11
|
type WithInputSignals<T> = {
|
|
11
12
|
readonly [K in keyof T]-?: Signal<T[K]>;
|
|
@@ -299,19 +300,151 @@ type IncludedKeys = 'label' | 'className' | 'hidden' | 'tabIndex';
|
|
|
299
300
|
type FieldComponent<T extends FieldDef<unknown, FieldMeta>> = Prettify<WithInputSignals<Pick<T, IncludedKeys>>>;
|
|
300
301
|
|
|
301
302
|
/**
|
|
302
|
-
*
|
|
303
|
-
*
|
|
303
|
+
* Field signal context - the "nervous system" of the dynamic form.
|
|
304
|
+
* Provided via FIELD_SIGNAL_CONTEXT injection token.
|
|
305
|
+
*
|
|
306
|
+
* Gives mappers and components access to form state, values, and configuration.
|
|
307
|
+
* Container fields (Group, Array) create scoped contexts with nested forms.
|
|
308
|
+
*
|
|
309
|
+
* The `form` property uses Angular's FieldTree which includes Subfields<TModel>
|
|
310
|
+
* for type-safe child field access via bracket notation when TModel is a Record.
|
|
311
|
+
*
|
|
312
|
+
* Note: Form-level configuration (defaultValidationMessages, formOptions, defaultProps)
|
|
313
|
+
* is provided via dedicated injection tokens (DEFAULT_VALIDATION_MESSAGES, FORM_OPTIONS,
|
|
314
|
+
* DEFAULT_PROPS) at the DynamicForm level and inherited by all children.
|
|
304
315
|
*/
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
316
|
+
interface FieldSignalContext<TModel extends Record<string, unknown> = Record<string, unknown>> {
|
|
317
|
+
injector: Injector;
|
|
318
|
+
value: WritableSignal<Partial<TModel> | undefined>;
|
|
319
|
+
defaultValues: () => TModel;
|
|
320
|
+
form: FieldTree<TModel>;
|
|
321
|
+
/** Current page validity signal for paged forms. Used by next button to determine disabled state. */
|
|
322
|
+
currentPageValid?: Signal<boolean>;
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Array context for fields rendered within arrays.
|
|
326
|
+
* Provides position and parent array information for components inside array fields.
|
|
327
|
+
*/
|
|
328
|
+
interface ArrayContext {
|
|
329
|
+
/** The key of the parent array field. */
|
|
330
|
+
arrayKey: string;
|
|
331
|
+
/**
|
|
332
|
+
* The index of this item within the array.
|
|
333
|
+
* Uses linkedSignal to automatically update when items are added/removed,
|
|
334
|
+
* allowing index-dependent logic to react without component recreation.
|
|
335
|
+
*/
|
|
336
|
+
index: Signal<number>;
|
|
337
|
+
/** The current form value for token resolution. */
|
|
338
|
+
formValue: unknown;
|
|
339
|
+
/** The array field definition. */
|
|
340
|
+
field: FieldDef<unknown>;
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Mapper function that converts a field definition to component inputs.
|
|
344
|
+
*
|
|
345
|
+
* Mappers run within an injection context and can inject FIELD_SIGNAL_CONTEXT.
|
|
346
|
+
* Returns a Signal to enable reactive updates when dependencies change.
|
|
347
|
+
*/
|
|
348
|
+
type MapperFn<T extends FieldDef<unknown>> = (input: T) => Signal<Record<string, unknown>>;
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Defines how a field type handles form values and data collection.
|
|
352
|
+
*
|
|
353
|
+
* - 'include': Field contributes to form values (default for input fields)
|
|
354
|
+
* - 'exclude': Field is excluded from form values (for display/layout fields)
|
|
355
|
+
* - 'flatten': Field's children are flattened to parent level (for container fields)
|
|
356
|
+
*/
|
|
357
|
+
type ValueHandlingMode = 'include' | 'exclude' | 'flatten';
|
|
358
|
+
/**
|
|
359
|
+
* Configuration interface for registering custom field types.
|
|
360
|
+
*
|
|
361
|
+
* Defines how a field type should be handled by the dynamic form system,
|
|
362
|
+
* including its component loading strategy and field-to-component mapping logic.
|
|
363
|
+
* Supports both eager-loaded and lazy-loaded components.
|
|
364
|
+
*
|
|
365
|
+
* @typeParam T - The field definition type this field type handles
|
|
366
|
+
*
|
|
367
|
+
* @example
|
|
368
|
+
* ```typescript
|
|
369
|
+
* const CustomInputType: FieldTypeDefinition<InputFieldDef> = {
|
|
370
|
+
* name: 'custom-input',
|
|
371
|
+
* loadComponent: () => import('./custom-input.component').then(m => m.CustomInputComponent),
|
|
372
|
+
* mapper: customInputMapper
|
|
373
|
+
* };
|
|
374
|
+
*
|
|
375
|
+
* // Register with providers
|
|
376
|
+
* provideDynamicForm(CustomInputType)
|
|
377
|
+
* ```
|
|
378
|
+
*/
|
|
379
|
+
interface FieldTypeDefinition<T extends FieldDef<any> = any> {
|
|
380
|
+
/** Unique identifier for the field type */
|
|
381
|
+
name: string;
|
|
382
|
+
/** Field definition type marker (internal use) */
|
|
383
|
+
_fieldDef?: T;
|
|
384
|
+
/**
|
|
385
|
+
* Function to load the component (supports lazy loading).
|
|
386
|
+
* Returns a Promise that resolves to the component class or module with default export.
|
|
387
|
+
*
|
|
388
|
+
* Optional - omit for componentless fields (e.g., hidden fields) that only
|
|
389
|
+
* contribute to form values without rendering any UI.
|
|
390
|
+
*/
|
|
391
|
+
loadComponent?: () => Promise<any>;
|
|
392
|
+
/**
|
|
393
|
+
* Mapper function that converts field definition to component bindings.
|
|
394
|
+
*
|
|
395
|
+
* Optional - omit for componentless fields (like hidden fields) that don't need
|
|
396
|
+
* input mapping. When omitted for componentless fields (no loadComponent), an empty
|
|
397
|
+
* signal is returned. When omitted for regular fields with a component, falls back
|
|
398
|
+
* to baseFieldMapper.
|
|
399
|
+
*/
|
|
400
|
+
mapper?: MapperFn<T>;
|
|
401
|
+
/** How this field type handles form values and data collection (defaults to 'include') */
|
|
402
|
+
valueHandling?: ValueHandlingMode;
|
|
403
|
+
/**
|
|
404
|
+
* List of prop keys to forward to the meta object.
|
|
405
|
+
*
|
|
406
|
+
* Some props (like `type` for inputs, `rows`/`cols` for textareas) are actually
|
|
407
|
+
* native HTML attributes. Specifying them here causes them to be merged into
|
|
408
|
+
* the meta object before being passed to the component, ensuring they're applied
|
|
409
|
+
* via the meta tracking mechanism.
|
|
410
|
+
*
|
|
411
|
+
* Note: Meta values always take precedence over forwarded props.
|
|
412
|
+
*
|
|
413
|
+
* @example
|
|
414
|
+
* ```typescript
|
|
415
|
+
* {
|
|
416
|
+
* name: 'input',
|
|
417
|
+
* propsToMeta: ['type'],
|
|
418
|
+
* // ...
|
|
419
|
+
* }
|
|
420
|
+
* ```
|
|
421
|
+
*/
|
|
422
|
+
propsToMeta?: string[];
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* Injection token for the global field type registry.
|
|
426
|
+
*
|
|
427
|
+
* Provides access to the map of registered field types throughout the application.
|
|
428
|
+
* The registry is populated by the provideDynamicForm function and used by
|
|
429
|
+
* field rendering components to resolve field types to their implementations.
|
|
430
|
+
*
|
|
431
|
+
* @example
|
|
432
|
+
* ```typescript
|
|
433
|
+
* constructor(@Inject(FIELD_REGISTRY) private registry: Map<string, FieldTypeDefinition>) {
|
|
434
|
+
* const inputType = registry.get('input');
|
|
435
|
+
* }
|
|
436
|
+
* ```
|
|
437
|
+
*/
|
|
438
|
+
declare const FIELD_REGISTRY: InjectionToken<Map<string, FieldTypeDefinition<any>>>;
|
|
439
|
+
|
|
440
|
+
/**
|
|
441
|
+
* Resolved field ready for rendering with ngComponentOutlet.
|
|
442
|
+
*/
|
|
443
|
+
interface ResolvedField {
|
|
444
|
+
key: string;
|
|
445
|
+
component: Type<unknown>;
|
|
446
|
+
injector: Injector;
|
|
447
|
+
inputs: Signal<Record<string, unknown>>;
|
|
315
448
|
}
|
|
316
449
|
|
|
317
450
|
/**
|
|
@@ -620,7 +753,86 @@ type FormStateCondition =
|
|
|
620
753
|
/** True when fields on the current page are invalid (for paged forms) */
|
|
621
754
|
| 'pageInvalid';
|
|
622
755
|
/**
|
|
623
|
-
*
|
|
756
|
+
* Logic type for controlling field state (hidden, readonly, disabled, required).
|
|
757
|
+
*
|
|
758
|
+
* @public
|
|
759
|
+
*/
|
|
760
|
+
type StateLogicType = 'hidden' | 'readonly' | 'disabled' | 'required';
|
|
761
|
+
/**
|
|
762
|
+
* Base configuration for conditional field state logic.
|
|
763
|
+
*
|
|
764
|
+
* @internal
|
|
765
|
+
*/
|
|
766
|
+
interface BaseStateLogicConfig {
|
|
767
|
+
/**
|
|
768
|
+
* Logic type identifier for field state.
|
|
769
|
+
*
|
|
770
|
+
* - `hidden`: Hide the field from view (still participates in form state)
|
|
771
|
+
* - `readonly`: Make the field read-only
|
|
772
|
+
* - `disabled`: Disable user interaction
|
|
773
|
+
* - `required`: Make the field required
|
|
774
|
+
*/
|
|
775
|
+
type: StateLogicType;
|
|
776
|
+
/**
|
|
777
|
+
* Condition that determines when this logic applies.
|
|
778
|
+
*
|
|
779
|
+
* Can be:
|
|
780
|
+
* - `boolean`: Static value (always applies or never applies)
|
|
781
|
+
* - `ConditionalExpression`: Expression evaluated against field/form values
|
|
782
|
+
* - `FormStateCondition`: Special form/page state check (for buttons)
|
|
783
|
+
*
|
|
784
|
+
* @example
|
|
785
|
+
* ```typescript
|
|
786
|
+
* // Static condition
|
|
787
|
+
* condition: true
|
|
788
|
+
*
|
|
789
|
+
* // Field value condition
|
|
790
|
+
* condition: {
|
|
791
|
+
* type: 'fieldValue',
|
|
792
|
+
* fieldPath: 'status',
|
|
793
|
+
* operator: 'equals',
|
|
794
|
+
* value: 'locked'
|
|
795
|
+
* }
|
|
796
|
+
*
|
|
797
|
+
* // Form state condition (for buttons)
|
|
798
|
+
* condition: 'formSubmitting'
|
|
799
|
+
* ```
|
|
800
|
+
*/
|
|
801
|
+
condition: ConditionalExpression | boolean | FormStateCondition;
|
|
802
|
+
}
|
|
803
|
+
/**
|
|
804
|
+
* State logic that evaluates immediately on change (default).
|
|
805
|
+
*
|
|
806
|
+
* @internal
|
|
807
|
+
*/
|
|
808
|
+
interface ImmediateStateLogicConfig extends BaseStateLogicConfig {
|
|
809
|
+
/**
|
|
810
|
+
* Trigger for immediate evaluation.
|
|
811
|
+
* @default 'onChange'
|
|
812
|
+
*/
|
|
813
|
+
trigger?: 'onChange';
|
|
814
|
+
/** Not allowed for onChange trigger */
|
|
815
|
+
debounceMs?: never;
|
|
816
|
+
}
|
|
817
|
+
/**
|
|
818
|
+
* State logic that evaluates after a debounce period.
|
|
819
|
+
*
|
|
820
|
+
* @internal
|
|
821
|
+
*/
|
|
822
|
+
interface DebouncedStateLogicConfig extends BaseStateLogicConfig {
|
|
823
|
+
/**
|
|
824
|
+
* Trigger for debounced evaluation.
|
|
825
|
+
* Evaluates after the value has stabilized for the debounce duration.
|
|
826
|
+
*/
|
|
827
|
+
trigger: 'debounced';
|
|
828
|
+
/**
|
|
829
|
+
* Debounce duration in milliseconds.
|
|
830
|
+
* @default 500
|
|
831
|
+
*/
|
|
832
|
+
debounceMs?: number;
|
|
833
|
+
}
|
|
834
|
+
/**
|
|
835
|
+
* Configuration for conditional field state logic.
|
|
624
836
|
*
|
|
625
837
|
* Defines how field behavior changes based on conditions.
|
|
626
838
|
* Supports hiding, disabling, making readonly, or requiring fields
|
|
@@ -644,47 +856,278 @@ type FormStateCondition =
|
|
|
644
856
|
* type: 'disabled',
|
|
645
857
|
* condition: 'formSubmitting'
|
|
646
858
|
* }
|
|
859
|
+
*
|
|
860
|
+
* // Debounced visibility (avoids flicker during rapid typing)
|
|
861
|
+
* {
|
|
862
|
+
* type: 'hidden',
|
|
863
|
+
* trigger: 'debounced',
|
|
864
|
+
* debounceMs: 300,
|
|
865
|
+
* condition: {
|
|
866
|
+
* type: 'fieldValue',
|
|
867
|
+
* fieldPath: 'search',
|
|
868
|
+
* operator: 'isEmpty'
|
|
869
|
+
* }
|
|
870
|
+
* }
|
|
647
871
|
* ```
|
|
648
872
|
*
|
|
649
873
|
* @public
|
|
650
874
|
*/
|
|
651
|
-
|
|
875
|
+
type StateLogicConfig = ImmediateStateLogicConfig | DebouncedStateLogicConfig;
|
|
876
|
+
/**
|
|
877
|
+
* Base configuration for value derivation logic.
|
|
878
|
+
*
|
|
879
|
+
* @internal
|
|
880
|
+
*/
|
|
881
|
+
interface BaseDerivationLogicConfig {
|
|
882
|
+
/**
|
|
883
|
+
* Logic type identifier for value derivation.
|
|
884
|
+
*/
|
|
885
|
+
type: 'derivation';
|
|
652
886
|
/**
|
|
653
|
-
*
|
|
887
|
+
* Optional name for this derivation for debugging purposes.
|
|
654
888
|
*
|
|
655
|
-
*
|
|
656
|
-
*
|
|
657
|
-
*
|
|
658
|
-
*
|
|
889
|
+
* When provided, this name appears in derivation debug logs,
|
|
890
|
+
* making it easier to identify specific derivations in complex forms.
|
|
891
|
+
*
|
|
892
|
+
* @example
|
|
893
|
+
* ```typescript
|
|
894
|
+
* {
|
|
895
|
+
* type: 'derivation',
|
|
896
|
+
* debugName: 'Calculate line total',
|
|
897
|
+
* targetField: '$.lineTotal',
|
|
898
|
+
* expression: 'formValue.quantity * formValue.unitPrice'
|
|
899
|
+
* }
|
|
900
|
+
* ```
|
|
659
901
|
*/
|
|
660
|
-
|
|
902
|
+
debugName?: string;
|
|
661
903
|
/**
|
|
662
|
-
*
|
|
904
|
+
* The field whose value will be modified.
|
|
905
|
+
*
|
|
906
|
+
* Can be:
|
|
907
|
+
* - Absolute path: 'fieldName' or 'nested.field.path'
|
|
908
|
+
* - Relative path for arrays: '$.siblingField' (same index as source)
|
|
909
|
+
*
|
|
910
|
+
* @example
|
|
911
|
+
* ```typescript
|
|
912
|
+
* targetField: 'phonePrefix' // Absolute path
|
|
913
|
+
* targetField: 'address.country' // Nested path
|
|
914
|
+
* targetField: '$.lineTotal' // Relative path (array sibling)
|
|
915
|
+
* ```
|
|
916
|
+
*/
|
|
917
|
+
targetField: string;
|
|
918
|
+
/**
|
|
919
|
+
* Condition that determines when this derivation applies.
|
|
663
920
|
*
|
|
664
921
|
* Can be:
|
|
665
922
|
* - `boolean`: Static value (always applies or never applies)
|
|
666
923
|
* - `ConditionalExpression`: Expression evaluated against field/form values
|
|
667
|
-
*
|
|
924
|
+
*
|
|
925
|
+
* Defaults to `true` (always apply).
|
|
926
|
+
*
|
|
927
|
+
* Note: FormStateCondition is not supported for derivations.
|
|
668
928
|
*
|
|
669
929
|
* @example
|
|
670
930
|
* ```typescript
|
|
671
|
-
* //
|
|
931
|
+
* // Always compute (default)
|
|
672
932
|
* condition: true
|
|
673
933
|
*
|
|
674
|
-
* //
|
|
934
|
+
* // Conditional derivation
|
|
675
935
|
* condition: {
|
|
676
936
|
* type: 'fieldValue',
|
|
677
|
-
* fieldPath: '
|
|
937
|
+
* fieldPath: 'country',
|
|
678
938
|
* operator: 'equals',
|
|
679
|
-
* value: '
|
|
939
|
+
* value: 'USA'
|
|
680
940
|
* }
|
|
941
|
+
* ```
|
|
942
|
+
*/
|
|
943
|
+
condition?: ConditionalExpression | boolean;
|
|
944
|
+
/**
|
|
945
|
+
* Static value to set on the target field.
|
|
681
946
|
*
|
|
682
|
-
*
|
|
683
|
-
*
|
|
947
|
+
* Use when the derived value is a constant.
|
|
948
|
+
* Mutually exclusive with `expression` and `functionName`.
|
|
949
|
+
*
|
|
950
|
+
* @example
|
|
951
|
+
* ```typescript
|
|
952
|
+
* value: '+1' // String
|
|
953
|
+
* value: 100 // Number
|
|
954
|
+
* value: true // Boolean
|
|
955
|
+
* value: { code: 'US' } // Object
|
|
684
956
|
* ```
|
|
685
957
|
*/
|
|
686
|
-
|
|
958
|
+
value?: unknown;
|
|
959
|
+
/**
|
|
960
|
+
* JavaScript expression to evaluate for the derived value.
|
|
961
|
+
*
|
|
962
|
+
* Has access to `formValue` object containing all form values.
|
|
963
|
+
* Uses the same secure AST-based parser as other expressions.
|
|
964
|
+
* Mutually exclusive with `value` and `functionName`.
|
|
965
|
+
*
|
|
966
|
+
* @example
|
|
967
|
+
* ```typescript
|
|
968
|
+
* expression: 'formValue.quantity * formValue.unitPrice'
|
|
969
|
+
* expression: 'formValue.firstName + " " + formValue.lastName'
|
|
970
|
+
* expression: 'formValue.price * (1 - formValue.discount / 100)'
|
|
971
|
+
* ```
|
|
972
|
+
*/
|
|
973
|
+
expression?: string;
|
|
974
|
+
/**
|
|
975
|
+
* Name of a registered custom derivation function.
|
|
976
|
+
*
|
|
977
|
+
* The function receives the evaluation context and returns the derived value.
|
|
978
|
+
* Register functions in `customFnConfig.derivations`.
|
|
979
|
+
* Mutually exclusive with `value` and `expression`.
|
|
980
|
+
*
|
|
981
|
+
* @example
|
|
982
|
+
* ```typescript
|
|
983
|
+
* functionName: 'getCurrencyForCountry'
|
|
984
|
+
* functionName: 'calculateTax'
|
|
985
|
+
* functionName: 'formatPhoneNumber'
|
|
986
|
+
* ```
|
|
987
|
+
*/
|
|
988
|
+
functionName?: string;
|
|
989
|
+
/**
|
|
990
|
+
* Explicit field dependencies for derivations.
|
|
991
|
+
*
|
|
992
|
+
* When using `functionName`, you can optionally specify which fields
|
|
993
|
+
* the function depends on. This enables more efficient re-evaluation
|
|
994
|
+
* by only triggering when specific dependencies change.
|
|
995
|
+
*
|
|
996
|
+
* If not provided with `functionName`, defaults to all fields ('*').
|
|
997
|
+
* For `expression`, dependencies are automatically extracted from the expression.
|
|
998
|
+
* For `value`, no dependencies are needed (static value).
|
|
999
|
+
*
|
|
1000
|
+
* @example
|
|
1001
|
+
* ```typescript
|
|
1002
|
+
* // Only re-evaluate when country changes
|
|
1003
|
+
* {
|
|
1004
|
+
* type: 'derivation',
|
|
1005
|
+
* targetField: 'currency',
|
|
1006
|
+
* functionName: 'getCurrencyForCountry',
|
|
1007
|
+
* dependsOn: ['country']
|
|
1008
|
+
* }
|
|
1009
|
+
*
|
|
1010
|
+
* // Override automatic detection for complex expressions
|
|
1011
|
+
* {
|
|
1012
|
+
* type: 'derivation',
|
|
1013
|
+
* targetField: 'total',
|
|
1014
|
+
* expression: 'calculateTotal(formValue)',
|
|
1015
|
+
* dependsOn: ['quantity', 'unitPrice', 'discount']
|
|
1016
|
+
* }
|
|
1017
|
+
* ```
|
|
1018
|
+
*/
|
|
1019
|
+
dependsOn?: string[];
|
|
1020
|
+
}
|
|
1021
|
+
/**
|
|
1022
|
+
* Derivation logic that evaluates immediately on change (default).
|
|
1023
|
+
*
|
|
1024
|
+
* @internal
|
|
1025
|
+
*/
|
|
1026
|
+
interface OnChangeDerivationLogicConfig extends BaseDerivationLogicConfig {
|
|
1027
|
+
/**
|
|
1028
|
+
* Trigger for immediate evaluation.
|
|
1029
|
+
* @default 'onChange'
|
|
1030
|
+
*/
|
|
1031
|
+
trigger?: 'onChange';
|
|
1032
|
+
/** Not allowed for onChange trigger */
|
|
1033
|
+
debounceMs?: never;
|
|
687
1034
|
}
|
|
1035
|
+
/**
|
|
1036
|
+
* Derivation logic that evaluates after a debounce period.
|
|
1037
|
+
*
|
|
1038
|
+
* Use this for self-transforms (lowercase, trim, format) to avoid
|
|
1039
|
+
* interrupting the user while they're actively typing.
|
|
1040
|
+
*
|
|
1041
|
+
* @internal
|
|
1042
|
+
*/
|
|
1043
|
+
interface DebouncedDerivationLogicConfig extends BaseDerivationLogicConfig {
|
|
1044
|
+
/**
|
|
1045
|
+
* Trigger for debounced evaluation.
|
|
1046
|
+
* Evaluates after the value has stabilized for the debounce duration.
|
|
1047
|
+
*/
|
|
1048
|
+
trigger: 'debounced';
|
|
1049
|
+
/**
|
|
1050
|
+
* Debounce duration in milliseconds.
|
|
1051
|
+
* @default 500
|
|
1052
|
+
*/
|
|
1053
|
+
debounceMs?: number;
|
|
1054
|
+
}
|
|
1055
|
+
/**
|
|
1056
|
+
* Configuration for value derivation logic.
|
|
1057
|
+
*
|
|
1058
|
+
* Enables programmatic value derivation based on conditions.
|
|
1059
|
+
* When the condition is met, the target field's value is set
|
|
1060
|
+
* using a static value, expression, or custom function.
|
|
1061
|
+
*
|
|
1062
|
+
* @example
|
|
1063
|
+
* ```typescript
|
|
1064
|
+
* // Set phone prefix based on country selection
|
|
1065
|
+
* {
|
|
1066
|
+
* type: 'derivation',
|
|
1067
|
+
* targetField: 'phonePrefix',
|
|
1068
|
+
* value: '+1',
|
|
1069
|
+
* condition: {
|
|
1070
|
+
* type: 'fieldValue',
|
|
1071
|
+
* fieldPath: 'country',
|
|
1072
|
+
* operator: 'equals',
|
|
1073
|
+
* value: 'USA'
|
|
1074
|
+
* }
|
|
1075
|
+
* }
|
|
1076
|
+
*
|
|
1077
|
+
* // Compute total from quantity and price
|
|
1078
|
+
* {
|
|
1079
|
+
* type: 'derivation',
|
|
1080
|
+
* targetField: 'total',
|
|
1081
|
+
* expression: 'formValue.quantity * formValue.unitPrice'
|
|
1082
|
+
* }
|
|
1083
|
+
*
|
|
1084
|
+
* // Use custom function for complex logic
|
|
1085
|
+
* {
|
|
1086
|
+
* type: 'derivation',
|
|
1087
|
+
* targetField: 'currency',
|
|
1088
|
+
* functionName: 'getCurrencyForCountry'
|
|
1089
|
+
* }
|
|
1090
|
+
*
|
|
1091
|
+
* // Self-transform with debounced trigger
|
|
1092
|
+
* // (applies after user stops typing)
|
|
1093
|
+
* {
|
|
1094
|
+
* type: 'derivation',
|
|
1095
|
+
* targetField: 'email',
|
|
1096
|
+
* expression: 'formValue.email.toLowerCase()',
|
|
1097
|
+
* trigger: 'debounced',
|
|
1098
|
+
* debounceMs: 500
|
|
1099
|
+
* }
|
|
1100
|
+
*
|
|
1101
|
+
* // Relative path for array items
|
|
1102
|
+
* {
|
|
1103
|
+
* type: 'derivation',
|
|
1104
|
+
* targetField: '$.lineTotal', // Same array index as source field
|
|
1105
|
+
* expression: 'formValue.quantity * formValue.unitPrice'
|
|
1106
|
+
* }
|
|
1107
|
+
* ```
|
|
1108
|
+
*
|
|
1109
|
+
* @public
|
|
1110
|
+
*/
|
|
1111
|
+
type DerivationLogicConfig = OnChangeDerivationLogicConfig | DebouncedDerivationLogicConfig;
|
|
1112
|
+
/**
|
|
1113
|
+
* Union type for all logic configurations.
|
|
1114
|
+
*
|
|
1115
|
+
* - `StateLogicConfig`: For field state changes (hidden, readonly, disabled, required)
|
|
1116
|
+
* - `DerivationLogicConfig`: For value derivation
|
|
1117
|
+
*
|
|
1118
|
+
* @public
|
|
1119
|
+
*/
|
|
1120
|
+
type LogicConfig = StateLogicConfig | DerivationLogicConfig;
|
|
1121
|
+
/**
|
|
1122
|
+
* Log level for derivation debug output.
|
|
1123
|
+
*
|
|
1124
|
+
* - 'none': No debug logging
|
|
1125
|
+
* - 'summary': Log cycle completion with counts (default in dev mode)
|
|
1126
|
+
* - 'verbose': Log individual derivation evaluations with details
|
|
1127
|
+
*
|
|
1128
|
+
* @public
|
|
1129
|
+
*/
|
|
1130
|
+
type DerivationLogLevel = 'none' | 'summary' | 'verbose';
|
|
688
1131
|
/**
|
|
689
1132
|
* Type guard to check if a condition is a FormStateCondition.
|
|
690
1133
|
*
|
|
@@ -693,7 +1136,7 @@ interface LogicConfig {
|
|
|
693
1136
|
*
|
|
694
1137
|
* @public
|
|
695
1138
|
*/
|
|
696
|
-
declare function isFormStateCondition(condition:
|
|
1139
|
+
declare function isFormStateCondition(condition: StateLogicConfig['condition'] | DerivationLogicConfig['condition']): condition is FormStateCondition;
|
|
697
1140
|
|
|
698
1141
|
/**
|
|
699
1142
|
* Text element type for rendering different HTML text elements
|
|
@@ -892,11 +1335,17 @@ type ProcessField<T, D extends number = 5> = [D] extends [never] ? Record<string
|
|
|
892
1335
|
[P in K]: Record<string, unknown>;
|
|
893
1336
|
} : never : T extends {
|
|
894
1337
|
type: 'text';
|
|
1338
|
+
} ? never : T extends {
|
|
1339
|
+
type: 'submit' | 'button';
|
|
895
1340
|
} ? never : T extends {
|
|
896
1341
|
key: infer K;
|
|
897
1342
|
value: infer V;
|
|
898
1343
|
} ? K extends string ? {
|
|
899
1344
|
[P in K]: MaybeOptional<T, InferValueType<T, V>>;
|
|
1345
|
+
} : never : T extends {
|
|
1346
|
+
key: infer K;
|
|
1347
|
+
} ? K extends string ? {
|
|
1348
|
+
[P in K]: MaybeOptional<T, string>;
|
|
900
1349
|
} : never : never;
|
|
901
1350
|
/**
|
|
902
1351
|
* Internal helper with depth tracking
|
|
@@ -1340,7 +1789,13 @@ interface Logger {
|
|
|
1340
1789
|
interface EvaluationContext<TValue = unknown> {
|
|
1341
1790
|
/** Current field value */
|
|
1342
1791
|
fieldValue: TValue;
|
|
1343
|
-
/**
|
|
1792
|
+
/**
|
|
1793
|
+
* Form value for the current evaluation scope.
|
|
1794
|
+
*
|
|
1795
|
+
* For regular (non-array) derivations, this contains the complete form value.
|
|
1796
|
+
* For array item derivations, this is scoped to the current array item.
|
|
1797
|
+
* Use `rootFormValue` to access the complete form when inside an array context.
|
|
1798
|
+
*/
|
|
1344
1799
|
formValue: Record<string, unknown>;
|
|
1345
1800
|
/** Field path for relative references */
|
|
1346
1801
|
fieldPath: string;
|
|
@@ -1348,6 +1803,38 @@ interface EvaluationContext<TValue = unknown> {
|
|
|
1348
1803
|
customFunctions?: Record<string, (context: EvaluationContext) => unknown>;
|
|
1349
1804
|
/** Logger for diagnostic output */
|
|
1350
1805
|
logger: Logger;
|
|
1806
|
+
/**
|
|
1807
|
+
* Root form value when inside an array context.
|
|
1808
|
+
*
|
|
1809
|
+
* This provides access to values outside the current array item.
|
|
1810
|
+
* When a derivation targets an array item field (e.g., `items.$.lineTotal`),
|
|
1811
|
+
* `formValue` is scoped to the current array item, while `rootFormValue`
|
|
1812
|
+
* provides access to the entire form value including fields outside the array.
|
|
1813
|
+
*
|
|
1814
|
+
* @example
|
|
1815
|
+
* ```typescript
|
|
1816
|
+
* // In an array item derivation (e.g., lineItems.$.lineTotal):
|
|
1817
|
+
* {
|
|
1818
|
+
* type: 'derivation',
|
|
1819
|
+
* targetField: '$.lineTotal',
|
|
1820
|
+
* // formValue = current array item { quantity: 2, unitPrice: 50 }
|
|
1821
|
+
* // rootFormValue = entire form { globalDiscount: 0.1, lineItems: [...] }
|
|
1822
|
+
* expression: 'formValue.quantity * formValue.unitPrice * (1 - rootFormValue.globalDiscount)'
|
|
1823
|
+
* }
|
|
1824
|
+
* ```
|
|
1825
|
+
*
|
|
1826
|
+
* For non-array derivations, `rootFormValue` is not set and `formValue`
|
|
1827
|
+
* contains the entire form value.
|
|
1828
|
+
*/
|
|
1829
|
+
rootFormValue?: Record<string, unknown>;
|
|
1830
|
+
/**
|
|
1831
|
+
* Current array index when inside an array derivation.
|
|
1832
|
+
*/
|
|
1833
|
+
arrayIndex?: number;
|
|
1834
|
+
/**
|
|
1835
|
+
* Path to the array field when inside an array derivation.
|
|
1836
|
+
*/
|
|
1837
|
+
arrayPath?: string;
|
|
1351
1838
|
/** Allow additional properties for flexible expression evaluation */
|
|
1352
1839
|
[key: string]: unknown;
|
|
1353
1840
|
}
|
|
@@ -1393,6 +1880,22 @@ interface EvaluationContext<TValue = unknown> {
|
|
|
1393
1880
|
*/
|
|
1394
1881
|
type CustomFunction = (context: EvaluationContext) => unknown;
|
|
1395
1882
|
|
|
1883
|
+
/**
|
|
1884
|
+
* Re-export Angular's ValidationError for consistency
|
|
1885
|
+
* This replaces our custom ValidationError interface
|
|
1886
|
+
*/
|
|
1887
|
+
type ValidationError = ValidationError$1;
|
|
1888
|
+
interface ValidationMessages {
|
|
1889
|
+
required?: DynamicText;
|
|
1890
|
+
email?: DynamicText;
|
|
1891
|
+
min?: DynamicText;
|
|
1892
|
+
max?: DynamicText;
|
|
1893
|
+
minLength?: DynamicText;
|
|
1894
|
+
maxLength?: DynamicText;
|
|
1895
|
+
pattern?: DynamicText;
|
|
1896
|
+
[key: string]: DynamicText | undefined;
|
|
1897
|
+
}
|
|
1898
|
+
|
|
1396
1899
|
/**
|
|
1397
1900
|
* The result type for submission actions.
|
|
1398
1901
|
* Can be either a Promise or an Observable.
|
|
@@ -1545,10 +2048,11 @@ interface SubmissionConfig<TValue = unknown> {
|
|
|
1545
2048
|
*
|
|
1546
2049
|
* @typeParam TFields - Array of registered field types available for this form
|
|
1547
2050
|
* @typeParam TValue - The strongly-typed interface for form values
|
|
2051
|
+
* @typeParam TProps - The type for form-level default props (library-specific)
|
|
1548
2052
|
*
|
|
1549
2053
|
* @public
|
|
1550
2054
|
*/
|
|
1551
|
-
interface FormConfig<TFields extends NarrowFields | RegisteredFieldTypes[] = RegisteredFieldTypes[], TValue = InferFormValue$1<TFields extends readonly RegisteredFieldTypes[] ? TFields : RegisteredFieldTypes[]
|
|
2055
|
+
interface FormConfig<TFields extends NarrowFields | RegisteredFieldTypes[] = RegisteredFieldTypes[], TValue = InferFormValue$1<TFields extends readonly RegisteredFieldTypes[] ? TFields : RegisteredFieldTypes[]>, TProps extends object = Record<string, unknown>, TSchemaValue = unknown> {
|
|
1552
2056
|
/**
|
|
1553
2057
|
* Array of field definitions that define the form structure.
|
|
1554
2058
|
*
|
|
@@ -1567,19 +2071,32 @@ interface FormConfig<TFields extends NarrowFields | RegisteredFieldTypes[] = Reg
|
|
|
1567
2071
|
*/
|
|
1568
2072
|
fields: TFields;
|
|
1569
2073
|
/**
|
|
1570
|
-
* Optional form-level validation schema.
|
|
2074
|
+
* Optional form-level validation schema using Standard Schema spec.
|
|
1571
2075
|
*
|
|
1572
2076
|
* Provides additional validation beyond field-level validation.
|
|
2077
|
+
* Supports Zod, Valibot, ArkType, and other Standard Schema compliant libraries.
|
|
1573
2078
|
* Useful for cross-field validation rules.
|
|
1574
2079
|
*
|
|
1575
2080
|
* @example
|
|
1576
2081
|
* ```typescript
|
|
1577
|
-
*
|
|
1578
|
-
*
|
|
1579
|
-
*
|
|
2082
|
+
* import { z } from 'zod';
|
|
2083
|
+
* import { standardSchema } from '@ng-forge/dynamic-forms/schema';
|
|
2084
|
+
*
|
|
2085
|
+
* const PasswordSchema = z.object({
|
|
2086
|
+
* password: z.string().min(8),
|
|
2087
|
+
* confirmPassword: z.string(),
|
|
2088
|
+
* }).refine(
|
|
2089
|
+
* (data) => data.password === data.confirmPassword,
|
|
2090
|
+
* { message: 'Passwords must match', path: ['confirmPassword'] }
|
|
2091
|
+
* );
|
|
2092
|
+
*
|
|
2093
|
+
* const formConfig = {
|
|
2094
|
+
* fields: [...],
|
|
2095
|
+
* schema: standardSchema(PasswordSchema),
|
|
2096
|
+
* } as const satisfies FormConfig;
|
|
1580
2097
|
* ```
|
|
1581
2098
|
*/
|
|
1582
|
-
schema?:
|
|
2099
|
+
schema?: FormSchema<TSchemaValue>;
|
|
1583
2100
|
/**
|
|
1584
2101
|
* Global form configuration options.
|
|
1585
2102
|
*
|
|
@@ -1659,6 +2176,32 @@ interface FormConfig<TFields extends NarrowFields | RegisteredFieldTypes[] = Reg
|
|
|
1659
2176
|
* ```
|
|
1660
2177
|
*/
|
|
1661
2178
|
submission?: SubmissionConfig<TValue>;
|
|
2179
|
+
/**
|
|
2180
|
+
* Default props applied to all fields in the form.
|
|
2181
|
+
*
|
|
2182
|
+
* These props serve as defaults that can be overridden at the field level.
|
|
2183
|
+
* Useful for setting consistent styling across the entire form (e.g., appearance,
|
|
2184
|
+
* size, or other UI library-specific props).
|
|
2185
|
+
*
|
|
2186
|
+
* The cascade order is: Library config → Form defaultProps → Field props
|
|
2187
|
+
* Each level can override the previous one.
|
|
2188
|
+
*
|
|
2189
|
+
* @example
|
|
2190
|
+
* ```typescript
|
|
2191
|
+
* // Material example
|
|
2192
|
+
* const config: MatFormConfig = {
|
|
2193
|
+
* defaultProps: {
|
|
2194
|
+
* appearance: 'outline',
|
|
2195
|
+
* subscriptSizing: 'dynamic',
|
|
2196
|
+
* },
|
|
2197
|
+
* fields: [
|
|
2198
|
+
* { type: 'input', key: 'name', label: 'Name' }, // Uses defaultProps
|
|
2199
|
+
* { type: 'input', key: 'email', props: { appearance: 'fill' } }, // Override
|
|
2200
|
+
* ],
|
|
2201
|
+
* };
|
|
2202
|
+
* ```
|
|
2203
|
+
*/
|
|
2204
|
+
defaultProps?: TProps;
|
|
1662
2205
|
}
|
|
1663
2206
|
/**
|
|
1664
2207
|
* Signal forms adapter configuration for advanced form behavior.
|
|
@@ -1676,6 +2219,14 @@ interface FormConfig<TFields extends NarrowFields | RegisteredFieldTypes[] = Reg
|
|
|
1676
2219
|
* currency: 'USD'
|
|
1677
2220
|
* }).format(context.value)
|
|
1678
2221
|
* },
|
|
2222
|
+
* derivations: {
|
|
2223
|
+
* getCurrencyForCountry: (context) => {
|
|
2224
|
+
* const countryToCurrency: Record<string, string> = {
|
|
2225
|
+
* 'USA': 'USD', 'Germany': 'EUR', 'UK': 'GBP'
|
|
2226
|
+
* };
|
|
2227
|
+
* return countryToCurrency[context.formValue.country as string] ?? 'USD';
|
|
2228
|
+
* }
|
|
2229
|
+
* },
|
|
1679
2230
|
* simpleValidators: {
|
|
1680
2231
|
* noSpaces: (value) => {
|
|
1681
2232
|
* return typeof value === 'string' && value.includes(' ')
|
|
@@ -1718,6 +2269,73 @@ interface CustomFnConfig {
|
|
|
1718
2269
|
* ```
|
|
1719
2270
|
*/
|
|
1720
2271
|
customFunctions?: Record<string, CustomFunction>;
|
|
2272
|
+
/**
|
|
2273
|
+
* Custom derivation functions for value derivation logic.
|
|
2274
|
+
*
|
|
2275
|
+
* These functions compute derived values and are called when a
|
|
2276
|
+
* `DerivationLogicConfig` references them by `functionName`.
|
|
2277
|
+
*
|
|
2278
|
+
* Derivation functions:
|
|
2279
|
+
* - Receive an `EvaluationContext` with access to `formValue`
|
|
2280
|
+
* - Return the value to set on the target field
|
|
2281
|
+
* - Are called reactively when dependencies change
|
|
2282
|
+
*
|
|
2283
|
+
* Use derivation functions for complex mappings or logic that
|
|
2284
|
+
* can't be easily expressed as a JavaScript expression.
|
|
2285
|
+
*
|
|
2286
|
+
* @example
|
|
2287
|
+
* ```typescript
|
|
2288
|
+
* derivations: {
|
|
2289
|
+
* // Country to currency mapping
|
|
2290
|
+
* getCurrencyForCountry: (context) => {
|
|
2291
|
+
* const countryToCurrency: Record<string, string> = {
|
|
2292
|
+
* 'USA': 'USD',
|
|
2293
|
+
* 'Germany': 'EUR',
|
|
2294
|
+
* 'France': 'EUR',
|
|
2295
|
+
* 'UK': 'GBP',
|
|
2296
|
+
* 'Japan': 'JPY'
|
|
2297
|
+
* };
|
|
2298
|
+
* return countryToCurrency[context.formValue.country as string] ?? 'USD';
|
|
2299
|
+
* },
|
|
2300
|
+
*
|
|
2301
|
+
* // Complex tax calculation
|
|
2302
|
+
* calculateTax: (context) => {
|
|
2303
|
+
* const subtotal = context.formValue.subtotal as number ?? 0;
|
|
2304
|
+
* const state = context.formValue.state as string;
|
|
2305
|
+
* const taxRates: Record<string, number> = {
|
|
2306
|
+
* 'CA': 0.0725, 'NY': 0.08, 'TX': 0.0625
|
|
2307
|
+
* };
|
|
2308
|
+
* return subtotal * (taxRates[state] ?? 0);
|
|
2309
|
+
* },
|
|
2310
|
+
*
|
|
2311
|
+
* // Format phone number
|
|
2312
|
+
* formatPhoneNumber: (context) => {
|
|
2313
|
+
* const phone = context.fieldValue as string ?? '';
|
|
2314
|
+
* const digits = phone.replace(/\D/g, '');
|
|
2315
|
+
* if (digits.length === 10) {
|
|
2316
|
+
* return `(${digits.slice(0,3)}) ${digits.slice(3,6)}-${digits.slice(6)}`;
|
|
2317
|
+
* }
|
|
2318
|
+
* return phone;
|
|
2319
|
+
* }
|
|
2320
|
+
* }
|
|
2321
|
+
* ```
|
|
2322
|
+
*
|
|
2323
|
+
* Field configuration using a derivation function:
|
|
2324
|
+
* ```typescript
|
|
2325
|
+
* {
|
|
2326
|
+
* key: 'country',
|
|
2327
|
+
* type: 'select',
|
|
2328
|
+
* logic: [
|
|
2329
|
+
* {
|
|
2330
|
+
* type: 'derivation',
|
|
2331
|
+
* targetField: 'currency',
|
|
2332
|
+
* functionName: 'getCurrencyForCountry'
|
|
2333
|
+
* }
|
|
2334
|
+
* ]
|
|
2335
|
+
* }
|
|
2336
|
+
* ```
|
|
2337
|
+
*/
|
|
2338
|
+
derivations?: Record<string, CustomFunction>;
|
|
1721
2339
|
/**
|
|
1722
2340
|
* Custom validators using Angular's public FieldContext API
|
|
1723
2341
|
*
|
|
@@ -1930,226 +2548,92 @@ interface FormOptions {
|
|
|
1930
2548
|
*/
|
|
1931
2549
|
disabled?: boolean;
|
|
1932
2550
|
/**
|
|
1933
|
-
*
|
|
2551
|
+
* Maximum number of iterations for derivation chain processing.
|
|
1934
2552
|
*
|
|
1935
|
-
*
|
|
1936
|
-
*
|
|
2553
|
+
* Derivations can trigger other derivations (e.g., A → B → C).
|
|
2554
|
+
* This limit prevents infinite loops in case of circular dependencies
|
|
2555
|
+
* that weren't caught at build time.
|
|
1937
2556
|
*
|
|
1938
|
-
*
|
|
1939
|
-
*
|
|
1940
|
-
*
|
|
1941
|
-
*
|
|
1942
|
-
* disableWhenInvalid: true, // Disable when form is invalid
|
|
1943
|
-
* disableWhileSubmitting: true, // Disable during submission
|
|
1944
|
-
* }
|
|
1945
|
-
* }
|
|
1946
|
-
* ```
|
|
2557
|
+
* Increase this value if you have legitimate deep derivation chains
|
|
2558
|
+
* (more than 10 levels deep).
|
|
2559
|
+
*
|
|
2560
|
+
* @default 10
|
|
1947
2561
|
*/
|
|
1948
|
-
|
|
2562
|
+
maxDerivationIterations?: number;
|
|
1949
2563
|
/**
|
|
1950
|
-
* Default disabled behavior for
|
|
2564
|
+
* Default disabled behavior for submit buttons.
|
|
1951
2565
|
*
|
|
1952
|
-
* Controls when
|
|
2566
|
+
* Controls when submit buttons are automatically disabled.
|
|
1953
2567
|
* Can be overridden per-button via the `logic` array on individual button fields.
|
|
1954
2568
|
*
|
|
1955
2569
|
* @example
|
|
1956
2570
|
* ```typescript
|
|
1957
2571
|
* options: {
|
|
1958
|
-
*
|
|
1959
|
-
*
|
|
2572
|
+
* submitButton: {
|
|
2573
|
+
* disableWhenInvalid: true, // Disable when form is invalid
|
|
1960
2574
|
* disableWhileSubmitting: true, // Disable during submission
|
|
1961
2575
|
* }
|
|
1962
2576
|
* }
|
|
1963
2577
|
* ```
|
|
1964
2578
|
*/
|
|
1965
|
-
|
|
1966
|
-
}
|
|
1967
|
-
/**
|
|
1968
|
-
* Options for controlling submit button disabled behavior.
|
|
1969
|
-
*
|
|
1970
|
-
* @public
|
|
1971
|
-
*/
|
|
1972
|
-
interface SubmitButtonOptions {
|
|
1973
|
-
/**
|
|
1974
|
-
* Disable submit button when the form is invalid.
|
|
1975
|
-
*
|
|
1976
|
-
* @default true
|
|
1977
|
-
*/
|
|
1978
|
-
disableWhenInvalid?: boolean;
|
|
1979
|
-
/**
|
|
1980
|
-
* Disable submit button while the form is submitting.
|
|
1981
|
-
*
|
|
1982
|
-
* Requires `submission.action` to be configured for automatic detection.
|
|
1983
|
-
*
|
|
1984
|
-
* @default true
|
|
1985
|
-
*/
|
|
1986
|
-
disableWhileSubmitting?: boolean;
|
|
1987
|
-
}
|
|
1988
|
-
/**
|
|
1989
|
-
* Options for controlling next page button disabled behavior.
|
|
1990
|
-
*
|
|
1991
|
-
* @public
|
|
1992
|
-
*/
|
|
1993
|
-
interface NextButtonOptions {
|
|
1994
|
-
/**
|
|
1995
|
-
* Disable next button when the current page has invalid fields.
|
|
1996
|
-
*
|
|
1997
|
-
* @default true
|
|
1998
|
-
*/
|
|
1999
|
-
disableWhenPageInvalid?: boolean;
|
|
2000
|
-
/**
|
|
2001
|
-
* Disable next button while the form is submitting.
|
|
2002
|
-
*
|
|
2003
|
-
* @default true
|
|
2004
|
-
*/
|
|
2005
|
-
disableWhileSubmitting?: boolean;
|
|
2006
|
-
}
|
|
2007
|
-
|
|
2008
|
-
/**
|
|
2009
|
-
* Field signal context - the "nervous system" of the dynamic form.
|
|
2010
|
-
* Provided via FIELD_SIGNAL_CONTEXT injection token.
|
|
2011
|
-
*
|
|
2012
|
-
* Gives mappers and components access to form state, values, and configuration.
|
|
2013
|
-
* Container fields (Group, Array) create scoped contexts with nested forms.
|
|
2014
|
-
*
|
|
2015
|
-
* The `form` property uses Angular's FieldTree which includes Subfields<TModel>
|
|
2016
|
-
* for type-safe child field access via bracket notation when TModel is a Record.
|
|
2017
|
-
*/
|
|
2018
|
-
interface FieldSignalContext<TModel extends Record<string, unknown> = Record<string, unknown>> {
|
|
2019
|
-
injector: Injector;
|
|
2020
|
-
value: WritableSignal<Partial<TModel> | undefined>;
|
|
2021
|
-
defaultValues: () => TModel;
|
|
2022
|
-
form: FieldTree<TModel>;
|
|
2023
|
-
defaultValidationMessages?: ValidationMessages;
|
|
2024
|
-
/** Form-level options used by button mappers to determine disabled state defaults. */
|
|
2025
|
-
formOptions?: FormOptions;
|
|
2026
|
-
/** Current page validity signal for paged forms. Used by next button to determine disabled state. */
|
|
2027
|
-
currentPageValid?: Signal<boolean>;
|
|
2028
|
-
}
|
|
2029
|
-
/**
|
|
2030
|
-
* Array context for fields rendered within arrays.
|
|
2031
|
-
* Provides position and parent array information for components inside array fields.
|
|
2032
|
-
*/
|
|
2033
|
-
interface ArrayContext {
|
|
2034
|
-
/** The key of the parent array field. */
|
|
2035
|
-
arrayKey: string;
|
|
2036
|
-
/**
|
|
2037
|
-
* The index of this item within the array.
|
|
2038
|
-
* Uses linkedSignal to automatically update when items are added/removed,
|
|
2039
|
-
* allowing index-dependent logic to react without component recreation.
|
|
2040
|
-
*/
|
|
2041
|
-
index: Signal<number>;
|
|
2042
|
-
/** The current form value for token resolution. */
|
|
2043
|
-
formValue: unknown;
|
|
2044
|
-
/** The array field definition. */
|
|
2045
|
-
field: FieldDef<unknown>;
|
|
2046
|
-
}
|
|
2047
|
-
/**
|
|
2048
|
-
* Mapper function that converts a field definition to component inputs.
|
|
2049
|
-
*
|
|
2050
|
-
* Mappers run within an injection context and can inject FIELD_SIGNAL_CONTEXT.
|
|
2051
|
-
* Returns a Signal to enable reactive updates when dependencies change.
|
|
2052
|
-
*/
|
|
2053
|
-
type MapperFn<T extends FieldDef<unknown>> = (input: T) => Signal<Record<string, unknown>>;
|
|
2054
|
-
|
|
2055
|
-
/**
|
|
2056
|
-
* Defines how a field type handles form values and data collection.
|
|
2057
|
-
*
|
|
2058
|
-
* - 'include': Field contributes to form values (default for input fields)
|
|
2059
|
-
* - 'exclude': Field is excluded from form values (for display/layout fields)
|
|
2060
|
-
* - 'flatten': Field's children are flattened to parent level (for container fields)
|
|
2061
|
-
*/
|
|
2062
|
-
type ValueHandlingMode = 'include' | 'exclude' | 'flatten';
|
|
2063
|
-
/**
|
|
2064
|
-
* Configuration interface for registering custom field types.
|
|
2065
|
-
*
|
|
2066
|
-
* Defines how a field type should be handled by the dynamic form system,
|
|
2067
|
-
* including its component loading strategy and field-to-component mapping logic.
|
|
2068
|
-
* Supports both eager-loaded and lazy-loaded components.
|
|
2069
|
-
*
|
|
2070
|
-
* @typeParam T - The field definition type this field type handles
|
|
2071
|
-
*
|
|
2072
|
-
* @example
|
|
2073
|
-
* ```typescript
|
|
2074
|
-
* const CustomInputType: FieldTypeDefinition<InputFieldDef> = {
|
|
2075
|
-
* name: 'custom-input',
|
|
2076
|
-
* loadComponent: () => import('./custom-input.component').then(m => m.CustomInputComponent),
|
|
2077
|
-
* mapper: customInputMapper
|
|
2078
|
-
* };
|
|
2079
|
-
*
|
|
2080
|
-
* // Register with providers
|
|
2081
|
-
* provideDynamicForm(CustomInputType)
|
|
2082
|
-
* ```
|
|
2083
|
-
*/
|
|
2084
|
-
interface FieldTypeDefinition<T extends FieldDef<any> = any> {
|
|
2085
|
-
/** Unique identifier for the field type */
|
|
2086
|
-
name: string;
|
|
2087
|
-
/** Field definition type marker (internal use) */
|
|
2088
|
-
_fieldDef?: T;
|
|
2089
|
-
/**
|
|
2090
|
-
* Function to load the component (supports lazy loading).
|
|
2091
|
-
* Returns a Promise that resolves to the component class or module with default export.
|
|
2092
|
-
*
|
|
2093
|
-
* Optional - omit for componentless fields (e.g., hidden fields) that only
|
|
2094
|
-
* contribute to form values without rendering any UI.
|
|
2095
|
-
*/
|
|
2096
|
-
loadComponent?: () => Promise<any>;
|
|
2097
|
-
/**
|
|
2098
|
-
* Mapper function that converts field definition to component bindings.
|
|
2099
|
-
*
|
|
2100
|
-
* Optional - omit for componentless fields (like hidden fields) that don't need
|
|
2101
|
-
* input mapping. When omitted for componentless fields (no loadComponent), an empty
|
|
2102
|
-
* signal is returned. When omitted for regular fields with a component, falls back
|
|
2103
|
-
* to baseFieldMapper.
|
|
2104
|
-
*/
|
|
2105
|
-
mapper?: MapperFn<T>;
|
|
2106
|
-
/** How this field type handles form values and data collection (defaults to 'include') */
|
|
2107
|
-
valueHandling?: ValueHandlingMode;
|
|
2579
|
+
submitButton?: SubmitButtonOptions;
|
|
2108
2580
|
/**
|
|
2109
|
-
*
|
|
2110
|
-
*
|
|
2111
|
-
* Some props (like `type` for inputs, `rows`/`cols` for textareas) are actually
|
|
2112
|
-
* native HTML attributes. Specifying them here causes them to be merged into
|
|
2113
|
-
* the meta object before being passed to the component, ensuring they're applied
|
|
2114
|
-
* via the meta tracking mechanism.
|
|
2581
|
+
* Default disabled behavior for next page buttons.
|
|
2115
2582
|
*
|
|
2116
|
-
*
|
|
2583
|
+
* Controls when next page buttons are automatically disabled in paged forms.
|
|
2584
|
+
* Can be overridden per-button via the `logic` array on individual button fields.
|
|
2117
2585
|
*
|
|
2118
2586
|
* @example
|
|
2119
2587
|
* ```typescript
|
|
2120
|
-
* {
|
|
2121
|
-
*
|
|
2122
|
-
*
|
|
2123
|
-
*
|
|
2588
|
+
* options: {
|
|
2589
|
+
* nextButton: {
|
|
2590
|
+
* disableWhenPageInvalid: true, // Disable when current page is invalid
|
|
2591
|
+
* disableWhileSubmitting: true, // Disable during submission
|
|
2592
|
+
* }
|
|
2124
2593
|
* }
|
|
2125
2594
|
* ```
|
|
2126
2595
|
*/
|
|
2127
|
-
|
|
2596
|
+
nextButton?: NextButtonOptions;
|
|
2128
2597
|
}
|
|
2129
2598
|
/**
|
|
2130
|
-
*
|
|
2131
|
-
*
|
|
2132
|
-
* Provides access to the map of registered field types throughout the application.
|
|
2133
|
-
* The registry is populated by the provideDynamicForm function and used by
|
|
2134
|
-
* field rendering components to resolve field types to their implementations.
|
|
2599
|
+
* Options for controlling submit button disabled behavior.
|
|
2135
2600
|
*
|
|
2136
|
-
* @
|
|
2137
|
-
* ```typescript
|
|
2138
|
-
* constructor(@Inject(FIELD_REGISTRY) private registry: Map<string, FieldTypeDefinition>) {
|
|
2139
|
-
* const inputType = registry.get('input');
|
|
2140
|
-
* }
|
|
2141
|
-
* ```
|
|
2601
|
+
* @public
|
|
2142
2602
|
*/
|
|
2143
|
-
|
|
2144
|
-
|
|
2603
|
+
interface SubmitButtonOptions {
|
|
2604
|
+
/**
|
|
2605
|
+
* Disable submit button when the form is invalid.
|
|
2606
|
+
*
|
|
2607
|
+
* @default true
|
|
2608
|
+
*/
|
|
2609
|
+
disableWhenInvalid?: boolean;
|
|
2610
|
+
/**
|
|
2611
|
+
* Disable submit button while the form is submitting.
|
|
2612
|
+
*
|
|
2613
|
+
* Requires `submission.action` to be configured for automatic detection.
|
|
2614
|
+
*
|
|
2615
|
+
* @default true
|
|
2616
|
+
*/
|
|
2617
|
+
disableWhileSubmitting?: boolean;
|
|
2618
|
+
}
|
|
2145
2619
|
/**
|
|
2146
|
-
*
|
|
2620
|
+
* Options for controlling next page button disabled behavior.
|
|
2621
|
+
*
|
|
2622
|
+
* @public
|
|
2147
2623
|
*/
|
|
2148
|
-
interface
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2624
|
+
interface NextButtonOptions {
|
|
2625
|
+
/**
|
|
2626
|
+
* Disable next button when the current page has invalid fields.
|
|
2627
|
+
*
|
|
2628
|
+
* @default true
|
|
2629
|
+
*/
|
|
2630
|
+
disableWhenPageInvalid?: boolean;
|
|
2631
|
+
/**
|
|
2632
|
+
* Disable next button while the form is submitting.
|
|
2633
|
+
*
|
|
2634
|
+
* @default true
|
|
2635
|
+
*/
|
|
2636
|
+
disableWhileSubmitting?: boolean;
|
|
2153
2637
|
}
|
|
2154
2638
|
|
|
2155
2639
|
/**
|
|
@@ -2210,6 +2694,109 @@ type FieldPathAccess<TValue> = {
|
|
|
2210
2694
|
[K in keyof TValue]: SchemaPath<TValue[K]> | SchemaPathTree<TValue[K]>;
|
|
2211
2695
|
};
|
|
2212
2696
|
|
|
2697
|
+
/**
|
|
2698
|
+
* Result of processing all pending derivations.
|
|
2699
|
+
*
|
|
2700
|
+
* @public
|
|
2701
|
+
*/
|
|
2702
|
+
interface DerivationProcessingResult {
|
|
2703
|
+
/** Number of derivations successfully applied */
|
|
2704
|
+
appliedCount: number;
|
|
2705
|
+
/** Number of derivations skipped (condition not met or value unchanged) */
|
|
2706
|
+
skippedCount: number;
|
|
2707
|
+
/** Number of derivations that failed with errors */
|
|
2708
|
+
errorCount: number;
|
|
2709
|
+
/**
|
|
2710
|
+
* Number of derivations that encountered warnings (e.g., missing target field).
|
|
2711
|
+
*
|
|
2712
|
+
* These are not counted as errors because they may be intentional (conditional fields)
|
|
2713
|
+
* but indicate potential configuration issues if unexpected.
|
|
2714
|
+
*/
|
|
2715
|
+
warnCount: number;
|
|
2716
|
+
/** Total iterations performed */
|
|
2717
|
+
iterations: number;
|
|
2718
|
+
/** Whether max iterations was reached (potential loop) */
|
|
2719
|
+
maxIterationsReached: boolean;
|
|
2720
|
+
}
|
|
2721
|
+
|
|
2722
|
+
/**
|
|
2723
|
+
* Information about a single derivation evaluation for logging.
|
|
2724
|
+
*
|
|
2725
|
+
* @public
|
|
2726
|
+
*/
|
|
2727
|
+
interface DerivationLogEntry {
|
|
2728
|
+
/** Debug name if provided in the derivation config */
|
|
2729
|
+
debugName?: string;
|
|
2730
|
+
/** Source field key where the derivation is defined */
|
|
2731
|
+
sourceFieldKey: string;
|
|
2732
|
+
/** Target field key that will be modified */
|
|
2733
|
+
targetFieldKey: string;
|
|
2734
|
+
/** Result of the derivation evaluation */
|
|
2735
|
+
result: 'applied' | 'skipped' | 'error';
|
|
2736
|
+
/** Reason for skipping (if result is 'skipped') */
|
|
2737
|
+
skipReason?: 'condition-false' | 'value-unchanged' | 'already-applied' | 'target-not-found';
|
|
2738
|
+
/** The new value that was set (if result is 'applied') */
|
|
2739
|
+
newValue?: unknown;
|
|
2740
|
+
/** The previous value before the derivation (if result is 'applied') */
|
|
2741
|
+
previousValue?: unknown;
|
|
2742
|
+
/** Error message (if result is 'error') */
|
|
2743
|
+
error?: string;
|
|
2744
|
+
/** Duration in milliseconds (optional, for performance tracking) */
|
|
2745
|
+
durationMs?: number;
|
|
2746
|
+
}
|
|
2747
|
+
|
|
2748
|
+
/**
|
|
2749
|
+
* Service interface for derivation logging.
|
|
2750
|
+
*
|
|
2751
|
+
* Provides methods to log derivation processing events at different verbosity levels.
|
|
2752
|
+
* Use `DERIVATION_LOGGER` injection token to get an instance.
|
|
2753
|
+
*
|
|
2754
|
+
* @public
|
|
2755
|
+
*/
|
|
2756
|
+
interface DerivationLogger {
|
|
2757
|
+
/**
|
|
2758
|
+
* Logs the start of a derivation processing cycle.
|
|
2759
|
+
* Only logs when config level is 'verbose'.
|
|
2760
|
+
*/
|
|
2761
|
+
cycleStart(trigger: 'onChange' | 'debounced', entryCount: number): void;
|
|
2762
|
+
/**
|
|
2763
|
+
* Logs the start of a derivation iteration within a cycle.
|
|
2764
|
+
* Only logs when config level is 'verbose'.
|
|
2765
|
+
*/
|
|
2766
|
+
iteration(iterationNumber: number): void;
|
|
2767
|
+
/**
|
|
2768
|
+
* Logs a single derivation evaluation result.
|
|
2769
|
+
* Only logs when config level is 'verbose'.
|
|
2770
|
+
*/
|
|
2771
|
+
evaluation(entry: DerivationLogEntry): void;
|
|
2772
|
+
/**
|
|
2773
|
+
* Logs a summary of derivation processing results.
|
|
2774
|
+
* Logs when config level is 'summary' or 'verbose' and something interesting happened.
|
|
2775
|
+
*/
|
|
2776
|
+
summary(result: DerivationProcessingResult, trigger: 'onChange' | 'debounced'): void;
|
|
2777
|
+
/**
|
|
2778
|
+
* Logs when max iterations are reached (always logged as warning).
|
|
2779
|
+
*/
|
|
2780
|
+
maxIterationsReached(result: DerivationProcessingResult, trigger: 'onChange' | 'debounced'): void;
|
|
2781
|
+
}
|
|
2782
|
+
|
|
2783
|
+
/**
|
|
2784
|
+
* Minimal configuration for creating a DerivationOrchestrator.
|
|
2785
|
+
* Only includes form-specific signals that cannot be injected.
|
|
2786
|
+
*
|
|
2787
|
+
* @internal
|
|
2788
|
+
*/
|
|
2789
|
+
interface DerivationOrchestratorConfig {
|
|
2790
|
+
/** Signal containing the flattened schema fields */
|
|
2791
|
+
schemaFields: Signal<FieldDef<unknown>[] | undefined>;
|
|
2792
|
+
/** Signal containing the current form value */
|
|
2793
|
+
formValue: Signal<Record<string, unknown>>;
|
|
2794
|
+
/** Signal containing the form accessor */
|
|
2795
|
+
form: Signal<FieldTree<unknown>>;
|
|
2796
|
+
/** Signal containing the derivation logger */
|
|
2797
|
+
derivationLogger: Signal<DerivationLogger>;
|
|
2798
|
+
}
|
|
2799
|
+
|
|
2213
2800
|
/**
|
|
2214
2801
|
* Base interface for all form events in the dynamic form system.
|
|
2215
2802
|
*
|
|
@@ -2369,6 +2956,7 @@ declare class DynamicForm<TFields extends RegisteredFieldTypes[] = RegisteredFie
|
|
|
2369
2956
|
private readonly functionRegistry;
|
|
2370
2957
|
private readonly schemaRegistry;
|
|
2371
2958
|
private readonly logger;
|
|
2959
|
+
private readonly derivationLogConfig;
|
|
2372
2960
|
/** Form configuration defining the structure, validation, and behavior. */
|
|
2373
2961
|
config: InputSignal<FormConfig<TFields>>;
|
|
2374
2962
|
/** Runtime form options that override config options when provided. */
|
|
@@ -2385,14 +2973,26 @@ declare class DynamicForm<TFields extends RegisteredFieldTypes[] = RegisteredFie
|
|
|
2385
2973
|
readonly pageFieldDefinitions: Signal<PageField<_ng_forge_dynamic_forms.PageAllowedChildren[]>[]>;
|
|
2386
2974
|
readonly effectiveFormOptions: Signal<{
|
|
2387
2975
|
disabled?: boolean;
|
|
2976
|
+
maxDerivationIterations?: number;
|
|
2388
2977
|
submitButton?: _ng_forge_dynamic_forms.SubmitButtonOptions;
|
|
2389
2978
|
nextButton?: _ng_forge_dynamic_forms.NextButtonOptions;
|
|
2390
2979
|
}>;
|
|
2980
|
+
/**
|
|
2981
|
+
* Computed derivation logger based on injected config.
|
|
2982
|
+
*
|
|
2983
|
+
* Uses factory pattern to return no-op logger when logging is disabled,
|
|
2984
|
+
* avoiding any logging overhead in production.
|
|
2985
|
+
*/
|
|
2986
|
+
private readonly derivationLogger;
|
|
2391
2987
|
readonly fieldSignalContext: Signal<FieldSignalContext<TModel>>;
|
|
2988
|
+
/**
|
|
2989
|
+
* Injector for field components with FIELD_SIGNAL_CONTEXT.
|
|
2990
|
+
* Other form-level tokens (DEFAULT_PROPS, etc.) are provided at component level.
|
|
2991
|
+
*/
|
|
2392
2992
|
private readonly fieldInjector;
|
|
2393
2993
|
readonly defaultValues: _angular_core.WritableSignal<TModel>;
|
|
2394
2994
|
private readonly entity;
|
|
2395
|
-
readonly form: Signal<
|
|
2995
|
+
readonly form: Signal<FieldTree<TModel, string | number>>;
|
|
2396
2996
|
private readonly componentId;
|
|
2397
2997
|
private readonly totalComponentsCount;
|
|
2398
2998
|
private readonly fieldsSource;
|
|
@@ -2418,6 +3018,13 @@ declare class DynamicForm<TFields extends RegisteredFieldTypes[] = RegisteredFie
|
|
|
2418
3018
|
readonly disabled: Signal<boolean>;
|
|
2419
3019
|
/** Whether the form is currently submitting. */
|
|
2420
3020
|
readonly submitting: Signal<boolean>;
|
|
3021
|
+
/**
|
|
3022
|
+
* Configuration for the derivation orchestrator.
|
|
3023
|
+
* Bundles the form-specific signals needed by the orchestrator.
|
|
3024
|
+
*
|
|
3025
|
+
* @internal Used by DERIVATION_ORCHESTRATOR provider.
|
|
3026
|
+
*/
|
|
3027
|
+
readonly derivationOrchestratorConfig: DerivationOrchestratorConfig;
|
|
2421
3028
|
readonly initialized$: rxjs.Observable<boolean>;
|
|
2422
3029
|
/** Emits when form validity changes. */
|
|
2423
3030
|
readonly validityChange: _angular_core.OutputRef<boolean>;
|
|
@@ -2618,20 +3225,55 @@ type ExtractFormValue<T> = T extends {
|
|
|
2618
3225
|
*/
|
|
2619
3226
|
declare const BUILT_IN_FIELDS: FieldTypeDefinition[];
|
|
2620
3227
|
|
|
3228
|
+
/**
|
|
3229
|
+
* Configuration options for the logger feature.
|
|
3230
|
+
*
|
|
3231
|
+
* @public
|
|
3232
|
+
*/
|
|
3233
|
+
interface LoggerConfigOptions {
|
|
3234
|
+
/**
|
|
3235
|
+
* Whether general logging is enabled.
|
|
3236
|
+
*
|
|
3237
|
+
* @default true
|
|
3238
|
+
*/
|
|
3239
|
+
enabled?: boolean;
|
|
3240
|
+
/**
|
|
3241
|
+
* Derivation logging level.
|
|
3242
|
+
*
|
|
3243
|
+
* - `'none'`: No derivation debug logging (default)
|
|
3244
|
+
* - `'summary'`: Log cycle completion with counts
|
|
3245
|
+
* - `'verbose'`: Log individual derivation evaluations with details
|
|
3246
|
+
*
|
|
3247
|
+
* @default 'none'
|
|
3248
|
+
*/
|
|
3249
|
+
derivations?: DerivationLogLevel;
|
|
3250
|
+
}
|
|
2621
3251
|
/**
|
|
2622
3252
|
* Configure logging for dynamic forms.
|
|
2623
3253
|
*
|
|
2624
|
-
* By default, logging is enabled (ConsoleLogger)
|
|
2625
|
-
*
|
|
3254
|
+
* By default, general logging is enabled (ConsoleLogger) and derivation
|
|
3255
|
+
* logging is disabled ('none'). Use this feature to enable derivation debugging.
|
|
2626
3256
|
*
|
|
2627
3257
|
* @example
|
|
2628
3258
|
* ```typescript
|
|
2629
|
-
* // Disable logging
|
|
3259
|
+
* // Disable all logging
|
|
2630
3260
|
* provideDynamicForm(
|
|
2631
3261
|
* ...withMaterialFields(),
|
|
2632
3262
|
* withLoggerConfig(false)
|
|
2633
3263
|
* )
|
|
2634
3264
|
*
|
|
3265
|
+
* // Enable verbose derivation logging
|
|
3266
|
+
* provideDynamicForm(
|
|
3267
|
+
* ...withMaterialFields(),
|
|
3268
|
+
* withLoggerConfig({ derivations: 'verbose' })
|
|
3269
|
+
* )
|
|
3270
|
+
*
|
|
3271
|
+
* // Disable derivation logging but keep general logging
|
|
3272
|
+
* provideDynamicForm(
|
|
3273
|
+
* ...withMaterialFields(),
|
|
3274
|
+
* withLoggerConfig({ derivations: 'none' })
|
|
3275
|
+
* )
|
|
3276
|
+
*
|
|
2635
3277
|
* // Conditional logging (e.g., only in dev mode)
|
|
2636
3278
|
* provideDynamicForm(
|
|
2637
3279
|
* ...withMaterialFields(),
|
|
@@ -2639,10 +3281,12 @@ declare const BUILT_IN_FIELDS: FieldTypeDefinition[];
|
|
|
2639
3281
|
* )
|
|
2640
3282
|
* ```
|
|
2641
3283
|
*
|
|
2642
|
-
* @param
|
|
3284
|
+
* @param config - Boolean to enable/disable logging, a function returning boolean, or a config object
|
|
2643
3285
|
* @returns A DynamicFormFeature that configures logging
|
|
3286
|
+
*
|
|
3287
|
+
* @public
|
|
2644
3288
|
*/
|
|
2645
|
-
declare function withLoggerConfig(
|
|
3289
|
+
declare function withLoggerConfig(config?: boolean | (() => boolean) | LoggerConfigOptions): DynamicFormFeature<'logger'>;
|
|
2646
3290
|
|
|
2647
3291
|
/**
|
|
2648
3292
|
* Injection token for the dynamic forms logger.
|
|
@@ -2731,6 +3375,82 @@ declare const FIELD_SIGNAL_CONTEXT: InjectionToken<FieldSignalContext<Record<str
|
|
|
2731
3375
|
* ```
|
|
2732
3376
|
*/
|
|
2733
3377
|
declare const ARRAY_CONTEXT: InjectionToken<ArrayContext>;
|
|
3378
|
+
/**
|
|
3379
|
+
* Injection token for form-level default props.
|
|
3380
|
+
*
|
|
3381
|
+
* Default props are form-wide property defaults that are merged with field-level props.
|
|
3382
|
+
* Field props take precedence over default props.
|
|
3383
|
+
*
|
|
3384
|
+
* Unlike FIELD_SIGNAL_CONTEXT which is re-provided by container components (Group, Array),
|
|
3385
|
+
* DEFAULT_PROPS is provided ONCE at the DynamicForm level and inherited by all children
|
|
3386
|
+
* via Angular's hierarchical injector.
|
|
3387
|
+
*
|
|
3388
|
+
* The token provides a Signal to enable reactivity - when config changes, mappers
|
|
3389
|
+
* that read the signal inside their computed() will automatically update.
|
|
3390
|
+
*
|
|
3391
|
+
* @example
|
|
3392
|
+
* ```typescript
|
|
3393
|
+
* // In a mapper function
|
|
3394
|
+
* const defaultPropsSignal = inject(DEFAULT_PROPS);
|
|
3395
|
+
*
|
|
3396
|
+
* return computed(() => {
|
|
3397
|
+
* const defaultProps = defaultPropsSignal?.(); // Read inside computed for reactivity
|
|
3398
|
+
* const baseInputs = buildBaseInputs(fieldDef, defaultProps);
|
|
3399
|
+
* // ...
|
|
3400
|
+
* });
|
|
3401
|
+
* ```
|
|
3402
|
+
*/
|
|
3403
|
+
declare const DEFAULT_PROPS: InjectionToken<Signal<Record<string, unknown> | undefined>>;
|
|
3404
|
+
/**
|
|
3405
|
+
* Injection token for form-level default validation messages.
|
|
3406
|
+
*
|
|
3407
|
+
* Default validation messages act as fallbacks when fields have validation
|
|
3408
|
+
* errors but no field-level `validationMessages` defined.
|
|
3409
|
+
*
|
|
3410
|
+
* Like DEFAULT_PROPS, this token is provided ONCE at the DynamicForm level
|
|
3411
|
+
* and inherited by all children via Angular's hierarchical injector.
|
|
3412
|
+
*
|
|
3413
|
+
* The token provides a Signal to enable reactivity - when config changes, mappers
|
|
3414
|
+
* that read the signal inside their computed() will automatically update.
|
|
3415
|
+
*
|
|
3416
|
+
* @example
|
|
3417
|
+
* ```typescript
|
|
3418
|
+
* // In a mapper or component
|
|
3419
|
+
* const defaultMessagesSignal = inject(DEFAULT_VALIDATION_MESSAGES);
|
|
3420
|
+
*
|
|
3421
|
+
* return computed(() => {
|
|
3422
|
+
* const defaultMessages = defaultMessagesSignal?.(); // Read inside computed for reactivity
|
|
3423
|
+
* const message = defaultMessages?.required ?? 'Field is required';
|
|
3424
|
+
* // ...
|
|
3425
|
+
* });
|
|
3426
|
+
* ```
|
|
3427
|
+
*/
|
|
3428
|
+
declare const DEFAULT_VALIDATION_MESSAGES: InjectionToken<Signal<ValidationMessages | undefined>>;
|
|
3429
|
+
/**
|
|
3430
|
+
* Injection token for form-level options.
|
|
3431
|
+
*
|
|
3432
|
+
* Form options control form-wide behavior including button disabled states.
|
|
3433
|
+
* Used by button mappers to determine default disabled behavior.
|
|
3434
|
+
*
|
|
3435
|
+
* Like DEFAULT_PROPS, this token is provided ONCE at the DynamicForm level
|
|
3436
|
+
* and inherited by all children via Angular's hierarchical injector.
|
|
3437
|
+
*
|
|
3438
|
+
* The token provides a Signal to enable reactivity - when config changes, mappers
|
|
3439
|
+
* that read the signal inside their computed() will automatically update.
|
|
3440
|
+
*
|
|
3441
|
+
* @example
|
|
3442
|
+
* ```typescript
|
|
3443
|
+
* // In a button mapper
|
|
3444
|
+
* const formOptionsSignal = inject(FORM_OPTIONS);
|
|
3445
|
+
*
|
|
3446
|
+
* return computed(() => {
|
|
3447
|
+
* const formOptions = formOptionsSignal?.(); // Read inside computed for reactivity
|
|
3448
|
+
* const disableWhenInvalid = formOptions?.submitButton?.disableWhenInvalid ?? true;
|
|
3449
|
+
* // ...
|
|
3450
|
+
* });
|
|
3451
|
+
* ```
|
|
3452
|
+
*/
|
|
3453
|
+
declare const FORM_OPTIONS: InjectionToken<Signal<FormOptions | undefined>>;
|
|
2734
3454
|
|
|
2735
3455
|
/**
|
|
2736
3456
|
* Context for resolving button disabled state.
|
|
@@ -2817,6 +3537,43 @@ interface FieldWithValidation {
|
|
|
2817
3537
|
readonly validators?: ValidatorConfig[];
|
|
2818
3538
|
readonly validationMessages?: ValidationMessages;
|
|
2819
3539
|
readonly logic?: LogicConfig[];
|
|
3540
|
+
/**
|
|
3541
|
+
* Shorthand for simple computed/derived fields.
|
|
3542
|
+
*
|
|
3543
|
+
* The expression is evaluated whenever its dependencies change,
|
|
3544
|
+
* and the result is set as this field's value.
|
|
3545
|
+
*
|
|
3546
|
+
* Has access to `formValue` object containing all form values.
|
|
3547
|
+
* Uses the same secure AST-based parser as other expressions.
|
|
3548
|
+
*
|
|
3549
|
+
* For conditional derivations or derivations targeting other fields,
|
|
3550
|
+
* use the full `logic` array with `{ type: 'derivation', ... }`.
|
|
3551
|
+
*
|
|
3552
|
+
* @example
|
|
3553
|
+
* ```typescript
|
|
3554
|
+
* // Compute total from quantity and price
|
|
3555
|
+
* {
|
|
3556
|
+
* key: 'total',
|
|
3557
|
+
* type: 'number',
|
|
3558
|
+
* derivation: 'formValue.quantity * formValue.unitPrice'
|
|
3559
|
+
* }
|
|
3560
|
+
*
|
|
3561
|
+
* // Concatenate names
|
|
3562
|
+
* {
|
|
3563
|
+
* key: 'fullName',
|
|
3564
|
+
* type: 'input',
|
|
3565
|
+
* derivation: 'formValue.firstName + " " + formValue.lastName'
|
|
3566
|
+
* }
|
|
3567
|
+
*
|
|
3568
|
+
* // Calculate discounted price
|
|
3569
|
+
* {
|
|
3570
|
+
* key: 'discountedPrice',
|
|
3571
|
+
* type: 'number',
|
|
3572
|
+
* derivation: 'formValue.price * (1 - formValue.discountPercent / 100)'
|
|
3573
|
+
* }
|
|
3574
|
+
* ```
|
|
3575
|
+
*/
|
|
3576
|
+
readonly derivation?: string;
|
|
2820
3577
|
readonly schemas?: SchemaApplicationConfig[];
|
|
2821
3578
|
}
|
|
2822
3579
|
|
|
@@ -2835,7 +3592,7 @@ interface BaseValueField<TProps, TValue, TMeta extends FieldMeta = FieldMeta> ex
|
|
|
2835
3592
|
required?: boolean;
|
|
2836
3593
|
}
|
|
2837
3594
|
declare function isValueField<TProps, TMeta extends FieldMeta = FieldMeta>(field: FieldDef<TProps, TMeta>): field is BaseValueField<TProps, ValueType, TMeta>;
|
|
2838
|
-
type ExcludedKeys$1 = 'type' | 'conditionals' | 'value' | 'valueType' | 'disabled' | 'readonly' | 'hidden' | 'col' | 'minValue' | 'maxValue' | 'step' | 'required' | 'email' | 'min' | 'max' | 'minLength' | 'maxLength' | 'pattern' | 'validators' | 'logic' | 'schemas';
|
|
3595
|
+
type ExcludedKeys$1 = 'type' | 'conditionals' | 'value' | 'valueType' | 'disabled' | 'readonly' | 'hidden' | 'col' | 'minValue' | 'maxValue' | 'step' | 'required' | 'email' | 'min' | 'max' | 'minLength' | 'maxLength' | 'pattern' | 'validators' | 'logic' | 'derivation' | 'schemas';
|
|
2839
3596
|
type ValueFieldComponent<T extends BaseValueField<Record<string, unknown> | unknown, unknown>> = Prettify<WithInputSignals<Omit<T, ExcludedKeys$1>>>;
|
|
2840
3597
|
|
|
2841
3598
|
interface BaseCheckedField<TProps, TMeta extends FieldMeta = FieldMeta> extends FieldDef<TProps, TMeta>, FieldWithValidation {
|
|
@@ -3060,6 +3817,62 @@ interface ArrayItemContext {
|
|
|
3060
3817
|
formValue?: unknown;
|
|
3061
3818
|
}
|
|
3062
3819
|
|
|
3820
|
+
/**
|
|
3821
|
+
* Type-safe form config builder that ensures schema matches field structure.
|
|
3822
|
+
*
|
|
3823
|
+
* This helper function provides type safety when using form-level schemas by
|
|
3824
|
+
* automatically inferring the form value type from fields and constraining
|
|
3825
|
+
* the schema type parameter accordingly.
|
|
3826
|
+
*
|
|
3827
|
+
* **When to use:**
|
|
3828
|
+
* - When you have a form-level `schema` and want type safety between fields and schema
|
|
3829
|
+
* - When you prefer function syntax over `as const satisfies FormConfig`
|
|
3830
|
+
*
|
|
3831
|
+
* **Note:** This is optional. Users who don't need schema type safety can
|
|
3832
|
+
* continue using `as const satisfies FormConfig` directly.
|
|
3833
|
+
*
|
|
3834
|
+
* @typeParam TFields - The field definitions array (narrowed via `as const`)
|
|
3835
|
+
* @typeParam TProps - Optional form-level default props type
|
|
3836
|
+
*
|
|
3837
|
+
* @param config - The form configuration object
|
|
3838
|
+
* @returns The same configuration with proper type inference
|
|
3839
|
+
*
|
|
3840
|
+
* @example Basic usage with Zod schema
|
|
3841
|
+
* ```typescript
|
|
3842
|
+
* import { z } from 'zod';
|
|
3843
|
+
* import { formConfig } from '@ng-forge/dynamic-forms';
|
|
3844
|
+
* import { standardSchema } from '@ng-forge/dynamic-forms/schema';
|
|
3845
|
+
*
|
|
3846
|
+
* const passwordSchema = z.object({
|
|
3847
|
+
* password: z.string().min(8),
|
|
3848
|
+
* confirmPassword: z.string(),
|
|
3849
|
+
* }).refine(
|
|
3850
|
+
* (data) => data.password === data.confirmPassword,
|
|
3851
|
+
* { message: 'Passwords must match', path: ['confirmPassword'] }
|
|
3852
|
+
* );
|
|
3853
|
+
*
|
|
3854
|
+
* const config = formConfig({
|
|
3855
|
+
* schema: standardSchema(passwordSchema),
|
|
3856
|
+
* fields: [
|
|
3857
|
+
* { key: 'password', type: 'input', label: 'Password', required: true, props: { type: 'password' } },
|
|
3858
|
+
* { key: 'confirmPassword', type: 'input', label: 'Confirm', required: true, props: { type: 'password' } },
|
|
3859
|
+
* { key: 'submit', type: 'submit', label: 'Register' },
|
|
3860
|
+
* ] as const,
|
|
3861
|
+
* });
|
|
3862
|
+
* ```
|
|
3863
|
+
*
|
|
3864
|
+
* @example Equivalent without helper
|
|
3865
|
+
* ```typescript
|
|
3866
|
+
* const config = {
|
|
3867
|
+
* schema: standardSchema(passwordSchema),
|
|
3868
|
+
* fields: [...],
|
|
3869
|
+
* } as const satisfies FormConfig;
|
|
3870
|
+
* ```
|
|
3871
|
+
*/
|
|
3872
|
+
declare function formConfig<const TFields extends NarrowFields, TProps extends object = Record<string, unknown>>(config: Omit<FormConfig<TFields, InferFormValue$1<TFields>, TProps>, 'schema'> & {
|
|
3873
|
+
schema?: FormSchema<InferFormValue$1<TFields>>;
|
|
3874
|
+
}): FormConfig<TFields, InferFormValue$1<TFields>, TProps>;
|
|
3875
|
+
|
|
3063
3876
|
/**
|
|
3064
3877
|
* Base error class for all Dynamic Forms errors.
|
|
3065
3878
|
*
|
|
@@ -3079,9 +3892,10 @@ declare class DynamicFormError extends Error {
|
|
|
3079
3892
|
* Used by mappers to build the inputs record.
|
|
3080
3893
|
*
|
|
3081
3894
|
* @param fieldDef The field definition to extract properties from
|
|
3895
|
+
* @param defaultProps Optional form-level default props to merge with field props
|
|
3082
3896
|
* @returns Record of input names to values
|
|
3083
3897
|
*/
|
|
3084
|
-
declare function buildBaseInputs(fieldDef: FieldDef<unknown>): Record<string, unknown>;
|
|
3898
|
+
declare function buildBaseInputs(fieldDef: FieldDef<unknown>, defaultProps?: Record<string, unknown>): Record<string, unknown>;
|
|
3085
3899
|
/**
|
|
3086
3900
|
* Base field mapper that extracts common field properties into component inputs.
|
|
3087
3901
|
*
|
|
@@ -3367,6 +4181,32 @@ declare function getArrayLength<T>(arrayFieldTree: ArrayFieldTree<T>): number;
|
|
|
3367
4181
|
* Native JavaScript utility functions to replace lodash-es
|
|
3368
4182
|
* These are simple implementations for common object manipulation patterns
|
|
3369
4183
|
*/
|
|
4184
|
+
/**
|
|
4185
|
+
* Performs a deep equality comparison between two values.
|
|
4186
|
+
*
|
|
4187
|
+
* Handles:
|
|
4188
|
+
* - Primitives (including NaN via Object.is)
|
|
4189
|
+
* - Dates (by timestamp)
|
|
4190
|
+
* - Arrays (deep element comparison)
|
|
4191
|
+
* - Plain objects (deep property comparison)
|
|
4192
|
+
* - RegExp (by source and flags)
|
|
4193
|
+
* - Map and Set (by entries)
|
|
4194
|
+
* - Circular references (via WeakMap tracking)
|
|
4195
|
+
*
|
|
4196
|
+
* @param a - First value
|
|
4197
|
+
* @param b - Second value
|
|
4198
|
+
* @returns true if values are deeply equal
|
|
4199
|
+
*
|
|
4200
|
+
* @example
|
|
4201
|
+
* ```typescript
|
|
4202
|
+
* isEqual({ a: 1 }, { a: 1 }); // true
|
|
4203
|
+
* isEqual([1, 2], [1, 2]); // true
|
|
4204
|
+
* isEqual({ a: 1 }, { a: 2 }); // false
|
|
4205
|
+
* isEqual(new Date('2024-01-01'), new Date('2024-01-01')); // true
|
|
4206
|
+
* isEqual(/abc/gi, /abc/gi); // true
|
|
4207
|
+
* ```
|
|
4208
|
+
*/
|
|
4209
|
+
declare function isEqual(a: unknown, b: unknown): boolean;
|
|
3370
4210
|
/**
|
|
3371
4211
|
* Creates a new object without the specified keys
|
|
3372
4212
|
* Native replacement for lodash omit()
|
|
@@ -3396,5 +4236,98 @@ declare function omit<T extends object, K extends keyof T>(obj: T, keys: K[]): O
|
|
|
3396
4236
|
*/
|
|
3397
4237
|
declare function interpolateParams(message: string, error: ValidationError): string;
|
|
3398
4238
|
|
|
3399
|
-
|
|
4239
|
+
/**
|
|
4240
|
+
* Registry service that maintains references to root form fields.
|
|
4241
|
+
* This provides a type-safe way to access root form values from child fields
|
|
4242
|
+
* without relying on internal Angular Forms API navigation.
|
|
4243
|
+
*
|
|
4244
|
+
* This service should be provided at the component level to ensure proper
|
|
4245
|
+
* isolation between different form instances.
|
|
4246
|
+
*
|
|
4247
|
+
* IMPORTANT: This registry supports two registration patterns:
|
|
4248
|
+
* 1. registerFormValueSignal() - Register the SOURCE signal BEFORE form creation
|
|
4249
|
+
* This allows logic functions to read form values during schema evaluation.
|
|
4250
|
+
* 2. registerRootForm() - Register the FieldTree AFTER form creation
|
|
4251
|
+
* This provides access to the full form structure.
|
|
4252
|
+
*
|
|
4253
|
+
* For cross-field logic to work correctly, registerFormValueSignal() should be
|
|
4254
|
+
* called BEFORE the form() call.
|
|
4255
|
+
*/
|
|
4256
|
+
declare class RootFormRegistryService {
|
|
4257
|
+
private readonly _rootForms;
|
|
4258
|
+
private readonly _formValueSignals;
|
|
4259
|
+
private readonly formContexts;
|
|
4260
|
+
/**
|
|
4261
|
+
* Registers the form value signal BEFORE form creation.
|
|
4262
|
+
*
|
|
4263
|
+
* This is the recommended pattern for cross-field logic:
|
|
4264
|
+
* 1. Create the formValue signal
|
|
4265
|
+
* 2. Register it with registerFormValueSignal()
|
|
4266
|
+
* 3. Create the form with form(formValue, schema(...))
|
|
4267
|
+
*
|
|
4268
|
+
* This allows logic functions to access form values during schema evaluation.
|
|
4269
|
+
*/
|
|
4270
|
+
registerFormValueSignal(valueSignal: Signal<Record<string, unknown>>, formId?: string): void;
|
|
4271
|
+
/**
|
|
4272
|
+
* Gets the registered form value signal by id.
|
|
4273
|
+
*
|
|
4274
|
+
* This allows direct access to the source signal, which can be read
|
|
4275
|
+
* reactively to get form values.
|
|
4276
|
+
*/
|
|
4277
|
+
getFormValueSignal(formId?: string): Signal<Record<string, unknown>> | undefined;
|
|
4278
|
+
/**
|
|
4279
|
+
* Registers a root form field with an optional identifier.
|
|
4280
|
+
* If no id is provided, uses 'default' as the key.
|
|
4281
|
+
*
|
|
4282
|
+
* This triggers reactive updates for any computed signals that
|
|
4283
|
+
* depend on getRootForm().
|
|
4284
|
+
*/
|
|
4285
|
+
registerRootForm(rootField: FieldTree<unknown>, formId?: string): void;
|
|
4286
|
+
/**
|
|
4287
|
+
* Gets a registered root form field by id.
|
|
4288
|
+
*
|
|
4289
|
+
* IMPORTANT: This method reads from a signal, which means any computed
|
|
4290
|
+
* signal that calls this method will automatically re-evaluate when
|
|
4291
|
+
* the form is registered or updated.
|
|
4292
|
+
*/
|
|
4293
|
+
getRootForm(formId?: string): FieldTree<unknown> | undefined;
|
|
4294
|
+
/**
|
|
4295
|
+
* Gets the form value, preferring the direct signal if available.
|
|
4296
|
+
*
|
|
4297
|
+
* This method tries in order:
|
|
4298
|
+
* 1. Form value signal (if registered) - reads directly from source signal
|
|
4299
|
+
* 2. Root form's .value() (if registered) - reads from FieldTree
|
|
4300
|
+
* 3. Returns empty object if nothing is registered
|
|
4301
|
+
*
|
|
4302
|
+
* Reading from signals creates reactive dependencies, so computeds will
|
|
4303
|
+
* re-evaluate when form values change.
|
|
4304
|
+
*/
|
|
4305
|
+
getFormValue(formId?: string): Record<string, unknown>;
|
|
4306
|
+
/**
|
|
4307
|
+
* Registers form context (field paths and metadata) for a specific form.
|
|
4308
|
+
* This can be used to store additional context information.
|
|
4309
|
+
*/
|
|
4310
|
+
registerFormContext(context: Record<string, unknown>, formId?: string): void;
|
|
4311
|
+
/**
|
|
4312
|
+
* Gets form context by id.
|
|
4313
|
+
*/
|
|
4314
|
+
getFormContext(formId?: string): Record<string, unknown>;
|
|
4315
|
+
/**
|
|
4316
|
+
* Unregisters a form and its context.
|
|
4317
|
+
* This should be called when a form component is destroyed to prevent memory leaks.
|
|
4318
|
+
*/
|
|
4319
|
+
unregisterForm(formId?: string): void;
|
|
4320
|
+
/**
|
|
4321
|
+
* Gets all registered form IDs.
|
|
4322
|
+
*/
|
|
4323
|
+
getRegisteredFormIds(): string[];
|
|
4324
|
+
/**
|
|
4325
|
+
* Clears all registered forms. Useful for testing.
|
|
4326
|
+
*/
|
|
4327
|
+
clear(): void;
|
|
4328
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<RootFormRegistryService, never>;
|
|
4329
|
+
static ɵprov: _angular_core.ɵɵInjectableDeclaration<RootFormRegistryService>;
|
|
4330
|
+
}
|
|
4331
|
+
|
|
4332
|
+
export { ARRAY_CONTEXT, AddArrayItemEvent, 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, NextPageEvent, NoopLogger, PageChangeEvent, PreviousPageEvent, RemoveArrayItemEvent, RootFormRegistryService, RowFieldComponent, SubmitEvent, applyMetaToElement, applyValidator, applyValidators, arrayFieldMapper, baseFieldMapper, buildBaseInputs, dynamicTextToObservable, formConfig, getArrayLength, groupFieldMapper, interpolateParams, isArrayField, isCheckedField, isContainerField, isDisplayOnlyField, isEqual, isFormStateCondition, isGroupField, isLeafField, isPageField, isRowField, isValueBearingField, isValueField, omit, pageFieldMapper, provideDynamicForm, resolveNextButtonDisabled, resolveSubmitButtonDisabled, resolveTokens, rowFieldMapper, textFieldMapper, withLoggerConfig };
|
|
3400
4333
|
export type { ArrayAllowedChildren, ArrayContext, ArrayField, ArrayFieldTree, ArrayItemContext, AsyncCustomValidator, AsyncValidatorConfig, AvailableFieldTypes, BaseCheckedField, BaseValidatorConfig, BaseValueField, BuiltInValidatorConfig, ButtonLogicContext, CheckedFieldComponent, ConditionalExpression, ContainerFieldTypes, CustomFnConfig, CustomValidator, CustomValidatorConfig, DynamicFormFieldRegistry, DynamicText, EvaluationContext, ExtractField, ExtractFieldDefs, ExtractFormValue, FieldComponent, FieldDef, FieldMeta, FieldOption, FieldPathAccess, FieldRegistryContainers, FieldRegistryLeaves, FieldSignalContext, FieldTypeDefinition, FieldWithValidation, FormConfig, FormEvent, FormEventConstructor, FormMode, FormModeDetectionResult, FormOptions, FormStateCondition, GroupAllowedChildren, GroupField, HttpCustomValidator, HttpResourceRequest, HttpValidatorConfig, InferFormValue$1 as InferFormValue, LeafFieldTypes, Logger, LogicConfig, MapperFn, NarrowField, NarrowFields, NextButtonOptions, PageAllowedChildren, PageField, Prettify, RegisteredFieldTypes, RowAllowedChildren, RowField, SchemaApplicationConfig, SchemaDefinition, SubmissionActionResult, SubmissionConfig, SubmitButtonOptions, TextElementType, TextField, TextProps, TokenContext, ValidationError, ValidationMessages, ValidatorConfig, ValueFieldComponent, ValueHandlingMode, ValueType, WithInputSignals };
|