@ng-forge/dynamic-forms 0.5.0 → 0.5.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.
- package/fesm2022/ng-forge-dynamic-forms-integration.mjs +120 -6
- package/fesm2022/ng-forge-dynamic-forms-integration.mjs.map +1 -1
- package/fesm2022/{ng-forge-dynamic-forms-ng-forge-dynamic-forms-WGww2nXx.mjs → ng-forge-dynamic-forms-ng-forge-dynamic-forms-BWFdMPyw.mjs} +740 -325
- package/fesm2022/ng-forge-dynamic-forms-ng-forge-dynamic-forms-BWFdMPyw.mjs.map +1 -0
- package/fesm2022/{ng-forge-dynamic-forms-page-field.component-CrO9WTDw.mjs → ng-forge-dynamic-forms-page-field.component-RN1hmG69.mjs} +2 -2
- package/fesm2022/{ng-forge-dynamic-forms-page-field.component-CrO9WTDw.mjs.map → ng-forge-dynamic-forms-page-field.component-RN1hmG69.mjs.map} +1 -1
- package/fesm2022/{ng-forge-dynamic-forms-text-field.component-BcFx_kOz.mjs → ng-forge-dynamic-forms-text-field.component-DIVyioMX.mjs} +2 -2
- package/fesm2022/{ng-forge-dynamic-forms-text-field.component-BcFx_kOz.mjs.map → ng-forge-dynamic-forms-text-field.component-DIVyioMX.mjs.map} +1 -1
- package/fesm2022/ng-forge-dynamic-forms.mjs +1 -1
- package/package.json +1 -1
- package/types/ng-forge-dynamic-forms-integration.d.ts +3 -0
- package/types/ng-forge-dynamic-forms.d.ts +341 -77
- package/fesm2022/ng-forge-dynamic-forms-ng-forge-dynamic-forms-WGww2nXx.mjs.map +0 -1
|
@@ -876,6 +876,10 @@ type StateLogicConfig = ImmediateStateLogicConfig | DebouncedStateLogicConfig;
|
|
|
876
876
|
/**
|
|
877
877
|
* Base configuration for value derivation logic.
|
|
878
878
|
*
|
|
879
|
+
* All derivations target the field they are defined on (self-targeting).
|
|
880
|
+
* This simplifies configuration by removing the need for `targetField` -
|
|
881
|
+
* derivation logic is placed on the field that should receive the computed value.
|
|
882
|
+
*
|
|
879
883
|
* @internal
|
|
880
884
|
*/
|
|
881
885
|
interface BaseDerivationLogicConfig {
|
|
@@ -892,29 +896,17 @@ interface BaseDerivationLogicConfig {
|
|
|
892
896
|
* @example
|
|
893
897
|
* ```typescript
|
|
894
898
|
* {
|
|
895
|
-
*
|
|
896
|
-
*
|
|
897
|
-
*
|
|
898
|
-
*
|
|
899
|
+
* key: 'lineTotal',
|
|
900
|
+
* type: 'input',
|
|
901
|
+
* logic: [{
|
|
902
|
+
* type: 'derivation',
|
|
903
|
+
* debugName: 'Calculate line total',
|
|
904
|
+
* expression: 'formValue.quantity * formValue.unitPrice'
|
|
905
|
+
* }]
|
|
899
906
|
* }
|
|
900
907
|
* ```
|
|
901
908
|
*/
|
|
902
909
|
debugName?: string;
|
|
903
|
-
/**
|
|
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
910
|
/**
|
|
919
911
|
* Condition that determines when this derivation applies.
|
|
920
912
|
*
|
|
@@ -942,7 +934,7 @@ interface BaseDerivationLogicConfig {
|
|
|
942
934
|
*/
|
|
943
935
|
condition?: ConditionalExpression | boolean;
|
|
944
936
|
/**
|
|
945
|
-
* Static value to set on
|
|
937
|
+
* Static value to set on this field.
|
|
946
938
|
*
|
|
947
939
|
* Use when the derived value is a constant.
|
|
948
940
|
* Mutually exclusive with `expression` and `functionName`.
|
|
@@ -960,6 +952,7 @@ interface BaseDerivationLogicConfig {
|
|
|
960
952
|
* JavaScript expression to evaluate for the derived value.
|
|
961
953
|
*
|
|
962
954
|
* Has access to `formValue` object containing all form values.
|
|
955
|
+
* For array fields, `formValue` is scoped to the current array item.
|
|
963
956
|
* Uses the same secure AST-based parser as other expressions.
|
|
964
957
|
* Mutually exclusive with `value` and `functionName`.
|
|
965
958
|
*
|
|
@@ -1001,18 +994,22 @@ interface BaseDerivationLogicConfig {
|
|
|
1001
994
|
* ```typescript
|
|
1002
995
|
* // Only re-evaluate when country changes
|
|
1003
996
|
* {
|
|
1004
|
-
*
|
|
1005
|
-
*
|
|
1006
|
-
*
|
|
1007
|
-
*
|
|
997
|
+
* key: 'currency',
|
|
998
|
+
* logic: [{
|
|
999
|
+
* type: 'derivation',
|
|
1000
|
+
* functionName: 'getCurrencyForCountry',
|
|
1001
|
+
* dependsOn: ['country']
|
|
1002
|
+
* }]
|
|
1008
1003
|
* }
|
|
1009
1004
|
*
|
|
1010
1005
|
* // Override automatic detection for complex expressions
|
|
1011
1006
|
* {
|
|
1012
|
-
*
|
|
1013
|
-
*
|
|
1014
|
-
*
|
|
1015
|
-
*
|
|
1007
|
+
* key: 'total',
|
|
1008
|
+
* logic: [{
|
|
1009
|
+
* type: 'derivation',
|
|
1010
|
+
* expression: 'calculateTotal(formValue)',
|
|
1011
|
+
* dependsOn: ['quantity', 'unitPrice', 'discount']
|
|
1012
|
+
* }]
|
|
1016
1013
|
* }
|
|
1017
1014
|
* ```
|
|
1018
1015
|
*/
|
|
@@ -1056,53 +1053,57 @@ interface DebouncedDerivationLogicConfig extends BaseDerivationLogicConfig {
|
|
|
1056
1053
|
* Configuration for value derivation logic.
|
|
1057
1054
|
*
|
|
1058
1055
|
* Enables programmatic value derivation based on conditions.
|
|
1059
|
-
*
|
|
1060
|
-
*
|
|
1056
|
+
* Derivations are self-targeting: the logic is placed on the field
|
|
1057
|
+
* that should receive the computed value.
|
|
1061
1058
|
*
|
|
1062
1059
|
* @example
|
|
1063
1060
|
* ```typescript
|
|
1064
1061
|
* // Set phone prefix based on country selection
|
|
1065
1062
|
* {
|
|
1066
|
-
*
|
|
1067
|
-
*
|
|
1068
|
-
*
|
|
1069
|
-
*
|
|
1070
|
-
*
|
|
1071
|
-
*
|
|
1072
|
-
*
|
|
1073
|
-
*
|
|
1074
|
-
*
|
|
1063
|
+
* key: 'phonePrefix',
|
|
1064
|
+
* logic: [{
|
|
1065
|
+
* type: 'derivation',
|
|
1066
|
+
* value: '+1',
|
|
1067
|
+
* condition: {
|
|
1068
|
+
* type: 'fieldValue',
|
|
1069
|
+
* fieldPath: 'country',
|
|
1070
|
+
* operator: 'equals',
|
|
1071
|
+
* value: 'USA'
|
|
1072
|
+
* }
|
|
1073
|
+
* }]
|
|
1075
1074
|
* }
|
|
1076
1075
|
*
|
|
1077
1076
|
* // Compute total from quantity and price
|
|
1078
1077
|
* {
|
|
1079
|
-
*
|
|
1080
|
-
*
|
|
1081
|
-
* expression: 'formValue.quantity * formValue.unitPrice'
|
|
1078
|
+
* key: 'total',
|
|
1079
|
+
* derivation: 'formValue.quantity * formValue.unitPrice'
|
|
1082
1080
|
* }
|
|
1083
1081
|
*
|
|
1084
1082
|
* // Use custom function for complex logic
|
|
1085
1083
|
* {
|
|
1086
|
-
*
|
|
1087
|
-
*
|
|
1088
|
-
*
|
|
1084
|
+
* key: 'currency',
|
|
1085
|
+
* logic: [{
|
|
1086
|
+
* type: 'derivation',
|
|
1087
|
+
* functionName: 'getCurrencyForCountry'
|
|
1088
|
+
* }]
|
|
1089
1089
|
* }
|
|
1090
1090
|
*
|
|
1091
1091
|
* // Self-transform with debounced trigger
|
|
1092
1092
|
* // (applies after user stops typing)
|
|
1093
1093
|
* {
|
|
1094
|
-
*
|
|
1095
|
-
*
|
|
1096
|
-
*
|
|
1097
|
-
*
|
|
1098
|
-
*
|
|
1094
|
+
* key: 'email',
|
|
1095
|
+
* logic: [{
|
|
1096
|
+
* type: 'derivation',
|
|
1097
|
+
* expression: 'formValue.email.toLowerCase()',
|
|
1098
|
+
* trigger: 'debounced',
|
|
1099
|
+
* debounceMs: 500
|
|
1100
|
+
* }]
|
|
1099
1101
|
* }
|
|
1100
1102
|
*
|
|
1101
|
-
* //
|
|
1103
|
+
* // Array item derivation (formValue is scoped to current item)
|
|
1102
1104
|
* {
|
|
1103
|
-
*
|
|
1104
|
-
*
|
|
1105
|
-
* expression: 'formValue.quantity * formValue.unitPrice'
|
|
1105
|
+
* key: 'lineTotal', // Inside array field
|
|
1106
|
+
* derivation: 'formValue.quantity * formValue.unitPrice'
|
|
1106
1107
|
* }
|
|
1107
1108
|
* ```
|
|
1108
1109
|
*
|
|
@@ -1315,8 +1316,13 @@ type InferValueType<T, V> = T extends {
|
|
|
1315
1316
|
type: 'number';
|
|
1316
1317
|
};
|
|
1317
1318
|
} ? number : Widen<V>;
|
|
1318
|
-
/**
|
|
1319
|
+
/**
|
|
1320
|
+
* Make type optional if field is not required.
|
|
1321
|
+
* Hidden fields are never optional since they require a value property.
|
|
1322
|
+
*/
|
|
1319
1323
|
type MaybeOptional<T, V> = T extends {
|
|
1324
|
+
type: 'hidden';
|
|
1325
|
+
} ? V : T extends {
|
|
1320
1326
|
required: true;
|
|
1321
1327
|
} ? V : V | undefined;
|
|
1322
1328
|
/**
|
|
@@ -1333,10 +1339,18 @@ type ProcessField<T, D extends number = 5> = [D] extends [never] ? Record<string
|
|
|
1333
1339
|
[P in K]: InferFormValueWithDepth<F, Depth[D]>;
|
|
1334
1340
|
} : {
|
|
1335
1341
|
[P in K]: Record<string, unknown>;
|
|
1342
|
+
} : never : T extends {
|
|
1343
|
+
type: 'array';
|
|
1344
|
+
key: infer K;
|
|
1345
|
+
fields: infer F;
|
|
1346
|
+
} ? K extends string ? F extends RegisteredFieldTypes[] ? {
|
|
1347
|
+
[P in K]: InferFormValueWithDepth<F, Depth[D]>[];
|
|
1348
|
+
} : {
|
|
1349
|
+
[P in K]: unknown[];
|
|
1336
1350
|
} : never : T extends {
|
|
1337
1351
|
type: 'text';
|
|
1338
1352
|
} ? never : T extends {
|
|
1339
|
-
type: 'submit' | 'button';
|
|
1353
|
+
type: 'submit' | 'button' | 'next' | 'previous' | 'addArrayItem' | 'removeArrayItem';
|
|
1340
1354
|
} ? never : T extends {
|
|
1341
1355
|
key: infer K;
|
|
1342
1356
|
value: infer V;
|
|
@@ -1813,13 +1827,13 @@ interface EvaluationContext<TValue = unknown> {
|
|
|
1813
1827
|
*
|
|
1814
1828
|
* @example
|
|
1815
1829
|
* ```typescript
|
|
1816
|
-
* // In an array item derivation (
|
|
1830
|
+
* // In an array item derivation (on the lineTotal field inside lineItems array):
|
|
1817
1831
|
* {
|
|
1818
|
-
*
|
|
1819
|
-
*
|
|
1832
|
+
* key: 'lineTotal',
|
|
1833
|
+
* type: 'input',
|
|
1820
1834
|
* // formValue = current array item { quantity: 2, unitPrice: 50 }
|
|
1821
1835
|
* // rootFormValue = entire form { globalDiscount: 0.1, lineItems: [...] }
|
|
1822
|
-
*
|
|
1836
|
+
* derivation: 'formValue.quantity * formValue.unitPrice * (1 - rootFormValue.globalDiscount)'
|
|
1823
1837
|
* }
|
|
1824
1838
|
* ```
|
|
1825
1839
|
*
|
|
@@ -1835,6 +1849,28 @@ interface EvaluationContext<TValue = unknown> {
|
|
|
1835
1849
|
* Path to the array field when inside an array derivation.
|
|
1836
1850
|
*/
|
|
1837
1851
|
arrayPath?: string;
|
|
1852
|
+
/**
|
|
1853
|
+
* External data signals resolved to their current values.
|
|
1854
|
+
*
|
|
1855
|
+
* This allows forms to reference data from outside the form context
|
|
1856
|
+
* in conditional logic, derivations, and other expressions.
|
|
1857
|
+
*
|
|
1858
|
+
* @example
|
|
1859
|
+
* ```typescript
|
|
1860
|
+
* // In form config:
|
|
1861
|
+
* externalData: {
|
|
1862
|
+
* userRole: computed(() => this.userService.currentRole()),
|
|
1863
|
+
* permissions: computed(() => this.authService.permissions()),
|
|
1864
|
+
* }
|
|
1865
|
+
*
|
|
1866
|
+
* // In JavaScript expression:
|
|
1867
|
+
* condition: {
|
|
1868
|
+
* type: 'javascript',
|
|
1869
|
+
* expression: "externalData.userRole === 'admin'"
|
|
1870
|
+
* }
|
|
1871
|
+
* ```
|
|
1872
|
+
*/
|
|
1873
|
+
externalData?: Record<string, unknown>;
|
|
1838
1874
|
/** Allow additional properties for flexible expression evaluation */
|
|
1839
1875
|
[key: string]: unknown;
|
|
1840
1876
|
}
|
|
@@ -2202,6 +2238,54 @@ interface FormConfig<TFields extends NarrowFields | RegisteredFieldTypes[] = Reg
|
|
|
2202
2238
|
* ```
|
|
2203
2239
|
*/
|
|
2204
2240
|
defaultProps?: TProps;
|
|
2241
|
+
/**
|
|
2242
|
+
* External data signals available to conditional logic and derivations.
|
|
2243
|
+
*
|
|
2244
|
+
* Provides a way to inject external application state into form expressions.
|
|
2245
|
+
* Each property is a Signal that will be unwrapped and made available in the
|
|
2246
|
+
* `EvaluationContext` under `externalData`.
|
|
2247
|
+
*
|
|
2248
|
+
* The signals are read reactively in logic functions (when/readonly/disabled)
|
|
2249
|
+
* so changes to the external data will trigger re-evaluation of conditions.
|
|
2250
|
+
*
|
|
2251
|
+
* @example
|
|
2252
|
+
* ```typescript
|
|
2253
|
+
* const config: FormConfig = {
|
|
2254
|
+
* externalData: {
|
|
2255
|
+
* userRole: computed(() => this.authService.currentRole()),
|
|
2256
|
+
* permissions: computed(() => this.authService.permissions()),
|
|
2257
|
+
* featureFlags: computed(() => this.featureFlagService.flags()),
|
|
2258
|
+
* },
|
|
2259
|
+
* fields: [
|
|
2260
|
+
* {
|
|
2261
|
+
* type: 'input',
|
|
2262
|
+
* key: 'adminField',
|
|
2263
|
+
* label: 'Admin Only Field',
|
|
2264
|
+
* logic: [{
|
|
2265
|
+
* effect: 'show',
|
|
2266
|
+
* condition: {
|
|
2267
|
+
* type: 'javascript',
|
|
2268
|
+
* expression: "externalData.userRole === 'admin'"
|
|
2269
|
+
* }
|
|
2270
|
+
* }]
|
|
2271
|
+
* },
|
|
2272
|
+
* {
|
|
2273
|
+
* type: 'select',
|
|
2274
|
+
* key: 'advancedOption',
|
|
2275
|
+
* label: 'Advanced Option',
|
|
2276
|
+
* logic: [{
|
|
2277
|
+
* effect: 'show',
|
|
2278
|
+
* condition: {
|
|
2279
|
+
* type: 'javascript',
|
|
2280
|
+
* expression: "externalData.featureFlags.advancedMode === true"
|
|
2281
|
+
* }
|
|
2282
|
+
* }]
|
|
2283
|
+
* }
|
|
2284
|
+
* ]
|
|
2285
|
+
* };
|
|
2286
|
+
* ```
|
|
2287
|
+
*/
|
|
2288
|
+
externalData?: Record<string, Signal<unknown>>;
|
|
2205
2289
|
}
|
|
2206
2290
|
/**
|
|
2207
2291
|
* Signal forms adapter configuration for advanced form behavior.
|
|
@@ -2322,14 +2406,15 @@ interface CustomFnConfig {
|
|
|
2322
2406
|
*
|
|
2323
2407
|
* Field configuration using a derivation function:
|
|
2324
2408
|
* ```typescript
|
|
2409
|
+
* // Derivation is defined on the target field (currency), not the source field (country)
|
|
2325
2410
|
* {
|
|
2326
|
-
* key: '
|
|
2411
|
+
* key: 'currency',
|
|
2327
2412
|
* type: 'select',
|
|
2328
2413
|
* logic: [
|
|
2329
2414
|
* {
|
|
2330
2415
|
* type: 'derivation',
|
|
2331
|
-
*
|
|
2332
|
-
*
|
|
2416
|
+
* functionName: 'getCurrencyForCountry',
|
|
2417
|
+
* dependsOn: ['country']
|
|
2333
2418
|
* }
|
|
2334
2419
|
* ]
|
|
2335
2420
|
* }
|
|
@@ -2594,6 +2679,35 @@ interface FormOptions {
|
|
|
2594
2679
|
* ```
|
|
2595
2680
|
*/
|
|
2596
2681
|
nextButton?: NextButtonOptions;
|
|
2682
|
+
/**
|
|
2683
|
+
* Whether to attach the current form value to all events dispatched through the EventBus.
|
|
2684
|
+
*
|
|
2685
|
+
* This per-form setting overrides the global `withEventFormValue()` feature:
|
|
2686
|
+
* - `true` - Enable form value emission for this form (even if globally disabled)
|
|
2687
|
+
* - `false` - Disable form value emission for this form (even if globally enabled)
|
|
2688
|
+
* - `undefined` - Use global setting (default)
|
|
2689
|
+
*
|
|
2690
|
+
* When enabled, events will include a `formValue` property with the current form state.
|
|
2691
|
+
* Use the `hasFormValue()` type guard to safely access this property.
|
|
2692
|
+
*
|
|
2693
|
+
* @example
|
|
2694
|
+
* ```typescript
|
|
2695
|
+
* // Enable for this form only (no global withEventFormValue() needed)
|
|
2696
|
+
* const config: FormConfig = {
|
|
2697
|
+
* fields: [...],
|
|
2698
|
+
* options: { emitFormValueOnEvents: true }
|
|
2699
|
+
* };
|
|
2700
|
+
*
|
|
2701
|
+
* // Disable for this form (when globally enabled)
|
|
2702
|
+
* const config: FormConfig = {
|
|
2703
|
+
* fields: [...],
|
|
2704
|
+
* options: { emitFormValueOnEvents: false }
|
|
2705
|
+
* };
|
|
2706
|
+
* ```
|
|
2707
|
+
*
|
|
2708
|
+
* @default undefined (uses global setting)
|
|
2709
|
+
*/
|
|
2710
|
+
emitFormValueOnEvents?: boolean;
|
|
2597
2711
|
}
|
|
2598
2712
|
/**
|
|
2599
2713
|
* Options for controlling submit button disabled behavior.
|
|
@@ -2727,10 +2841,8 @@ interface DerivationProcessingResult {
|
|
|
2727
2841
|
interface DerivationLogEntry {
|
|
2728
2842
|
/** Debug name if provided in the derivation config */
|
|
2729
2843
|
debugName?: string;
|
|
2730
|
-
/**
|
|
2731
|
-
|
|
2732
|
-
/** Target field key that will be modified */
|
|
2733
|
-
targetFieldKey: string;
|
|
2844
|
+
/** Field key where the derivation is defined and targets */
|
|
2845
|
+
fieldKey: string;
|
|
2734
2846
|
/** Result of the derivation evaluation */
|
|
2735
2847
|
result: 'applied' | 'skipped' | 'error';
|
|
2736
2848
|
/** Reason for skipping (if result is 'skipped') */
|
|
@@ -2819,7 +2931,38 @@ interface DerivationOrchestratorConfig {
|
|
|
2819
2931
|
interface FormEvent {
|
|
2820
2932
|
/** Unique identifier for the event type used for filtering and subscriptions */
|
|
2821
2933
|
readonly type: string;
|
|
2934
|
+
/**
|
|
2935
|
+
* Optional form value attached to the event when `withEventFormValue()` is enabled
|
|
2936
|
+
* or `options.emitFormValueOnEvents` is set to `true` in the form config.
|
|
2937
|
+
*
|
|
2938
|
+
* Use the `hasFormValue()` type guard to check if this property is present.
|
|
2939
|
+
*/
|
|
2940
|
+
readonly formValue?: unknown;
|
|
2822
2941
|
}
|
|
2942
|
+
/**
|
|
2943
|
+
* Type guard to check if a form event has a form value attached.
|
|
2944
|
+
*
|
|
2945
|
+
* Use this to safely access the `formValue` property on events when
|
|
2946
|
+
* `withEventFormValue()` is enabled globally or `options.emitFormValueOnEvents`
|
|
2947
|
+
* is set to `true` in the form config.
|
|
2948
|
+
*
|
|
2949
|
+
* @example
|
|
2950
|
+
* ```typescript
|
|
2951
|
+
* eventBus.on<SubmitEvent>('submit').subscribe(event => {
|
|
2952
|
+
* if (hasFormValue(event)) {
|
|
2953
|
+
* console.log('Form value:', event.formValue);
|
|
2954
|
+
* }
|
|
2955
|
+
* });
|
|
2956
|
+
* ```
|
|
2957
|
+
*
|
|
2958
|
+
* @param event - The form event to check
|
|
2959
|
+
* @returns `true` if the event has a form value attached, narrowing the type
|
|
2960
|
+
*
|
|
2961
|
+
* @public
|
|
2962
|
+
*/
|
|
2963
|
+
declare function hasFormValue<T extends FormEvent>(event: T): event is T & {
|
|
2964
|
+
formValue: unknown;
|
|
2965
|
+
};
|
|
2823
2966
|
/**
|
|
2824
2967
|
* Constructor type for form event classes.
|
|
2825
2968
|
*
|
|
@@ -2976,6 +3119,7 @@ declare class DynamicForm<TFields extends RegisteredFieldTypes[] = RegisteredFie
|
|
|
2976
3119
|
maxDerivationIterations?: number;
|
|
2977
3120
|
submitButton?: _ng_forge_dynamic_forms.SubmitButtonOptions;
|
|
2978
3121
|
nextButton?: _ng_forge_dynamic_forms.NextButtonOptions;
|
|
3122
|
+
emitFormValueOnEvents?: boolean;
|
|
2979
3123
|
}>;
|
|
2980
3124
|
/**
|
|
2981
3125
|
* Computed derivation logger based on injected config.
|
|
@@ -3031,10 +3175,15 @@ declare class DynamicForm<TFields extends RegisteredFieldTypes[] = RegisteredFie
|
|
|
3031
3175
|
/** Emits when form dirty state changes. */
|
|
3032
3176
|
readonly dirtyChange: _angular_core.OutputRef<boolean>;
|
|
3033
3177
|
/**
|
|
3034
|
-
* Emits form values when submitted (via SubmitEvent).
|
|
3178
|
+
* Emits form values when submitted (via SubmitEvent) and form is valid.
|
|
3179
|
+
*
|
|
3180
|
+
* **Important:** This output only emits when the form is valid. If you need to
|
|
3181
|
+
* handle submit events regardless of validity, use the `(events)` output and
|
|
3182
|
+
* filter for `'submit'` events.
|
|
3183
|
+
*
|
|
3035
3184
|
* Note: Does not emit when `submission.action` is configured - use one or the other.
|
|
3036
3185
|
*/
|
|
3037
|
-
readonly submitted: _angular_core.OutputRef<
|
|
3186
|
+
readonly submitted: _angular_core.OutputRef<TModel>;
|
|
3038
3187
|
/** Emits when form is reset to default values. */
|
|
3039
3188
|
readonly reset: _angular_core.OutputRef<FormResetEvent>;
|
|
3040
3189
|
/** Emits when form is cleared to empty state. */
|
|
@@ -3099,13 +3248,9 @@ type ExtractFieldDef<T> = T extends FieldTypeDefinition<infer F> ? F : never;
|
|
|
3099
3248
|
*/
|
|
3100
3249
|
type FieldDefUnion<T extends FieldTypeDefinition[]> = ExtractFieldDef<T[number]>;
|
|
3101
3250
|
/**
|
|
3102
|
-
* Infer form value type from field definitions
|
|
3103
|
-
* Note: Full value type inference requires complex recursive type mapping.
|
|
3104
|
-
* Using unknown as placeholder until full inference is implemented.
|
|
3251
|
+
* Infer form value type from field definitions using the real inference type.
|
|
3105
3252
|
*/
|
|
3106
|
-
type InferFormValue<TFieldDefs extends FieldDef<unknown>[]> =
|
|
3107
|
-
[K in TFieldDefs[number]['key']]: unknown;
|
|
3108
|
-
};
|
|
3253
|
+
type InferFormValue<TFieldDefs extends FieldDef<unknown>[]> = InferFormValue$1<TFieldDefs>;
|
|
3109
3254
|
/**
|
|
3110
3255
|
* Provider result with type inference
|
|
3111
3256
|
*/
|
|
@@ -3318,6 +3463,52 @@ declare class NoopLogger implements Logger {
|
|
|
3318
3463
|
error(): void;
|
|
3319
3464
|
}
|
|
3320
3465
|
|
|
3466
|
+
/**
|
|
3467
|
+
* Enables automatic form value attachment to all events dispatched through the EventBus.
|
|
3468
|
+
*
|
|
3469
|
+
* When this feature is enabled, events dispatched via `eventBus.dispatch()` will include
|
|
3470
|
+
* the current form value in the `formValue` property. This is useful for event handlers
|
|
3471
|
+
* that need access to the complete form state at the time of the event.
|
|
3472
|
+
*
|
|
3473
|
+
* @example Global opt-in
|
|
3474
|
+
* ```typescript
|
|
3475
|
+
* provideDynamicForm(
|
|
3476
|
+
* ...withMaterialFields(),
|
|
3477
|
+
* withEventFormValue()
|
|
3478
|
+
* )
|
|
3479
|
+
* ```
|
|
3480
|
+
*
|
|
3481
|
+
* @example Consumer usage
|
|
3482
|
+
* ```typescript
|
|
3483
|
+
* eventBus.on<SubmitEvent>('submit').subscribe(event => {
|
|
3484
|
+
* if (hasFormValue(event)) {
|
|
3485
|
+
* console.log('Form value:', event.formValue);
|
|
3486
|
+
* }
|
|
3487
|
+
* });
|
|
3488
|
+
* ```
|
|
3489
|
+
*
|
|
3490
|
+
* @example Per-form disable (when globally enabled)
|
|
3491
|
+
* ```typescript
|
|
3492
|
+
* const config: FormConfig = {
|
|
3493
|
+
* fields: [...],
|
|
3494
|
+
* options: { emitFormValueOnEvents: false }
|
|
3495
|
+
* };
|
|
3496
|
+
* ```
|
|
3497
|
+
*
|
|
3498
|
+
* @remarks
|
|
3499
|
+
* **Precedence rules:**
|
|
3500
|
+
* 1. Per-form `false` - Disables for this form, regardless of global setting
|
|
3501
|
+
* 2. Per-form `true` - Enables for this form, regardless of global setting
|
|
3502
|
+
* 3. Per-form `undefined` - Uses global setting
|
|
3503
|
+
* 4. Global `withEventFormValue()` - Enables globally
|
|
3504
|
+
* 5. No global feature - Disabled globally (default)
|
|
3505
|
+
*
|
|
3506
|
+
* @returns A DynamicFormFeature that enables form value attachment to events
|
|
3507
|
+
*
|
|
3508
|
+
* @public
|
|
3509
|
+
*/
|
|
3510
|
+
declare function withEventFormValue(): DynamicFormFeature<'event-form-value'>;
|
|
3511
|
+
|
|
3321
3512
|
interface FieldOption<T = unknown> {
|
|
3322
3513
|
label: DynamicText;
|
|
3323
3514
|
value: T;
|
|
@@ -3728,7 +3919,10 @@ declare class RemoveArrayItemEvent implements FormEvent {
|
|
|
3728
3919
|
* ```
|
|
3729
3920
|
*/
|
|
3730
3921
|
declare class EventBus {
|
|
3731
|
-
private pipeline$;
|
|
3922
|
+
private readonly pipeline$;
|
|
3923
|
+
private readonly globalEmitFormValue;
|
|
3924
|
+
private readonly rootFormRegistry;
|
|
3925
|
+
private readonly formOptions;
|
|
3732
3926
|
events$: Observable<FormEvent>;
|
|
3733
3927
|
/**
|
|
3734
3928
|
* Dispatches an event to all subscribers.
|
|
@@ -3736,6 +3930,10 @@ declare class EventBus {
|
|
|
3736
3930
|
* Creates an instance of the provided event constructor and broadcasts it
|
|
3737
3931
|
* through the event pipeline to all active subscribers.
|
|
3738
3932
|
*
|
|
3933
|
+
* If `withEventFormValue()` is enabled globally or `options.emitFormValueOnEvents`
|
|
3934
|
+
* is set to `true` in the form config, the current form value will be attached
|
|
3935
|
+
* to the event's `formValue` property.
|
|
3936
|
+
*
|
|
3739
3937
|
* @param eventConstructor - Constructor function for the event to dispatch
|
|
3740
3938
|
*
|
|
3741
3939
|
* @example
|
|
@@ -3748,6 +3946,14 @@ declare class EventBus {
|
|
|
3748
3946
|
* ```
|
|
3749
3947
|
*/
|
|
3750
3948
|
dispatch<T extends FormEventConstructor>(eventConstructor: T, ...args: ConstructorParameters<T>): void;
|
|
3949
|
+
/**
|
|
3950
|
+
* Determines whether form value should be attached to events.
|
|
3951
|
+
*
|
|
3952
|
+
* Precedence rules:
|
|
3953
|
+
* 1. Per-form setting (if defined) takes precedence
|
|
3954
|
+
* 2. Falls back to global setting
|
|
3955
|
+
*/
|
|
3956
|
+
private shouldEmitFormValue;
|
|
3751
3957
|
/**
|
|
3752
3958
|
* Subscribes to events of a specific type.
|
|
3753
3959
|
*
|
|
@@ -3873,6 +4079,64 @@ declare function formConfig<const TFields extends NarrowFields, TProps extends o
|
|
|
3873
4079
|
schema?: FormSchema<InferFormValue$1<TFields>>;
|
|
3874
4080
|
}): FormConfig<TFields, InferFormValue$1<TFields>, TProps>;
|
|
3875
4081
|
|
|
4082
|
+
/**
|
|
4083
|
+
* Creates a typed field configuration with helpful error messages for common mistakes.
|
|
4084
|
+
*
|
|
4085
|
+
* This helper function provides early validation and clear error messages
|
|
4086
|
+
* for common configuration pitfalls that would otherwise cause runtime errors.
|
|
4087
|
+
*
|
|
4088
|
+
* @example
|
|
4089
|
+
* ```typescript
|
|
4090
|
+
* // Basic usage
|
|
4091
|
+
* const nameField = createField('input', {
|
|
4092
|
+
* key: 'name',
|
|
4093
|
+
* label: 'Name',
|
|
4094
|
+
* value: ''
|
|
4095
|
+
* });
|
|
4096
|
+
*
|
|
4097
|
+
* // With validation
|
|
4098
|
+
* const emailField = createField('input', {
|
|
4099
|
+
* key: 'email',
|
|
4100
|
+
* label: 'Email',
|
|
4101
|
+
* required: true,
|
|
4102
|
+
* email: true,
|
|
4103
|
+
* props: { type: 'email' }
|
|
4104
|
+
* });
|
|
4105
|
+
*
|
|
4106
|
+
* // Select with options (at field level)
|
|
4107
|
+
* const countryField = createField('select', {
|
|
4108
|
+
* key: 'country',
|
|
4109
|
+
* label: 'Country',
|
|
4110
|
+
* options: [{ label: 'USA', value: 'us' }]
|
|
4111
|
+
* });
|
|
4112
|
+
*
|
|
4113
|
+
* // Slider with minValue/maxValue (at field level)
|
|
4114
|
+
* const ratingField = createField('slider', {
|
|
4115
|
+
* key: 'rating',
|
|
4116
|
+
* label: 'Rating',
|
|
4117
|
+
* minValue: 1,
|
|
4118
|
+
* maxValue: 10,
|
|
4119
|
+
* step: 1,
|
|
4120
|
+
* value: 5
|
|
4121
|
+
* });
|
|
4122
|
+
* ```
|
|
4123
|
+
*
|
|
4124
|
+
* @param type - The field type (e.g., 'input', 'select', 'group')
|
|
4125
|
+
* @param config - The field configuration (excluding the 'type' property)
|
|
4126
|
+
* @returns A properly typed field configuration
|
|
4127
|
+
* @throws DynamicFormError if the configuration contains common mistakes
|
|
4128
|
+
*/
|
|
4129
|
+
declare function createField<T extends AvailableFieldTypes>(type: T, config: Omit<ExtractField<T>, 'type'>): ExtractField<T>;
|
|
4130
|
+
/**
|
|
4131
|
+
* Shorthand alias for createField
|
|
4132
|
+
*
|
|
4133
|
+
* @example
|
|
4134
|
+
* ```typescript
|
|
4135
|
+
* const nameField = field('input', { key: 'name', label: 'Name', value: '' });
|
|
4136
|
+
* ```
|
|
4137
|
+
*/
|
|
4138
|
+
declare const field: typeof createField;
|
|
4139
|
+
|
|
3876
4140
|
/**
|
|
3877
4141
|
* Base error class for all Dynamic Forms errors.
|
|
3878
4142
|
*
|
|
@@ -4329,5 +4593,5 @@ declare class RootFormRegistryService {
|
|
|
4329
4593
|
static ɵprov: _angular_core.ɵɵInjectableDeclaration<RootFormRegistryService>;
|
|
4330
4594
|
}
|
|
4331
4595
|
|
|
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 };
|
|
4596
|
+
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, createField, dynamicTextToObservable, field, formConfig, getArrayLength, groupFieldMapper, hasFormValue, interpolateParams, isArrayField, isCheckedField, isContainerField, isDisplayOnlyField, isEqual, isFormStateCondition, isGroupField, isLeafField, isPageField, isRowField, isValueBearingField, isValueField, omit, pageFieldMapper, provideDynamicForm, resolveNextButtonDisabled, resolveSubmitButtonDisabled, resolveTokens, rowFieldMapper, textFieldMapper, withEventFormValue, withLoggerConfig };
|
|
4333
4597
|
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 };
|