@angular/forms 21.0.0-next.1 → 21.0.0-next.3

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.
@@ -0,0 +1,2613 @@
1
+ /**
2
+ * @license Angular v21.0.0-next.3
3
+ * (c) 2010-2025 Google LLC. https://angular.io/
4
+ * License: MIT
5
+ */
6
+
7
+ import { HttpResourceRequest, HttpResourceOptions } from '@angular/common/http';
8
+ import * as i0 from '@angular/core';
9
+ import { ElementRef, WritableSignal, Signal, ResourceRef, InputSignal, ModelSignal, OutputRef, DestroyableInjector, Injector } from '@angular/core';
10
+ import { ControlValueAccessor, NgControl } from '@angular/forms';
11
+ import { StandardSchemaV1 } from '@standard-schema/spec';
12
+
13
+ /**
14
+ * Binds a form `Field` to a UI control that edits it. A UI control can be one of several things:
15
+ * 1. A native HTML input or textarea
16
+ * 2. A signal forms custom control that implements `FormValueControl` or `FormCheckboxControl`
17
+ * 3. A component that provides a ControlValueAccessor. This should only be used to backwards
18
+ * compatibility with reactive forms. Prefer options (1) and (2).
19
+ *
20
+ * This directive has several responsibilities:
21
+ * 1. Two-way binds the field's value with the UI control's value
22
+ * 2. Binds additional forms related state on the field to the UI control (disabled, required, etc.)
23
+ * 3. Relays relevant events on the control to the field (e.g. marks field touched on blur)
24
+ * 4. Provides a fake `NgControl` that implements a subset of the features available on the reactive
25
+ * forms `NgControl`. This is provided to improve interoperability with controls designed to work
26
+ * with reactive forms. It should not be used by controls written for signal forms.
27
+ *
28
+ * @experimental 21.0.0
29
+ */
30
+ declare class Control<T> {
31
+ /** The injector for this component. */
32
+ private readonly injector;
33
+ private readonly renderer;
34
+ /** Whether state synchronization with the field has been setup yet. */
35
+ private initialized;
36
+ /** The field that is bound to this control. */
37
+ readonly field: i0.WritableSignal<Field<T>>;
38
+ set _field(value: Field<T>);
39
+ /** The field state of the bound field. */
40
+ readonly state: i0.Signal<FieldState<T, string | number>>;
41
+ /** The HTMLElement this directive is attached to. */
42
+ readonly el: ElementRef<HTMLElement>;
43
+ /** The NG_VALUE_ACCESSOR array for the host component. */
44
+ readonly cvaArray: ControlValueAccessor[] | null;
45
+ /** The Cached value for the lazily created interop NgControl. */
46
+ private _ngControl;
47
+ /** A fake NgControl provided for better interop with reactive forms. */
48
+ get ngControl(): NgControl;
49
+ /** The ControlValueAccessor for the host component. */
50
+ get cva(): ControlValueAccessor | undefined;
51
+ /** Initializes state synchronization between the field and the host UI control. */
52
+ private initialize;
53
+ /**
54
+ * Set up state synchronization between the field and a native <input>, <textarea>, or <select>.
55
+ */
56
+ private setupNativeInput;
57
+ /** Set up state synchronization between the field and a ControlValueAccessor. */
58
+ private setupControlValueAccessor;
59
+ /** Set up state synchronization between the field and a FormUiControl. */
60
+ private setupCustomUiControl;
61
+ /** Synchronize a value from a reactive source to a given sink. */
62
+ private maybeSynchronize;
63
+ /** Creates a reactive value source by reading the given AggregateProperty from the field. */
64
+ private propertySource;
65
+ /** Creates a (non-boolean) value sync that writes the given attribute of the given element. */
66
+ private withAttribute;
67
+ /** Creates a boolean value sync that writes the given attribute of the given element. */
68
+ private withBooleanAttribute;
69
+ static ɵfac: i0.ɵɵFactoryDeclaration<Control<any>, never>;
70
+ static ɵdir: i0.ɵɵDirectiveDeclaration<Control<any>, "[control]", never, { "_field": { "alias": "control"; "required": true; }; }, {}, never, never, true, never>;
71
+ }
72
+
73
+ /**
74
+ * Represents a property that may be defined on a field when it is created using a `property` rule
75
+ * in the schema. A particular `Property` can only be defined on a particular field **once**.
76
+ *
77
+ * @experimental 21.0.0
78
+ */
79
+ declare class Property<TValue> {
80
+ private brand;
81
+ /** Use {@link createProperty}. */
82
+ private constructor();
83
+ }
84
+ /**
85
+ * Creates a {@link Property}.
86
+ *
87
+ * @experimental 21.0.0
88
+ */
89
+ declare function createProperty<TValue>(): Property<TValue>;
90
+ /**
91
+ * Represents a property that is aggregated from multiple parts according to the property's reducer
92
+ * function. A value can be contributed to the aggregated value for a field using an
93
+ * `aggregateProperty` rule in the schema. There may be multiple rules in a schema that contribute
94
+ * values to the same `AggregateProperty` of the same field.
95
+ *
96
+ * @experimental 21.0.0
97
+ */
98
+ declare class AggregateProperty<TAcc, TItem> {
99
+ readonly reduce: (acc: TAcc, item: TItem) => TAcc;
100
+ readonly getInitial: () => TAcc;
101
+ private brand;
102
+ /** Use {@link reducedProperty}. */
103
+ private constructor();
104
+ }
105
+ /**
106
+ * Creates an aggregate property that reduces its individual values into an accumulated value using
107
+ * the given `reduce` and `getInitial` functions.
108
+ * @param reduce The reducer function.
109
+ * @param getInitial A function that gets the initial value for the reduce operation.
110
+ *
111
+ * @experimental 21.0.0
112
+ */
113
+ declare function reducedProperty<TAcc, TItem>(reduce: (acc: TAcc, item: TItem) => TAcc, getInitial: () => TAcc): AggregateProperty<TAcc, TItem>;
114
+ /**
115
+ * Creates an aggregate property that reduces its individual values into a list.
116
+ *
117
+ * @experimental 21.0.0
118
+ */
119
+ declare function listProperty<TItem>(): AggregateProperty<TItem[], TItem | undefined>;
120
+ /**
121
+ * Creates an aggregate property that reduces its individual values by taking their min.
122
+ *
123
+ * @experimental 21.0.0
124
+ */
125
+ declare function minProperty(): AggregateProperty<number | undefined, number | undefined>;
126
+ /**
127
+ * Creates an aggregate property that reduces its individual values by taking their max.
128
+ *
129
+ * @experimental 21.0.0
130
+ */
131
+ declare function maxProperty(): AggregateProperty<number | undefined, number | undefined>;
132
+ /**
133
+ * Creates an aggregate property that reduces its individual values by logically or-ing them.
134
+ *
135
+ * @experimental 21.0.0
136
+ */
137
+ declare function orProperty(): AggregateProperty<boolean, boolean>;
138
+ /**
139
+ * Creates an aggregate property that reduces its individual values by logically and-ing them.
140
+ *
141
+ * @experimental 21.0.0
142
+ */
143
+ declare function andProperty(): AggregateProperty<boolean, boolean>;
144
+ /**
145
+ * An aggregate property representing whether the field is required.
146
+ *
147
+ * @experimental 21.0.0
148
+ */
149
+ declare const REQUIRED: AggregateProperty<boolean, boolean>;
150
+ /**
151
+ * An aggregate property representing the min value of the field.
152
+ *
153
+ * @experimental 21.0.0
154
+ */
155
+ declare const MIN: AggregateProperty<number | undefined, number | undefined>;
156
+ /**
157
+ * An aggregate property representing the max value of the field.
158
+ *
159
+ * @experimental 21.0.0
160
+ */
161
+ declare const MAX: AggregateProperty<number | undefined, number | undefined>;
162
+ /**
163
+ * An aggregate property representing the min length of the field.
164
+ *
165
+ * @experimental 21.0.0
166
+ */
167
+ declare const MIN_LENGTH: AggregateProperty<number | undefined, number | undefined>;
168
+ /**
169
+ * An aggregate property representing the max length of the field.
170
+ *
171
+ * @experimental 21.0.0
172
+ */
173
+ declare const MAX_LENGTH: AggregateProperty<number | undefined, number | undefined>;
174
+ /**
175
+ * An aggregate property representing the patterns the field must match.
176
+ *
177
+ * @experimental 21.0.0
178
+ */
179
+ declare const PATTERN: AggregateProperty<RegExp[], RegExp | undefined>;
180
+
181
+ /**
182
+ * Options used to create a `ValidationError`.
183
+ */
184
+ interface ValidationErrorOptions {
185
+ /** Human readable error message. */
186
+ message?: string;
187
+ }
188
+ /**
189
+ * A type that requires the given type `T` to have a `field` property.
190
+ * @template T The type to add a `field` to.
191
+ *
192
+ * @experimental 21.0.0
193
+ */
194
+ type WithField<T> = T & {
195
+ field: Field<unknown>;
196
+ };
197
+ /**
198
+ * A type that allows the given type `T` to optionally have a `field` property.
199
+ * @template T The type to optionally add a `field` to.
200
+ *
201
+ * @experimental 21.0.0
202
+ */
203
+ type WithOptionalField<T> = Omit<T, 'field'> & {
204
+ field?: Field<unknown>;
205
+ };
206
+ /**
207
+ * A type that ensures the given type `T` does not have a `field` property.
208
+ * @template T The type to remove the `field` from.
209
+ *
210
+ * @experimental 21.0.0
211
+ */
212
+ type WithoutField<T> = T & {
213
+ field: never;
214
+ };
215
+ /**
216
+ * Create a required error associated with the target field
217
+ * @param options The validation error options
218
+ *
219
+ * @experimental 21.0.0
220
+ */
221
+ declare function requiredError(options: WithField<ValidationErrorOptions>): RequiredValidationError;
222
+ /**
223
+ * Create a required error
224
+ * @param options The optional validation error options
225
+ *
226
+ * @experimental 21.0.0
227
+ */
228
+ declare function requiredError(options?: ValidationErrorOptions): WithoutField<RequiredValidationError>;
229
+ /**
230
+ * Create a min value error associated with the target field
231
+ * @param min The min value constraint
232
+ * @param options The validation error options
233
+ *
234
+ * @experimental 21.0.0
235
+ */
236
+ declare function minError(min: number, options: WithField<ValidationErrorOptions>): MinValidationError;
237
+ /**
238
+ * Create a min value error
239
+ * @param min The min value constraint
240
+ * @param options The optional validation error options
241
+ *
242
+ * @experimental 21.0.0
243
+ */
244
+ declare function minError(min: number, options?: ValidationErrorOptions): WithoutField<MinValidationError>;
245
+ /**
246
+ * Create a max value error associated with the target field
247
+ * @param max The max value constraint
248
+ * @param options The validation error options
249
+ *
250
+ * @experimental 21.0.0
251
+ */
252
+ declare function maxError(max: number, options: WithField<ValidationErrorOptions>): MaxValidationError;
253
+ /**
254
+ * Create a max value error
255
+ * @param max The max value constraint
256
+ * @param options The optional validation error options
257
+ *
258
+ * @experimental 21.0.0
259
+ */
260
+ declare function maxError(max: number, options?: ValidationErrorOptions): WithoutField<MaxValidationError>;
261
+ /**
262
+ * Create a minLength error associated with the target field
263
+ * @param minLength The minLength constraint
264
+ * @param options The validation error options
265
+ *
266
+ * @experimental 21.0.0
267
+ */
268
+ declare function minLengthError(minLength: number, options: WithField<ValidationErrorOptions>): MinLengthValidationError;
269
+ /**
270
+ * Create a minLength error
271
+ * @param minLength The minLength constraint
272
+ * @param options The optional validation error options
273
+ *
274
+ * @experimental 21.0.0
275
+ */
276
+ declare function minLengthError(minLength: number, options?: ValidationErrorOptions): WithoutField<MinLengthValidationError>;
277
+ /**
278
+ * Create a maxLength error associated with the target field
279
+ * @param maxLength The maxLength constraint
280
+ * @param options The validation error options
281
+ *
282
+ * @experimental 21.0.0
283
+ */
284
+ declare function maxLengthError(maxLength: number, options: WithField<ValidationErrorOptions>): MaxLengthValidationError;
285
+ /**
286
+ * Create a maxLength error
287
+ * @param maxLength The maxLength constraint
288
+ * @param options The optional validation error options
289
+ *
290
+ * @experimental 21.0.0
291
+ */
292
+ declare function maxLengthError(maxLength: number, options?: ValidationErrorOptions): WithoutField<MaxLengthValidationError>;
293
+ /**
294
+ * Create a pattern matching error associated with the target field
295
+ * @param pattern The violated pattern
296
+ * @param options The validation error options
297
+ *
298
+ * @experimental 21.0.0
299
+ */
300
+ declare function patternError(pattern: RegExp, options: WithField<ValidationErrorOptions>): PatternValidationError;
301
+ /**
302
+ * Create a pattern matching error
303
+ * @param pattern The violated pattern
304
+ * @param options The optional validation error options
305
+ *
306
+ * @experimental 21.0.0
307
+ */
308
+ declare function patternError(pattern: RegExp, options?: ValidationErrorOptions): WithoutField<PatternValidationError>;
309
+ /**
310
+ * Create an email format error associated with the target field
311
+ * @param options The validation error options
312
+ *
313
+ * @experimental 21.0.0
314
+ */
315
+ declare function emailError(options: WithField<ValidationErrorOptions>): EmailValidationError;
316
+ /**
317
+ * Create an email format error
318
+ * @param options The optional validation error options
319
+ *
320
+ * @experimental 21.0.0
321
+ */
322
+ declare function emailError(options?: ValidationErrorOptions): WithoutField<EmailValidationError>;
323
+ /**
324
+ * Create a standard schema issue error associated with the target field
325
+ * @param issue The standard schema issue
326
+ * @param options The validation error options
327
+ *
328
+ * @experimental 21.0.0
329
+ */
330
+ declare function standardSchemaError(issue: StandardSchemaV1.Issue, options: WithField<ValidationErrorOptions>): StandardSchemaValidationError;
331
+ /**
332
+ * Create a standard schema issue error
333
+ * @param issue The standard schema issue
334
+ * @param options The optional validation error options
335
+ *
336
+ * @experimental 21.0.0
337
+ */
338
+ declare function standardSchemaError(issue: StandardSchemaV1.Issue, options?: ValidationErrorOptions): WithoutField<StandardSchemaValidationError>;
339
+ /**
340
+ * Create a custom error associated with the target field
341
+ * @param obj The object to create an error from
342
+ *
343
+ * @experimental 21.0.0
344
+ */
345
+ declare function customError<E extends Partial<ValidationError>>(obj: WithField<E>): CustomValidationError;
346
+ /**
347
+ * Create a custom error
348
+ * @param obj The object to create an error from
349
+ *
350
+ * @experimental 21.0.0
351
+ */
352
+ declare function customError<E extends Partial<ValidationError>>(obj?: E): WithoutField<CustomValidationError>;
353
+ /**
354
+ * Common interface for all validation errors.
355
+ *
356
+ * Use the creation functions to create an instance (e.g. `requiredError`, `minError`, etc.).
357
+ *
358
+ * @experimental 21.0.0
359
+ */
360
+ interface ValidationError {
361
+ /** Identifies the kind of error. */
362
+ readonly kind: string;
363
+ /** The field associated with this error. */
364
+ readonly field: Field<unknown>;
365
+ /** Human readable error message. */
366
+ readonly message?: string;
367
+ }
368
+ /**
369
+ * A custom error that may contain additional properties
370
+ *
371
+ * @experimental 21.0.0
372
+ */
373
+ declare class CustomValidationError implements ValidationError {
374
+ /** Brand the class to avoid Typescript structural matching */
375
+ private __brand;
376
+ /**
377
+ * Allow the user to attach arbitrary other properties.
378
+ */
379
+ [key: PropertyKey]: unknown;
380
+ /** Identifies the kind of error. */
381
+ readonly kind: string;
382
+ /** The field associated with this error. */
383
+ readonly field: Field<unknown>;
384
+ /** Human readable error message. */
385
+ readonly message?: string;
386
+ constructor(options?: ValidationErrorOptions);
387
+ }
388
+ /**
389
+ * Internal version of `NgValidationError`, we create this separately so we can change its type on
390
+ * the exported version to a type union of the possible sub-classes.
391
+ *
392
+ * @experimental 21.0.0
393
+ */
394
+ declare abstract class _NgValidationError implements ValidationError {
395
+ /** Brand the class to avoid Typescript structural matching */
396
+ private __brand;
397
+ /** Identifies the kind of error. */
398
+ readonly kind: string;
399
+ /** The field associated with this error. */
400
+ readonly field: Field<unknown>;
401
+ /** Human readable error message. */
402
+ readonly message?: string;
403
+ constructor(options?: ValidationErrorOptions);
404
+ }
405
+ /**
406
+ * An error used to indicate that a required field is empty.
407
+ *
408
+ * @experimental 21.0.0
409
+ */
410
+ declare class RequiredValidationError extends _NgValidationError {
411
+ readonly kind = "required";
412
+ }
413
+ /**
414
+ * An error used to indicate that a value is lower than the minimum allowed.
415
+ *
416
+ * @experimental 21.0.0
417
+ */
418
+ declare class MinValidationError extends _NgValidationError {
419
+ readonly min: number;
420
+ readonly kind = "min";
421
+ constructor(min: number, options?: ValidationErrorOptions);
422
+ }
423
+ /**
424
+ * An error used to indicate that a value is higher than the maximum allowed.
425
+ *
426
+ * @experimental 21.0.0
427
+ */
428
+ declare class MaxValidationError extends _NgValidationError {
429
+ readonly max: number;
430
+ readonly kind = "max";
431
+ constructor(max: number, options?: ValidationErrorOptions);
432
+ }
433
+ /**
434
+ * An error used to indicate that a value is shorter than the minimum allowed length.
435
+ *
436
+ * @experimental 21.0.0
437
+ */
438
+ declare class MinLengthValidationError extends _NgValidationError {
439
+ readonly minLength: number;
440
+ readonly kind = "minLength";
441
+ constructor(minLength: number, options?: ValidationErrorOptions);
442
+ }
443
+ /**
444
+ * An error used to indicate that a value is longer than the maximum allowed length.
445
+ *
446
+ * @experimental 21.0.0
447
+ */
448
+ declare class MaxLengthValidationError extends _NgValidationError {
449
+ readonly maxLength: number;
450
+ readonly kind = "maxLength";
451
+ constructor(maxLength: number, options?: ValidationErrorOptions);
452
+ }
453
+ /**
454
+ * An error used to indicate that a value does not match the required pattern.
455
+ *
456
+ * @experimental 21.0.0
457
+ */
458
+ declare class PatternValidationError extends _NgValidationError {
459
+ readonly pattern: RegExp;
460
+ readonly kind = "pattern";
461
+ constructor(pattern: RegExp, options?: ValidationErrorOptions);
462
+ }
463
+ /**
464
+ * An error used to indicate that a value is not a valid email.
465
+ *
466
+ * @experimental 21.0.0
467
+ */
468
+ declare class EmailValidationError extends _NgValidationError {
469
+ readonly kind = "email";
470
+ }
471
+ /**
472
+ * An error used to indicate an issue validating against a standard schema.
473
+ *
474
+ * @experimental 21.0.0
475
+ */
476
+ declare class StandardSchemaValidationError extends _NgValidationError {
477
+ readonly issue: StandardSchemaV1.Issue;
478
+ readonly kind = "standardSchema";
479
+ constructor(issue: StandardSchemaV1.Issue, options?: ValidationErrorOptions);
480
+ }
481
+ /**
482
+ * The base class for all built-in, non-custom errors. This class can be used to check if an error
483
+ * is one of the standard kinds, allowing you to switch on the kind to further narrow the type.
484
+ *
485
+ * @example
486
+ * ```
487
+ * const f = form(...);
488
+ * for (const e of form().errors()) {
489
+ * if (e instanceof NgValidationError) {
490
+ * switch(e.kind) {
491
+ * case 'required':
492
+ * console.log('This is required!');
493
+ * break;
494
+ * case 'min':
495
+ * console.log(`Must be at least ${e.min}`);
496
+ * break;
497
+ * ...
498
+ * }
499
+ * }
500
+ * }
501
+ * ```
502
+ *
503
+ * @experimental 21.0.0
504
+ */
505
+ declare const NgValidationError: abstract new () => NgValidationError;
506
+ type NgValidationError = RequiredValidationError | MinValidationError | MaxValidationError | MinLengthValidationError | MaxLengthValidationError | PatternValidationError | EmailValidationError | StandardSchemaValidationError;
507
+
508
+ /**
509
+ * Symbol used to retain generic type information when it would otherwise be lost.
510
+ */
511
+ declare const ɵɵTYPE: unique symbol;
512
+ /**
513
+ * Creates a type based on the given type T, but with all readonly properties made writable.
514
+ * @template T The type to create a mutable version of.
515
+ *
516
+ * @experimental 21.0.0
517
+ */
518
+ type Mutable<T> = {
519
+ -readonly [P in keyof T]: T[P];
520
+ };
521
+ /**
522
+ * A type that represents either a single value of type `T` or a readonly array of `T`.
523
+ * @template T The type of the value(s).
524
+ *
525
+ * @experimental 21.0.0
526
+ */
527
+ type OneOrMany<T> = T | readonly T[];
528
+ /**
529
+ * The kind of `FieldPath` (`Root`, `Child` of another `FieldPath`, or `Item` in a `FieldPath` array)
530
+ *
531
+ * @experimental 21.0.0
532
+ */
533
+ declare namespace PathKind {
534
+ /**
535
+ * The `PathKind` for a `FieldPath` that is at the root of its field tree.
536
+ */
537
+ interface Root {
538
+ /**
539
+ * The `ɵɵTYPE` is constructed to allow the `extends` clause on `Child` and `Item` to narrow the
540
+ * type. Another way to think about this is, if we have a function that expects this kind of
541
+ * path, the `ɵɵTYPE` lists the kinds of path we are allowed to pass to it.
542
+ */
543
+ [ɵɵTYPE]: 'root' | 'child' | 'item';
544
+ }
545
+ /**
546
+ * The `PathKind` for a `FieldPath` that is a child of another `FieldPath`.
547
+ */
548
+ interface Child extends PathKind.Root {
549
+ [ɵɵTYPE]: 'child' | 'item';
550
+ }
551
+ /**
552
+ * The `PathKind` for a `FieldPath` that is an item in a `FieldPath` array.
553
+ */
554
+ interface Item extends PathKind.Child {
555
+ [ɵɵTYPE]: 'item';
556
+ }
557
+ }
558
+ type PathKind = PathKind.Root | PathKind.Child | PathKind.Item;
559
+ /**
560
+ * A status indicating whether a field is unsubmitted, submitted, or currently submitting.
561
+ *
562
+ * @experimental 21.0.0
563
+ */
564
+ type SubmittedStatus = 'unsubmitted' | 'submitted' | 'submitting';
565
+ /**
566
+ * A reason for a field's disablement.
567
+ *
568
+ * @experimental 21.0.0
569
+ */
570
+ interface DisabledReason {
571
+ /** The field that is disabled. */
572
+ readonly field: Field<unknown>;
573
+ /** A user-facing message describing the reason for the disablement. */
574
+ readonly message?: string;
575
+ }
576
+ /**
577
+ * The absence of an error which indicates a successful validation result.
578
+ *
579
+ * @experimental 21.0.0
580
+ */
581
+ type ValidationSuccess = null | undefined | void;
582
+ /**
583
+ * The result of running a field validation function.
584
+ *
585
+ * The result may be one of the following:
586
+ * 1. A {@link ValidationSuccess} to indicate no errors.
587
+ * 2. A {@link ValidationError} without a field to indicate an error on the field being validated.
588
+ * 3. A list of {@link ValidationError} without fields to indicate multiple errors on the field
589
+ * being validated.
590
+ *
591
+ * @template E the type of error (defaults to {@link ValidationError}).
592
+ *
593
+ * @experimental 21.0.0
594
+ */
595
+ type FieldValidationResult<E extends ValidationError = ValidationError> = ValidationSuccess | OneOrMany<WithoutField<E>>;
596
+ /**
597
+ * The result of running a tree validation function.
598
+ *
599
+ * The result may be one of the following:
600
+ * 1. A {@link ValidationSuccess} to indicate no errors.
601
+ * 2. A {@link ValidationError} without a field to indicate an error on the field being validated.
602
+ * 3. A {@link ValidationError} with a field to indicate an error on the target field.
603
+ * 4. A list of {@link ValidationError} with or without fields to indicate multiple errors.
604
+ *
605
+ * @template E the type of error (defaults to {@link ValidationError}).
606
+ *
607
+ * @experimental 21.0.0
608
+ */
609
+ type TreeValidationResult<E extends ValidationError = ValidationError> = ValidationSuccess | OneOrMany<WithOptionalField<E>>;
610
+ /**
611
+ * A validation result where all errors explicitly define their target field.
612
+ *
613
+ * The result may be one of the following:
614
+ * 1. A {@link ValidationSuccess} to indicate no errors.
615
+ * 2. A {@link ValidationError} with a field to indicate an error on the target field.
616
+ * 3. A list of {@link ValidationError} with fields to indicate multiple errors.
617
+ *
618
+ * @template E the type of error (defaults to {@link ValidationError}).
619
+ *
620
+ * @experimental 21.0.0
621
+ */
622
+ type ValidationResult<E extends ValidationError = ValidationError> = ValidationSuccess | OneOrMany<E>;
623
+ /**
624
+ * An asynchronous validation result where all errors explicitly define their target field.
625
+ *
626
+ * The result may be one of the following:
627
+ * 1. A {@link ValidationResult} to indicate the result if resolved.
628
+ * 5. 'pending' if the validation is not yet resolved.
629
+ *
630
+ * @template E the type of error (defaults to {@link ValidationError}).
631
+ *
632
+ * @experimental 21.0.0
633
+ */
634
+ type AsyncValidationResult<E extends ValidationError = ValidationError> = ValidationResult<E> | 'pending';
635
+ /**
636
+ * An object that represents a single field in a form. This includes both primitive value fields
637
+ * (e.g. fields that contain a `string` or `number`), as well as "grouping fields" that contain
638
+ * sub-fields. `Field` objects are arranged in a tree whose structure mimics the structure of the
639
+ * underlying data. For example a `Field<{x: number}>` has a property `x` which contains a
640
+ * `Field<number>`. To access the state associated with a field, call it as a function.
641
+ *
642
+ * @template TValue The type of the data which the field is wrapped around.
643
+ * @template TKey The type of the property key which this field resides under in its parent.
644
+ *
645
+ * @experimental 21.0.0
646
+ */
647
+ type Field<TValue, TKey extends string | number = string | number> = (() => FieldState<TValue, TKey>) & (TValue extends Array<infer U> ? ReadonlyArrayLike<MaybeField<U, number>> : TValue extends Record<string, any> ? Subfields<TValue> : unknown);
648
+ /**
649
+ * The sub-fields that a user can navigate to from a `Field<TValue>`.
650
+ *
651
+ * @template TValue The type of the data which the parent field is wrapped around.
652
+ *
653
+ * @experimental 21.0.0
654
+ */
655
+ type Subfields<TValue> = {
656
+ readonly [K in keyof TValue as TValue[K] extends Function ? never : K]: MaybeField<TValue[K], string>;
657
+ };
658
+ /**
659
+ * An iterable object with the same shape as a readonly array.
660
+ *
661
+ * @template T The array item type.
662
+ *
663
+ * @experimental 21.0.0
664
+ */
665
+ type ReadonlyArrayLike<T> = Pick<ReadonlyArray<T>, number | 'length' | typeof Symbol.iterator>;
666
+ /**
667
+ * Helper type for defining `Field`. Given a type `TValue` that may include `undefined`, it extracts
668
+ * the `undefined` outside the `Field` type.
669
+ *
670
+ * For example `MaybeField<{a: number} | undefined, TKey>` would be equivalent to
671
+ * `undefined | Field<{a: number}, TKey>`.
672
+ *
673
+ * @template TValue The type of the data which the field is wrapped around.
674
+ * @template TKey The type of the property key which this field resides under in its parent.
675
+ *
676
+ * @experimental 21.0.0
677
+ */
678
+ type MaybeField<TValue, TKey extends string | number = string | number> = (TValue & undefined) | Field<Exclude<TValue, undefined>, TKey>;
679
+ /**
680
+ * Contains all of the state (e.g. value, statuses, etc.) associated with a `Field`, exposed as
681
+ * signals.
682
+ *
683
+ * @experimental 21.0.0
684
+ */
685
+ interface FieldState<TValue, TKey extends string | number = string | number> {
686
+ /**
687
+ * A writable signal containing the value for this field. Updating this signal will update the
688
+ * data model that the field is bound to.
689
+ */
690
+ readonly value: WritableSignal<TValue>;
691
+ /**
692
+ * A signal indicating whether the field has been touched by the user.
693
+ */
694
+ readonly touched: Signal<boolean>;
695
+ /**
696
+ * A signal indicating whether field value has been changed by user.
697
+ */
698
+ readonly dirty: Signal<boolean>;
699
+ /**
700
+ * A signal indicating whether a field is hidden.
701
+ *
702
+ * When a field is hidden it is ignored when determining the valid, touched, and dirty states.
703
+ *
704
+ * Note: This doesn't hide the field in the template, that must be done manually.
705
+ * ```
706
+ * @if (!field.hidden()) {
707
+ * ...
708
+ * }
709
+ * ```
710
+ */
711
+ readonly hidden: Signal<boolean>;
712
+ /**
713
+ * A signal indicating whether the field is currently disabled.
714
+ */
715
+ readonly disabled: Signal<boolean>;
716
+ /**
717
+ * A signal containing the reasons why the field is currently disabled.
718
+ */
719
+ readonly disabledReasons: Signal<readonly DisabledReason[]>;
720
+ /**
721
+ * A signal indicating whether the field is currently readonly.
722
+ */
723
+ readonly readonly: Signal<boolean>;
724
+ /**
725
+ * A signal containing the current errors for the field.
726
+ */
727
+ readonly errors: Signal<ValidationError[]>;
728
+ /**
729
+ * A signal containing the {@link errors} of the field and its descendants.
730
+ */
731
+ readonly errorSummary: Signal<ValidationError[]>;
732
+ /**
733
+ * A signal indicating whether the field's value is currently valid.
734
+ *
735
+ * Note: `valid()` is not the same as `!invalid()`.
736
+ * - `valid()` is `true` when there are no validation errors *and* no pending validators.
737
+ * - `invalid()` is `true` when there are validation errors, regardless of pending validators.
738
+ *
739
+ * Ex: consider the situation where a field has 3 validators, 2 of which have no errors and 1 of
740
+ * which is still pending. In this case `valid()` is `false` because of the pending validator.
741
+ * However `invalid()` is also `false` because there are no errors.
742
+ */
743
+ readonly valid: Signal<boolean>;
744
+ /**
745
+ * A signal indicating whether the field's value is currently invalid.
746
+ *
747
+ * Note: `invalid()` is not the same as `!valid()`.
748
+ * - `invalid()` is `true` when there are validation errors, regardless of pending validators.
749
+ * - `valid()` is `true` when there are no validation errors *and* no pending validators.
750
+ *
751
+ * Ex: consider the situation where a field has 3 validators, 2 of which have no errors and 1 of
752
+ * which is still pending. In this case `invalid()` is `false` because there are no errors.
753
+ * However `valid()` is also `false` because of the pending validator.
754
+ */
755
+ readonly invalid: Signal<boolean>;
756
+ /**
757
+ * Whether there are any validators still pending for this field.
758
+ */
759
+ readonly pending: Signal<boolean>;
760
+ /**
761
+ * A signal indicating whether the field is currently in the process of being submitted.
762
+ */
763
+ readonly submitting: Signal<boolean>;
764
+ /**
765
+ * A signal of a unique name for the field, by default based on the name of its parent field.
766
+ */
767
+ readonly name: Signal<string>;
768
+ /**
769
+ * The property key in the parent field under which this field is stored. If the parent field is
770
+ * array-valued, for example, this is the index of this field in that array.
771
+ */
772
+ readonly keyInParent: Signal<TKey>;
773
+ /**
774
+ * A signal containing the `Control` directives this field is currently bound to.
775
+ */
776
+ readonly controls: Signal<readonly Control<unknown>[]>;
777
+ /**
778
+ * Reads an aggregate property value from the field.
779
+ * @param prop The property to read.
780
+ */
781
+ property<M>(prop: AggregateProperty<M, any>): Signal<M>;
782
+ /**
783
+ * Reads a property value from the field.
784
+ * @param prop The property key to read.
785
+ */
786
+ property<M>(prop: Property<M>): M | undefined;
787
+ /**
788
+ * Checks whether the given metadata key has been defined for this field.
789
+ */
790
+ hasProperty(key: Property<any> | AggregateProperty<any, any>): boolean;
791
+ /**
792
+ * Sets the touched status of the field to `true`.
793
+ */
794
+ markAsTouched(): void;
795
+ /**
796
+ * Sets the dirty status of the field to `true`.
797
+ */
798
+ markAsDirty(): void;
799
+ /**
800
+ * Resets the {@link touched} and {@link dirty} state of the field and its descendants.
801
+ *
802
+ * Note this does not change the data model, which can be reset directly if desired.
803
+ */
804
+ reset(): void;
805
+ }
806
+ /**
807
+ * An object that represents a location in the `Field` tree structure and is used to bind logic to a
808
+ * particular part of the structure prior to the creation of the form. Because the `FieldPath`
809
+ * exists prior to the form's creation, it cannot be used to access any of the field state.
810
+ *
811
+ * @template TValue The type of the data which the form is wrapped around.
812
+ * @template TPathKind The kind of path (root field, child field, or item of an array)
813
+ *
814
+ * @experimental 21.0.0
815
+ */
816
+ type FieldPath<TValue, TPathKind extends PathKind = PathKind.Root> = {
817
+ [ɵɵTYPE]: [TValue, TPathKind];
818
+ } & (TValue extends Array<unknown> ? unknown : TValue extends Record<string, any> ? {
819
+ [K in keyof TValue]: MaybeFieldPath<TValue[K], PathKind.Child>;
820
+ } : unknown);
821
+ /**
822
+ * Helper type for defining `FieldPath`. Given a type `TValue` that may include `undefined`, it
823
+ * extracts the `undefined` outside the `FieldPath` type.
824
+ *
825
+ * For example `MaybeFieldPath<{a: number} | undefined, PathKind.Child>` would be equivalent to
826
+ * `undefined | Field<{a: number}, PathKind.child>`.
827
+ *
828
+ * @template TValue The type of the data which the field is wrapped around.
829
+ * @template TPathKind The kind of path (root field, child field, or item of an array)
830
+ *
831
+ * @experimental 21.0.0
832
+ */
833
+ type MaybeFieldPath<TValue, TPathKind extends PathKind = PathKind.Root> = (TValue & undefined) | FieldPath<Exclude<TValue, undefined>, TPathKind>;
834
+ /**
835
+ * Defines logic for a form.
836
+ *
837
+ * @template TValue The type of data stored in the form that this schema is attached to.
838
+ *
839
+ * @experimental 21.0.0
840
+ */
841
+ type Schema<in TValue> = {
842
+ [ɵɵTYPE]: SchemaFn<TValue, PathKind.Root>;
843
+ };
844
+ /**
845
+ * Function that defines rules for a schema.
846
+ *
847
+ * @template TValue The type of data stored in the form that this schema function is attached to.
848
+ * @template TPathKind The kind of path this schema function can be bound to.
849
+ *
850
+ * @experimental 21.0.0
851
+ */
852
+ type SchemaFn<TValue, TPathKind extends PathKind = PathKind.Root> = (p: FieldPath<TValue, TPathKind>) => void;
853
+ /**
854
+ * A schema or schema definition function.
855
+ *
856
+ * @template TValue The type of data stored in the form that this schema function is attached to.
857
+ * @template TPathKind The kind of path this schema function can be bound to.
858
+ *
859
+ * @experimental 21.0.0
860
+ */
861
+ type SchemaOrSchemaFn<TValue, TPathKind extends PathKind = PathKind.Root> = Schema<TValue> | SchemaFn<TValue, TPathKind>;
862
+ /**
863
+ * A function that receives the `FieldContext` for the field the logic is bound to and returns
864
+ * a specific result type.
865
+ *
866
+ * @template TValue The data type for the field the logic is bound to.
867
+ * @template TReturn The type of the result returned by the logic function.
868
+ * @template TPathKind The kind of path the logic is applied to (root field, child field, or item of an array)
869
+ *
870
+ * @experimental 21.0.0
871
+ */
872
+ type LogicFn<TValue, TReturn, TPathKind extends PathKind = PathKind.Root> = (ctx: FieldContext<TValue, TPathKind>) => TReturn;
873
+ /**
874
+ * A function that takes the `FieldContext` for the field being validated and returns a
875
+ * `ValidationResult` indicating errors for the field.
876
+ *
877
+ * @template TValue The type of value stored in the field being validated
878
+ * @template TPathKind The kind of path being validated (root field, child field, or item of an array)
879
+ *
880
+ * @experimental 21.0.0
881
+ */
882
+ type FieldValidator<TValue, TPathKind extends PathKind = PathKind.Root> = LogicFn<TValue, FieldValidationResult, TPathKind>;
883
+ /**
884
+ * A function that takes the `FieldContext` for the field being validated and returns a
885
+ * `TreeValidationResult` indicating errors for the field and its sub-fields.
886
+ *
887
+ * @template TValue The type of value stored in the field being validated
888
+ * @template TPathKind The kind of path being validated (root field, child field, or item of an array)
889
+ *
890
+ * @experimental 21.0.0
891
+ */
892
+ type TreeValidator<TValue, TPathKind extends PathKind = PathKind.Root> = LogicFn<TValue, TreeValidationResult, TPathKind>;
893
+ /**
894
+ * A function that takes the `FieldContext` for the field being validated and returns a
895
+ * `ValidationResult` indicating errors for the field and its sub-fields. In a `Validator` all
896
+ * errors must explicitly define their target field.
897
+ *
898
+ * @template TValue The type of value stored in the field being validated
899
+ * @template TPathKind The kind of path being validated (root field, child field, or item of an array)
900
+ *
901
+ * @experimental 21.0.0
902
+ */
903
+ type Validator<TValue, TPathKind extends PathKind = PathKind.Root> = LogicFn<TValue, ValidationResult, TPathKind>;
904
+ /**
905
+ * Provides access to the state of the current field as well as functions that can be used to look
906
+ * up state of other fields based on a `FieldPath`.
907
+ *
908
+ * @experimental 21.0.0
909
+ */
910
+ type FieldContext<TValue, TPathKind extends PathKind = PathKind.Root> = TPathKind extends PathKind.Item ? ItemFieldContext<TValue> : TPathKind extends PathKind.Child ? ChildFieldContext<TValue> : RootFieldContext<TValue>;
911
+ /**
912
+ * The base field context that is available for all fields.
913
+ *
914
+ * @experimental 21.0.0
915
+ */
916
+ interface RootFieldContext<TValue> {
917
+ /** A signal containing the value of the current field. */
918
+ readonly value: Signal<TValue>;
919
+ /** The state of the current field. */
920
+ readonly state: FieldState<TValue>;
921
+ /** The current field. */
922
+ readonly field: Field<TValue>;
923
+ /** Gets the value of the field represented by the given path. */
924
+ readonly valueOf: <P>(p: FieldPath<P>) => P;
925
+ /** Gets the state of the field represented by the given path. */
926
+ readonly stateOf: <P>(p: FieldPath<P>) => FieldState<P>;
927
+ /** Gets the field represented by the given path. */
928
+ readonly fieldOf: <P>(p: FieldPath<P>) => Field<P>;
929
+ }
930
+ /**
931
+ * Field context that is available for all fields that are a child of another field.
932
+ *
933
+ * @experimental 21.0.0
934
+ */
935
+ interface ChildFieldContext<TValue> extends RootFieldContext<TValue> {
936
+ /** The key of the current field in its parent field. */
937
+ readonly key: Signal<string>;
938
+ }
939
+ /**
940
+ * Field context that is available for all fields that are an item in an array field.
941
+ *
942
+ * @experimental 21.0.0
943
+ */
944
+ interface ItemFieldContext<TValue> extends ChildFieldContext<TValue> {
945
+ /** The index of the current field in its parent field. */
946
+ readonly index: Signal<number>;
947
+ }
948
+
949
+ /**
950
+ * A function that takes the result of an async operation and the current field context, and maps it
951
+ * to a list of validation errors.
952
+ *
953
+ * @param result The result of the async operation.
954
+ * @param ctx The context for the field the validator is attached to.
955
+ * @return A validation error, or list of validation errors to report based on the result of the async operation.
956
+ * The returned errors can optionally specify a field that the error should be targeted to.
957
+ * A targeted error will show up as an error on its target field rather than the field being validated.
958
+ * If a field is not given, the error is assumed to apply to the field being validated.
959
+ * @template TValue The type of value stored in the field being validated.
960
+ * @template TResult The type of result returned by the async operation
961
+ * @template TPathKind The kind of path being validated (a root path, child path, or item of an array)
962
+ *
963
+ * @experimental 21.0.0
964
+ */
965
+ type MapToErrorsFn<TValue, TResult, TPathKind extends PathKind = PathKind.Root> = (result: TResult, ctx: FieldContext<TValue, TPathKind>) => TreeValidationResult;
966
+ /**
967
+ * Options that indicate how to create a resource for async validation for a field,
968
+ * and map its result to validation errors.
969
+ *
970
+ * @template TValue The type of value stored in the field being validated.
971
+ * @template TParams The type of parameters to the resource.
972
+ * @template TResult The type of result returned by the resource
973
+ * @template TPathKind The kind of path being validated (a root path, child path, or item of an array)
974
+ *
975
+ * @experimental 21.0.0
976
+ */
977
+ interface AsyncValidatorOptions<TValue, TParams, TResult, TPathKind extends PathKind = PathKind.Root> {
978
+ /**
979
+ * A function that receives the field context and returns the params for the resource.
980
+ *
981
+ * @param ctx The field context for the field being validated.
982
+ * @returns The params for the resource.
983
+ */
984
+ readonly params: (ctx: FieldContext<TValue, TPathKind>) => TParams;
985
+ /**
986
+ * A function that receives the resource params and returns a resource of the given params.
987
+ * The given params should be used as is to create the resource.
988
+ * The forms system will report the params as `undefined` when this validation doesn't need to be run.
989
+ *
990
+ * @param params The params to use for constructing the resource
991
+ * @returns A reference to the constructed resource.
992
+ */
993
+ readonly factory: (params: Signal<TParams | undefined>) => ResourceRef<TResult | undefined>;
994
+ /**
995
+ * A function that takes the resource result, and the current field context and maps it to a list
996
+ * of validation errors.
997
+ *
998
+ * @param result The resource result.
999
+ * @param ctx The context for the field the validator is attached to.
1000
+ * @return A validation error, or list of validation errors to report based on the resource result.
1001
+ * The returned errors can optionally specify a field that the error should be targeted to.
1002
+ * A targeted error will show up as an error on its target field rather than the field being validated.
1003
+ * If a field is not given, the error is assumed to apply to the field being validated.
1004
+ */
1005
+ readonly errors: MapToErrorsFn<TValue, TResult, TPathKind>;
1006
+ }
1007
+ /**
1008
+ * Options that indicate how to create an httpResource for async validation for a field,
1009
+ * and map its result to validation errors.
1010
+ *
1011
+ * @template TValue The type of value stored in the field being validated.
1012
+ * @template TResult The type of result returned by the httpResource
1013
+ * @template TPathKind The kind of path being validated (a root path, child path, or item of an array)
1014
+ *
1015
+ * @experimental 21.0.0
1016
+ */
1017
+ interface HttpValidatorOptions<TValue, TResult, TPathKind extends PathKind = PathKind.Root> {
1018
+ /**
1019
+ * A function that receives the field context and returns the url or request for the httpResource.
1020
+ * If given a URL, the underlying httpResource will perform an HTTP GET on it.
1021
+ *
1022
+ * @param ctx The field context for the field being validated.
1023
+ * @returns The URL or request for creating the httpResource.
1024
+ */
1025
+ readonly request: ((ctx: FieldContext<TValue, TPathKind>) => string | undefined) | ((ctx: FieldContext<TValue, TPathKind>) => HttpResourceRequest | undefined);
1026
+ /**
1027
+ * A function that takes the httpResource result, and the current field context and maps it to a
1028
+ * list of validation errors.
1029
+ *
1030
+ * @param result The httpResource result.
1031
+ * @param ctx The context for the field the validator is attached to.
1032
+ * @return A validation error, or list of validation errors to report based on the httpResource result.
1033
+ * The returned errors can optionally specify a field that the error should be targeted to.
1034
+ * A targeted error will show up as an error on its target field rather than the field being validated.
1035
+ * If a field is not given, the error is assumed to apply to the field being validated.
1036
+ */
1037
+ readonly errors: MapToErrorsFn<TValue, TResult, TPathKind>;
1038
+ /**
1039
+ * The options to use when creating the httpResource.
1040
+ */
1041
+ readonly options?: HttpResourceOptions<TResult, unknown>;
1042
+ }
1043
+ /**
1044
+ * Adds async validation to the field corresponding to the given path based on a resource.
1045
+ * Async validation for a field only runs once all synchronous validation is passing.
1046
+ *
1047
+ * @param path A path indicating the field to bind the async validation logic to.
1048
+ * @param opts The async validation options.
1049
+ * @template TValue The type of value stored in the field being validated.
1050
+ * @template TParams The type of parameters to the resource.
1051
+ * @template TResult The type of result returned by the resource
1052
+ * @template TPathKind The kind of path being validated (a root path, child path, or item of an array)
1053
+ *
1054
+ * @experimental 21.0.0
1055
+ */
1056
+ declare function validateAsync<TValue, TParams, TResult, TPathKind extends PathKind = PathKind.Root>(path: FieldPath<TValue, TPathKind>, opts: AsyncValidatorOptions<TValue, TParams, TResult, TPathKind>): void;
1057
+ /**
1058
+ * Adds async validation to the field corresponding to the given path based on an httpResource.
1059
+ * Async validation for a field only runs once all synchronous validation is passing.
1060
+ *
1061
+ * @param path A path indicating the field to bind the async validation logic to.
1062
+ * @param opts The http validation options.
1063
+ * @template TValue The type of value stored in the field being validated.
1064
+ * @template TResult The type of result returned by the httpResource
1065
+ * @template TPathKind The kind of path being validated (a root path, child path, or item of an array)
1066
+ *
1067
+ * @experimental 21.0.0
1068
+ */
1069
+ declare function validateHttp<TValue, TResult = unknown, TPathKind extends PathKind = PathKind.Root>(path: FieldPath<TValue, TPathKind>, opts: HttpValidatorOptions<TValue, TResult, TPathKind>): void;
1070
+
1071
+ /**
1072
+ * The base set of properties shared by all form control contracts.
1073
+ *
1074
+ * @experimental 21.0.0
1075
+ */
1076
+ interface FormUiControl {
1077
+ /**
1078
+ * An input to receive the errors for the field. If implemented, the `Control` directive will
1079
+ * automatically bind errors from the bound field to this input.
1080
+ */
1081
+ readonly errors?: InputSignal<readonly WithOptionalField<ValidationError>[]>;
1082
+ /**
1083
+ * An input to receive the disabled status for the field. If implemented, the `Control` directive
1084
+ * will automatically bind the disabled status from the bound field to this input.
1085
+ */
1086
+ readonly disabled?: InputSignal<boolean>;
1087
+ /**
1088
+ * An input to receive the reasons for the disablement of the field. If implemented, the `Control`
1089
+ * directive will automatically bind the disabled reason from the bound field to this input.
1090
+ */
1091
+ readonly disabledReasons?: InputSignal<readonly WithOptionalField<DisabledReason>[]>;
1092
+ /**
1093
+ * An input to receive the readonly status for the field. If implemented, the `Control` directive
1094
+ * will automatically bind the readonly status from the bound field to this input.
1095
+ */
1096
+ readonly readonly?: InputSignal<boolean>;
1097
+ /**
1098
+ * An input to receive the hidden status for the field. If implemented, the `Control` directive
1099
+ * will automatically bind the hidden status from the bound field to this input.
1100
+ */
1101
+ readonly hidden?: InputSignal<boolean>;
1102
+ /**
1103
+ * An input to receive the invalid status for the field. If implemented, the `Control` directive
1104
+ * will automatically bind the invalid status from the bound field to this input.
1105
+ */
1106
+ readonly invalid?: InputSignal<boolean>;
1107
+ /**
1108
+ * An input to receive the pending status for the field. If implemented, the `Control` directive
1109
+ * will automatically bind the pending status from the bound field to this input.
1110
+ */
1111
+ readonly pending?: InputSignal<boolean>;
1112
+ /**
1113
+ * An input to receive the touched status for the field. If implemented, the `Control` directive
1114
+ * will automatically bind the touched status from the bound field to this input.
1115
+ */
1116
+ readonly touched?: ModelSignal<boolean> | InputSignal<boolean> | OutputRef<boolean>;
1117
+ /**
1118
+ * An input to receive the dirty status for the field. If implemented, the `Control` directive
1119
+ * will automatically bind the dirty status from the bound field to this input.
1120
+ */
1121
+ readonly dirty?: InputSignal<boolean>;
1122
+ /**
1123
+ * An input to receive the name for the field. If implemented, the `Control` directive will
1124
+ * automatically bind the name from the bound field to this input.
1125
+ */
1126
+ readonly name?: InputSignal<string>;
1127
+ /**
1128
+ * An input to receive the required status for the field. If implemented, the `Control` directive
1129
+ * will automatically bind the required status from the bound field to this input.
1130
+ */
1131
+ readonly required?: InputSignal<boolean>;
1132
+ /**
1133
+ * An input to receive the min value for the field. If implemented, the `Control` directive will
1134
+ * automatically bind the min value from the bound field to this input.
1135
+ */
1136
+ readonly min?: InputSignal<number | undefined>;
1137
+ /**
1138
+ * An input to receive the min length for the field. If implemented, the `Control` directive will
1139
+ * automatically bind the min length from the bound field to this input.
1140
+ */
1141
+ readonly minLength?: InputSignal<number | undefined>;
1142
+ /**
1143
+ * An input to receive the max value for the field. If implemented, the `Control` directive will
1144
+ * automatically bind the max value from the bound field to this input.
1145
+ */
1146
+ readonly max?: InputSignal<number | undefined>;
1147
+ /**
1148
+ * An input to receive the max length for the field. If implemented, the `Control` directive will
1149
+ * automatically bind the max length from the bound field to this input.
1150
+ */
1151
+ readonly maxLength?: InputSignal<number | undefined>;
1152
+ /**
1153
+ * An input to receive the value patterns for the field. If implemented, the `Control` directive
1154
+ * will automatically bind the value patterns from the bound field to this input.
1155
+ */
1156
+ readonly pattern?: InputSignal<readonly RegExp[]>;
1157
+ }
1158
+ /**
1159
+ * A contract for a form control that edits a `Field` of type `TValue`. Any component that
1160
+ * implements this contract can be used with the `Control` directive.
1161
+ *
1162
+ * Many of the properties declared on this contract are optional. They do not need to be
1163
+ * implemented, but if they are will be kept in sync with the field state of the field bound to the
1164
+ * `Control` directive.
1165
+ *
1166
+ * @template TValue The type of `Field` that the implementing component can edit.
1167
+ *
1168
+ * @experimental 21.0.0
1169
+ */
1170
+ interface FormValueControl<TValue> extends FormUiControl {
1171
+ /**
1172
+ * The value is the only required property in this contract. A component that wants to integrate
1173
+ * with the `Control` directive via this contract, *must* provide a `model()` that will be kept in
1174
+ * sync with the value of the bound `Field`.
1175
+ */
1176
+ readonly value: ModelSignal<TValue>;
1177
+ /**
1178
+ * The implementing component *must not* define a `checked` property. This is reserved for
1179
+ * components that want to integrate with the `Control` directive as a checkbox.
1180
+ */
1181
+ readonly checked?: undefined;
1182
+ }
1183
+ /**
1184
+ * A contract for a form control that edits a boolean checkbox `Field`. Any component that
1185
+ * implements this contract can be used with the `Control` directive.
1186
+ *
1187
+ * Many of the properties declared on this contract are optional. They do not need to be
1188
+ * implemented, but if they are will be kept in sync with the field state of the field bound to the
1189
+ * `Control` directive.
1190
+ *
1191
+ * @experimental 21.0.0
1192
+ */
1193
+ interface FormCheckboxControl extends FormUiControl {
1194
+ /**
1195
+ * The checked is the only required property in this contract. A component that wants to integrate
1196
+ * with the `Control` directive, *must* provide a `model()` that will be kept in sync with the
1197
+ * value of the bound `Field`.
1198
+ */
1199
+ readonly checked: ModelSignal<boolean>;
1200
+ /**
1201
+ * The implementing component *must not* define a `value` property. This is reserved for
1202
+ * components that want to integrate with the `Control` directive as a standard input.
1203
+ */
1204
+ readonly value?: undefined;
1205
+ }
1206
+
1207
+ /**
1208
+ * Adds logic to a field to conditionally disable it. A disabled field does not contribute to the
1209
+ * validation, touched/dirty, or other state of its parent field.
1210
+ *
1211
+ * @param path The target path to add the disabled logic to.
1212
+ * @param logic A reactive function that returns `true` (or a string reason) when the field is disabled,
1213
+ * and `false` when it is not disabled.
1214
+ * @template TValue The type of value stored in the field the logic is bound to.
1215
+ * @template TPathKind The kind of path the logic is bound to (a root path, child path, or item of an array)
1216
+ *
1217
+ * @experimental 21.0.0
1218
+ */
1219
+ declare function disabled<TValue, TPathKind extends PathKind = PathKind.Root>(path: FieldPath<TValue, TPathKind>, logic?: string | NoInfer<LogicFn<TValue, boolean | string, TPathKind>>): void;
1220
+ /**
1221
+ * Adds logic to a field to conditionally make it readonly. A readonly field does not contribute to
1222
+ * the validation, touched/dirty, or other state of its parent field.
1223
+ *
1224
+ * @param path The target path to make readonly.
1225
+ * @param logic A reactive function that returns `true` when the field is readonly.
1226
+ * @template TValue The type of value stored in the field the logic is bound to.
1227
+ * @template TPathKind The kind of path the logic is bound to (a root path, child path, or item of an array)
1228
+ *
1229
+ * @experimental 21.0.0
1230
+ */
1231
+ declare function readonly<TValue, TPathKind extends PathKind = PathKind.Root>(path: FieldPath<TValue, TPathKind>, logic?: NoInfer<LogicFn<TValue, boolean, TPathKind>>): void;
1232
+ /**
1233
+ * Adds logic to a field to conditionally hide it. A hidden field does not contribute to the
1234
+ * validation, touched/dirty, or other state of its parent field.
1235
+ *
1236
+ * If a field may be hidden it is recommended to guard it with an `@if` in the template:
1237
+ * ```
1238
+ * @if (!email().hidden()) {
1239
+ * <label for="email">Email</label>
1240
+ * <input id="email" type="email" [control]="email" />
1241
+ * }
1242
+ * ```
1243
+ *
1244
+ * @param path The target path to add the hidden logic to.
1245
+ * @param logic A reactive function that returns `true` when the field is hidden.
1246
+ * @template TValue The type of value stored in the field the logic is bound to.
1247
+ * @template TPathKind The kind of path the logic is bound to (a root path, child path, or item of an array)
1248
+ *
1249
+ * @experimental 21.0.0
1250
+ */
1251
+ declare function hidden<TValue, TPathKind extends PathKind = PathKind.Root>(path: FieldPath<TValue, TPathKind>, logic: NoInfer<LogicFn<TValue, boolean, TPathKind>>): void;
1252
+ /**
1253
+ * Adds logic to a field to determine if the field has validation errors.
1254
+ *
1255
+ * @param path The target path to add the validation logic to.
1256
+ * @param logic A `Validator` that returns the current validation errors.
1257
+ * @template TValue The type of value stored in the field the logic is bound to.
1258
+ * @template TPathKind The kind of path the logic is bound to (a root path, child path, or item of an array)
1259
+ *
1260
+ * @experimental 21.0.0
1261
+ */
1262
+ declare function validate<TValue, TPathKind extends PathKind = PathKind.Root>(path: FieldPath<TValue, TPathKind>, logic: NoInfer<FieldValidator<TValue, TPathKind>>): void;
1263
+ /**
1264
+ * Adds logic to a field to determine if the field or any of its child fields has validation errors.
1265
+ *
1266
+ * @param path The target path to add the validation logic to.
1267
+ * @param logic A `TreeValidator` that returns the current validation errors.
1268
+ * Errors returned by the validator may specify a target field to indicate an error on a child field.
1269
+ * @template TValue The type of value stored in the field the logic is bound to.
1270
+ * @template TPathKind The kind of path the logic is bound to (a root path, child path, or item of an array)
1271
+ *
1272
+ * @experimental 21.0.0
1273
+ */
1274
+ declare function validateTree<TValue, TPathKind extends PathKind = PathKind.Root>(path: FieldPath<TValue, TPathKind>, logic: NoInfer<TreeValidator<TValue, TPathKind>>): void;
1275
+ /**
1276
+ * Adds a value to an `AggregateProperty` of a field.
1277
+ *
1278
+ * @param path The target path to set the aggregate property on.
1279
+ * @param prop The aggregate property
1280
+ * @param logic A function that receives the `FieldContext` and returns a value to add to the aggregate property.
1281
+ * @template TValue The type of value stored in the field the logic is bound to.
1282
+ * @template TPropItem The type of value the property aggregates over.
1283
+ * @template TPathKind The kind of path the logic is bound to (a root path, child path, or item of an array)
1284
+ *
1285
+ * @experimental 21.0.0
1286
+ */
1287
+ declare function aggregateProperty<TValue, TPropItem, TPathKind extends PathKind = PathKind.Root>(path: FieldPath<TValue, TPathKind>, prop: AggregateProperty<any, TPropItem>, logic: NoInfer<LogicFn<TValue, TPropItem, TPathKind>>): void;
1288
+ /**
1289
+ * Creates a new `Property` and defines the value of the new property for the given field.
1290
+ *
1291
+ * @param path The path to define the property for.
1292
+ * @param factory A factory function that creates the value for the property.
1293
+ * This function is **not** reactive. It is run once when the field is created.
1294
+ * @returns The newly created property
1295
+ *
1296
+ * @experimental 21.0.0
1297
+ */
1298
+ declare function property<TValue, TData, TPathKind extends PathKind = PathKind.Root>(path: FieldPath<TValue, TPathKind>, factory: (ctx: FieldContext<TValue, TPathKind>) => TData): Property<TData>;
1299
+ /**
1300
+ * Defines the value of a `Property` for a given field.
1301
+ *
1302
+ * @param path The path to define the property for.
1303
+ * @param prop The property to define.
1304
+ * @param factory A factory function that creates the value for the property.
1305
+ * This function is **not** reactive. It is run once when the field is created.
1306
+ * @returns The given property
1307
+ *
1308
+ * @experimental 21.0.0
1309
+ */
1310
+ declare function property<TValue, TData, TPathKind extends PathKind = PathKind.Root>(path: FieldPath<TValue, TPathKind>, prop: Property<TData>, factory: (ctx: FieldContext<TValue, TPathKind>) => TData): Property<TData>;
1311
+
1312
+ /** Represents a result that should be ignored because its predicate indicates it is not active. */
1313
+ declare const IGNORED: unique symbol;
1314
+ /**
1315
+ * A predicate that indicates whether an `AbstractLogic` instance is currently active, or should be
1316
+ * ignored.
1317
+ */
1318
+ interface Predicate {
1319
+ /** A boolean logic function that returns true if the logic is considered active. */
1320
+ readonly fn: LogicFn<any, boolean>;
1321
+ /**
1322
+ * The path which this predicate was created for. This is used to determine the correct
1323
+ * `FieldContext` to pass to the predicate function.
1324
+ */
1325
+ readonly path: FieldPath<any>;
1326
+ }
1327
+ /**
1328
+ * Represents a predicate that is bound to a particular depth in the field tree. This is needed for
1329
+ * recursively applied logic to ensure that the predicate is evaluated against the correct
1330
+ * application of that logic.
1331
+ *
1332
+ * Consider the following example:
1333
+ *
1334
+ * ```
1335
+ * const s = schema(p => {
1336
+ * disabled(p.data);
1337
+ * applyWhen(p.next, ({valueOf}) => valueOf(p.data) === 1, s);
1338
+ * });
1339
+ *
1340
+ * const f = form(signal({data: 0, next: {data: 1, next: {data: 2, next: undefined}}}), s);
1341
+ *
1342
+ * const isDisabled = f.next.next.data().disabled();
1343
+ * ```
1344
+ *
1345
+ * In order to determine `isDisabled` we need to evaluate the predicate from `applyWhen` *twice*.
1346
+ * Once to see if the schema should be applied to `f.next` and again to see if it should be applied
1347
+ * to `f.next.next`. The `depth` tells us which field we should be evaluating against each time.
1348
+ */
1349
+ interface BoundPredicate extends Predicate {
1350
+ /** The depth in the field tree at which this predicate is bound. */
1351
+ readonly depth: number;
1352
+ }
1353
+ /**
1354
+ * Base class for all logic. It is responsible for combining the results from multiple individual
1355
+ * logic functions registered in the schema, and using them to derive the value for some associated
1356
+ * piece of field state.
1357
+ */
1358
+ declare abstract class AbstractLogic<TReturn, TValue = TReturn> {
1359
+ /**
1360
+ * A list of predicates that conditionally enable all logic in this logic instance.
1361
+ * The logic is only enabled when *all* of the predicates evaluate to true.
1362
+ */
1363
+ private predicates;
1364
+ /** The set of logic functions that contribute to the value of the associated state. */
1365
+ protected readonly fns: Array<LogicFn<any, TValue | typeof IGNORED>>;
1366
+ constructor(
1367
+ /**
1368
+ * A list of predicates that conditionally enable all logic in this logic instance.
1369
+ * The logic is only enabled when *all* of the predicates evaluate to true.
1370
+ */
1371
+ predicates: ReadonlyArray<BoundPredicate>);
1372
+ /**
1373
+ * Computes the value of the associated field state based on the logic functions and predicates
1374
+ * registered with this logic instance.
1375
+ */
1376
+ abstract compute(arg: FieldContext<any>): TReturn;
1377
+ /**
1378
+ * The default value that the associated field state should assume if there are no logic functions
1379
+ * registered by the schema (or if the logic is disabled by a predicate).
1380
+ */
1381
+ abstract get defaultValue(): TReturn;
1382
+ /** Registers a logic function with this logic instance. */
1383
+ push(logicFn: LogicFn<any, TValue>): void;
1384
+ /**
1385
+ * Merges in the logic from another logic instance, subject to the predicates of both the other
1386
+ * instance and this instance.
1387
+ */
1388
+ mergeIn(other: AbstractLogic<TReturn, TValue>): void;
1389
+ }
1390
+ /** Logic that combines its individual logic function results with logical OR. */
1391
+ declare class BooleanOrLogic extends AbstractLogic<boolean> {
1392
+ get defaultValue(): boolean;
1393
+ compute(arg: FieldContext<any>): boolean;
1394
+ }
1395
+ /**
1396
+ * Logic that combines its individual logic function results by aggregating them in an array.
1397
+ * Depending on its `ignore` function it may ignore certain values, omitting them from the array.
1398
+ */
1399
+ declare class ArrayMergeIgnoreLogic<TElement, TIgnore = never> extends AbstractLogic<readonly TElement[], TElement | readonly (TElement | TIgnore)[] | TIgnore | undefined | void> {
1400
+ private ignore;
1401
+ /** Creates an instance of this class that ignores `null` values. */
1402
+ static ignoreNull<TElement>(predicates: ReadonlyArray<BoundPredicate>): ArrayMergeIgnoreLogic<TElement, null>;
1403
+ constructor(predicates: ReadonlyArray<BoundPredicate>, ignore: undefined | ((e: TElement | undefined | TIgnore) => e is TIgnore));
1404
+ get defaultValue(): never[];
1405
+ compute(arg: FieldContext<any>): readonly TElement[];
1406
+ }
1407
+ /** Logic that combines its individual logic function results by aggregating them in an array. */
1408
+ declare class ArrayMergeLogic<TElement> extends ArrayMergeIgnoreLogic<TElement, never> {
1409
+ constructor(predicates: ReadonlyArray<BoundPredicate>);
1410
+ }
1411
+ /**
1412
+ * Container for all the different types of logic that can be applied to a field
1413
+ * (disabled, hidden, errors, etc.)
1414
+ */
1415
+ declare class LogicContainer {
1416
+ private predicates;
1417
+ /** Logic that determines if the field is hidden. */
1418
+ readonly hidden: BooleanOrLogic;
1419
+ /** Logic that determines reasons for the field being disabled. */
1420
+ readonly disabledReasons: ArrayMergeLogic<DisabledReason>;
1421
+ /** Logic that determines if the field is read-only. */
1422
+ readonly readonly: BooleanOrLogic;
1423
+ /** Logic that produces synchronous validation errors for the field. */
1424
+ readonly syncErrors: ArrayMergeIgnoreLogic<ValidationError, null>;
1425
+ /** Logic that produces synchronous validation errors for the field's subtree. */
1426
+ readonly syncTreeErrors: ArrayMergeIgnoreLogic<ValidationError, null>;
1427
+ /** Logic that produces asynchronous validation results (errors or 'pending'). */
1428
+ readonly asyncErrors: ArrayMergeIgnoreLogic<ValidationError | 'pending', null>;
1429
+ /** A map of aggregate properties to the `AbstractLogic` instances that compute their values. */
1430
+ private readonly aggregateProperties;
1431
+ /** A map of property keys to the factory functions that create their values. */
1432
+ private readonly propertyFactories;
1433
+ /**
1434
+ * Constructs a new `Logic` container.
1435
+ * @param predicates An array of predicates that must all be true for the logic
1436
+ * functions within this container to be active.
1437
+ */
1438
+ constructor(predicates: ReadonlyArray<BoundPredicate>);
1439
+ /** Checks whether there is logic for the given aggregate property. */
1440
+ hasAggregateProperty(prop: AggregateProperty<unknown, unknown>): boolean;
1441
+ /**
1442
+ * Gets an iterable of [aggregate property, logic function] pairs.
1443
+ * @returns An iterable of aggregate property entries.
1444
+ */
1445
+ getAggregatePropertyEntries(): MapIterator<[AggregateProperty<unknown, unknown>, AbstractLogic<unknown, unknown>]>;
1446
+ /**
1447
+ * Gets an iterable of [property, value factory function] pairs.
1448
+ * @returns An iterable of property factory entries.
1449
+ */
1450
+ getPropertyFactoryEntries(): MapIterator<[Property<unknown>, (ctx: FieldContext<unknown>) => unknown]>;
1451
+ /**
1452
+ * Retrieves or creates the `AbstractLogic` for a given aggregate property.
1453
+ * @param prop The `AggregateProperty` for which to get the logic.
1454
+ * @returns The `AbstractLogic` associated with the key.
1455
+ */
1456
+ getAggregateProperty<T>(prop: AggregateProperty<unknown, T>): AbstractLogic<T>;
1457
+ /**
1458
+ * Adds a factory function for a given property.
1459
+ * @param prop The `Property` to associate the factory with.
1460
+ * @param factory The factory function.
1461
+ * @throws If a factory is already defined for the given key.
1462
+ */
1463
+ addPropertyFactory(prop: Property<unknown>, factory: (ctx: FieldContext<unknown>) => unknown): void;
1464
+ /**
1465
+ * Merges logic from another `Logic` instance into this one.
1466
+ * @param other The `Logic` instance to merge from.
1467
+ */
1468
+ mergeIn(other: LogicContainer): void;
1469
+ }
1470
+
1471
+ /**
1472
+ * Abstract base class for building a `LogicNode`.
1473
+ * This class defines the interface for adding various logic rules (e.g., hidden, disabled)
1474
+ * and data factories to a node in the logic tree.
1475
+ * LogicNodeBuilders are 1:1 with nodes in the Schema tree.
1476
+ */
1477
+ declare abstract class AbstractLogicNodeBuilder {
1478
+ /** The depth of this node in the schema tree. */
1479
+ protected readonly depth: number;
1480
+ constructor(
1481
+ /** The depth of this node in the schema tree. */
1482
+ depth: number);
1483
+ /** Adds a rule to determine if a field should be hidden. */
1484
+ abstract addHiddenRule(logic: LogicFn<any, boolean>): void;
1485
+ /** Adds a rule to determine if a field should be disabled, and for what reason. */
1486
+ abstract addDisabledReasonRule(logic: LogicFn<any, DisabledReason | undefined>): void;
1487
+ /** Adds a rule to determine if a field should be read-only. */
1488
+ abstract addReadonlyRule(logic: LogicFn<any, boolean>): void;
1489
+ /** Adds a rule for synchronous validation errors for a field. */
1490
+ abstract addSyncErrorRule(logic: LogicFn<any, ValidationResult>): void;
1491
+ /** Adds a rule for synchronous validation errors that apply to a subtree. */
1492
+ abstract addSyncTreeErrorRule(logic: LogicFn<any, ValidationResult>): void;
1493
+ /** Adds a rule for asynchronous validation errors for a field. */
1494
+ abstract addAsyncErrorRule(logic: LogicFn<any, AsyncValidationResult>): void;
1495
+ /** Adds a rule to compute an aggregate property for a field. */
1496
+ abstract addAggregatePropertyRule<M>(key: AggregateProperty<unknown, M>, logic: LogicFn<any, M>): void;
1497
+ /** Adds a factory function to produce a data value associated with a field. */
1498
+ abstract addPropertyFactory<D>(key: Property<D>, factory: (ctx: FieldContext<any>) => D): void;
1499
+ /**
1500
+ * Gets a builder for a child node associated with the given property key.
1501
+ * @param key The property key of the child.
1502
+ * @returns A `LogicNodeBuilder` for the child.
1503
+ */
1504
+ abstract getChild(key: PropertyKey): LogicNodeBuilder;
1505
+ /**
1506
+ * Checks whether a particular `AbstractLogicNodeBuilder` has been merged into this one.
1507
+ * @param builder The builder to check for.
1508
+ * @returns True if the builder has been merged, false otherwise.
1509
+ */
1510
+ abstract hasLogic(builder: AbstractLogicNodeBuilder): boolean;
1511
+ /**
1512
+ * Builds the `LogicNode` from the accumulated rules and child builders.
1513
+ * @returns The constructed `LogicNode`.
1514
+ */
1515
+ build(): LogicNode;
1516
+ }
1517
+ /**
1518
+ * A builder for `LogicNode`. Used to add logic to the final `LogicNode` tree.
1519
+ * This builder supports merging multiple sources of logic, potentially with predicates,
1520
+ * preserving the order of rule application.
1521
+ */
1522
+ declare class LogicNodeBuilder extends AbstractLogicNodeBuilder {
1523
+ constructor(depth: number);
1524
+ /**
1525
+ * The current `NonMergeableLogicNodeBuilder` being used to add rules directly to this
1526
+ * `LogicNodeBuilder`. Do not use this directly, call `getCurrent()` which will create a current
1527
+ * builder if there is none.
1528
+ */
1529
+ private current;
1530
+ /**
1531
+ * Stores all builders that contribute to this node, along with any predicates
1532
+ * that gate their application.
1533
+ */
1534
+ readonly all: {
1535
+ builder: AbstractLogicNodeBuilder;
1536
+ predicate?: Predicate;
1537
+ }[];
1538
+ addHiddenRule(logic: LogicFn<any, boolean>): void;
1539
+ addDisabledReasonRule(logic: LogicFn<any, DisabledReason | undefined>): void;
1540
+ addReadonlyRule(logic: LogicFn<any, boolean>): void;
1541
+ addSyncErrorRule(logic: LogicFn<any, ValidationResult>): void;
1542
+ addSyncTreeErrorRule(logic: LogicFn<any, ValidationResult>): void;
1543
+ addAsyncErrorRule(logic: LogicFn<any, AsyncValidationResult>): void;
1544
+ addAggregatePropertyRule<T>(key: AggregateProperty<unknown, T>, logic: LogicFn<any, T>): void;
1545
+ addPropertyFactory<D>(key: Property<D>, factory: (ctx: FieldContext<any>) => D): void;
1546
+ getChild(key: PropertyKey): LogicNodeBuilder;
1547
+ hasLogic(builder: AbstractLogicNodeBuilder): boolean;
1548
+ /**
1549
+ * Merges logic from another `LogicNodeBuilder` into this one.
1550
+ * If a `predicate` is provided, all logic from the `other` builder will only apply
1551
+ * when the predicate evaluates to true.
1552
+ * @param other The `LogicNodeBuilder` to merge in.
1553
+ * @param predicate An optional predicate to gate the merged logic.
1554
+ */
1555
+ mergeIn(other: LogicNodeBuilder, predicate?: Predicate): void;
1556
+ /**
1557
+ * Gets the current `NonMergeableLogicNodeBuilder` for adding rules directly to this
1558
+ * `LogicNodeBuilder`. If no current builder exists, a new one is created.
1559
+ * The current builder is cleared whenever `mergeIn` is called to preserve the order
1560
+ * of rules when merging separate builder trees.
1561
+ * @returns The current `NonMergeableLogicNodeBuilder`.
1562
+ */
1563
+ private getCurrent;
1564
+ /**
1565
+ * Creates a new root `LogicNodeBuilder`.
1566
+ * @returns A new instance of `LogicNodeBuilder`.
1567
+ */
1568
+ static newRoot(): LogicNodeBuilder;
1569
+ }
1570
+ /**
1571
+ * Represents a node in the logic tree, containing all logic applicable
1572
+ * to a specific field or path in the form structure.
1573
+ * LogicNodes are 1:1 with nodes in the Field tree.
1574
+ */
1575
+ interface LogicNode {
1576
+ /** The collection of logic rules (hidden, disabled, errors, etc.) for this node. */
1577
+ readonly logic: LogicContainer;
1578
+ /**
1579
+ * Retrieves the `LogicNode` for a child identified by the given property key.
1580
+ * @param key The property key of the child.
1581
+ * @returns The `LogicNode` for the specified child.
1582
+ */
1583
+ getChild(key: PropertyKey): LogicNode;
1584
+ /**
1585
+ * Checks whether the logic from a particular `AbstractLogicNodeBuilder` has been merged into this
1586
+ * node.
1587
+ * @param builder The builder to check for.
1588
+ * @returns True if the builder has been merged, false otherwise.
1589
+ */
1590
+ hasLogic(builder: AbstractLogicNodeBuilder): boolean;
1591
+ }
1592
+
1593
+ /**
1594
+ * Implements the `Schema` concept.
1595
+ */
1596
+ declare class SchemaImpl {
1597
+ private schemaFn;
1598
+ constructor(schemaFn: SchemaFn<unknown>);
1599
+ /**
1600
+ * Compiles this schema within the current root compilation context. If the schema was previously
1601
+ * compiled within this context, we reuse the cached FieldPathNode, otherwise we create a new one
1602
+ * and cache it in the compilation context.
1603
+ */
1604
+ compile(): FieldPathNode;
1605
+ /**
1606
+ * Creates a SchemaImpl from the given SchemaOrSchemaFn.
1607
+ */
1608
+ static create(schema: SchemaImpl | SchemaOrSchemaFn<any>): SchemaImpl;
1609
+ /**
1610
+ * Compiles the given schema in a fresh compilation context. This clears the cached results of any
1611
+ * previous compilations.
1612
+ */
1613
+ static rootCompile(schema: SchemaImpl | SchemaOrSchemaFn<any> | undefined): FieldPathNode;
1614
+ }
1615
+
1616
+ /**
1617
+ * A path in the schema on which logic is stored so that it can be added to the corresponding field
1618
+ * when the field is created.
1619
+ */
1620
+ declare class FieldPathNode {
1621
+ /** The property keys used to navigate from the root path to this path. */
1622
+ readonly keys: PropertyKey[];
1623
+ /** The logic builder used to accumulate logic on this path node. */
1624
+ readonly logic: LogicNodeBuilder;
1625
+ /** The root path node from which this path node is descended. */
1626
+ readonly root: FieldPathNode;
1627
+ /**
1628
+ * A map containing all child path nodes that have been created on this path.
1629
+ * Child path nodes are created automatically on first access if they do not exist already.
1630
+ */
1631
+ private readonly children;
1632
+ /**
1633
+ * A proxy that wraps the path node, allowing navigation to its child paths via property access.
1634
+ */
1635
+ readonly fieldPathProxy: FieldPath<any>;
1636
+ protected constructor(
1637
+ /** The property keys used to navigate from the root path to this path. */
1638
+ keys: PropertyKey[],
1639
+ /** The logic builder used to accumulate logic on this path node. */
1640
+ logic: LogicNodeBuilder, root: FieldPathNode);
1641
+ /**
1642
+ * Gets the special path node containing the per-element logic that applies to *all* children paths.
1643
+ */
1644
+ get element(): FieldPathNode;
1645
+ /**
1646
+ * Gets the path node for the given child property key.
1647
+ * Child paths are created automatically on first access if they do not exist already.
1648
+ */
1649
+ getChild(key: PropertyKey): FieldPathNode;
1650
+ /**
1651
+ * Merges in logic from another schema to this one.
1652
+ * @param other The other schema to merge in the logic from
1653
+ * @param predicate A predicate indicating when the merged in logic should be active.
1654
+ */
1655
+ mergeIn(other: SchemaImpl, predicate?: Predicate): void;
1656
+ /** Extracts the underlying path node from the given path proxy. */
1657
+ static unwrapFieldPath(formPath: FieldPath<unknown>): FieldPathNode;
1658
+ /** Creates a new root path node to be passed in to a schema function. */
1659
+ static newRoot(): FieldPathNode;
1660
+ }
1661
+
1662
+ /**
1663
+ * Tracks custom properties associated with a `FieldNode`.
1664
+ */
1665
+ declare class FieldPropertyState {
1666
+ private readonly node;
1667
+ /** A map of all `Property` and `AggregateProperty` that have been defined for this field. */
1668
+ private readonly properties;
1669
+ constructor(node: FieldNode);
1670
+ /** Gets the value of a `Property` or `AggregateProperty` for the field. */
1671
+ get<T>(prop: Property<T> | AggregateProperty<T, unknown>): T | undefined | Signal<T>;
1672
+ /**
1673
+ * Checks whether the current property state has the given property.
1674
+ * @param prop
1675
+ * @returns
1676
+ */
1677
+ has(prop: Property<unknown> | AggregateProperty<unknown, unknown>): boolean;
1678
+ }
1679
+
1680
+ /**
1681
+ * The non-validation and non-submit state associated with a `FieldNode`, such as touched and dirty
1682
+ * status, as well as derived logical state.
1683
+ */
1684
+ declare class FieldNodeState {
1685
+ private readonly node;
1686
+ /**
1687
+ * Indicates whether this field has been touched directly by the user (as opposed to indirectly by
1688
+ * touching a child field).
1689
+ *
1690
+ * A field is considered directly touched when a user stops editing it for the first time (i.e. on blur)
1691
+ */
1692
+ private readonly selfTouched;
1693
+ /**
1694
+ * Indicates whether this field has been dirtied directly by the user (as opposed to indirectly by
1695
+ * dirtying a child field).
1696
+ *
1697
+ * A field is considered directly dirtied if a user changed the value of the field at least once.
1698
+ */
1699
+ private readonly selfDirty;
1700
+ /**
1701
+ * Marks this specific field as touched.
1702
+ */
1703
+ markAsTouched(): void;
1704
+ /**
1705
+ * Marks this specific field as dirty.
1706
+ */
1707
+ markAsDirty(): void;
1708
+ /**
1709
+ * Marks this specific field as not dirty.
1710
+ */
1711
+ markAsPristine(): void;
1712
+ /**
1713
+ * Marks this specific field as not touched.
1714
+ */
1715
+ markAsUntouched(): void;
1716
+ /** The UI controls the field is currently bound to. */
1717
+ readonly controls: i0.WritableSignal<readonly Control<unknown>[]>;
1718
+ constructor(node: FieldNode);
1719
+ /**
1720
+ * Whether this field is considered dirty.
1721
+ *
1722
+ * A field is considered dirty if one of the following is true:
1723
+ * - It was directly dirtied
1724
+ * - One of its children is considered dirty
1725
+ */
1726
+ readonly dirty: Signal<boolean>;
1727
+ /**
1728
+ * Whether this field is considered touched.
1729
+ *
1730
+ * A field is considered touched if one of the following is true:
1731
+ * - It was directly touched
1732
+ * - One of its children is considered touched
1733
+ */
1734
+ readonly touched: Signal<boolean>;
1735
+ /**
1736
+ * The reasons for this field's disablement. This includes disabled reasons for any parent field
1737
+ * that may have been disabled, indirectly causing this field to be disabled as well.
1738
+ * The `field` property of the `DisabledReason` can be used to determine which field ultimately
1739
+ * caused the disablement.
1740
+ */
1741
+ readonly disabledReasons: Signal<readonly DisabledReason[]>;
1742
+ /**
1743
+ * Whether this field is considered disabled.
1744
+ *
1745
+ * A field is considered disabled if one of the following is true:
1746
+ * - The schema contains logic that directly disabled it
1747
+ * - Its parent field is considered disabled
1748
+ */
1749
+ readonly disabled: Signal<boolean>;
1750
+ /**
1751
+ * Whether this field is considered readonly.
1752
+ *
1753
+ * A field is considered readonly if one of the following is true:
1754
+ * - The schema contains logic that directly made it readonly
1755
+ * - Its parent field is considered readonly
1756
+ */
1757
+ readonly readonly: Signal<boolean>;
1758
+ /**
1759
+ * Whether this field is considered hidden.
1760
+ *
1761
+ * A field is considered hidden if one of the following is true:
1762
+ * - The schema contains logic that directly hides it
1763
+ * - Its parent field is considered hidden
1764
+ */
1765
+ readonly hidden: Signal<boolean>;
1766
+ readonly name: Signal<string>;
1767
+ }
1768
+
1769
+ /**
1770
+ * State of a `FieldNode` that's associated with form submission.
1771
+ */
1772
+ declare class FieldSubmitState {
1773
+ private readonly node;
1774
+ /**
1775
+ * Whether this field was directly submitted (as opposed to indirectly by a parent field being submitted)
1776
+ * and is still in the process of submitting.
1777
+ */
1778
+ readonly selfSubmitting: WritableSignal<boolean>;
1779
+ /** Server errors that are associated with this field. */
1780
+ readonly serverErrors: WritableSignal<readonly ValidationError[]>;
1781
+ constructor(node: FieldNode);
1782
+ /**
1783
+ * Whether this form is currently in the process of being submitted.
1784
+ * Either because the field was submitted directly, or because a parent field was submitted.
1785
+ */
1786
+ readonly submitting: Signal<boolean>;
1787
+ }
1788
+
1789
+ interface ValidationState {
1790
+ /**
1791
+ * The full set of synchronous tree errors visible to this field. This includes ones that are
1792
+ * targeted at a descendant field rather than at this field.
1793
+ */
1794
+ rawSyncTreeErrors: Signal<ValidationError[]>;
1795
+ /**
1796
+ * The full set of synchronous errors for this field, including synchronous tree errors and server
1797
+ * errors. Server errors are considered "synchronous" because they are imperatively added. From
1798
+ * the perspective of the field state they are either there or not, they are never in a pending
1799
+ * state.
1800
+ */
1801
+ syncErrors: Signal<ValidationError[]>;
1802
+ /**
1803
+ * Whether the field is considered valid according solely to its synchronous validators.
1804
+ * Errors resulting from a previous submit attempt are also considered for this state.
1805
+ */
1806
+ syncValid: Signal<boolean>;
1807
+ /**
1808
+ * The full set of asynchronous tree errors visible to this field. This includes ones that are
1809
+ * targeted at a descendant field rather than at this field, as well as sentinel 'pending' values
1810
+ * indicating that the validator is still running and an error could still occur.
1811
+ */
1812
+ rawAsyncErrors: Signal<(ValidationError | 'pending')[]>;
1813
+ /**
1814
+ * The asynchronous tree errors visible to this field that are specifically targeted at this field
1815
+ * rather than a descendant. This also includes all 'pending' sentinel values, since those could
1816
+ * theoretically result in errors for this field.
1817
+ */
1818
+ asyncErrors: Signal<(ValidationError | 'pending')[]>;
1819
+ /**
1820
+ * The combined set of all errors that currently apply to this field.
1821
+ */
1822
+ errors: Signal<ValidationError[]>;
1823
+ /**
1824
+ * The combined set of all errors that currently apply to this field and its descendants.
1825
+ */
1826
+ errorSummary: Signal<ValidationError[]>;
1827
+ /**
1828
+ * Whether this field has any asynchronous validators still pending.
1829
+ */
1830
+ pending: Signal<boolean>;
1831
+ /**
1832
+ * The validation status of the field.
1833
+ * - The status is 'valid' if neither the field nor any of its children has any errors or pending
1834
+ * validators.
1835
+ * - The status is 'invalid' if the field or any of its children has an error
1836
+ * (regardless of pending validators)
1837
+ * - The status is 'unknown' if neither the field nor any of its children has any errors,
1838
+ * but the field or any of its children does have a pending validator.
1839
+ *
1840
+ * A field is considered valid if *all* of the following are true:
1841
+ * - It has no errors or pending validators
1842
+ * - All of its children are considered valid
1843
+ * A field is considered invalid if *any* of the following are true:
1844
+ * - It has an error
1845
+ * - Any of its children is considered invalid
1846
+ * A field is considered to have unknown validity status if it is not valid or invalid.
1847
+ */
1848
+ status: Signal<'valid' | 'invalid' | 'unknown'>;
1849
+ /**
1850
+ * Whether the field is considered valid.
1851
+ *
1852
+ * A field is considered valid if *all* of the following are true:
1853
+ * - It has no errors or pending validators
1854
+ * - All of its children are considered valid
1855
+ *
1856
+ * Note: `!valid()` is *not* the same as `invalid()`. Both `valid()` and `invalid()` can be false
1857
+ * if there are currently no errors, but validators are still pending.
1858
+ */
1859
+ valid: Signal<boolean>;
1860
+ /**
1861
+ * Whether the field is considered invalid.
1862
+ *
1863
+ * A field is considered invalid if *any* of the following are true:
1864
+ * - It has an error
1865
+ * - Any of its children is considered invalid
1866
+ *
1867
+ * Note: `!invalid()` is *not* the same as `valid()`. Both `valid()` and `invalid()` can be false
1868
+ * if there are currently no errors, but validators are still pending.
1869
+ */
1870
+ invalid: Signal<boolean>;
1871
+ /**
1872
+ * Indicates whether validation should be skipped for this field because it is hidden, disabled,
1873
+ * or readonly.
1874
+ */
1875
+ shouldSkipValidation: Signal<boolean>;
1876
+ }
1877
+
1878
+ /**
1879
+ * Internal node in the form tree for a given field.
1880
+ *
1881
+ * Field nodes have several responsibilities:
1882
+ * - They track instance state for the particular field (touched)
1883
+ * - They compute signals for derived state (valid, disabled, etc) based on their associated
1884
+ * `LogicNode`
1885
+ * - They act as the public API for the field (they implement the `FieldState` interface)
1886
+ * - They implement navigation of the form tree via `.parent` and `.getChild()`.
1887
+ *
1888
+ * This class is largely a wrapper that aggregates several smaller pieces that each manage a subset of
1889
+ * the responsibilities.
1890
+ */
1891
+ declare class FieldNode implements FieldState<unknown> {
1892
+ readonly structure: FieldNodeStructure;
1893
+ readonly validationState: ValidationState;
1894
+ readonly propertyState: FieldPropertyState;
1895
+ readonly nodeState: FieldNodeState;
1896
+ readonly submitState: FieldSubmitState;
1897
+ private _context;
1898
+ readonly fieldAdapter: FieldAdapter;
1899
+ get context(): FieldContext<unknown>;
1900
+ /**
1901
+ * Proxy to this node which allows navigation of the form graph below it.
1902
+ */
1903
+ readonly fieldProxy: Field<any>;
1904
+ constructor(options: FieldNodeOptions);
1905
+ get logicNode(): LogicNode;
1906
+ get value(): WritableSignal<unknown>;
1907
+ get keyInParent(): Signal<string | number>;
1908
+ get errors(): Signal<ValidationError[]>;
1909
+ get errorSummary(): Signal<ValidationError[]>;
1910
+ get pending(): Signal<boolean>;
1911
+ get valid(): Signal<boolean>;
1912
+ get invalid(): Signal<boolean>;
1913
+ get dirty(): Signal<boolean>;
1914
+ get touched(): Signal<boolean>;
1915
+ get disabled(): Signal<boolean>;
1916
+ get disabledReasons(): Signal<readonly DisabledReason[]>;
1917
+ get hidden(): Signal<boolean>;
1918
+ get readonly(): Signal<boolean>;
1919
+ get controls(): Signal<readonly Control<unknown>[]>;
1920
+ get submitting(): Signal<boolean>;
1921
+ get name(): Signal<string>;
1922
+ property<M>(prop: AggregateProperty<M, any>): Signal<M>;
1923
+ property<M>(prop: Property<M>): M | undefined;
1924
+ hasProperty(prop: Property<unknown> | AggregateProperty<unknown, any>): boolean;
1925
+ /**
1926
+ * Marks this specific field as touched.
1927
+ */
1928
+ markAsTouched(): void;
1929
+ /**
1930
+ * Marks this specific field as dirty.
1931
+ */
1932
+ markAsDirty(): void;
1933
+ /**
1934
+ * Resets the {@link touched} and {@link dirty} state of the field and its descendants.
1935
+ *
1936
+ * Note this does not change the data model, which can be reset directly if desired.
1937
+ */
1938
+ reset(): void;
1939
+ /**
1940
+ * Creates a new root field node for a new form.
1941
+ */
1942
+ static newRoot<T>(fieldManager: FormFieldManager, value: WritableSignal<T>, pathNode: FieldPathNode, adapter: FieldAdapter): FieldNode;
1943
+ /**
1944
+ * Creates a child field node based on the given options.
1945
+ */
1946
+ private static newChild;
1947
+ createStructure(options: FieldNodeOptions): RootFieldNodeStructure | ChildFieldNodeStructure;
1948
+ }
1949
+ /**
1950
+ * Field node of a field that has children.
1951
+ * This simplifies and makes certain types cleaner.
1952
+ */
1953
+ interface ParentFieldNode extends FieldNode {
1954
+ readonly value: WritableSignal<Record<string, unknown>>;
1955
+ readonly structure: FieldNodeStructure & {
1956
+ value: WritableSignal<Record<string, unknown>>;
1957
+ };
1958
+ }
1959
+
1960
+ /**
1961
+ * Key by which a parent `FieldNode` tracks its children.
1962
+ *
1963
+ * Often this is the actual property key of the child, but in the case of arrays it could be a
1964
+ * tracking key allocated for the object.
1965
+ */
1966
+ type TrackingKey = PropertyKey & {
1967
+ __brand: 'FieldIdentity';
1968
+ };
1969
+ /** Structural component of a `FieldNode` which tracks its path, parent, and children. */
1970
+ declare abstract class FieldNodeStructure {
1971
+ /** The logic to apply to this field. */
1972
+ readonly logic: LogicNode;
1973
+ /** Computed map of child fields, based on the current value of this field. */
1974
+ abstract readonly childrenMap: Signal<Map<TrackingKey, FieldNode> | undefined>;
1975
+ /** The field's value. */
1976
+ abstract readonly value: WritableSignal<unknown>;
1977
+ /**
1978
+ * The key of this field in its parent field.
1979
+ * Attempting to read this for the root field will result in an error being thrown.
1980
+ */
1981
+ abstract readonly keyInParent: Signal<string>;
1982
+ /** The field manager responsible for managing this field. */
1983
+ abstract readonly fieldManager: FormFieldManager;
1984
+ /** The root field that this field descends from. */
1985
+ abstract readonly root: FieldNode;
1986
+ /** The list of property keys to follow to get from the `root` to this field. */
1987
+ abstract readonly pathKeys: Signal<readonly PropertyKey[]>;
1988
+ /** The parent field of this field. */
1989
+ abstract readonly parent: FieldNode | undefined;
1990
+ /** Added to array elements for tracking purposes. */
1991
+ readonly identitySymbol: symbol;
1992
+ /** Lazily initialized injector. Do not access directly, access via `injector` getter instead. */
1993
+ private _injector;
1994
+ /** Lazily initialized injector. */
1995
+ get injector(): DestroyableInjector;
1996
+ constructor(
1997
+ /** The logic to apply to this field. */
1998
+ logic: LogicNode);
1999
+ /** Gets the child fields of this field. */
2000
+ children(): Iterable<FieldNode>;
2001
+ /** Retrieve a child `FieldNode` of this node by property key. */
2002
+ getChild(key: PropertyKey): FieldNode | undefined;
2003
+ /** Destroys the field when it is no longer needed. */
2004
+ destroy(): void;
2005
+ }
2006
+ /** The structural component of a `FieldNode` that is the root of its field tree. */
2007
+ declare class RootFieldNodeStructure extends FieldNodeStructure {
2008
+ /** The full field node that corresponds to this structure. */
2009
+ private readonly node;
2010
+ readonly fieldManager: FormFieldManager;
2011
+ readonly value: WritableSignal<unknown>;
2012
+ get parent(): undefined;
2013
+ get root(): FieldNode;
2014
+ get pathKeys(): Signal<readonly PropertyKey[]>;
2015
+ get keyInParent(): Signal<string>;
2016
+ readonly childrenMap: Signal<Map<TrackingKey, FieldNode> | undefined>;
2017
+ /**
2018
+ * Creates the structure for the root node of a field tree.
2019
+ *
2020
+ * @param node The full field node that this structure belongs to
2021
+ * @param pathNode The path corresponding to this node in the schema
2022
+ * @param logic The logic to apply to this field
2023
+ * @param fieldManager The field manager for this field
2024
+ * @param value The value signal for this field
2025
+ * @param adapter Adapter that knows how to create new fields and appropriate state.
2026
+ * @param createChildNode A factory function to create child nodes for this field.
2027
+ */
2028
+ constructor(
2029
+ /** The full field node that corresponds to this structure. */
2030
+ node: FieldNode, pathNode: FieldPathNode, logic: LogicNode, fieldManager: FormFieldManager, value: WritableSignal<unknown>, adapter: FieldAdapter, createChildNode: (options: ChildFieldNodeOptions) => FieldNode);
2031
+ }
2032
+ /** The structural component of a child `FieldNode` within a field tree. */
2033
+ declare class ChildFieldNodeStructure extends FieldNodeStructure {
2034
+ readonly parent: ParentFieldNode;
2035
+ readonly root: FieldNode;
2036
+ readonly pathKeys: Signal<readonly PropertyKey[]>;
2037
+ readonly keyInParent: Signal<string>;
2038
+ readonly value: WritableSignal<unknown>;
2039
+ readonly childrenMap: Signal<Map<TrackingKey, FieldNode> | undefined>;
2040
+ get fieldManager(): FormFieldManager;
2041
+ /**
2042
+ * Creates the structure for a child field node in a field tree.
2043
+ *
2044
+ * @param node The full field node that this structure belongs to
2045
+ * @param pathNode The path corresponding to this node in the schema
2046
+ * @param logic The logic to apply to this field
2047
+ * @param parent The parent field node for this node
2048
+ * @param identityInParent The identity used to track this field in its parent
2049
+ * @param initialKeyInParent The key of this field in its parent at the time of creation
2050
+ * @param adapter Adapter that knows how to create new fields and appropriate state.
2051
+ * @param createChildNode A factory function to create child nodes for this field.
2052
+ */
2053
+ constructor(node: FieldNode, pathNode: FieldPathNode, logic: LogicNode, parent: ParentFieldNode, identityInParent: TrackingKey | undefined, initialKeyInParent: string, adapter: FieldAdapter, createChildNode: (options: ChildFieldNodeOptions) => FieldNode);
2054
+ }
2055
+ /** Options passed when constructing a root field node. */
2056
+ interface RootFieldNodeOptions {
2057
+ /** Kind of node, used to differentiate root node options from child node options. */
2058
+ readonly kind: 'root';
2059
+ /** The path node corresponding to this field in the schema. */
2060
+ readonly pathNode: FieldPathNode;
2061
+ /** The logic to apply to this field. */
2062
+ readonly logic: LogicNode;
2063
+ /** The value signal for this field. */
2064
+ readonly value: WritableSignal<unknown>;
2065
+ /** The field manager for this field. */
2066
+ readonly fieldManager: FormFieldManager;
2067
+ /** This allows for more granular field and state management, and is currently used for compat. */
2068
+ readonly fieldAdapter: FieldAdapter;
2069
+ }
2070
+ /** Options passed when constructing a child field node. */
2071
+ interface ChildFieldNodeOptions {
2072
+ /** Kind of node, used to differentiate root node options from child node options. */
2073
+ readonly kind: 'child';
2074
+ /** The parent field node of this field. */
2075
+ readonly parent: ParentFieldNode;
2076
+ /** The path node corresponding to this field in the schema. */
2077
+ readonly pathNode: FieldPathNode;
2078
+ /** The logic to apply to this field. */
2079
+ readonly logic: LogicNode;
2080
+ /** The key of this field in its parent at the time of creation. */
2081
+ readonly initialKeyInParent: string;
2082
+ /** The identity used to track this field in its parent. */
2083
+ readonly identityInParent: TrackingKey | undefined;
2084
+ /** This allows for more granular field and state management, and is currently used for compat. */
2085
+ readonly fieldAdapter: FieldAdapter;
2086
+ }
2087
+ /** Options passed when constructing a field node. */
2088
+ type FieldNodeOptions = RootFieldNodeOptions | ChildFieldNodeOptions;
2089
+
2090
+ /**
2091
+ * Manages the collection of fields associated with a given `form`.
2092
+ *
2093
+ * Fields are created implicitly, through reactivity, and may create "owned" entities like effects
2094
+ * or resources. When a field is no longer connected to the form, these owned entities should be
2095
+ * destroyed, which is the job of the `FormFieldManager`.
2096
+ */
2097
+ declare class FormFieldManager {
2098
+ readonly injector: Injector;
2099
+ readonly rootName: string;
2100
+ constructor(injector: Injector, rootName: string | undefined);
2101
+ /**
2102
+ * Contains all child field structures that have been created as part of the current form.
2103
+ * New child structures are automatically added when they are created.
2104
+ * Structures are destroyed and removed when they are no longer reachable from the root.
2105
+ */
2106
+ readonly structures: Set<FieldNodeStructure>;
2107
+ /**
2108
+ * Creates an effect that runs when the form's structure changes and checks for structures that
2109
+ * have become unreachable to clean up.
2110
+ *
2111
+ * For example, consider a form wrapped around the following model: `signal([0, 1, 2])`.
2112
+ * This form would have 4 nodes as part of its structure tree.
2113
+ * One structure for the root array, and one structure for each element of the array.
2114
+ * Now imagine the data is updated: `model.set([0])`. In this case the structure for the first
2115
+ * element can still be reached from the root, but the structures for the second and third
2116
+ * elements are now orphaned and not connected to the root. Thus they will be destroyed.
2117
+ *
2118
+ * @param root The root field structure.
2119
+ */
2120
+ createFieldManagementEffect(root: FieldNodeStructure): void;
2121
+ /**
2122
+ * Collects all structures reachable from the given structure into the given set.
2123
+ *
2124
+ * @param structure The root structure
2125
+ * @param liveStructures The set of reachable structures to populate
2126
+ */
2127
+ private markStructuresLive;
2128
+ }
2129
+
2130
+ /**
2131
+ * Adapter allowing customization of the creation logic for a field and its associated
2132
+ * structure and state.
2133
+ */
2134
+ interface FieldAdapter {
2135
+ /**
2136
+ * Creates a node structure.
2137
+ * @param node
2138
+ * @param options
2139
+ */
2140
+ createStructure(node: FieldNode, options: FieldNodeOptions): FieldNodeStructure;
2141
+ /**
2142
+ * Creates node validation state
2143
+ * @param param
2144
+ * @param options
2145
+ */
2146
+ createValidationState(param: FieldNode, options: FieldNodeOptions): ValidationState;
2147
+ /**
2148
+ * Creates node state.
2149
+ * @param param
2150
+ * @param options
2151
+ */
2152
+ createNodeState(param: FieldNode, options: FieldNodeOptions): FieldNodeState;
2153
+ /**
2154
+ * Creates a custom child node.
2155
+ * @param options
2156
+ */
2157
+ newChild(options: ChildFieldNodeOptions): FieldNode;
2158
+ /**
2159
+ * Creates a custom root node.
2160
+ * @param fieldManager
2161
+ * @param model
2162
+ * @param pathNode
2163
+ * @param adapter
2164
+ */
2165
+ newRoot<TValue>(fieldManager: FormFieldManager, model: WritableSignal<TValue>, pathNode: FieldPathNode, adapter: FieldAdapter): FieldNode;
2166
+ }
2167
+
2168
+ /**
2169
+ * Options that may be specified when creating a form.
2170
+ *
2171
+ * @experimental 21.0.0
2172
+ */
2173
+ interface FormOptions {
2174
+ /**
2175
+ * The injector to use for dependency injection. If this is not provided, the injector for the
2176
+ * current [injection context](guide/di/dependency-injection-context), will be used.
2177
+ */
2178
+ injector?: Injector;
2179
+ name?: string;
2180
+ /**
2181
+ * Adapter allows managing fields in a more flexible way.
2182
+ * Currently this is used to support interop with reactive forms.
2183
+ */
2184
+ adapter?: FieldAdapter;
2185
+ }
2186
+ /**
2187
+ * Creates a form wrapped around the given model data. A form is represented as simply a `Field` of
2188
+ * the model data.
2189
+ *
2190
+ * `form` uses the given model as the source of truth and *does not* maintain its own copy of the
2191
+ * data. This means that updating the value on a `FieldState` updates the originally passed in model
2192
+ * as well.
2193
+ *
2194
+ * @example
2195
+ * ```
2196
+ * const nameModel = signal({first: '', last: ''});
2197
+ * const nameForm = form(nameModel);
2198
+ * nameForm.first().value.set('John');
2199
+ * nameForm().value(); // {first: 'John', last: ''}
2200
+ * nameModel(); // {first: 'John', last: ''}
2201
+ * ```
2202
+ *
2203
+ * @param model A writable signal that contains the model data for the form. The resulting field
2204
+ * structure will match the shape of the model and any changes to the form data will be written to
2205
+ * the model.
2206
+ * @return A `Field` representing a form around the data model.
2207
+ * @template TValue The type of the data model.
2208
+ *
2209
+ * @experimental 21.0.0
2210
+ */
2211
+ declare function form<TValue>(model: WritableSignal<TValue>): Field<TValue>;
2212
+ /**
2213
+ * Creates a form wrapped around the given model data. A form is represented as simply a `Field` of
2214
+ * the model data.
2215
+ *
2216
+ * `form` uses the given model as the source of truth and *does not* maintain its own copy of the
2217
+ * data. This means that updating the value on a `FieldState` updates the originally passed in model
2218
+ * as well.
2219
+ *
2220
+ * @example
2221
+ * ```
2222
+ * const nameModel = signal({first: '', last: ''});
2223
+ * const nameForm = form(nameModel);
2224
+ * nameForm.first().value.set('John');
2225
+ * nameForm().value(); // {first: 'John', last: ''}
2226
+ * nameModel(); // {first: 'John', last: ''}
2227
+ * ```
2228
+ *
2229
+ * The form can also be created with a schema, which is a set of rules that define the logic for the
2230
+ * form. The schema can be either a pre-defined schema created with the `schema` function, or a
2231
+ * function that builds the schema by binding logic to a parts of the field structure.
2232
+ *
2233
+ * @example
2234
+ * ```
2235
+ * const nameForm = form(signal({first: '', last: ''}), (name) => {
2236
+ * required(name.first);
2237
+ * pattern(name.last, /^[a-z]+$/i, {message: 'Alphabet characters only'});
2238
+ * });
2239
+ * nameForm().valid(); // false
2240
+ * nameForm().value.set({first: 'John', last: 'Doe'});
2241
+ * nameForm().valid(); // true
2242
+ * ```
2243
+ *
2244
+ * @param model A writable signal that contains the model data for the form. The resulting field
2245
+ * structure will match the shape of the model and any changes to the form data will be written to
2246
+ * the model.
2247
+ * @param schemaOrOptions The second argument can be either
2248
+ * 1. A schema or a function used to specify logic for the form (e.g. validation, disabled fields, etc.).
2249
+ * When passing a schema, the form options can be passed as a third argument if needed.
2250
+ * 2. The form options
2251
+ * @return A `Field` representing a form around the data model
2252
+ * @template TValue The type of the data model.
2253
+ *
2254
+ * @experimental 21.0.0
2255
+ */
2256
+ declare function form<TValue>(model: WritableSignal<TValue>, schemaOrOptions: SchemaOrSchemaFn<TValue> | FormOptions): Field<TValue>;
2257
+ /**
2258
+ * Creates a form wrapped around the given model data. A form is represented as simply a `Field` of
2259
+ * the model data.
2260
+ *
2261
+ * `form` uses the given model as the source of truth and *does not* maintain its own copy of the
2262
+ * data. This means that updating the value on a `FieldState` updates the originally passed in model
2263
+ * as well.
2264
+ *
2265
+ * @example
2266
+ * ```
2267
+ * const nameModel = signal({first: '', last: ''});
2268
+ * const nameForm = form(nameModel);
2269
+ * nameForm.first().value.set('John');
2270
+ * nameForm().value(); // {first: 'John', last: ''}
2271
+ * nameModel(); // {first: 'John', last: ''}
2272
+ * ```
2273
+ *
2274
+ * The form can also be created with a schema, which is a set of rules that define the logic for the
2275
+ * form. The schema can be either a pre-defined schema created with the `schema` function, or a
2276
+ * function that builds the schema by binding logic to a parts of the field structure.
2277
+ *
2278
+ * @example
2279
+ * ```
2280
+ * const nameForm = form(signal({first: '', last: ''}), (name) => {
2281
+ * required(name.first);
2282
+ * error(name.last, ({value}) => !/^[a-z]+$/i.test(value()), 'Alphabet characters only');
2283
+ * });
2284
+ * nameForm().valid(); // false
2285
+ * nameForm().value.set({first: 'John', last: 'Doe'});
2286
+ * nameForm().valid(); // true
2287
+ * ```
2288
+ *
2289
+ * @param model A writable signal that contains the model data for the form. The resulting field
2290
+ * structure will match the shape of the model and any changes to the form data will be written to
2291
+ * the model.
2292
+ * @param schema A schema or a function used to specify logic for the form (e.g. validation, disabled fields, etc.)
2293
+ * @param options The form options
2294
+ * @return A `Field` representing a form around the data model.
2295
+ * @template TValue The type of the data model.
2296
+ *
2297
+ * @experimental 21.0.0
2298
+ */
2299
+ declare function form<TValue>(model: WritableSignal<TValue>, schema: SchemaOrSchemaFn<TValue>, options: FormOptions): Field<TValue>;
2300
+ /**
2301
+ * Applies a schema to each item of an array.
2302
+ *
2303
+ * @example
2304
+ * ```
2305
+ * const nameSchema = schema<{first: string, last: string}>((name) => {
2306
+ * required(name.first);
2307
+ * required(name.last);
2308
+ * });
2309
+ * const namesForm = form(signal([{first: '', last: ''}]), (names) => {
2310
+ * applyEach(names, nameSchema);
2311
+ * });
2312
+ * ```
2313
+ *
2314
+ * When binding logic to the array items, the `Field` for the array item is passed as an additional
2315
+ * argument. This can be used to reference other properties on the item.
2316
+ *
2317
+ * @example
2318
+ * ```
2319
+ * const namesForm = form(signal([{first: '', last: ''}]), (names) => {
2320
+ * applyEach(names, (name) => {
2321
+ * error(
2322
+ * name.last,
2323
+ * (value, nameField) => value === nameField.first().value(),
2324
+ * 'Last name must be different than first name',
2325
+ * );
2326
+ * });
2327
+ * });
2328
+ * ```
2329
+ *
2330
+ * @param path The target path for an array field whose items the schema will be applied to.
2331
+ * @param schema A schema for an element of the array, or function that binds logic to an
2332
+ * element of the array.
2333
+ * @template TValue The data type of the item field to apply the schema to.
2334
+ *
2335
+ * @experimental 21.0.0
2336
+ */
2337
+ declare function applyEach<TValue>(path: FieldPath<TValue[]>, schema: NoInfer<SchemaOrSchemaFn<TValue, PathKind.Item>>): void;
2338
+ /**
2339
+ * Applies a predefined schema to a given `FieldPath`.
2340
+ *
2341
+ * @example
2342
+ * ```
2343
+ * const nameSchema = schema<{first: string, last: string}>((name) => {
2344
+ * required(name.first);
2345
+ * required(name.last);
2346
+ * });
2347
+ * const profileForm = form(signal({name: {first: '', last: ''}, age: 0}), (profile) => {
2348
+ * apply(profile.name, nameSchema);
2349
+ * });
2350
+ * ```
2351
+ *
2352
+ * @param path The target path to apply the schema to.
2353
+ * @param schema The schema to apply to the property
2354
+ * @template TValue The data type of the field to apply the schema to.
2355
+ *
2356
+ * @experimental 21.0.0
2357
+ */
2358
+ declare function apply<TValue>(path: FieldPath<TValue>, schema: NoInfer<SchemaOrSchemaFn<TValue>>): void;
2359
+ /**
2360
+ * Conditionally applies a predefined schema to a given `FieldPath`.
2361
+ *
2362
+ * @param path The target path to apply the schema to.
2363
+ * @param logic A `LogicFn<T, boolean>` that returns `true` when the schema should be applied.
2364
+ * @param schema The schema to apply to the field when the `logic` function returns `true`.
2365
+ * @template TValue The data type of the field to apply the schema to.
2366
+ *
2367
+ * @experimental 21.0.0
2368
+ */
2369
+ declare function applyWhen<TValue>(path: FieldPath<TValue>, logic: LogicFn<TValue, boolean>, schema: NoInfer<SchemaOrSchemaFn<TValue>>): void;
2370
+ /**
2371
+ * Conditionally applies a predefined schema to a given `FieldPath`.
2372
+ *
2373
+ * @param path The target path to apply the schema to.
2374
+ * @param predicate A type guard that accepts a value `T` and returns `true` if `T` is of type
2375
+ * `TNarrowed`.
2376
+ * @param schema The schema to apply to the field when `predicate` returns `true`.
2377
+ * @template TValue The data type of the field to apply the schema to.
2378
+ * @template TNarrowed The data type of the schema (a narrowed type of TValue).
2379
+ *
2380
+ * @experimental 21.0.0
2381
+ */
2382
+ declare function applyWhenValue<TValue, TNarrowed extends TValue>(path: FieldPath<TValue>, predicate: (value: TValue) => value is TNarrowed, schema: SchemaOrSchemaFn<TNarrowed>): void;
2383
+ /**
2384
+ * Conditionally applies a predefined schema to a given `FieldPath`.
2385
+ *
2386
+ * @param path The target path to apply the schema to.
2387
+ * @param predicate A function that accepts a value `T` and returns `true` when the schema
2388
+ * should be applied.
2389
+ * @param schema The schema to apply to the field when `predicate` returns `true`.
2390
+ * @template TValue The data type of the field to apply the schema to.
2391
+ *
2392
+ * @experimental 21.0.0
2393
+ */
2394
+ declare function applyWhenValue<TValue>(path: FieldPath<TValue>, predicate: (value: TValue) => boolean, schema: NoInfer<SchemaOrSchemaFn<TValue>>): void;
2395
+ /**
2396
+ * Submits a given `Field` using the given action function and applies any server errors resulting
2397
+ * from the action to the field. Server errors returned by the `action` will be integrated into the
2398
+ * field as a `ValidationError` on the sub-field indicated by the `field` property of the server
2399
+ * error.
2400
+ *
2401
+ * @example
2402
+ * ```
2403
+ * async function registerNewUser(registrationForm: Field<{username: string, password: string}>) {
2404
+ * const result = await myClient.registerNewUser(registrationForm().value());
2405
+ * if (result.errorCode === myClient.ErrorCode.USERNAME_TAKEN) {
2406
+ * return [{
2407
+ * field: registrationForm.username,
2408
+ * error: {kind: 'server', message: 'Username already taken'}
2409
+ * }];
2410
+ * }
2411
+ * return undefined;
2412
+ * }
2413
+ *
2414
+ * const registrationForm = form(signal({username: 'god', password: ''}));
2415
+ * submit(registrationForm, async (f) => {
2416
+ * return registerNewUser(registrationForm);
2417
+ * });
2418
+ * registrationForm.username().errors(); // [{kind: 'server', message: 'Username already taken'}]
2419
+ * ```
2420
+ *
2421
+ * @param form The field to submit.
2422
+ * @param action An asynchronous action used to submit the field. The action may return server
2423
+ * errors.
2424
+ * @template TValue The data type of the field being submitted.
2425
+ *
2426
+ * @experimental 21.0.0
2427
+ */
2428
+ declare function submit<TValue>(form: Field<TValue>, action: (form: Field<TValue>) => Promise<TreeValidationResult>): Promise<void>;
2429
+ /**
2430
+ * Creates a `Schema` that adds logic rules to a form.
2431
+ * @param fn A **non-reactive** function that sets up reactive logic rules for the form.
2432
+ * @returns A schema object that implements the given logic.
2433
+ * @template TValue The value type of a `Field` that this schema binds to.
2434
+ *
2435
+ * @experimental 21.0.0
2436
+ */
2437
+ declare function schema<TValue>(fn: SchemaFn<TValue>): Schema<TValue>;
2438
+
2439
+ /** Represents a value that has a length or size, such as an array or string, or set. */
2440
+ type ValueWithLengthOrSize = {
2441
+ length: number;
2442
+ } | {
2443
+ size: number;
2444
+ };
2445
+ /** Common options available on the standard validators. */
2446
+ type BaseValidatorConfig<TValue, TPathKind extends PathKind = PathKind.Root> = {
2447
+ /** A user-facing error message to include with the error. */
2448
+ message?: string | LogicFn<TValue, string, TPathKind>;
2449
+ error?: never;
2450
+ } | {
2451
+ /**
2452
+ * Custom validation error(s) to report instead of the default,
2453
+ * or a function that receives the `FieldContext` and returns custom validation error(s).
2454
+ */
2455
+ error?: OneOrMany<WithoutField<ValidationError>> | LogicFn<TValue, OneOrMany<WithoutField<ValidationError>>, TPathKind>;
2456
+ message?: never;
2457
+ };
2458
+
2459
+ /**
2460
+ * Binds a validator to the given path that requires the value to match the standard email format.
2461
+ * This function can only be called on string paths.
2462
+ *
2463
+ * @param path Path of the field to validate
2464
+ * @param config Optional, allows providing any of the following options:
2465
+ * - `error`: Custom validation error(s) to be used instead of the default `ValidationError.email()`
2466
+ * or a function that receives the `FieldContext` and returns custom validation error(s).
2467
+ * @template TPathKind The kind of path the logic is bound to (a root path, child path, or item of an array)
2468
+ *
2469
+ * @experimental 21.0.0
2470
+ */
2471
+ declare function email<TPathKind extends PathKind = PathKind.Root>(path: FieldPath<string, TPathKind>, config?: BaseValidatorConfig<string, TPathKind>): void;
2472
+
2473
+ /**
2474
+ * Binds a validator to the given path that requires the value to be less than or equal to the
2475
+ * given `maxValue`.
2476
+ * This function can only be called on number paths.
2477
+ * In addition to binding a validator, this function adds `MAX` property to the field.
2478
+ *
2479
+ * @param path Path of the field to validate
2480
+ * @param maxValue The maximum value, or a LogicFn that returns the maximum value.
2481
+ * @param config Optional, allows providing any of the following options:
2482
+ * - `error`: Custom validation error(s) to be used instead of the default `ValidationError.max(maxValue)`
2483
+ * or a function that receives the `FieldContext` and returns custom validation error(s).
2484
+ * @template TPathKind The kind of path the logic is bound to (a root path, child path, or item of an array)
2485
+ *
2486
+ * @experimental 21.0.0
2487
+ */
2488
+ declare function max<TPathKind extends PathKind = PathKind.Root>(path: FieldPath<number, TPathKind>, maxValue: number | LogicFn<number, number | undefined, TPathKind>, config?: BaseValidatorConfig<number, TPathKind>): void;
2489
+
2490
+ /**
2491
+ * Binds a validator to the given path that requires the length of the value to be less than or
2492
+ * equal to the given `maxLength`.
2493
+ * This function can only be called on string or array paths.
2494
+ * In addition to binding a validator, this function adds `MAX_LENGTH` property to the field.
2495
+ *
2496
+ * @param path Path of the field to validate
2497
+ * @param maxLength The maximum length, or a LogicFn that returns the maximum length.
2498
+ * @param config Optional, allows providing any of the following options:
2499
+ * - `error`: Custom validation error(s) to be used instead of the default `ValidationError.maxLength(maxLength)`
2500
+ * or a function that receives the `FieldContext` and returns custom validation error(s).
2501
+ * @template TValue The type of value stored in the field the logic is bound to.
2502
+ * @template TPathKind The kind of path the logic is bound to (a root path, child path, or item of an array)
2503
+ *
2504
+ * @experimental 21.0.0
2505
+ */
2506
+ declare function maxLength<TValue extends ValueWithLengthOrSize, TPathKind extends PathKind = PathKind.Root>(path: FieldPath<TValue, TPathKind>, maxLength: number | LogicFn<TValue, number | undefined, TPathKind>, config?: BaseValidatorConfig<TValue, TPathKind>): void;
2507
+
2508
+ /**
2509
+ * Binds a validator to the given path that requires the value to be greater than or equal to
2510
+ * the given `minValue`.
2511
+ * This function can only be called on number paths.
2512
+ * In addition to binding a validator, this function adds `MIN` property to the field.
2513
+ *
2514
+ * @param path Path of the field to validate
2515
+ * @param minValue The minimum value, or a LogicFn that returns the minimum value.
2516
+ * @param config Optional, allows providing any of the following options:
2517
+ * - `error`: Custom validation error(s) to be used instead of the default `ValidationError.min(minValue)`
2518
+ * or a function that receives the `FieldContext` and returns custom validation error(s).
2519
+ * @template TPathKind The kind of path the logic is bound to (a root path, child path, or item of an array)
2520
+ *
2521
+ * @experimental 21.0.0
2522
+ */
2523
+ declare function min<TPathKind extends PathKind = PathKind.Root>(path: FieldPath<number, TPathKind>, minValue: number | LogicFn<number, number | undefined, TPathKind>, config?: BaseValidatorConfig<number, TPathKind>): void;
2524
+
2525
+ /**
2526
+ * Binds a validator to the given path that requires the length of the value to be greater than or
2527
+ * equal to the given `minLength`.
2528
+ * This function can only be called on string or array paths.
2529
+ * In addition to binding a validator, this function adds `MIN_LENGTH` property to the field.
2530
+ *
2531
+ * @param path Path of the field to validate
2532
+ * @param minLength The minimum length, or a LogicFn that returns the minimum length.
2533
+ * @param config Optional, allows providing any of the following options:
2534
+ * - `error`: Custom validation error(s) to be used instead of the default `ValidationError.minLength(minLength)`
2535
+ * or a function that receives the `FieldContext` and returns custom validation error(s).
2536
+ * @template TValue The type of value stored in the field the logic is bound to.
2537
+ * @template TPathKind The kind of path the logic is bound to (a root path, child path, or item of an array)
2538
+ *
2539
+ * @experimental 21.0.0
2540
+ */
2541
+ declare function minLength<TValue extends ValueWithLengthOrSize, TPathKind extends PathKind = PathKind.Root>(path: FieldPath<TValue, TPathKind>, minLength: number | LogicFn<TValue, number | undefined, TPathKind>, config?: BaseValidatorConfig<TValue, TPathKind>): void;
2542
+
2543
+ /**
2544
+ * Binds a validator to the given path that requires the value to match a specific regex pattern.
2545
+ * This function can only be called on string paths.
2546
+ * In addition to binding a validator, this function adds `PATTERN` property to the field.
2547
+ *
2548
+ * @param path Path of the field to validate
2549
+ * @param pattern The RegExp pattern to match, or a LogicFn that returns the RegExp pattern.
2550
+ * @param config Optional, allows providing any of the following options:
2551
+ * - `error`: Custom validation error(s) to be used instead of the default `ValidationError.pattern(pattern)`
2552
+ * or a function that receives the `FieldContext` and returns custom validation error(s).
2553
+ * @template TPathKind The kind of path the logic is bound to (a root path, child path, or item of an array)
2554
+ *
2555
+ * @experimental 21.0.0
2556
+ */
2557
+ declare function pattern<TPathKind extends PathKind = PathKind.Root>(path: FieldPath<string, TPathKind>, pattern: RegExp | LogicFn<string | undefined, RegExp | undefined, TPathKind>, config?: BaseValidatorConfig<string, TPathKind>): void;
2558
+
2559
+ /**
2560
+ * Binds a validator to the given path that requires the value to be non-empty.
2561
+ * This function can only be called on any type of path.
2562
+ * In addition to binding a validator, this function adds `REQUIRED` property to the field.
2563
+ *
2564
+ * @param path Path of the field to validate
2565
+ * @param config Optional, allows providing any of the following options:
2566
+ * - `message`: A user-facing message for the error.
2567
+ * - `error`: Custom validation error(s) to be used instead of the default `ValidationError.required()`
2568
+ * or a function that receives the `FieldContext` and returns custom validation error(s).
2569
+ * - `when`: A function that receives the `FieldContext` and returns true if the field is required
2570
+ * @template TValue The type of value stored in the field the logic is bound to.
2571
+ * @template TPathKind The kind of path the logic is bound to (a root path, child path, or item of an array)
2572
+ *
2573
+ * @experimental 21.0.0
2574
+ */
2575
+ declare function required<TValue, TPathKind extends PathKind = PathKind.Root>(path: FieldPath<TValue, TPathKind>, config?: BaseValidatorConfig<TValue, TPathKind> & {
2576
+ when?: NoInfer<LogicFn<TValue, boolean, TPathKind>>;
2577
+ }): void;
2578
+
2579
+ /**
2580
+ * Utility type that removes a string index key when its value is `unknown`,
2581
+ * i.e. `{[key: string]: unknown}`. It allows specific string keys to pass through, even if their
2582
+ * value is `unknown`, e.g. `{key: unknown}`.
2583
+ *
2584
+ * @experimental 21.0.0
2585
+ */
2586
+ type RemoveStringIndexUnknownKey<K, V> = string extends K ? unknown extends V ? never : K : K;
2587
+ /**
2588
+ * Utility type that recursively ignores unknown string index properties on the given object.
2589
+ * We use this on the `TSchema` type in `validateStandardSchema` in order to accommodate Zod's
2590
+ * `looseObject` which includes `{[key: string]: unknown}` as part of the type.
2591
+ *
2592
+ * @experimental 21.0.0
2593
+ */
2594
+ type IgnoreUnknownProperties<T> = T extends Record<PropertyKey, unknown> ? {
2595
+ [K in keyof T as RemoveStringIndexUnknownKey<K, T[K]>]: IgnoreUnknownProperties<T[K]>;
2596
+ } : T;
2597
+ /**
2598
+ * Validates a field using a `StandardSchemaV1` compatible validator (e.g. a Zod validator).
2599
+ *
2600
+ * See https://github.com/standard-schema/standard-schema for more about standard schema.
2601
+ *
2602
+ * @param path The `FieldPath` to the field to validate.
2603
+ * @param schema The standard schema compatible validator to use for validation.
2604
+ * @template TSchema The type validated by the schema. This may be either the full `TValue` type,
2605
+ * or a partial of it.
2606
+ * @template TValue The type of value stored in the field being validated.
2607
+ *
2608
+ * @experimental 21.0.0
2609
+ */
2610
+ declare function validateStandardSchema<TSchema, TValue extends IgnoreUnknownProperties<TSchema>>(path: FieldPath<TValue>, schema: StandardSchemaV1<TSchema>): void;
2611
+
2612
+ export { AggregateProperty, Control, CustomValidationError, EmailValidationError, MAX, MAX_LENGTH, MIN, MIN_LENGTH, MaxLengthValidationError, MaxValidationError, MinLengthValidationError, MinValidationError, NgValidationError, PATTERN, PathKind, PatternValidationError, Property, REQUIRED, RequiredValidationError, StandardSchemaValidationError, aggregateProperty, andProperty, apply, applyEach, applyWhen, applyWhenValue, createProperty, customError, disabled, email, emailError, form, hidden, listProperty, max, maxError, maxLength, maxLengthError, maxProperty, min, minError, minLength, minLengthError, minProperty, orProperty, pattern, patternError, property, readonly, reducedProperty, required, requiredError, schema, standardSchemaError, submit, validate, validateAsync, validateHttp, validateStandardSchema, validateTree };
2613
+ export type { AsyncValidationResult, AsyncValidatorOptions, ChildFieldContext, DisabledReason, Field, FieldContext, FieldPath, FieldState, FieldValidationResult, FieldValidator, FormCheckboxControl, FormOptions, FormUiControl, FormValueControl, HttpValidatorOptions, IgnoreUnknownProperties, ItemFieldContext, LogicFn, MapToErrorsFn, MaybeField, MaybeFieldPath, Mutable, OneOrMany, ReadonlyArrayLike, RemoveStringIndexUnknownKey, RootFieldContext, Schema, SchemaFn, SchemaOrSchemaFn, Subfields, SubmittedStatus, TreeValidationResult, TreeValidator, ValidationError, ValidationResult, ValidationSuccess, Validator, WithField, WithOptionalField, WithoutField };