@ng-forge/dynamic-forms 0.6.0 → 0.7.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/fesm2022/ng-forge-dynamic-forms-integration.mjs +4 -4
- package/fesm2022/ng-forge-dynamic-forms-integration.mjs.map +1 -1
- package/fesm2022/{ng-forge-dynamic-forms-ng-forge-dynamic-forms-Bf6Qnz0T.mjs → ng-forge-dynamic-forms-ng-forge-dynamic-forms-Sad9wa1d.mjs} +1163 -702
- package/fesm2022/ng-forge-dynamic-forms-ng-forge-dynamic-forms-Sad9wa1d.mjs.map +1 -0
- package/fesm2022/{ng-forge-dynamic-forms-page-field.component-_mRHaw7x.mjs → ng-forge-dynamic-forms-page-field.component-Cen4ArED.mjs} +23 -18
- package/fesm2022/ng-forge-dynamic-forms-page-field.component-Cen4ArED.mjs.map +1 -0
- package/fesm2022/{ng-forge-dynamic-forms-text-field.component-CmkBZk4p.mjs → ng-forge-dynamic-forms-text-field.component-cE1EUmYR.mjs} +18 -12
- package/fesm2022/ng-forge-dynamic-forms-text-field.component-cE1EUmYR.mjs.map +1 -0
- package/fesm2022/ng-forge-dynamic-forms.mjs +1 -1
- package/package.json +4 -4
- package/types/ng-forge-dynamic-forms.d.ts +282 -451
- package/fesm2022/ng-forge-dynamic-forms-ng-forge-dynamic-forms-Bf6Qnz0T.mjs.map +0 -1
- package/fesm2022/ng-forge-dynamic-forms-page-field.component-_mRHaw7x.mjs.map +0 -1
- package/fesm2022/ng-forge-dynamic-forms-text-field.component-CmkBZk4p.mjs.map +0 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as rxjs from 'rxjs';
|
|
2
2
|
import { Observable } from 'rxjs';
|
|
3
3
|
import * as _angular_core from '@angular/core';
|
|
4
|
-
import { Signal, Injector, WritableSignal, InjectionToken, Type, ResourceRef, Provider, EnvironmentProviders, PipeTransform } from '@angular/core';
|
|
4
|
+
import { Signal, Injector, WritableSignal, InjectionToken, Type, ResourceRef, EnvironmentInjector, Provider, EnvironmentProviders, Resource, PipeTransform } from '@angular/core';
|
|
5
5
|
import * as _angular_forms_signals from '@angular/forms/signals';
|
|
6
|
-
import { FieldTree, FieldContext, ValidationError as ValidationError$1,
|
|
6
|
+
import { FieldTree, FieldContext, TreeValidationResult, ValidationError as ValidationError$1, SchemaPath, SchemaPathTree } from '@angular/forms/signals';
|
|
7
7
|
import * as _angular_forms from '@angular/forms';
|
|
8
8
|
import * as _ng_forge_dynamic_forms from '@ng-forge/dynamic-forms';
|
|
9
9
|
import { FormSchema } from '@ng-forge/dynamic-forms/schema';
|
|
@@ -379,6 +379,14 @@ type MapperFn<T extends FieldDef<unknown>> = (input: T) => Signal<Record<string,
|
|
|
379
379
|
* - 'flatten': Field's children are flattened to parent level (for container fields)
|
|
380
380
|
*/
|
|
381
381
|
type ValueHandlingMode = 'include' | 'exclude' | 'flatten';
|
|
382
|
+
/**
|
|
383
|
+
* Semantic grouping of interchangeable field UI alternatives.
|
|
384
|
+
*
|
|
385
|
+
* Used by tooling (e.g., openapi-generator) to discover which field types
|
|
386
|
+
* can substitute for each other. A field with scope 'boolean' means it's
|
|
387
|
+
* one of several ways to render a boolean value (checkbox, toggle, etc.).
|
|
388
|
+
*/
|
|
389
|
+
type FieldScope = 'boolean' | 'single-select' | 'multi-select' | 'text-input' | 'numeric' | 'date';
|
|
382
390
|
/**
|
|
383
391
|
* Configuration interface for registering custom field types.
|
|
384
392
|
*
|
|
@@ -444,6 +452,8 @@ interface FieldTypeDefinition<T extends FieldDef<any> = any> {
|
|
|
444
452
|
* ```
|
|
445
453
|
*/
|
|
446
454
|
propsToMeta?: string[];
|
|
455
|
+
/** Semantic scope for tooling to discover interchangeable field alternatives */
|
|
456
|
+
scope?: FieldScope | FieldScope[];
|
|
447
457
|
}
|
|
448
458
|
/**
|
|
449
459
|
* Injection token for the global field type registry.
|
|
@@ -533,56 +543,17 @@ interface FieldValueCondition {
|
|
|
533
543
|
value?: unknown;
|
|
534
544
|
}
|
|
535
545
|
/**
|
|
536
|
-
* Condition that
|
|
537
|
-
*
|
|
538
|
-
* @deprecated Use `FieldValueCondition` for specific field checks, or
|
|
539
|
-
* `JavascriptCondition` with an expression for complex form-level comparisons.
|
|
540
|
-
* Will be removed in a future minor version.
|
|
541
|
-
*
|
|
542
|
-
* @public
|
|
543
|
-
*/
|
|
544
|
-
interface FormValueCondition {
|
|
545
|
-
type: 'formValue';
|
|
546
|
-
/** Comparison operator */
|
|
547
|
-
operator: ComparisonOperator;
|
|
548
|
-
/** Value to compare against */
|
|
549
|
-
value?: unknown;
|
|
550
|
-
}
|
|
551
|
-
/**
|
|
552
|
-
* Condition that invokes a registered custom function by name (new API).
|
|
546
|
+
* Condition that invokes a registered custom function by name.
|
|
553
547
|
*
|
|
554
548
|
* Register functions via `customFnConfig.customFunctions`.
|
|
555
549
|
*
|
|
556
|
-
* @
|
|
550
|
+
* @public
|
|
557
551
|
*/
|
|
558
|
-
interface
|
|
552
|
+
interface CustomCondition {
|
|
559
553
|
type: 'custom';
|
|
560
554
|
/** Name of the registered custom function to invoke */
|
|
561
555
|
functionName: string;
|
|
562
556
|
}
|
|
563
|
-
/**
|
|
564
|
-
* @deprecated Use `CustomCondition` with `functionName` instead.
|
|
565
|
-
* The `expression` field was misnamed — it holds a function registry key, not a JS expression.
|
|
566
|
-
* Will be removed in a future minor version.
|
|
567
|
-
*
|
|
568
|
-
* @internal
|
|
569
|
-
*/
|
|
570
|
-
interface CustomConditionDeprecated {
|
|
571
|
-
type: 'custom';
|
|
572
|
-
/**
|
|
573
|
-
* @deprecated Use `functionName` instead. Will be removed in a future minor version.
|
|
574
|
-
*/
|
|
575
|
-
expression: string;
|
|
576
|
-
}
|
|
577
|
-
/**
|
|
578
|
-
* Condition that invokes a registered custom function by name.
|
|
579
|
-
*
|
|
580
|
-
* Use `functionName` (new API). The `expression` field is deprecated.
|
|
581
|
-
* Register functions via `customFnConfig.customFunctions`.
|
|
582
|
-
*
|
|
583
|
-
* @public
|
|
584
|
-
*/
|
|
585
|
-
type CustomCondition = CustomConditionNew | CustomConditionDeprecated;
|
|
586
557
|
/**
|
|
587
558
|
* Condition that evaluates a JavaScript expression using the secure AST-based parser.
|
|
588
559
|
*
|
|
@@ -697,7 +668,7 @@ interface OrCondition {
|
|
|
697
668
|
*
|
|
698
669
|
* @public
|
|
699
670
|
*/
|
|
700
|
-
type ConditionalExpression = FieldValueCondition |
|
|
671
|
+
type ConditionalExpression = FieldValueCondition | CustomCondition | JavascriptCondition | HttpCondition | AsyncCondition | AndCondition | OrCondition;
|
|
701
672
|
|
|
702
673
|
/**
|
|
703
674
|
* Logic configuration for container fields (page, group, row, array).
|
|
@@ -1772,161 +1743,15 @@ type DebouncedFunctionDerivationLogicConfig = FunctionDerivationBase & Debounced
|
|
|
1772
1743
|
* @public
|
|
1773
1744
|
*/
|
|
1774
1745
|
type DerivationLogicConfig = OnChangeHttpDerivationLogicConfig | DebouncedHttpDerivationLogicConfig | OnChangeAsyncFunctionDerivationLogicConfig | DebouncedAsyncFunctionDerivationLogicConfig | OnChangeExpressionDerivationLogicConfig | DebouncedExpressionDerivationLogicConfig | OnChangeValueDerivationLogicConfig | DebouncedValueDerivationLogicConfig | OnChangeFunctionDerivationLogicConfig | DebouncedFunctionDerivationLogicConfig;
|
|
1775
|
-
/**
|
|
1776
|
-
* Base configuration for property derivation logic.
|
|
1777
|
-
*
|
|
1778
|
-
* Property derivations compute values for field properties (like `minDate`, `options`,
|
|
1779
|
-
* `label`, `placeholder`) based on form values and external data. Unlike value derivations
|
|
1780
|
-
* which set the field's value, property derivations update component input properties.
|
|
1781
|
-
*
|
|
1782
|
-
* All property derivations are self-targeting: the logic is placed on the field whose
|
|
1783
|
-
* property should be derived.
|
|
1784
|
-
*
|
|
1785
|
-
* @internal
|
|
1786
|
-
*/
|
|
1787
|
-
interface BasePropertyDerivationLogicConfig {
|
|
1788
|
-
/**
|
|
1789
|
-
* Logic type identifier for property derivation.
|
|
1790
|
-
*/
|
|
1791
|
-
type: 'propertyDerivation';
|
|
1792
|
-
/**
|
|
1793
|
-
* The target property to set on the field component.
|
|
1794
|
-
*
|
|
1795
|
-
* **Depth limit (max 2 levels):** Only simple and single-dot-nested paths are
|
|
1796
|
-
* supported. Paths with 2+ dots (e.g., `'a.b.c'`) will throw a `DynamicFormError`
|
|
1797
|
-
* at runtime. This is an architectural constraint of the override merging strategy.
|
|
1798
|
-
*
|
|
1799
|
-
* Supported formats:
|
|
1800
|
-
* - Simple: `'minDate'`, `'options'`, `'label'`, `'placeholder'`
|
|
1801
|
-
* - Nested (1 dot): `'props.appearance'`, `'meta.autocomplete'`
|
|
1802
|
-
*
|
|
1803
|
-
* **Note:** There is no compile-time validation that the property name matches
|
|
1804
|
-
* an actual input on the field component. Typos will silently write to the
|
|
1805
|
-
* override store with no visible effect. A dev-mode warning is emitted when
|
|
1806
|
-
* the override key doesn't match any existing input property.
|
|
1807
|
-
*
|
|
1808
|
-
* @example
|
|
1809
|
-
* ```typescript
|
|
1810
|
-
* targetProperty: 'minDate' // ✅ Simple property
|
|
1811
|
-
* targetProperty: 'options' // ✅ Simple property
|
|
1812
|
-
* targetProperty: 'props.appearance' // ✅ Single-nested property
|
|
1813
|
-
* targetProperty: 'a.b.c' // ❌ Throws DynamicFormError (too deep)
|
|
1814
|
-
* ```
|
|
1815
|
-
*/
|
|
1816
|
-
targetProperty: string;
|
|
1817
|
-
/**
|
|
1818
|
-
* Optional name for this derivation for debugging purposes.
|
|
1819
|
-
*
|
|
1820
|
-
* When provided, this name appears in property derivation debug logs.
|
|
1821
|
-
*/
|
|
1822
|
-
debugName?: string;
|
|
1823
|
-
/**
|
|
1824
|
-
* Condition that determines when this property derivation applies.
|
|
1825
|
-
*
|
|
1826
|
-
* Defaults to `true` (always apply).
|
|
1827
|
-
*
|
|
1828
|
-
* Note: FormStateCondition is not supported for property derivations.
|
|
1829
|
-
*/
|
|
1830
|
-
condition?: ConditionalExpression | boolean;
|
|
1831
|
-
/**
|
|
1832
|
-
* Static value to set on the target property.
|
|
1833
|
-
*
|
|
1834
|
-
* Mutually exclusive with `expression` and `functionName`.
|
|
1835
|
-
*/
|
|
1836
|
-
value?: unknown;
|
|
1837
|
-
/**
|
|
1838
|
-
* JavaScript expression to evaluate for the derived property value.
|
|
1839
|
-
*
|
|
1840
|
-
* Has access to `formValue` object containing all form values.
|
|
1841
|
-
* For array fields, `formValue` is scoped to the current array item.
|
|
1842
|
-
*
|
|
1843
|
-
* Mutually exclusive with `value` and `functionName`.
|
|
1844
|
-
*
|
|
1845
|
-
* @example
|
|
1846
|
-
* ```typescript
|
|
1847
|
-
* expression: 'formValue.startDate'
|
|
1848
|
-
* expression: 'formValue.quantity > 10 ? "bulk" : "standard"'
|
|
1849
|
-
* ```
|
|
1850
|
-
*/
|
|
1851
|
-
expression?: string;
|
|
1852
|
-
/**
|
|
1853
|
-
* Name of a registered custom property derivation function.
|
|
1854
|
-
*
|
|
1855
|
-
* Register functions in `customFnConfig.propertyDerivations`.
|
|
1856
|
-
* Mutually exclusive with `value` and `expression`.
|
|
1857
|
-
*/
|
|
1858
|
-
functionName?: string;
|
|
1859
|
-
/**
|
|
1860
|
-
* Explicit field dependencies for property derivations.
|
|
1861
|
-
*
|
|
1862
|
-
* When using `functionName`, you can optionally specify which fields
|
|
1863
|
-
* the function depends on. If not provided with `functionName`, defaults
|
|
1864
|
-
* to all fields ('*').
|
|
1865
|
-
* For `expression`, dependencies are automatically extracted.
|
|
1866
|
-
* For `value`, no dependencies are needed (static value).
|
|
1867
|
-
*/
|
|
1868
|
-
dependsOn?: string[];
|
|
1869
|
-
}
|
|
1870
|
-
/**
|
|
1871
|
-
* Property derivation that evaluates immediately on change (default).
|
|
1872
|
-
*
|
|
1873
|
-
* @internal
|
|
1874
|
-
*/
|
|
1875
|
-
interface OnChangePropertyDerivationLogicConfig extends BasePropertyDerivationLogicConfig {
|
|
1876
|
-
/**
|
|
1877
|
-
* Trigger for immediate evaluation.
|
|
1878
|
-
* @default 'onChange'
|
|
1879
|
-
*/
|
|
1880
|
-
trigger?: 'onChange';
|
|
1881
|
-
/** Not allowed for onChange trigger */
|
|
1882
|
-
debounceMs?: never;
|
|
1883
|
-
}
|
|
1884
|
-
/**
|
|
1885
|
-
* Property derivation that evaluates after a debounce period.
|
|
1886
|
-
*
|
|
1887
|
-
* @internal
|
|
1888
|
-
*/
|
|
1889
|
-
interface DebouncedPropertyDerivationLogicConfig extends BasePropertyDerivationLogicConfig {
|
|
1890
|
-
/**
|
|
1891
|
-
* Trigger for debounced evaluation.
|
|
1892
|
-
*/
|
|
1893
|
-
trigger: 'debounced';
|
|
1894
|
-
/**
|
|
1895
|
-
* Debounce duration in milliseconds.
|
|
1896
|
-
* @default 500
|
|
1897
|
-
*/
|
|
1898
|
-
debounceMs?: number;
|
|
1899
|
-
}
|
|
1900
|
-
/**
|
|
1901
|
-
* Configuration for property derivation logic.
|
|
1902
|
-
*
|
|
1903
|
-
* @deprecated Use `DerivationLogicConfig` with `targetProperty` instead.
|
|
1904
|
-
* The unified `type: 'derivation'` with `targetProperty` provides the same
|
|
1905
|
-
* functionality with a simpler API surface.
|
|
1906
|
-
*
|
|
1907
|
-
* ```typescript
|
|
1908
|
-
* // Before (deprecated)
|
|
1909
|
-
* { type: 'propertyDerivation', targetProperty: 'minDate', expression: '...' }
|
|
1910
|
-
*
|
|
1911
|
-
* // After (preferred)
|
|
1912
|
-
* { type: 'derivation', targetProperty: 'minDate', expression: '...' }
|
|
1913
|
-
* ```
|
|
1914
|
-
*
|
|
1915
|
-
* Will be removed in a future minor version.
|
|
1916
|
-
*
|
|
1917
|
-
* @public
|
|
1918
|
-
*/
|
|
1919
|
-
type PropertyDerivationLogicConfig = OnChangePropertyDerivationLogicConfig | DebouncedPropertyDerivationLogicConfig;
|
|
1920
1746
|
/**
|
|
1921
1747
|
* Union type for all logic configurations.
|
|
1922
1748
|
*
|
|
1923
1749
|
* - `StateLogicConfig`: For field state changes (hidden, readonly, disabled, required)
|
|
1924
|
-
* - `DerivationLogicConfig`: For value derivation
|
|
1925
|
-
* - `PropertyDerivationLogicConfig`: For property derivation
|
|
1750
|
+
* - `DerivationLogicConfig`: For value derivation (including property derivation via `targetProperty`)
|
|
1926
1751
|
*
|
|
1927
1752
|
* @public
|
|
1928
1753
|
*/
|
|
1929
|
-
type LogicConfig = StateLogicConfig | DerivationLogicConfig
|
|
1754
|
+
type LogicConfig = StateLogicConfig | DerivationLogicConfig;
|
|
1930
1755
|
/**
|
|
1931
1756
|
* Log level for derivation debug output.
|
|
1932
1757
|
*
|
|
@@ -1946,18 +1771,6 @@ type DerivationLogLevel = 'none' | 'summary' | 'verbose';
|
|
|
1946
1771
|
* @public
|
|
1947
1772
|
*/
|
|
1948
1773
|
declare function isFormStateCondition(condition: StateLogicConfig['condition'] | DerivationLogicConfig['condition']): condition is FormStateCondition;
|
|
1949
|
-
/**
|
|
1950
|
-
* Type guard to check if a logic config is a PropertyDerivationLogicConfig.
|
|
1951
|
-
*
|
|
1952
|
-
* @deprecated Use `isDerivationLogicConfig(config) && hasTargetProperty(config)` instead.
|
|
1953
|
-
* Will be removed in a future minor version.
|
|
1954
|
-
*
|
|
1955
|
-
* @param config - The logic config to check
|
|
1956
|
-
* @returns true if the config is for property derivation
|
|
1957
|
-
*
|
|
1958
|
-
* @public
|
|
1959
|
-
*/
|
|
1960
|
-
declare function isPropertyDerivationLogicConfig(config: LogicConfig): config is PropertyDerivationLogicConfig;
|
|
1961
1774
|
|
|
1962
1775
|
/**
|
|
1963
1776
|
* Interface for dynamic forms logger implementations.
|
|
@@ -2362,19 +2175,36 @@ type MaybeOptional<T, V> = T extends {
|
|
|
2362
2175
|
} ? V : T extends {
|
|
2363
2176
|
required: true;
|
|
2364
2177
|
} ? V : V | undefined;
|
|
2178
|
+
/**
|
|
2179
|
+
* Infers the value type from a single template field (for primitive arrays).
|
|
2180
|
+
* Mirrors InferValueType logic: slider → number, input[number] → number, else string.
|
|
2181
|
+
*/
|
|
2182
|
+
type InferSingleTemplateValue<T, D extends number> = T extends {
|
|
2183
|
+
type: 'slider';
|
|
2184
|
+
} ? number : T extends {
|
|
2185
|
+
type: 'input';
|
|
2186
|
+
props: {
|
|
2187
|
+
type: 'number';
|
|
2188
|
+
};
|
|
2189
|
+
} ? number : T extends {
|
|
2190
|
+
type: 'checkbox' | 'toggle';
|
|
2191
|
+
} ? boolean : T extends {
|
|
2192
|
+
value: infer V;
|
|
2193
|
+
} ? Widen<V, Depth[D]> : string;
|
|
2365
2194
|
/**
|
|
2366
2195
|
* Infers the value type for an array field.
|
|
2367
|
-
* Handles
|
|
2196
|
+
* Handles four cases:
|
|
2368
2197
|
* 1. Simplified array with template + value → infer item type from value
|
|
2369
|
-
* 2. Simplified array with template
|
|
2370
|
-
* 3.
|
|
2198
|
+
* 2. Simplified array with array template (no value) → infer object type from template fields
|
|
2199
|
+
* 3. Simplified array with single-field template (no value) → infer primitive type from template field
|
|
2200
|
+
* 4. Full-API array with fields → infer from children
|
|
2371
2201
|
*/
|
|
2372
2202
|
type InferArrayValue<T, D extends number> = T extends {
|
|
2373
2203
|
template: unknown;
|
|
2374
2204
|
value: readonly (infer Item)[];
|
|
2375
2205
|
} ? Widen<Item>[] : T extends {
|
|
2376
|
-
template:
|
|
2377
|
-
} ?
|
|
2206
|
+
template: infer TArr;
|
|
2207
|
+
} ? TArr extends readonly RegisteredFieldTypes[] ? InferFormValueWithDepth<[...TArr], Depth[D]>[] : InferSingleTemplateValue<TArr, D>[] : T extends {
|
|
2378
2208
|
fields: infer F;
|
|
2379
2209
|
} ? F extends RegisteredFieldTypes[] ? InferFormValueWithDepth<F, Depth[D]>[] : unknown[] : unknown[];
|
|
2380
2210
|
/**
|
|
@@ -2457,11 +2287,11 @@ type InferFormValue$1<T> = ExtractFields<T> extends readonly RegisteredFieldType
|
|
|
2457
2287
|
*/
|
|
2458
2288
|
interface HttpValidationResponseMapping {
|
|
2459
2289
|
/**
|
|
2460
|
-
* Expression evaluated with scope `{ response }`.
|
|
2290
|
+
* Expression evaluated with scope `{ response }`. Must evaluate to `true` (strict boolean) to be valid.
|
|
2461
2291
|
*
|
|
2462
2292
|
* NOTE: This is the OPPOSITE of the function-based HttpCustomValidator.onSuccess
|
|
2463
2293
|
* convention, which maps successful HTTP responses to validation errors.
|
|
2464
|
-
* Here,
|
|
2294
|
+
* Here, `=== true` means "validation passed". Non-boolean results are treated as invalid and trigger a warning.
|
|
2465
2295
|
*/
|
|
2466
2296
|
validWhen: string;
|
|
2467
2297
|
/** Error kind returned when validation fails — maps to field-level `validationMessages` */
|
|
@@ -2527,16 +2357,10 @@ interface CustomValidatorConfig extends BaseValidatorConfig {
|
|
|
2527
2357
|
* Async custom validator configuration using Angular's validateAsync API.
|
|
2528
2358
|
* Returns Observable<ValidationError | ValidationError[] | null>.
|
|
2529
2359
|
*
|
|
2530
|
-
* Accepts both `'async'` (preferred) and `'customAsync'` (deprecated) type literals.
|
|
2531
2360
|
*/
|
|
2532
2361
|
interface AsyncValidatorConfig extends BaseValidatorConfig {
|
|
2533
|
-
/**
|
|
2534
|
-
|
|
2535
|
-
*
|
|
2536
|
-
* Use `'async'` for new code. `'customAsync'` is accepted for backward compatibility
|
|
2537
|
-
* but emits a deprecation warning in dev mode.
|
|
2538
|
-
*/
|
|
2539
|
-
type: 'async' | 'customAsync';
|
|
2362
|
+
/** Validator type identifier. */
|
|
2363
|
+
type: 'async';
|
|
2540
2364
|
/** Name of registered async validator function */
|
|
2541
2365
|
functionName: string;
|
|
2542
2366
|
/** Optional parameters to pass to validator function */
|
|
@@ -2550,28 +2374,15 @@ interface AsyncValidatorConfig extends BaseValidatorConfig {
|
|
|
2550
2374
|
*
|
|
2551
2375
|
* Discriminated from `DeclarativeHttpValidatorConfig` by the presence of `functionName`.
|
|
2552
2376
|
*
|
|
2553
|
-
* Accepts both `'http'` (preferred) and `'customHttp'` (deprecated) type literals.
|
|
2554
|
-
*
|
|
2555
|
-
* @deprecated Prefer `DeclarativeHttpValidatorConfig` (`type: 'http'` with `http` + `responseMapping`)
|
|
2556
|
-
* for fully JSON-serializable validation. Use this form only when function registration is required.
|
|
2557
2377
|
*/
|
|
2558
2378
|
interface FunctionHttpValidatorConfig extends BaseValidatorConfig {
|
|
2559
|
-
/**
|
|
2560
|
-
|
|
2561
|
-
*
|
|
2562
|
-
* Use `'http'` for new code. `'customHttp'` is accepted for backward compatibility
|
|
2563
|
-
* but emits a deprecation warning in dev mode.
|
|
2564
|
-
*/
|
|
2565
|
-
type: 'http' | 'customHttp';
|
|
2379
|
+
/** Validator type identifier. */
|
|
2380
|
+
type: 'http';
|
|
2566
2381
|
/** Name of registered HTTP validator configuration */
|
|
2567
2382
|
functionName: string;
|
|
2568
2383
|
/** Optional parameters to pass to HTTP validator */
|
|
2569
2384
|
params?: Record<string, unknown>;
|
|
2570
2385
|
}
|
|
2571
|
-
/**
|
|
2572
|
-
* @deprecated Use `FunctionHttpValidatorConfig` instead. Will be removed in a future minor version.
|
|
2573
|
-
*/
|
|
2574
|
-
type HttpValidatorConfig = FunctionHttpValidatorConfig;
|
|
2575
2386
|
/**
|
|
2576
2387
|
* Declarative HTTP validator configuration — fully JSON-serializable, no function registration required.
|
|
2577
2388
|
*
|
|
@@ -2963,7 +2774,7 @@ type FormFieldStateMap = Record<string, FieldStateInfo | undefined>;
|
|
|
2963
2774
|
*/
|
|
2964
2775
|
type FieldStateContext = FieldStateInfo;
|
|
2965
2776
|
|
|
2966
|
-
interface EvaluationContext<TValue = unknown> {
|
|
2777
|
+
interface EvaluationContext<TValue = unknown, TFormValue extends Record<string, unknown> = any> {
|
|
2967
2778
|
/** Current field value */
|
|
2968
2779
|
fieldValue: TValue;
|
|
2969
2780
|
/**
|
|
@@ -2973,7 +2784,7 @@ interface EvaluationContext<TValue = unknown> {
|
|
|
2973
2784
|
* For array item derivations, this is scoped to the current array item.
|
|
2974
2785
|
* Use `rootFormValue` to access the complete form when inside an array context.
|
|
2975
2786
|
*/
|
|
2976
|
-
formValue:
|
|
2787
|
+
formValue: TFormValue;
|
|
2977
2788
|
/** Field path for relative references */
|
|
2978
2789
|
fieldPath: string;
|
|
2979
2790
|
/** Custom evaluation functions */
|
|
@@ -3114,7 +2925,7 @@ interface EvaluationContext<TValue = unknown> {
|
|
|
3114
2925
|
* };
|
|
3115
2926
|
* ```
|
|
3116
2927
|
*/
|
|
3117
|
-
type CustomFunction = (context: EvaluationContext) => unknown;
|
|
2928
|
+
type CustomFunction<TFormValue extends Record<string, unknown> = any> = (context: EvaluationContext<unknown, TFormValue>) => unknown;
|
|
3118
2929
|
|
|
3119
2930
|
/**
|
|
3120
2931
|
* Async function for derivations — returns any value.
|
|
@@ -3133,7 +2944,7 @@ type CustomFunction = (context: EvaluationContext) => unknown;
|
|
|
3133
2944
|
*
|
|
3134
2945
|
* @public
|
|
3135
2946
|
*/
|
|
3136
|
-
type AsyncDerivationFunction = (context: EvaluationContext) => Promise<unknown> | Observable<unknown>;
|
|
2947
|
+
type AsyncDerivationFunction<TFormValue extends Record<string, unknown> = any> = (context: EvaluationContext<unknown, TFormValue>) => Promise<unknown> | Observable<unknown>;
|
|
3137
2948
|
/**
|
|
3138
2949
|
* Async function for conditions — returns boolean.
|
|
3139
2950
|
*
|
|
@@ -3151,7 +2962,7 @@ type AsyncDerivationFunction = (context: EvaluationContext) => Promise<unknown>
|
|
|
3151
2962
|
*
|
|
3152
2963
|
* @public
|
|
3153
2964
|
*/
|
|
3154
|
-
type AsyncConditionFunction = (context: EvaluationContext) => Promise<boolean> | Observable<boolean>;
|
|
2965
|
+
type AsyncConditionFunction<TFormValue extends Record<string, unknown> = any> = (context: EvaluationContext<unknown, TFormValue>) => Promise<boolean> | Observable<boolean>;
|
|
3155
2966
|
|
|
3156
2967
|
/**
|
|
3157
2968
|
* Re-export Angular's ValidationError for consistency
|
|
@@ -3416,7 +3227,7 @@ interface FormConfig<TFields extends NarrowFields | RegisteredFieldTypes[] = Reg
|
|
|
3416
3227
|
/**
|
|
3417
3228
|
* Signal forms adapter configuration.
|
|
3418
3229
|
*/
|
|
3419
|
-
customFnConfig?: CustomFnConfig
|
|
3230
|
+
customFnConfig?: CustomFnConfig<TValue extends Record<string, unknown> ? TValue : Record<string, unknown>>;
|
|
3420
3231
|
/**
|
|
3421
3232
|
* Form submission configuration.
|
|
3422
3233
|
*
|
|
@@ -3571,7 +3382,7 @@ interface FormConfig<TFields extends NarrowFields | RegisteredFieldTypes[] = Reg
|
|
|
3571
3382
|
*
|
|
3572
3383
|
* @public
|
|
3573
3384
|
*/
|
|
3574
|
-
interface CustomFnConfig {
|
|
3385
|
+
interface CustomFnConfig<TFormValue extends Record<string, unknown> = Record<string, unknown>> {
|
|
3575
3386
|
/**
|
|
3576
3387
|
* Custom evaluation functions for conditional expressions.
|
|
3577
3388
|
*
|
|
@@ -3589,7 +3400,7 @@ interface CustomFnConfig {
|
|
|
3589
3400
|
* }
|
|
3590
3401
|
* ```
|
|
3591
3402
|
*/
|
|
3592
|
-
customFunctions?: Record<string, CustomFunction
|
|
3403
|
+
customFunctions?: Record<string, CustomFunction<TFormValue>>;
|
|
3593
3404
|
/**
|
|
3594
3405
|
* Custom derivation functions for value derivation logic.
|
|
3595
3406
|
*
|
|
@@ -3657,50 +3468,7 @@ interface CustomFnConfig {
|
|
|
3657
3468
|
* }
|
|
3658
3469
|
* ```
|
|
3659
3470
|
*/
|
|
3660
|
-
derivations?: Record<string, CustomFunction
|
|
3661
|
-
/**
|
|
3662
|
-
* @deprecated Register functions under `derivations` instead. Use `type: 'derivation'`
|
|
3663
|
-
* with `targetProperty` in field logic configs. Will be removed in a future minor version.
|
|
3664
|
-
*
|
|
3665
|
-
* Custom property derivation functions for reactive property updates.
|
|
3666
|
-
*
|
|
3667
|
-
* These functions compute derived values for field properties (like `minDate`,
|
|
3668
|
-
* `options`, `label`, `placeholder`) and are called when a
|
|
3669
|
-
* `PropertyDerivationLogicConfig` references them by `functionName`.
|
|
3670
|
-
*
|
|
3671
|
-
* Property derivation functions:
|
|
3672
|
-
* - Receive an `EvaluationContext` with access to `formValue`
|
|
3673
|
-
* - Return the value to set on the target property
|
|
3674
|
-
* - Are called reactively when dependencies change
|
|
3675
|
-
*
|
|
3676
|
-
* @example
|
|
3677
|
-
* ```typescript
|
|
3678
|
-
* propertyDerivations: {
|
|
3679
|
-
* getCitiesForCountry: (context) => {
|
|
3680
|
-
* const countryCities: Record<string, Array<{ label: string; value: string }>> = {
|
|
3681
|
-
* 'USA': [{ label: 'New York', value: 'ny' }, { label: 'LA', value: 'la' }],
|
|
3682
|
-
* 'Germany': [{ label: 'Berlin', value: 'berlin' }, { label: 'Munich', value: 'munich' }],
|
|
3683
|
-
* };
|
|
3684
|
-
* return countryCities[context.formValue.country as string] ?? [];
|
|
3685
|
-
* },
|
|
3686
|
-
* }
|
|
3687
|
-
* ```
|
|
3688
|
-
*
|
|
3689
|
-
* Field configuration using a property derivation function:
|
|
3690
|
-
* ```typescript
|
|
3691
|
-
* {
|
|
3692
|
-
* key: 'city',
|
|
3693
|
-
* type: 'select',
|
|
3694
|
-
* logic: [{
|
|
3695
|
-
* type: 'propertyDerivation',
|
|
3696
|
-
* targetProperty: 'options',
|
|
3697
|
-
* functionName: 'getCitiesForCountry',
|
|
3698
|
-
* dependsOn: ['country']
|
|
3699
|
-
* }]
|
|
3700
|
-
* }
|
|
3701
|
-
* ```
|
|
3702
|
-
*/
|
|
3703
|
-
propertyDerivations?: Record<string, CustomFunction>;
|
|
3471
|
+
derivations?: Record<string, CustomFunction<TFormValue>>;
|
|
3704
3472
|
/**
|
|
3705
3473
|
* Async derivation functions for asynchronous value derivation logic.
|
|
3706
3474
|
*
|
|
@@ -3730,7 +3498,7 @@ interface CustomFnConfig {
|
|
|
3730
3498
|
* }
|
|
3731
3499
|
* ```
|
|
3732
3500
|
*/
|
|
3733
|
-
asyncDerivations?: Record<string, AsyncDerivationFunction
|
|
3501
|
+
asyncDerivations?: Record<string, AsyncDerivationFunction<TFormValue>>;
|
|
3734
3502
|
/**
|
|
3735
3503
|
* Async condition functions for asynchronous field state logic.
|
|
3736
3504
|
*
|
|
@@ -3754,7 +3522,7 @@ interface CustomFnConfig {
|
|
|
3754
3522
|
* }
|
|
3755
3523
|
* ```
|
|
3756
3524
|
*/
|
|
3757
|
-
asyncConditions?: Record<string, AsyncConditionFunction
|
|
3525
|
+
asyncConditions?: Record<string, AsyncConditionFunction<TFormValue>>;
|
|
3758
3526
|
/**
|
|
3759
3527
|
* Custom validators using Angular's public FieldContext API
|
|
3760
3528
|
*
|
|
@@ -3872,72 +3640,18 @@ interface CustomFnConfig {
|
|
|
3872
3640
|
*/
|
|
3873
3641
|
asyncValidators?: Record<string, AsyncCustomValidator>;
|
|
3874
3642
|
/**
|
|
3875
|
-
*
|
|
3876
|
-
* in the validators array. Function-based HTTP validators now also use `type: 'http'` with `functionName`.
|
|
3877
|
-
* Will be removed in a future minor version.
|
|
3878
|
-
*
|
|
3879
|
-
* HTTP validators using Angular's validateHttp() API
|
|
3880
|
-
*
|
|
3881
|
-
* Angular's validateHttp provides HTTP validation with automatic request
|
|
3882
|
-
* cancellation and integration with the resource API.
|
|
3883
|
-
*
|
|
3884
|
-
* **Structure:**
|
|
3885
|
-
* - `request`: Function that returns URL string or HttpResourceRequest
|
|
3886
|
-
* - `onSuccess`: REQUIRED - Maps HTTP response to validation errors (inverted logic!)
|
|
3887
|
-
* - `onError`: Optional handler for HTTP errors
|
|
3888
|
-
*
|
|
3889
|
-
* **Benefits:**
|
|
3890
|
-
* - Automatic request cancellation when field value changes
|
|
3891
|
-
* - Built-in integration with Angular's resource management
|
|
3892
|
-
* - Simpler than asyncValidators for HTTP use cases
|
|
3643
|
+
* HTTP validators using Angular's validateHttp() API.
|
|
3893
3644
|
*
|
|
3894
|
-
*
|
|
3895
|
-
*
|
|
3896
|
-
*
|
|
3645
|
+
* For function-based HTTP validation with automatic request cancellation.
|
|
3646
|
+
* Prefer declarative HTTP validators (`type: 'http'` with `http` + `responseMapping`)
|
|
3647
|
+
* for fully JSON-serializable validation when possible.
|
|
3897
3648
|
*
|
|
3898
|
-
* @example
|
|
3649
|
+
* @example
|
|
3899
3650
|
* ```typescript
|
|
3900
3651
|
* httpValidators: {
|
|
3901
3652
|
* checkUsername: {
|
|
3902
|
-
* request: (ctx) => {
|
|
3903
|
-
*
|
|
3904
|
-
* if (!username) return undefined; // Skip validation if empty
|
|
3905
|
-
* return `/api/users/check-username?username=${encodeURIComponent(username)}`;
|
|
3906
|
-
* },
|
|
3907
|
-
* onSuccess: (response, ctx) => {
|
|
3908
|
-
* // Inverted logic: successful response may indicate validation failure
|
|
3909
|
-
* return response.available ? null : { kind: 'usernameTaken' };
|
|
3910
|
-
* },
|
|
3911
|
-
* onError: (error, ctx) => {
|
|
3912
|
-
* console.error('Availability check failed:', error);
|
|
3913
|
-
* return null; // Don't block form on network errors
|
|
3914
|
-
* }
|
|
3915
|
-
* }
|
|
3916
|
-
* }
|
|
3917
|
-
* ```
|
|
3918
|
-
*
|
|
3919
|
-
* @example Address Validation (POST with Body)
|
|
3920
|
-
* ```typescript
|
|
3921
|
-
* httpValidators: {
|
|
3922
|
-
* validateAddress: {
|
|
3923
|
-
* request: (ctx) => {
|
|
3924
|
-
* const zipCode = ctx.value();
|
|
3925
|
-
* if (!zipCode) return undefined;
|
|
3926
|
-
*
|
|
3927
|
-
* return {
|
|
3928
|
-
* url: '/api/validate-address',
|
|
3929
|
-
* method: 'POST',
|
|
3930
|
-
* body: {
|
|
3931
|
-
* street: ctx.valueOf('street' as any),
|
|
3932
|
-
* city: ctx.valueOf('city' as any),
|
|
3933
|
-
* zipCode: zipCode
|
|
3934
|
-
* },
|
|
3935
|
-
* headers: { 'Content-Type': 'application/json' }
|
|
3936
|
-
* };
|
|
3937
|
-
* },
|
|
3938
|
-
* onSuccess: (response) => {
|
|
3939
|
-
* return response.valid ? null : { kind: 'invalidAddress' };
|
|
3940
|
-
* }
|
|
3653
|
+
* request: (ctx) => `/api/users/check?username=${encodeURIComponent(ctx.value())}`,
|
|
3654
|
+
* onSuccess: (response) => response.available ? null : { kind: 'usernameTaken' },
|
|
3941
3655
|
* }
|
|
3942
3656
|
* }
|
|
3943
3657
|
* ```
|
|
@@ -4322,17 +4036,13 @@ declare class DynamicForm<TFields extends RegisteredFieldTypes[] = RegisteredFie
|
|
|
4322
4036
|
value: _angular_core.ModelSignal<Partial<TModel> | undefined>;
|
|
4323
4037
|
private destroyRef;
|
|
4324
4038
|
private injector;
|
|
4039
|
+
protected environmentInjector: EnvironmentInjector;
|
|
4325
4040
|
private eventBus;
|
|
4326
4041
|
private logger;
|
|
4327
|
-
|
|
4328
|
-
|
|
4329
|
-
*
|
|
4330
|
-
|
|
4331
|
-
* in computeds/effects, which are all lazy and evaluated after construction.
|
|
4332
|
-
*/
|
|
4333
|
-
private readonly _connectStateDeps;
|
|
4334
|
-
/** State manager that owns all form state. */
|
|
4335
|
-
private stateManager;
|
|
4042
|
+
private dispatcher;
|
|
4043
|
+
/** State manager that owns all form state. Initialized via connectDeps() to guarantee
|
|
4044
|
+
* FORM_STATE_DEPS is populated before FormStateManager is injected. */
|
|
4045
|
+
private readonly stateManager;
|
|
4336
4046
|
private componentId;
|
|
4337
4047
|
/** The currently active config used for form rendering */
|
|
4338
4048
|
activeConfig: Signal<FormConfig<TFields, InferFormValue$1<TFields extends readonly RegisteredFieldTypes[] ? TFields : RegisteredFieldTypes[]>, Record<string, unknown>, unknown> | undefined>;
|
|
@@ -4370,7 +4080,7 @@ declare class DynamicForm<TFields extends RegisteredFieldTypes[] = RegisteredFie
|
|
|
4370
4080
|
/** Whether any form field has been touched (blurred) */
|
|
4371
4081
|
touched: Signal<boolean>;
|
|
4372
4082
|
/** Current validation errors from all fields */
|
|
4373
|
-
errors: Signal<_angular_forms_signals.ValidationError.
|
|
4083
|
+
errors: Signal<_angular_forms_signals.ValidationError.WithFieldTree[]>;
|
|
4374
4084
|
/** Whether the form is disabled (from options or form state) */
|
|
4375
4085
|
disabled: Signal<boolean>;
|
|
4376
4086
|
/** Whether the form is currently submitting */
|
|
@@ -4381,6 +4091,13 @@ declare class DynamicForm<TFields extends RegisteredFieldTypes[] = RegisteredFie
|
|
|
4381
4091
|
shouldRender: Signal<boolean>;
|
|
4382
4092
|
/** Resolved fields ready for rendering */
|
|
4383
4093
|
protected resolvedFields: Signal<ResolvedField[]>;
|
|
4094
|
+
/**
|
|
4095
|
+
* Recursively counts container components that will emit ComponentInitializedEvent.
|
|
4096
|
+
* Includes the dynamic-form component itself (+1).
|
|
4097
|
+
*
|
|
4098
|
+
* Recurses into all container children, including those nested inside array
|
|
4099
|
+
* item templates, to avoid a premature (initialized) emission.
|
|
4100
|
+
*/
|
|
4384
4101
|
private totalComponentsCount;
|
|
4385
4102
|
initialized$: rxjs.Observable<boolean>;
|
|
4386
4103
|
/** Emits when form validity changes. */
|
|
@@ -4426,11 +4143,176 @@ declare class DynamicForm<TFields extends RegisteredFieldTypes[] = RegisteredFie
|
|
|
4426
4143
|
*/
|
|
4427
4144
|
protected onNativeSubmit(event: Event): void;
|
|
4428
4145
|
private setupEffects;
|
|
4146
|
+
/**
|
|
4147
|
+
* Populates FORM_STATE_DEPS with this component's input signals, then injects
|
|
4148
|
+
* FormStateManager. Must be called as a field initializer (after the input signals
|
|
4149
|
+
* are declared) so that FormStateManager reads populated deps when it is constructed.
|
|
4150
|
+
* inject() is valid here because field initializers run inside the injection context.
|
|
4151
|
+
*/
|
|
4152
|
+
private connectDeps;
|
|
4429
4153
|
private setupEventHandlers;
|
|
4430
4154
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<DynamicForm<any, any>, never>;
|
|
4431
4155
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DynamicForm<any, any>, "form[dynamic-form]", never, { "config": { "alias": "dynamic-form"; "required": true; "isSignal": true; }; "formOptions": { "alias": "formOptions"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "validityChange": "validityChange"; "dirtyChange": "dirtyChange"; "submitted": "submitted"; "reset": "reset"; "cleared": "cleared"; "events": "events"; "initialized": "initialized"; "onPageChange": "onPageChange"; "onPageNavigationStateChange": "onPageNavigationStateChange"; }, never, never, true, never>;
|
|
4432
4156
|
}
|
|
4433
4157
|
|
|
4158
|
+
declare class EventBus {
|
|
4159
|
+
private readonly pipeline$;
|
|
4160
|
+
private readonly globalEmitFormValue;
|
|
4161
|
+
private readonly rootFormRegistry;
|
|
4162
|
+
private readonly formOptions;
|
|
4163
|
+
private readonly logger;
|
|
4164
|
+
events$: Observable<FormEvent>;
|
|
4165
|
+
/**
|
|
4166
|
+
* Dispatches a pre-created event instance directly.
|
|
4167
|
+
*
|
|
4168
|
+
* Use this overload with the `arrayEvent()` factory or any other code that
|
|
4169
|
+
* produces a `FormEvent` instance rather than a constructor:
|
|
4170
|
+
*
|
|
4171
|
+
* ```typescript
|
|
4172
|
+
* eventBus.dispatch(arrayEvent('contacts').append(template));
|
|
4173
|
+
* eventBus.dispatch(arrayEvent('contacts').pop());
|
|
4174
|
+
* ```
|
|
4175
|
+
*
|
|
4176
|
+
* @param event - A FormEvent instance to dispatch
|
|
4177
|
+
*/
|
|
4178
|
+
dispatch(event: FormEvent): void;
|
|
4179
|
+
/**
|
|
4180
|
+
* Dispatches an event to all subscribers by instantiating the provided constructor.
|
|
4181
|
+
*
|
|
4182
|
+
* Creates an instance of the provided event constructor and broadcasts it
|
|
4183
|
+
* through the event pipeline to all active subscribers.
|
|
4184
|
+
*
|
|
4185
|
+
* If `withEventFormValue()` is enabled globally or `options.emitFormValueOnEvents`
|
|
4186
|
+
* is set to `true` in the form config, the current form value will be attached
|
|
4187
|
+
* to the event's `formValue` property.
|
|
4188
|
+
*
|
|
4189
|
+
* @param eventConstructor - Constructor function for the event to dispatch
|
|
4190
|
+
* @param args - Arguments to pass to the event constructor
|
|
4191
|
+
*
|
|
4192
|
+
* @example
|
|
4193
|
+
* ```typescript
|
|
4194
|
+
* // Dispatch a submit event
|
|
4195
|
+
* eventBus.dispatch(SubmitEvent);
|
|
4196
|
+
*
|
|
4197
|
+
* // Dispatch a custom event with args
|
|
4198
|
+
* eventBus.dispatch(CustomFormEvent, 'arg1', 42);
|
|
4199
|
+
* ```
|
|
4200
|
+
*/
|
|
4201
|
+
dispatch<T extends FormEventConstructor>(eventConstructor: T, ...args: ConstructorParameters<T>): void;
|
|
4202
|
+
/**
|
|
4203
|
+
* Dispatches a pre-created event instance directly.
|
|
4204
|
+
* Used internally by EventDispatcher to forward events into the bus.
|
|
4205
|
+
* @internal
|
|
4206
|
+
*/
|
|
4207
|
+
emitInstance(event: FormEvent): void;
|
|
4208
|
+
/**
|
|
4209
|
+
* Shared emit path for both dispatch() and emitInstance().
|
|
4210
|
+
* Attaches form value if configured, then pushes to the pipeline.
|
|
4211
|
+
*/
|
|
4212
|
+
private emit;
|
|
4213
|
+
/**
|
|
4214
|
+
* Emits an event through the pipeline. Catches any synchronous exception that escapes
|
|
4215
|
+
* RxJS's own error handling so dispatch() callers are never disrupted by a failing subscriber.
|
|
4216
|
+
*/
|
|
4217
|
+
private safeEmit;
|
|
4218
|
+
/**
|
|
4219
|
+
* Determines whether form value should be attached to events.
|
|
4220
|
+
*
|
|
4221
|
+
* Precedence rules:
|
|
4222
|
+
* 1. Per-form setting (if defined) takes precedence
|
|
4223
|
+
* 2. Falls back to global setting
|
|
4224
|
+
*/
|
|
4225
|
+
private shouldEmitFormValue;
|
|
4226
|
+
/**
|
|
4227
|
+
* Subscribes to events of a specific type.
|
|
4228
|
+
*
|
|
4229
|
+
* @param eventType - The type of event to subscribe to
|
|
4230
|
+
* @returns Observable that emits events of the specified type
|
|
4231
|
+
*/
|
|
4232
|
+
on<T extends FormEvent>(eventType: T['type']): Observable<T>;
|
|
4233
|
+
/**
|
|
4234
|
+
* Subscribes to events of multiple types.
|
|
4235
|
+
*
|
|
4236
|
+
* @param eventType - Array of event types to subscribe to
|
|
4237
|
+
* @returns Observable that emits events matching any of the specified types
|
|
4238
|
+
*/
|
|
4239
|
+
on<T extends FormEvent>(eventType: Array<T['type']>): Observable<T>;
|
|
4240
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<EventBus, never>;
|
|
4241
|
+
static ɵprov: _angular_core.ɵɵInjectableDeclaration<EventBus>;
|
|
4242
|
+
}
|
|
4243
|
+
|
|
4244
|
+
/**
|
|
4245
|
+
* Injectable service for dispatching events into a DynamicForm from outside the form.
|
|
4246
|
+
*
|
|
4247
|
+
* ## When to use
|
|
4248
|
+
*
|
|
4249
|
+
* Use `EventDispatcher` when you need to drive form behaviour **from the host component** —
|
|
4250
|
+
* for example, appending array items in response to a field value change, triggering a form
|
|
4251
|
+
* reset from a toolbar button, or reacting to external application state.
|
|
4252
|
+
*
|
|
4253
|
+
* This is the recommended alternative to accessing the form's internals via `viewChild`.
|
|
4254
|
+
*
|
|
4255
|
+
* ## Setup
|
|
4256
|
+
*
|
|
4257
|
+
* Provide `EventDispatcher` at the **host component** level (not root). DynamicForm
|
|
4258
|
+
* automatically detects it and connects its internal event bus to the dispatcher.
|
|
4259
|
+
*
|
|
4260
|
+
* ```typescript
|
|
4261
|
+
* @Component({
|
|
4262
|
+
* providers: [EventDispatcher],
|
|
4263
|
+
* template: `<form [dynamic-form]="config" [(value)]="formValue"></form>`
|
|
4264
|
+
* })
|
|
4265
|
+
* export class MyComponent {
|
|
4266
|
+
* readonly dispatcher = inject(EventDispatcher);
|
|
4267
|
+
* readonly formValue = signal<Record<string, unknown>>({});
|
|
4268
|
+
*
|
|
4269
|
+
* constructor() {
|
|
4270
|
+
* effect(() => {
|
|
4271
|
+
* const category = this.formValue()?.['category'] as string | undefined;
|
|
4272
|
+
* if (category) {
|
|
4273
|
+
* this.dispatcher.dispatch(
|
|
4274
|
+
* arrayEvent('tasks').append([{ key: 'name', type: 'input', label: 'Task', value: category }])
|
|
4275
|
+
* );
|
|
4276
|
+
* }
|
|
4277
|
+
* });
|
|
4278
|
+
* }
|
|
4279
|
+
* }
|
|
4280
|
+
* ```
|
|
4281
|
+
*
|
|
4282
|
+
* ## Multi-form note
|
|
4283
|
+
*
|
|
4284
|
+
* If multiple `DynamicForm` instances exist under the same provider scope, **all forms**
|
|
4285
|
+
* will receive dispatched events. To target a specific form, scope the provider to a
|
|
4286
|
+
* wrapper component that contains only that form.
|
|
4287
|
+
*
|
|
4288
|
+
* ## What events can be dispatched
|
|
4289
|
+
*
|
|
4290
|
+
* Any `FormEvent` instance is accepted — array events, reset/clear events, custom events, etc.
|
|
4291
|
+
* The `arrayEvent()` builder is the recommended way to construct array manipulation events:
|
|
4292
|
+
*
|
|
4293
|
+
* ```typescript
|
|
4294
|
+
* dispatcher.dispatch(arrayEvent('tasks').append(template));
|
|
4295
|
+
* dispatcher.dispatch(arrayEvent('tasks').removeAt(0));
|
|
4296
|
+
* dispatcher.dispatch(new FormResetEvent());
|
|
4297
|
+
* ```
|
|
4298
|
+
*/
|
|
4299
|
+
declare class EventDispatcher {
|
|
4300
|
+
private bus;
|
|
4301
|
+
/**
|
|
4302
|
+
* Dispatches a form event into the connected DynamicForm's event bus.
|
|
4303
|
+
* No-op if no form is currently connected.
|
|
4304
|
+
*
|
|
4305
|
+
* @param event - A FormEvent instance. Use the `arrayEvent()` builder for array operations.
|
|
4306
|
+
*/
|
|
4307
|
+
dispatch(event: FormEvent): void;
|
|
4308
|
+
/** @internal - Called by DynamicForm on init */
|
|
4309
|
+
connect(bus: EventBus): void;
|
|
4310
|
+
/** @internal - Called by DynamicForm on destroy */
|
|
4311
|
+
disconnect(): void;
|
|
4312
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<EventDispatcher, never>;
|
|
4313
|
+
static ɵprov: _angular_core.ɵɵInjectableDeclaration<EventDispatcher>;
|
|
4314
|
+
}
|
|
4315
|
+
|
|
4434
4316
|
/**
|
|
4435
4317
|
* Base interface for dynamic form features.
|
|
4436
4318
|
* Features are configuration options that can be passed to provideDynamicForm
|
|
@@ -5444,92 +5326,6 @@ declare function arrayEvent(arrayKey: string): {
|
|
|
5444
5326
|
removeAt: (index: number) => RemoveAtIndexEvent;
|
|
5445
5327
|
};
|
|
5446
5328
|
|
|
5447
|
-
/**
|
|
5448
|
-
* Event bus service for form-wide event communication.
|
|
5449
|
-
*
|
|
5450
|
-
* Provides type-safe event dispatching and subscription for form components
|
|
5451
|
-
* to communicate without direct coupling. Uses RxJS observables for reactive
|
|
5452
|
-
* event handling and supports both single event type and multiple event type subscriptions.
|
|
5453
|
-
*
|
|
5454
|
-
* @example
|
|
5455
|
-
* ```typescript
|
|
5456
|
-
* @Component({
|
|
5457
|
-
* providers: [EventBus]
|
|
5458
|
-
* })
|
|
5459
|
-
* export class MyFormComponent {
|
|
5460
|
-
* constructor(private eventBus: EventBus) {
|
|
5461
|
-
* // Subscribe to form submission events
|
|
5462
|
-
* this.eventBus.on<SubmitEvent>('submit').subscribe(() => {
|
|
5463
|
-
* console.log('Form was submitted');
|
|
5464
|
-
* });
|
|
5465
|
-
*
|
|
5466
|
-
* // Subscribe to multiple event types
|
|
5467
|
-
* this.eventBus.on<SubmitEvent | FormResetEvent>(['submit', 'form-reset']).subscribe(event => {
|
|
5468
|
-
* console.log('Form event:', event.type);
|
|
5469
|
-
* });
|
|
5470
|
-
* }
|
|
5471
|
-
*
|
|
5472
|
-
* onSubmit() {
|
|
5473
|
-
* // Dispatch a submit event
|
|
5474
|
-
* this.eventBus.dispatch(SubmitEvent);
|
|
5475
|
-
* }
|
|
5476
|
-
* }
|
|
5477
|
-
* ```
|
|
5478
|
-
*/
|
|
5479
|
-
declare class EventBus {
|
|
5480
|
-
private readonly pipeline$;
|
|
5481
|
-
private readonly globalEmitFormValue;
|
|
5482
|
-
private readonly rootFormRegistry;
|
|
5483
|
-
private readonly formOptions;
|
|
5484
|
-
events$: Observable<FormEvent>;
|
|
5485
|
-
/**
|
|
5486
|
-
* Dispatches an event to all subscribers.
|
|
5487
|
-
*
|
|
5488
|
-
* Creates an instance of the provided event constructor and broadcasts it
|
|
5489
|
-
* through the event pipeline to all active subscribers.
|
|
5490
|
-
*
|
|
5491
|
-
* If `withEventFormValue()` is enabled globally or `options.emitFormValueOnEvents`
|
|
5492
|
-
* is set to `true` in the form config, the current form value will be attached
|
|
5493
|
-
* to the event's `formValue` property.
|
|
5494
|
-
*
|
|
5495
|
-
* @param eventConstructor - Constructor function for the event to dispatch
|
|
5496
|
-
*
|
|
5497
|
-
* @example
|
|
5498
|
-
* ```typescript
|
|
5499
|
-
* // Dispatch a submit event
|
|
5500
|
-
* eventBus.dispatch(SubmitEvent);
|
|
5501
|
-
*
|
|
5502
|
-
* // Dispatch a custom event
|
|
5503
|
-
* eventBus.dispatch(CustomFormEvent);
|
|
5504
|
-
* ```
|
|
5505
|
-
*/
|
|
5506
|
-
dispatch<T extends FormEventConstructor>(eventConstructor: T, ...args: ConstructorParameters<T>): void;
|
|
5507
|
-
/**
|
|
5508
|
-
* Determines whether form value should be attached to events.
|
|
5509
|
-
*
|
|
5510
|
-
* Precedence rules:
|
|
5511
|
-
* 1. Per-form setting (if defined) takes precedence
|
|
5512
|
-
* 2. Falls back to global setting
|
|
5513
|
-
*/
|
|
5514
|
-
private shouldEmitFormValue;
|
|
5515
|
-
/**
|
|
5516
|
-
* Subscribes to events of a specific type.
|
|
5517
|
-
*
|
|
5518
|
-
* @param eventType - The type of event to subscribe to
|
|
5519
|
-
* @returns Observable that emits events of the specified type
|
|
5520
|
-
*/
|
|
5521
|
-
on<T extends FormEvent>(eventType: T['type']): Observable<T>;
|
|
5522
|
-
/**
|
|
5523
|
-
* Subscribes to events of multiple types.
|
|
5524
|
-
*
|
|
5525
|
-
* @param eventType - Array of event types to subscribe to
|
|
5526
|
-
* @returns Observable that emits events matching any of the specified types
|
|
5527
|
-
*/
|
|
5528
|
-
on<T extends FormEvent>(eventType: Array<T['type']>): Observable<T>;
|
|
5529
|
-
static ɵfac: _angular_core.ɵɵFactoryDeclaration<EventBus, never>;
|
|
5530
|
-
static ɵprov: _angular_core.ɵɵInjectableDeclaration<EventBus>;
|
|
5531
|
-
}
|
|
5532
|
-
|
|
5533
5329
|
/**
|
|
5534
5330
|
* Context for token resolution in event args
|
|
5535
5331
|
*/
|
|
@@ -5847,6 +5643,26 @@ declare function dynamicTextToObservable(value: DynamicText | undefined, injecto
|
|
|
5847
5643
|
*/
|
|
5848
5644
|
declare function applyMetaToElement(element: Element, meta: FieldMeta | undefined, previouslyApplied: Set<string>): Set<string>;
|
|
5849
5645
|
|
|
5646
|
+
/**
|
|
5647
|
+
* Wraps a `Resource` so that the previous resolved value is preserved while the resource
|
|
5648
|
+
* is loading or reloading. This prevents UI flicker when params change and a new request
|
|
5649
|
+
* is in-flight — the consumer sees the stale value with a `loading`/`reloading` status
|
|
5650
|
+
* instead of `undefined`.
|
|
5651
|
+
*
|
|
5652
|
+
* Uses Angular's `resource.snapshot` + `resourceFromSnapshots` composition pattern.
|
|
5653
|
+
*
|
|
5654
|
+
* @example
|
|
5655
|
+
* ```typescript
|
|
5656
|
+
* const user = withPreviousValue(
|
|
5657
|
+
* resource({ params: () => userId(), loader: ({ params }) => fetchUser(params) })
|
|
5658
|
+
* );
|
|
5659
|
+
* // user.value() keeps the old user data during loading transitions
|
|
5660
|
+
* ```
|
|
5661
|
+
*
|
|
5662
|
+
* @experimental Uses Angular's experimental resource composition APIs.
|
|
5663
|
+
*/
|
|
5664
|
+
declare function withPreviousValue<T>(input: Resource<T>): Resource<T>;
|
|
5665
|
+
|
|
5850
5666
|
/**
|
|
5851
5667
|
* Pipe that handles dynamic text resolution with support for static strings,
|
|
5852
5668
|
* Observables, and Signals.
|
|
@@ -5894,6 +5710,7 @@ declare class RowFieldComponent {
|
|
|
5894
5710
|
private readonly destroyRef;
|
|
5895
5711
|
private readonly fieldRegistry;
|
|
5896
5712
|
private readonly injector;
|
|
5713
|
+
protected readonly environmentInjector: EnvironmentInjector;
|
|
5897
5714
|
private readonly eventBus;
|
|
5898
5715
|
private readonly logger;
|
|
5899
5716
|
field: _angular_core.InputSignal<RowField<readonly _ng_forge_dynamic_forms.RowAllowedChildren[]>>;
|
|
@@ -5923,6 +5740,7 @@ declare class GroupFieldComponent<TModel extends Record<string, unknown> = Recor
|
|
|
5923
5740
|
private readonly fieldRegistry;
|
|
5924
5741
|
private readonly parentFieldSignalContext;
|
|
5925
5742
|
private readonly injector;
|
|
5743
|
+
protected readonly environmentInjector: EnvironmentInjector;
|
|
5926
5744
|
private readonly eventBus;
|
|
5927
5745
|
private readonly logger;
|
|
5928
5746
|
private readonly fieldProcessors;
|
|
@@ -5946,7 +5764,7 @@ declare class GroupFieldComponent<TModel extends Record<string, unknown> = Recor
|
|
|
5946
5764
|
readonly invalid: _angular_core.Signal<boolean>;
|
|
5947
5765
|
readonly dirty: _angular_core.Signal<boolean>;
|
|
5948
5766
|
readonly touched: _angular_core.Signal<boolean>;
|
|
5949
|
-
readonly errors: _angular_core.Signal<_angular_forms_signals.ValidationError.
|
|
5767
|
+
readonly errors: _angular_core.Signal<_angular_forms_signals.ValidationError.WithFieldTree[]>;
|
|
5950
5768
|
readonly disabled: _angular_core.Signal<boolean>;
|
|
5951
5769
|
private readonly nestedFieldTree;
|
|
5952
5770
|
private readonly groupFieldSignalContext;
|
|
@@ -5999,6 +5817,7 @@ declare class ArrayFieldComponent<TModel extends Record<string, unknown> = Recor
|
|
|
5999
5817
|
private readonly fieldRegistry;
|
|
6000
5818
|
private readonly parentFieldSignalContext;
|
|
6001
5819
|
private readonly parentInjector;
|
|
5820
|
+
protected readonly environmentInjector: EnvironmentInjector;
|
|
6002
5821
|
private readonly eventBus;
|
|
6003
5822
|
private readonly logger;
|
|
6004
5823
|
private readonly templateRegistry;
|
|
@@ -6007,7 +5826,7 @@ declare class ArrayFieldComponent<TModel extends Record<string, unknown> = Recor
|
|
|
6007
5826
|
key: _angular_core.InputSignal<string>;
|
|
6008
5827
|
className: _angular_core.InputSignal<string | undefined>;
|
|
6009
5828
|
hidden: _angular_core.InputSignal<boolean>;
|
|
6010
|
-
readonly hostClasses:
|
|
5829
|
+
readonly hostClasses: Signal<string>;
|
|
6011
5830
|
private readonly rawFieldRegistry;
|
|
6012
5831
|
/**
|
|
6013
5832
|
* Gets the auto-remove button FieldDef from normalization metadata.
|
|
@@ -6052,7 +5871,12 @@ declare class ArrayFieldComponent<TModel extends Record<string, unknown> = Recor
|
|
|
6052
5871
|
*/
|
|
6053
5872
|
private readonly itemPositionMap;
|
|
6054
5873
|
/** Read-only view of resolved items for template consumption. */
|
|
6055
|
-
readonly resolvedItems:
|
|
5874
|
+
readonly resolvedItems: Signal<ResolvedArrayItem[]>;
|
|
5875
|
+
/**
|
|
5876
|
+
* Whether the array has reached its configured maxLength.
|
|
5877
|
+
* Exposed as a public signal so add-button components can bind [disabled]="atMaxLength()".
|
|
5878
|
+
*/
|
|
5879
|
+
readonly atMaxLength: Signal<boolean>;
|
|
6056
5880
|
/**
|
|
6057
5881
|
* Caches the result of appending the auto-remove button to template arrays.
|
|
6058
5882
|
* Keyed by template array reference — cache hits occur during recreate/resolution
|
|
@@ -6191,5 +6015,12 @@ declare class RootFormRegistryService {
|
|
|
6191
6015
|
constructor(formValue: Signal<Record<string, unknown>>, rootForm: Signal<FieldTree<Record<string, unknown>> | undefined>);
|
|
6192
6016
|
}
|
|
6193
6017
|
|
|
6194
|
-
|
|
6195
|
-
|
|
6018
|
+
/**
|
|
6019
|
+
* Injection token for configuring the initialization timeout in milliseconds.
|
|
6020
|
+
* Defaults to 10 seconds. When the timeout is reached, a warning is logged
|
|
6021
|
+
* and (initialized) emits true as a best-effort fallback.
|
|
6022
|
+
*/
|
|
6023
|
+
declare const INITIALIZATION_TIMEOUT_MS: InjectionToken<number>;
|
|
6024
|
+
|
|
6025
|
+
export { ARRAY_CONTEXT, AppendArrayItemEvent, ArrayFieldComponent, BUILT_IN_FIELDS, ConsoleLogger, DEFAULT_PROPS, DEFAULT_VALIDATION_MESSAGES, DynamicForm, DynamicFormError, DynamicFormLogger, DynamicTextPipe, EventBus, EventDispatcher, FIELD_REGISTRY, FIELD_SIGNAL_CONTEXT, FORM_OPTIONS, FormClearEvent, FormResetEvent, GroupFieldComponent, INITIALIZATION_TIMEOUT_MS, InsertArrayItemEvent, NextPageEvent, NoopLogger, PageChangeEvent, PopArrayItemEvent, PrependArrayItemEvent, PreviousPageEvent, RemoveAtIndexEvent, RootFormRegistryService, RowFieldComponent, ShiftArrayItemEvent, SubmitEvent, applyMetaToElement, applyValidator, applyValidators, arrayEvent, arrayFieldMapper, baseFieldMapper, buildBaseInputs, createField, dynamicTextToObservable, evaluateNonFieldDisabled, evaluateNonFieldHidden, field, formConfig, getArrayLength, groupFieldMapper, hasFormValue, interpolateParams, isArrayField, isCheckedField, isContainerField, isDisplayOnlyField, isEqual, isFormStateCondition, isGroupField, isLeafField, isPageField, isRowField, isSimplifiedArrayField, isValueBearingField, isValueField, omit, pageFieldMapper, provideDynamicForm, resolveNextButtonDisabled, resolveNonFieldDisabled, resolveNonFieldHidden, resolveSubmitButtonDisabled, resolveTokens, rowFieldMapper, textFieldMapper, withEventFormValue, withLoggerConfig, withPreviousValue, withValueExclusionDefaults };
|
|
6026
|
+
export type { ArrayAllowedChildren, ArrayButtonConfig, ArrayContext, ArrayField, ArrayFieldTree, ArrayItemContext, ArrayItemDefinitionTemplate, ArrayItemTemplate, AsyncCondition, AsyncConditionFunction, AsyncCustomValidator, AsyncDerivationFunction, AsyncValidatorConfig, AvailableFieldTypes, BaseCheckedField, BaseValidatorConfig, BaseValueField, BuiltInValidatorConfig, ButtonLogicContext, CheckedFieldComponent, ConditionalExpression, ContainerFieldTypes, CustomFnConfig, CustomValidator, CustomValidatorConfig, DeclarativeHttpValidatorConfig, DynamicFormFieldRegistry, DynamicText, EvaluationContext, ExtractField, ExtractFieldDefs, ExtractFormValue, FieldComponent, FieldDef, FieldMeta, FieldOption, FieldPathAccess, FieldRegistryContainers, FieldRegistryLeaves, FieldScope, FieldSignalContext, FieldStateContext, FieldStateInfo, FieldTypeDefinition, FieldWithValidation, FormConfig, FormEvent, FormEventConstructor, FormFieldStateMap, FormMode, FormModeDetectionResult, FormOptions, FormStateCondition, GroupAllowedChildren, GroupField, HttpCondition, HttpCustomValidator, HttpRequestConfig, HttpResourceRequest, HttpValidationResponseMapping, InferFormValue$1 as InferFormValue, LeafFieldTypes, Logger, LogicConfig, MapperFn, NarrowField, NarrowFields, NextButtonOptions, NonFieldLogicConfig, NonFieldLogicContext, NonFieldLogicType, PageAllowedChildren, PageField, Prettify, RegisteredFieldTypes, ResolvedValueExclusionConfig, RowAllowedChildren, RowField, SchemaApplicationConfig, SchemaDefinition, SimplifiedArrayField, StateLogicConfig, SubmissionActionResult, SubmissionConfig, SubmitButtonOptions, TextElementType, TextField, TextProps, TokenContext, ValidationError, ValidationMessages, ValidatorConfig, ValueExclusionConfig, ValueFieldComponent, ValueHandlingMode, ValueType, WithInputSignals };
|