@dvirus-js/angular-signals 0.0.16 → 0.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -25
- package/fesm2022/dvirus-js-angular-signals-signal-form.mjs +1409 -0
- package/fesm2022/dvirus-js-angular-signals-signal-form.mjs.map +1 -0
- package/fesm2022/dvirus-js-angular-signals.mjs +1 -1401
- package/fesm2022/dvirus-js-angular-signals.mjs.map +1 -1
- package/package.json +5 -1
- package/types/dvirus-js-angular-signals-signal-form.d.ts +1000 -0
- package/types/dvirus-js-angular-signals.d.ts +2 -997
|
@@ -0,0 +1,1000 @@
|
|
|
1
|
+
import { Signal, WritableSignal } from '@angular/core';
|
|
2
|
+
import { SignalOrValue } from '@dvirus-js/angular-signals';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Recursively extracts the value type from a form structure.
|
|
6
|
+
*
|
|
7
|
+
* Converts form control types to their underlying value types:
|
|
8
|
+
* - Arrays become arrays of extracted values
|
|
9
|
+
* - Objects become objects with extracted property values
|
|
10
|
+
* - Primitives become `T | undefined`
|
|
11
|
+
*
|
|
12
|
+
* @template T - The form structure type to extract values from
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* type Person = { name: string; age: number };
|
|
17
|
+
* type PersonValue = SignalFormValueFor<Person>;
|
|
18
|
+
* // Result: { name: string | undefined; age: number | undefined }
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
type SignalFormValueFor<T> = T extends (infer U)[] ? SignalFormValueFor<U>[] : T extends object ? {
|
|
22
|
+
[Key in keyof T]: SignalFormValueFor<T[Key]>;
|
|
23
|
+
} : T | undefined;
|
|
24
|
+
/**
|
|
25
|
+
* Recursively defines the error structure for a form.
|
|
26
|
+
*
|
|
27
|
+
* Mirrors the form structure where:
|
|
28
|
+
* - Arrays become arrays of error structures
|
|
29
|
+
* - Objects become objects with error properties
|
|
30
|
+
* - Primitives become error maps (Record<string, string>) or undefined
|
|
31
|
+
*
|
|
32
|
+
* @template T - The form structure type to create error structure for
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```typescript
|
|
36
|
+
* type Person = { name: string; hobbies: string[] };
|
|
37
|
+
* type PersonErrors = SignalFormErrorFor<Person>;
|
|
38
|
+
* // Result: { name: Record<string, string> | undefined; hobbies: (Record<string, string> | undefined)[] }
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
type SignalFormErrorFor<T> = T extends (infer U)[] ? SignalFormErrorFor<U>[] : T extends object ? {
|
|
42
|
+
[Key in keyof T]: SignalFormErrorFor<T[Key]>;
|
|
43
|
+
} : Record<string, string> | undefined;
|
|
44
|
+
/**
|
|
45
|
+
* Represents the first error or warning found in a control.
|
|
46
|
+
*
|
|
47
|
+
* @template Type - Either 'error' or 'warning' to distinguish validation type
|
|
48
|
+
*
|
|
49
|
+
* @property name - The validator name that triggered this error/warning
|
|
50
|
+
* @property message - The human-readable error/warning message
|
|
51
|
+
* @property type - Whether this is an 'error' or 'warning'
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```typescript
|
|
55
|
+
* const firstError: FirstError<'error'> = {
|
|
56
|
+
* name: 'required',
|
|
57
|
+
* message: 'This field is required',
|
|
58
|
+
* type: 'error'
|
|
59
|
+
* };
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
type FirstError<Type extends 'warning' | 'error'> = {
|
|
63
|
+
name: string;
|
|
64
|
+
message: string;
|
|
65
|
+
type: Type;
|
|
66
|
+
} | undefined;
|
|
67
|
+
/**
|
|
68
|
+
* Represents a single form control (primitive value) with validation and state management.
|
|
69
|
+
*
|
|
70
|
+
* A control wraps a primitive value (string, number, etc.) and provides:
|
|
71
|
+
* - Reactive value through Angular signals
|
|
72
|
+
* - Validation with errors and warnings
|
|
73
|
+
* - State tracking (touched, dirty, disabled)
|
|
74
|
+
* - Manual error/warning management
|
|
75
|
+
*
|
|
76
|
+
* @template TValue - The type of value this control manages
|
|
77
|
+
*/
|
|
78
|
+
interface SignalFormControl<TValue> {
|
|
79
|
+
/** Discriminator property set to 'control' for type checking */
|
|
80
|
+
kind: 'control';
|
|
81
|
+
/** Writable signal containing the current control value */
|
|
82
|
+
value: WritableSignal<TValue | undefined>;
|
|
83
|
+
/** Signal indicating if the control is disabled */
|
|
84
|
+
disabled: Signal<boolean>;
|
|
85
|
+
/** Signal indicating if the control has been interacted with */
|
|
86
|
+
touched: Signal<boolean>;
|
|
87
|
+
/** Signal indicating if the value has changed from initial */
|
|
88
|
+
dirty: Signal<boolean>;
|
|
89
|
+
/** Signal containing all validation errors (from validators + manual) */
|
|
90
|
+
errors: Signal<Record<string, string>>;
|
|
91
|
+
/** Signal containing all validation warnings (from warnings + manual) */
|
|
92
|
+
warnings: Signal<Record<string, string>>;
|
|
93
|
+
/** Signal containing only manually set errors */
|
|
94
|
+
selfErrors: Signal<Record<string, string>>;
|
|
95
|
+
/** Signal containing only manually set warnings */
|
|
96
|
+
selfWarnings: Signal<Record<string, string>>;
|
|
97
|
+
/** Signal true when control has errors and is not disabled */
|
|
98
|
+
invalid: Signal<boolean>;
|
|
99
|
+
/** Signal true when control has no errors */
|
|
100
|
+
valid: Signal<boolean>;
|
|
101
|
+
/** Signal with the first error, if any */
|
|
102
|
+
firstError: Signal<FirstError<'error'>>;
|
|
103
|
+
/** Signal with the first warning, if any */
|
|
104
|
+
firstWarning: Signal<FirstError<'warning'>>;
|
|
105
|
+
/** Signal with the first error or warning */
|
|
106
|
+
firstErrorOrWarning: Signal<FirstError<'error' | 'warning'>>;
|
|
107
|
+
/**
|
|
108
|
+
* Updates the control value with optional state flags.
|
|
109
|
+
* @param value - New value to set
|
|
110
|
+
* @param options - Optional flags for marking dirty/touched
|
|
111
|
+
*/
|
|
112
|
+
setValue: (value: TValue | undefined, options?: SignalFormSetValueOptions) => void;
|
|
113
|
+
/**
|
|
114
|
+
* Resets control to initial value and clears all state.
|
|
115
|
+
* @param value - Optional new initial value
|
|
116
|
+
*/
|
|
117
|
+
reset: (value?: TValue | undefined) => void;
|
|
118
|
+
/** Marks the control as touched */
|
|
119
|
+
markTouched: () => void;
|
|
120
|
+
/** Marks the control as not touched */
|
|
121
|
+
markUntouched: () => void;
|
|
122
|
+
/** Marks the control as dirty (modified) */
|
|
123
|
+
markDirty: () => void;
|
|
124
|
+
/** Marks the control as pristine (unmodified) */
|
|
125
|
+
markPristine: () => void;
|
|
126
|
+
/**
|
|
127
|
+
* Sets the disabled state of the control.
|
|
128
|
+
* @param disabled - True to disable, false to enable
|
|
129
|
+
*/
|
|
130
|
+
setDisabled: (disabled: boolean) => void;
|
|
131
|
+
/**
|
|
132
|
+
* Adds a manual error with key and message.
|
|
133
|
+
* @param key - Error identifier key
|
|
134
|
+
* @param message - Error message
|
|
135
|
+
*/
|
|
136
|
+
setError: (key: string, message: string) => void;
|
|
137
|
+
/**
|
|
138
|
+
* Removes a specific manual error by key.
|
|
139
|
+
* @param key - Error identifier key to remove
|
|
140
|
+
*/
|
|
141
|
+
clearError: (key: string) => void;
|
|
142
|
+
/** Removes all manual errors */
|
|
143
|
+
clearErrors: () => void;
|
|
144
|
+
/**
|
|
145
|
+
* Adds a manual warning with key and message.
|
|
146
|
+
* @param key - Warning identifier key
|
|
147
|
+
* @param message - Warning message
|
|
148
|
+
*/
|
|
149
|
+
setWarning: (key: string, message: string) => void;
|
|
150
|
+
/**
|
|
151
|
+
* Removes a specific manual warning by key.
|
|
152
|
+
* @param key - Warning identifier key to remove
|
|
153
|
+
*/
|
|
154
|
+
clearWarning: (key: string) => void;
|
|
155
|
+
/** Removes all manual warnings */
|
|
156
|
+
clearWarnings: () => void;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Represents a form array - a collection of form controls/groups with dynamic add/remove capabilities.
|
|
160
|
+
*
|
|
161
|
+
* Manages an array of controls where each item can be a control, group, or nested array.
|
|
162
|
+
* Provides methods for array manipulation (push, insert, remove) and tracks collective state.
|
|
163
|
+
*
|
|
164
|
+
* @template TValue - The type of each item in the array
|
|
165
|
+
*/
|
|
166
|
+
interface SignalFormArray<TValue> {
|
|
167
|
+
/** Discriminator property set to 'array' for type checking */
|
|
168
|
+
kind: 'array';
|
|
169
|
+
/** Signal containing the array of child controls */
|
|
170
|
+
controls: Signal<SignalFormControlLike<TValue>[]>;
|
|
171
|
+
/** Signal containing array of extracted values from all controls */
|
|
172
|
+
value: Signal<SignalFormValueFor<TValue>[]>;
|
|
173
|
+
/** Signal containing array of error structures from all controls */
|
|
174
|
+
errors: Signal<SignalFormErrorFor<TValue>[]>;
|
|
175
|
+
/** Signal containing array of warning structures from all controls */
|
|
176
|
+
warnings: Signal<SignalFormErrorFor<TValue>[]>;
|
|
177
|
+
/** Signal containing manually set errors on the array itself */
|
|
178
|
+
selfErrors: Signal<Record<string, string>>;
|
|
179
|
+
/** Signal containing manually set warnings on the array itself */
|
|
180
|
+
selfWarnings: Signal<Record<string, string>>;
|
|
181
|
+
/** Signal indicating if the array is disabled */
|
|
182
|
+
disabled: Signal<boolean>;
|
|
183
|
+
/** Signal true when array or any child is touched */
|
|
184
|
+
touched: Signal<boolean>;
|
|
185
|
+
/** Signal true when array or any child is dirty */
|
|
186
|
+
dirty: Signal<boolean>;
|
|
187
|
+
/** Signal true when array or any child has errors */
|
|
188
|
+
invalid: Signal<boolean>;
|
|
189
|
+
/** Signal true when array and all children have no errors */
|
|
190
|
+
valid: Signal<boolean>;
|
|
191
|
+
/**
|
|
192
|
+
* Inserts a control at specified index (defaults to end).
|
|
193
|
+
* @param item - Item to insert (value, config, or control)
|
|
194
|
+
* @param index - Position to insert at (optional, defaults to end)
|
|
195
|
+
* @returns Index where item was inserted
|
|
196
|
+
*/
|
|
197
|
+
insert: (item: SignalFormInput<TValue, any> | SignalFormValueFor<TValue>, index?: number) => number;
|
|
198
|
+
/**
|
|
199
|
+
* Appends a control to the end of the array.
|
|
200
|
+
* @param item - Item to append (value, config, or control)
|
|
201
|
+
* @returns Index where item was inserted
|
|
202
|
+
*/
|
|
203
|
+
push: (item: SignalFormInput<TValue, any> | SignalFormValueFor<TValue>) => number;
|
|
204
|
+
/**
|
|
205
|
+
* Removes the control at specified index.
|
|
206
|
+
* @param index - Index of control to remove
|
|
207
|
+
*/
|
|
208
|
+
removeAt: (index: number) => void;
|
|
209
|
+
/** Removes all controls from the array */
|
|
210
|
+
clear: () => void;
|
|
211
|
+
/**
|
|
212
|
+
* Retrieves the control at specified index.
|
|
213
|
+
* @param index - Index of control to retrieve
|
|
214
|
+
* @returns Control at index, or undefined if out of bounds
|
|
215
|
+
*/
|
|
216
|
+
at: (index: number) => SignalFormControlLike<TValue> | undefined;
|
|
217
|
+
/**
|
|
218
|
+
* Sets values for all controls (recreates if length differs).
|
|
219
|
+
* @param value - Array of new values
|
|
220
|
+
* @param options - Optional flags for marking dirty/touched
|
|
221
|
+
*/
|
|
222
|
+
setValue: (value: SignalFormValueFor<TValue>[], options?: SignalFormSetValueOptions) => void;
|
|
223
|
+
/**
|
|
224
|
+
* Resets all controls to initial state or provided values.
|
|
225
|
+
* @param value - Optional new initial values
|
|
226
|
+
*/
|
|
227
|
+
reset: (value?: SignalFormValueFor<TValue>[]) => void;
|
|
228
|
+
/** Marks the array itself as touched */
|
|
229
|
+
markTouched: () => void;
|
|
230
|
+
/** Marks the array itself as untouched */
|
|
231
|
+
markUntouched: () => void;
|
|
232
|
+
/** Marks the array itself as dirty */
|
|
233
|
+
markDirty: () => void;
|
|
234
|
+
/** Marks the array itself as pristine */
|
|
235
|
+
markPristine: () => void;
|
|
236
|
+
/** Marks the array and all children as touched */
|
|
237
|
+
markAllTouched: () => void;
|
|
238
|
+
/**
|
|
239
|
+
* Sets disabled state for array and optionally children.
|
|
240
|
+
* @param disabled - True to disable, false to enable
|
|
241
|
+
* @param options - Options to control if children are affected
|
|
242
|
+
*/
|
|
243
|
+
setDisabled: (disabled: boolean, options?: SignalFormDisableOptions) => void;
|
|
244
|
+
/**
|
|
245
|
+
* Adds a manual error to the array.
|
|
246
|
+
* @param key - Error identifier key
|
|
247
|
+
* @param message - Error message
|
|
248
|
+
*/
|
|
249
|
+
setError: (key: string, message: string) => void;
|
|
250
|
+
/**
|
|
251
|
+
* Removes a specific manual error.
|
|
252
|
+
* @param key - Error identifier key to remove
|
|
253
|
+
*/
|
|
254
|
+
clearError: (key: string) => void;
|
|
255
|
+
/** Removes all manual errors */
|
|
256
|
+
clearErrors: () => void;
|
|
257
|
+
/**
|
|
258
|
+
* Adds a manual warning to the array.
|
|
259
|
+
* @param key - Warning identifier key
|
|
260
|
+
* @param message - Warning message
|
|
261
|
+
*/
|
|
262
|
+
setWarning: (key: string, message: string) => void;
|
|
263
|
+
/**
|
|
264
|
+
* Removes a specific manual warning.
|
|
265
|
+
* @param key - Warning identifier key to remove
|
|
266
|
+
*/
|
|
267
|
+
clearWarning: (key: string) => void;
|
|
268
|
+
/** Removes all manual warnings */
|
|
269
|
+
clearWarnings: () => void;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Represents a form group - a structured collection of named form controls.
|
|
273
|
+
*
|
|
274
|
+
* Manages an object/record of controls where each property is a control, group, or array.
|
|
275
|
+
* Provides type-safe access to controls and tracks collective validation state.
|
|
276
|
+
*
|
|
277
|
+
* @template TData - The object type defining the structure and types of all controls
|
|
278
|
+
*/
|
|
279
|
+
interface SignalForm<TData extends object> {
|
|
280
|
+
/** Discriminator property set to 'group' for type checking */
|
|
281
|
+
kind: 'group';
|
|
282
|
+
/** Object containing all named child controls */
|
|
283
|
+
controls: {
|
|
284
|
+
[Key in keyof TData]: SignalFormControlLike<TData[Key]>;
|
|
285
|
+
};
|
|
286
|
+
/** Signal containing object with extracted values from all controls */
|
|
287
|
+
value: Signal<{
|
|
288
|
+
[Key in keyof TData]: SignalFormValueFor<TData[Key]>;
|
|
289
|
+
}>;
|
|
290
|
+
/** Signal containing object with error structures from all controls */
|
|
291
|
+
errors: Signal<{
|
|
292
|
+
[Key in keyof TData]: SignalFormErrorFor<TData[Key]>;
|
|
293
|
+
}>;
|
|
294
|
+
/** Signal containing object with warning structures from all controls */
|
|
295
|
+
warnings: Signal<{
|
|
296
|
+
[Key in keyof TData]: SignalFormErrorFor<TData[Key]>;
|
|
297
|
+
}>;
|
|
298
|
+
/** Signal containing manually set errors on the group itself */
|
|
299
|
+
selfErrors: Signal<Record<string, string>>;
|
|
300
|
+
/** Signal containing manually set warnings on the group itself */
|
|
301
|
+
selfWarnings: Signal<Record<string, string>>;
|
|
302
|
+
/** Signal indicating if the group is disabled */
|
|
303
|
+
disabled: Signal<boolean>;
|
|
304
|
+
/** Signal true when group or any child is touched */
|
|
305
|
+
touched: Signal<boolean>;
|
|
306
|
+
/** Signal true when group or any child is dirty */
|
|
307
|
+
dirty: Signal<boolean>;
|
|
308
|
+
/** Signal true when group or any child has errors */
|
|
309
|
+
invalid: Signal<boolean>;
|
|
310
|
+
/** Signal true when group and all children have no errors */
|
|
311
|
+
valid: Signal<boolean>;
|
|
312
|
+
/**
|
|
313
|
+
* Type-safe method to retrieve a specific control by key.
|
|
314
|
+
* @param key - Control property name
|
|
315
|
+
* @returns The control for the specified key
|
|
316
|
+
*/
|
|
317
|
+
getControl: <Key extends keyof TData>(key: Key) => SignalFormControlLike<TData[Key]>;
|
|
318
|
+
/**
|
|
319
|
+
* Updates values for specified controls (partial updates supported).
|
|
320
|
+
* @param value - Partial object with new values
|
|
321
|
+
* @param options - Optional flags for marking dirty/touched
|
|
322
|
+
*/
|
|
323
|
+
setValue: (value: Partial<{
|
|
324
|
+
[Key in keyof TData]: SignalFormValueFor<TData[Key]>;
|
|
325
|
+
}>, options?: SignalFormSetValueOptions) => void;
|
|
326
|
+
/**
|
|
327
|
+
* Resets all controls to initial state or provided values.
|
|
328
|
+
* @param value - Optional partial object with new initial values
|
|
329
|
+
*/
|
|
330
|
+
reset: (value?: Partial<{
|
|
331
|
+
[Key in keyof TData]: SignalFormValueFor<TData[Key]>;
|
|
332
|
+
}>) => void;
|
|
333
|
+
/** Marks the group itself as touched */
|
|
334
|
+
markTouched: () => void;
|
|
335
|
+
/** Marks the group itself as untouched */
|
|
336
|
+
markUntouched: () => void;
|
|
337
|
+
/** Marks the group itself as dirty */
|
|
338
|
+
markDirty: () => void;
|
|
339
|
+
/** Marks the group itself as pristine */
|
|
340
|
+
markPristine: () => void;
|
|
341
|
+
/** Marks the group and all children as touched */
|
|
342
|
+
markAllTouched: () => void;
|
|
343
|
+
/**
|
|
344
|
+
* Sets disabled state for group and optionally children.
|
|
345
|
+
* @param disabled - True to disable, false to enable
|
|
346
|
+
* @param options - Options to control if children are affected
|
|
347
|
+
*/
|
|
348
|
+
setDisabled: (disabled: boolean, options?: SignalFormDisableOptions) => void;
|
|
349
|
+
/**
|
|
350
|
+
* Adds a manual error to the group.
|
|
351
|
+
* @param key - Error identifier key
|
|
352
|
+
* @param message - Error message
|
|
353
|
+
*/
|
|
354
|
+
setError: (key: string, message: string) => void;
|
|
355
|
+
/**
|
|
356
|
+
* Removes a specific manual error.
|
|
357
|
+
* @param key - Error identifier key to remove
|
|
358
|
+
*/
|
|
359
|
+
clearError: (key: string) => void;
|
|
360
|
+
/** Removes all manual errors */
|
|
361
|
+
clearErrors: () => void;
|
|
362
|
+
/**
|
|
363
|
+
* Adds a manual warning to the group.
|
|
364
|
+
* @param key - Warning identifier key
|
|
365
|
+
* @param message - Warning message
|
|
366
|
+
*/
|
|
367
|
+
setWarning: (key: string, message: string) => void;
|
|
368
|
+
/**
|
|
369
|
+
* Removes a specific manual warning.
|
|
370
|
+
* @param key - Warning identifier key to remove
|
|
371
|
+
*/
|
|
372
|
+
clearWarning: (key: string) => void;
|
|
373
|
+
/** Removes all manual warnings */
|
|
374
|
+
clearWarnings: () => void;
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Type utility that maps a value type to its appropriate control interface.
|
|
378
|
+
*
|
|
379
|
+
* Automatically determines the correct control type based on the value:
|
|
380
|
+
* - Arrays → SignalFormArray
|
|
381
|
+
* - Objects → SignalForm (group)
|
|
382
|
+
* - Primitives → SignalFormControl
|
|
383
|
+
*
|
|
384
|
+
* @template TValue - The value type to map to a control interface
|
|
385
|
+
*
|
|
386
|
+
* @example
|
|
387
|
+
* ```typescript
|
|
388
|
+
* type StringControl = SignalFormControlLike<string>; // SignalFormControl<string>
|
|
389
|
+
* type PersonControl = SignalFormControlLike<Person>; // SignalForm<Person>
|
|
390
|
+
* type HobbiesControl = SignalFormControlLike<string[]>; // SignalFormArray<string>
|
|
391
|
+
* ```
|
|
392
|
+
*/
|
|
393
|
+
type SignalFormControlLike<TValue> = TValue extends (infer U)[] ? SignalFormArray<U> : TValue extends object ? SignalForm<TValue> : SignalFormControl<TValue>;
|
|
394
|
+
/**
|
|
395
|
+
* Context object passed to validators and disabled functions.
|
|
396
|
+
*
|
|
397
|
+
* Provides access to the current control's value and sibling controls,
|
|
398
|
+
* enabling cross-field validation and dynamic behavior based on other form values.
|
|
399
|
+
*
|
|
400
|
+
* @template TControls - Object type defining all available sibling controls
|
|
401
|
+
* @template TValue - The type of the current control's value
|
|
402
|
+
*
|
|
403
|
+
* @example
|
|
404
|
+
* ```typescript
|
|
405
|
+
* const validator: SignalFormValidatorFn<FormModel, string> = (ctx) => {
|
|
406
|
+
* const otherControl = ctx.getControl('otherField');
|
|
407
|
+
* return ctx.item.value === otherControl.value() ? null : { mismatch: 'Values must match' };
|
|
408
|
+
* };
|
|
409
|
+
* ```
|
|
410
|
+
*/
|
|
411
|
+
interface SignalFormContext<TControls extends object, TValue> {
|
|
412
|
+
/** Object containing the current control's value */
|
|
413
|
+
item: {
|
|
414
|
+
value: TValue | undefined;
|
|
415
|
+
};
|
|
416
|
+
/**
|
|
417
|
+
* Function to retrieve sibling controls by key for cross-field logic.
|
|
418
|
+
* @param controlName - Key of the sibling control to retrieve
|
|
419
|
+
* @returns The sibling control
|
|
420
|
+
*/
|
|
421
|
+
getControl: <ControlKey extends keyof TControls>(controlName: ControlKey) => SignalFormControlLike<TControls[ControlKey]>;
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* Return type for validation functions.
|
|
425
|
+
*
|
|
426
|
+
* Validators return a map of error keys to messages when validation fails,
|
|
427
|
+
* or null/empty when validation passes. Empty strings and null values are ignored.
|
|
428
|
+
*
|
|
429
|
+
* @example
|
|
430
|
+
* ```typescript
|
|
431
|
+
* const result: SignalFormValidationError = { required: 'Field is required', min: 'Too small' };
|
|
432
|
+
* const success: SignalFormValidationError = null;
|
|
433
|
+
* ```
|
|
434
|
+
*/
|
|
435
|
+
type SignalFormValidationError = Record<string, string | undefined | null> | null;
|
|
436
|
+
/**
|
|
437
|
+
* Function signature for validators and warnings.
|
|
438
|
+
*
|
|
439
|
+
* Takes a context with the current value and sibling controls,
|
|
440
|
+
* returns error/warning messages or null when validation passes.
|
|
441
|
+
*
|
|
442
|
+
* @template TControls - Object type defining available sibling controls
|
|
443
|
+
* @template TValue - The type of value being validated
|
|
444
|
+
*
|
|
445
|
+
* @param ctx - Validation context with current value and control accessor
|
|
446
|
+
* @returns Error map when validation fails, null when it passes
|
|
447
|
+
*
|
|
448
|
+
* @example
|
|
449
|
+
* ```typescript
|
|
450
|
+
* const minValidator: SignalFormValidatorFn<any, number> = ({ item }) => {
|
|
451
|
+
* return item.value && item.value < 0 ? { min: 'Must be positive' } : null;
|
|
452
|
+
* };
|
|
453
|
+
* ```
|
|
454
|
+
*/
|
|
455
|
+
type SignalFormValidatorFn<TControls extends object, TValue> = (ctx: SignalFormContext<TControls, TValue>) => SignalFormValidationError;
|
|
456
|
+
/**
|
|
457
|
+
* Configuration object for creating a form control with advanced options.
|
|
458
|
+
*
|
|
459
|
+
* Allows specifying initial value, validators, warnings, and dynamic disabled logic.
|
|
460
|
+
*
|
|
461
|
+
* @template TValue - The type of value the control will manage
|
|
462
|
+
* @template TControls - Object type defining available sibling controls for validators
|
|
463
|
+
*
|
|
464
|
+
* @example
|
|
465
|
+
* ```typescript
|
|
466
|
+
* const config: SignalFormControlConfig<number, FormModel> = {
|
|
467
|
+
* value: 0,
|
|
468
|
+
* validators: [signalFormValidators.min(0)],
|
|
469
|
+
* warnings: [signalFormValidators.max(100)],
|
|
470
|
+
* disabled: (ctx) => ctx.getControl('otherField').value() === 'locked'
|
|
471
|
+
* };
|
|
472
|
+
* ```
|
|
473
|
+
*/
|
|
474
|
+
interface SignalFormControlConfig<TValue, TControls extends object> {
|
|
475
|
+
/** Initial value (can be a signal or static value) */
|
|
476
|
+
value: SignalOrValue<TValue | undefined>;
|
|
477
|
+
/** Disabled state (boolean, signal, or function based on form context) */
|
|
478
|
+
disabled?: SignalOrValue<boolean> | SignalFormDisabledFn<TControls, TValue>;
|
|
479
|
+
/** Array of validation functions that mark control as invalid */
|
|
480
|
+
validators?: SignalFormValidatorFn<TControls, TValue>[];
|
|
481
|
+
/** Array of validation functions that don't affect validity */
|
|
482
|
+
warnings?: SignalFormValidatorFn<TControls, TValue>[];
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* Input type accepted when creating a form control.
|
|
486
|
+
*
|
|
487
|
+
* Flexible input that accepts:
|
|
488
|
+
* - A raw value (primitive, signal)
|
|
489
|
+
* - A configuration object with validators and options
|
|
490
|
+
* - An existing SignalFormControl instance
|
|
491
|
+
*
|
|
492
|
+
* @template TValue - The value type for the control
|
|
493
|
+
* @template TControls - Object type defining available sibling controls
|
|
494
|
+
*/
|
|
495
|
+
type SignalFormControlInput<TValue, TControls extends object> = SignalOrValue<TValue | undefined> | SignalFormControlConfig<TValue, TControls> | SignalFormControl<TValue>;
|
|
496
|
+
/**
|
|
497
|
+
* Input type accepted when creating a form group.
|
|
498
|
+
*
|
|
499
|
+
* @template TData - Object type defining the structure of the group
|
|
500
|
+
*/
|
|
501
|
+
type SignalFormGroupInput<TData extends object> = SignalFormInputs<TData> | SignalForm<TData>;
|
|
502
|
+
/**
|
|
503
|
+
* Input type accepted when creating a form array.
|
|
504
|
+
*
|
|
505
|
+
* @template TItem - The type of each item in the array
|
|
506
|
+
* @template TControls - Object type defining available sibling controls
|
|
507
|
+
*/
|
|
508
|
+
type SignalFormArrayInput<TItem, TControls extends object> = SignalFormArray<TItem> | SignalFormInput<TItem, TControls>[];
|
|
509
|
+
/**
|
|
510
|
+
* Recursive input type that automatically maps to the correct control input type.
|
|
511
|
+
*
|
|
512
|
+
* Determines the appropriate input type based on value structure:
|
|
513
|
+
* - Arrays → SignalFormArrayInput
|
|
514
|
+
* - Objects → SignalFormGroupInput
|
|
515
|
+
* - Primitives → SignalFormControlInput
|
|
516
|
+
*
|
|
517
|
+
* @template TValue - The value type to create an input for
|
|
518
|
+
* @template TControls - Object type defining available sibling controls
|
|
519
|
+
*/
|
|
520
|
+
type SignalFormInput<TValue, TControls extends object> = TValue extends (infer U)[] ? SignalFormArrayInput<U, TControls> : TValue extends object ? SignalFormGroupInput<TValue> : SignalFormControlInput<TValue, TControls>;
|
|
521
|
+
/**
|
|
522
|
+
* Type for defining the inputs of a form group.
|
|
523
|
+
*
|
|
524
|
+
* Maps each property of TData to its appropriate input type,
|
|
525
|
+
* all properties are optional to allow partial form definitions.
|
|
526
|
+
*
|
|
527
|
+
* @template TData - Object type defining the structure of the form
|
|
528
|
+
*/
|
|
529
|
+
type SignalFormInputs<TData extends object> = {
|
|
530
|
+
[Key in keyof TData]?: SignalFormInput<TData[Key], TData>;
|
|
531
|
+
};
|
|
532
|
+
/**
|
|
533
|
+
* Function signature for dynamic disabled logic.
|
|
534
|
+
*
|
|
535
|
+
* Determines if a control should be disabled based on form context.
|
|
536
|
+
*
|
|
537
|
+
* @template TControls - Object type defining available sibling controls
|
|
538
|
+
* @template TValue - The type of value in the control
|
|
539
|
+
*
|
|
540
|
+
* @param ctx - Context with current value and sibling controls
|
|
541
|
+
* @returns Boolean indicating if control should be disabled
|
|
542
|
+
*/
|
|
543
|
+
type SignalFormDisabledFn<TControls extends object, TValue> = (ctx: SignalFormContext<TControls, TValue>) => boolean;
|
|
544
|
+
/**
|
|
545
|
+
* Options for setValue operations.
|
|
546
|
+
*/
|
|
547
|
+
interface SignalFormSetValueOptions {
|
|
548
|
+
/** Whether to mark the control as dirty (default: true) */
|
|
549
|
+
markDirty?: boolean;
|
|
550
|
+
/** Whether to mark the control as touched (default: false) */
|
|
551
|
+
markTouched?: boolean;
|
|
552
|
+
}
|
|
553
|
+
/**
|
|
554
|
+
* Options for setDisabled operations.
|
|
555
|
+
*/
|
|
556
|
+
interface SignalFormDisableOptions {
|
|
557
|
+
/** If true, only disable this control without affecting children (default: false) */
|
|
558
|
+
onlySelf?: boolean;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
/**
|
|
562
|
+
* Internal type for accessing sibling controls in a form.
|
|
563
|
+
*
|
|
564
|
+
* @internal
|
|
565
|
+
*/
|
|
566
|
+
type ControlAccessor$1<TControls extends object> = <Key extends keyof TControls>(controlName: Key) => SignalFormControlLike<TControls[Key]>;
|
|
567
|
+
/**
|
|
568
|
+
* Type guard to check if an object is a SignalFormArray.
|
|
569
|
+
*
|
|
570
|
+
* @template TValue - The type of items in the array
|
|
571
|
+
* @param obj - Object to check
|
|
572
|
+
* @returns True if obj is a SignalFormArray
|
|
573
|
+
*
|
|
574
|
+
* @example
|
|
575
|
+
* ```typescript
|
|
576
|
+
* if (isSignalFormArray(value)) {
|
|
577
|
+
* console.log(value.controls().length); // TypeScript knows this is an array
|
|
578
|
+
* }
|
|
579
|
+
* ```
|
|
580
|
+
*/
|
|
581
|
+
declare function isSignalFormArray<TValue>(obj: unknown): obj is SignalFormArray<TValue>;
|
|
582
|
+
/**
|
|
583
|
+
* Creates a reactive form array for managing dynamic collections of controls.
|
|
584
|
+
*
|
|
585
|
+
* Builds an array container that can hold multiple controls (primitives, groups, or nested arrays)
|
|
586
|
+
* with full signal-based reactivity. Provides methods for dynamic addition/removal of items
|
|
587
|
+
* and tracks collective validation state.
|
|
588
|
+
*
|
|
589
|
+
* Features:
|
|
590
|
+
* - Dynamic array operations (push, insert, remove, clear)
|
|
591
|
+
* - Reactive value and error tracking across all items
|
|
592
|
+
* - Collective state management (touched, dirty, valid)
|
|
593
|
+
* - Manual error/warning management at array level
|
|
594
|
+
* - Type-safe access to individual controls
|
|
595
|
+
*
|
|
596
|
+
* @template TItem - The type of each item in the array
|
|
597
|
+
* @template TControls - Object type defining available sibling controls
|
|
598
|
+
*
|
|
599
|
+
* @param inputItems - Array of initial items (values, configs, or controls)
|
|
600
|
+
* @param getControl - Optional accessor for sibling controls
|
|
601
|
+
* @returns Fully configured SignalFormArray instance
|
|
602
|
+
*
|
|
603
|
+
* @example
|
|
604
|
+
* ```typescript
|
|
605
|
+
* // Array of primitives
|
|
606
|
+
* const tagsArray = createSignalFormArray(['tag1', 'tag2']);
|
|
607
|
+
* tagsArray.push('tag3');
|
|
608
|
+
*
|
|
609
|
+
* // Array of objects
|
|
610
|
+
* const addressesArray = createSignalFormArray<Address>([
|
|
611
|
+
* { street: '123 Main', city: 'NYC' },
|
|
612
|
+
* { street: '456 Oak', city: 'LA' }
|
|
613
|
+
* ]);
|
|
614
|
+
*
|
|
615
|
+
* // Array with validators
|
|
616
|
+
* const hobbiesArray = createSignalFormArray([
|
|
617
|
+
* { value: 'coding', validators: [signalFormValidators.minLength(3)] },
|
|
618
|
+
* 'gaming'
|
|
619
|
+
* ]);
|
|
620
|
+
* ```
|
|
621
|
+
*/
|
|
622
|
+
declare function createSignalFormArray<TItem, TControls extends object = object>(inputItems: SignalFormInput<TItem, TControls>[], getControl?: ControlAccessor$1<TControls>): SignalFormArray<TItem>;
|
|
623
|
+
|
|
624
|
+
/**
|
|
625
|
+
* Internal type for accessing sibling controls in a form.
|
|
626
|
+
*
|
|
627
|
+
* @internal
|
|
628
|
+
*/
|
|
629
|
+
type ControlAccessor<TControls extends object> = <Key extends keyof TControls>(controlName: Key) => SignalFormControlLike<TControls[Key]>;
|
|
630
|
+
/**
|
|
631
|
+
* Type guard to check if an object is a SignalFormControl.
|
|
632
|
+
*
|
|
633
|
+
* @template TValue - The type of value the control manages
|
|
634
|
+
* @param obj - Object to check
|
|
635
|
+
* @returns True if obj is a SignalFormControl
|
|
636
|
+
*
|
|
637
|
+
* @example
|
|
638
|
+
* ```typescript
|
|
639
|
+
* if (isSignalFormControl(value)) {
|
|
640
|
+
* console.log(value.value()); // TypeScript knows this is a control
|
|
641
|
+
* }
|
|
642
|
+
* ```
|
|
643
|
+
*/
|
|
644
|
+
declare function isSignalFormControl<TValue>(obj: unknown): obj is SignalFormControl<TValue>;
|
|
645
|
+
/**
|
|
646
|
+
* Creates a reactive form control with signal-based state management.
|
|
647
|
+
*
|
|
648
|
+
* Builds a control that wraps a primitive value (string, number, boolean, etc.)
|
|
649
|
+
* with validation, state tracking, and reactive updates using Angular signals.
|
|
650
|
+
*
|
|
651
|
+
* Features:
|
|
652
|
+
* - Reactive value updates through signals
|
|
653
|
+
* - Validators for errors (mark control as invalid)
|
|
654
|
+
* - Warnings (validation messages without invalidating)
|
|
655
|
+
* - Dynamic disabled state based on form context
|
|
656
|
+
* - State tracking (touched, dirty)
|
|
657
|
+
* - Manual error/warning management
|
|
658
|
+
*
|
|
659
|
+
* @template TControls - Object type defining available sibling controls for cross-field validation
|
|
660
|
+
* @template TValue - The type of value this control manages
|
|
661
|
+
*
|
|
662
|
+
* @param input - Control input (raw value, config object, or existing control)
|
|
663
|
+
* @param getControl - Optional accessor function for sibling controls
|
|
664
|
+
* @returns Fully configured SignalFormControl instance
|
|
665
|
+
*
|
|
666
|
+
* @example
|
|
667
|
+
* ```typescript
|
|
668
|
+
* // Simple control
|
|
669
|
+
* const nameControl = createSignalFormControl('John');
|
|
670
|
+
*
|
|
671
|
+
* // With validators
|
|
672
|
+
* const ageControl = createSignalFormControl({
|
|
673
|
+
* value: 25,
|
|
674
|
+
* validators: [signalFormValidators.required, signalFormValidators.min(0)],
|
|
675
|
+
* warnings: [signalFormValidators.max(120)]
|
|
676
|
+
* });
|
|
677
|
+
*
|
|
678
|
+
* // With dynamic disabled
|
|
679
|
+
* const emailControl = createSignalFormControl({
|
|
680
|
+
* value: '',
|
|
681
|
+
* disabled: (ctx) => ctx.getControl('accountType').value() === 'guest'
|
|
682
|
+
* });
|
|
683
|
+
* ```
|
|
684
|
+
*/
|
|
685
|
+
declare function createSignalFormControl<TControls extends object, TValue>(input: SignalFormControlInput<TValue, TControls>, getControl?: ControlAccessor<TControls>): SignalFormControl<TValue>;
|
|
686
|
+
|
|
687
|
+
/**
|
|
688
|
+
* Type guard to check if an object is a SignalForm (form group).
|
|
689
|
+
*
|
|
690
|
+
* @template TData - Object type defining the form structure
|
|
691
|
+
* @param obj - Object to check
|
|
692
|
+
* @returns True if obj is a SignalForm
|
|
693
|
+
*
|
|
694
|
+
* @example
|
|
695
|
+
* ```typescript
|
|
696
|
+
* if (isSignalFormGroup(value)) {
|
|
697
|
+
* console.log(value.controls.name); // TypeScript knows this is a form group
|
|
698
|
+
* }
|
|
699
|
+
* ```
|
|
700
|
+
*/
|
|
701
|
+
declare function isSignalFormGroup<TData extends object>(obj: unknown): obj is SignalForm<TData>;
|
|
702
|
+
/**
|
|
703
|
+
* Creates a reactive form group for managing structured form data.
|
|
704
|
+
*
|
|
705
|
+
* Builds a typed form container that holds multiple named controls, groups, or arrays.
|
|
706
|
+
* Each property in the input object becomes a control with full signal-based reactivity.
|
|
707
|
+
* Provides type-safe access to controls and tracks collective validation state.
|
|
708
|
+
*
|
|
709
|
+
* Features:
|
|
710
|
+
* - Type-safe control access via `.controls` property
|
|
711
|
+
* - Reactive value and error tracking across all controls
|
|
712
|
+
* - Collective state management (touched, dirty, valid)
|
|
713
|
+
* - Manual error/warning management at group level
|
|
714
|
+
* - Support for nested groups and arrays
|
|
715
|
+
* - Cross-field validation via getControl accessor
|
|
716
|
+
*
|
|
717
|
+
* @template TData - Object type defining the structure and types of all controls
|
|
718
|
+
*
|
|
719
|
+
* @param inputs - Object mapping property names to their control inputs
|
|
720
|
+
* @returns Fully configured SignalForm instance
|
|
721
|
+
*
|
|
722
|
+
* @example
|
|
723
|
+
* ```typescript
|
|
724
|
+
* // Simple form
|
|
725
|
+
* const form = createSignalFormGroup({
|
|
726
|
+
* name: 'John',
|
|
727
|
+
* age: 25
|
|
728
|
+
* });
|
|
729
|
+
*
|
|
730
|
+
* // With validators and nested structure
|
|
731
|
+
* const form = createSignalFormGroup<User>({
|
|
732
|
+
* email: {
|
|
733
|
+
* value: '',
|
|
734
|
+
* validators: [signalFormValidators.required, signalFormValidators.email]
|
|
735
|
+
* },
|
|
736
|
+
* age: {
|
|
737
|
+
* value: 25,
|
|
738
|
+
* validators: [signalFormValidators.min(0)],
|
|
739
|
+
* warnings: [signalFormValidators.max(120)]
|
|
740
|
+
* },
|
|
741
|
+
* address: {
|
|
742
|
+
* street: '123 Main St',
|
|
743
|
+
* city: 'NYC'
|
|
744
|
+
* },
|
|
745
|
+
* hobbies: ['coding', 'gaming']
|
|
746
|
+
* });
|
|
747
|
+
*
|
|
748
|
+
* // Access controls
|
|
749
|
+
* form.controls.email.value(); // Type-safe access
|
|
750
|
+
* form.getControl('age').setValue(30);
|
|
751
|
+
* ```
|
|
752
|
+
*/
|
|
753
|
+
declare function createSignalFormGroup<TData extends object>(inputs: SignalFormInputs<TData>): SignalForm<TData>;
|
|
754
|
+
/**
|
|
755
|
+
* Helper function to create a standalone form control.
|
|
756
|
+
*
|
|
757
|
+
* Creates a control without sibling control access. Useful for creating
|
|
758
|
+
* individual controls outside of a form group context.
|
|
759
|
+
*
|
|
760
|
+
* @template TValue - The type of value the control manages
|
|
761
|
+
* @param input - Control input (raw value, config object, or existing control)
|
|
762
|
+
* @returns SignalFormControl instance
|
|
763
|
+
*
|
|
764
|
+
* @example
|
|
765
|
+
* ```typescript
|
|
766
|
+
* const nameControl = formControl('John');
|
|
767
|
+
* const ageControl = formControl({
|
|
768
|
+
* value: 25,
|
|
769
|
+
* validators: [signalFormValidators.min(0)]
|
|
770
|
+
* });
|
|
771
|
+
* ```
|
|
772
|
+
*/
|
|
773
|
+
declare function formControl<TValue>(input: SignalFormControlInput<TValue, object>): SignalFormControl<TValue>;
|
|
774
|
+
/**
|
|
775
|
+
* Helper function to create a standalone form array.
|
|
776
|
+
*
|
|
777
|
+
* Creates an array without sibling control access. Useful for creating
|
|
778
|
+
* array controls outside of a form group context.
|
|
779
|
+
*
|
|
780
|
+
* @template TValue - The type of each item in the array
|
|
781
|
+
* @param input - Array of initial items
|
|
782
|
+
* @returns SignalFormArray instance
|
|
783
|
+
*
|
|
784
|
+
* @example
|
|
785
|
+
* ```typescript
|
|
786
|
+
* const tagsArray = formArray(['tag1', 'tag2', 'tag3']);
|
|
787
|
+
* const addressesArray = formArray<Address>([
|
|
788
|
+
* { street: '123 Main', city: 'NYC' }
|
|
789
|
+
* ]);
|
|
790
|
+
* ```
|
|
791
|
+
*/
|
|
792
|
+
declare function formArray<TValue>(input: SignalFormInput<TValue, object>[]): SignalFormArray<TValue>;
|
|
793
|
+
/**
|
|
794
|
+
* Helper function to create a form group.
|
|
795
|
+
*
|
|
796
|
+
* Alias for createSignalFormGroup. Creates a typed form with multiple controls.
|
|
797
|
+
*
|
|
798
|
+
* @template TData - Object type defining the form structure
|
|
799
|
+
* @param input - Object mapping property names to control inputs
|
|
800
|
+
* @returns SignalForm instance
|
|
801
|
+
*
|
|
802
|
+
* @example
|
|
803
|
+
* ```typescript
|
|
804
|
+
* const form = formGroup({
|
|
805
|
+
* name: 'John',
|
|
806
|
+
* email: {
|
|
807
|
+
* value: 'john@example.com',
|
|
808
|
+
* validators: [signalFormValidators.email]
|
|
809
|
+
* }
|
|
810
|
+
* });
|
|
811
|
+
* ```
|
|
812
|
+
*/
|
|
813
|
+
declare function formGroup<TData extends object>(input: SignalFormInputs<TData>): SignalForm<TData>;
|
|
814
|
+
/**
|
|
815
|
+
* Primary API for creating signal-based reactive forms.
|
|
816
|
+
*
|
|
817
|
+
* Alias for `formGroup`. This is the main entry point for creating forms.
|
|
818
|
+
* Provides type-safe, signal-based form state management with built-in validation.
|
|
819
|
+
*
|
|
820
|
+
* @example
|
|
821
|
+
* ```typescript
|
|
822
|
+
* // Basic form
|
|
823
|
+
* const form = signalForm({ name: 'John', age: 25 });
|
|
824
|
+
*
|
|
825
|
+
* // Complex form with validation
|
|
826
|
+
* const form = signalForm<Person>({
|
|
827
|
+
* name: {
|
|
828
|
+
* value: '',
|
|
829
|
+
* validators: [signalFormValidators.required, signalFormValidators.minLength(2)]
|
|
830
|
+
* },
|
|
831
|
+
* age: {
|
|
832
|
+
* value: 30,
|
|
833
|
+
* validators: [signalFormValidators.min(0)],
|
|
834
|
+
* warnings: [signalFormValidators.max(120)],
|
|
835
|
+
* disabled: (ctx) => ctx.getControl('name').value() === 'admin'
|
|
836
|
+
* },
|
|
837
|
+
* address: {
|
|
838
|
+
* street: '123 Main St',
|
|
839
|
+
* city: 'NYC'
|
|
840
|
+
* },
|
|
841
|
+
* hobbies: ['coding', 'gaming']
|
|
842
|
+
* });
|
|
843
|
+
*
|
|
844
|
+
* // Access form state
|
|
845
|
+
* console.log(form.value()); // { name: '', age: 30, address: {...}, hobbies: [...] }
|
|
846
|
+
* console.log(form.valid()); // boolean
|
|
847
|
+
* console.log(form.controls.name.errors()); // { required: 'This field is required' }
|
|
848
|
+
* ```
|
|
849
|
+
*/
|
|
850
|
+
declare const signalForm: typeof formGroup;
|
|
851
|
+
|
|
852
|
+
type ValidatorFn = SignalFormValidatorFn<any, any>;
|
|
853
|
+
/**
|
|
854
|
+
* Validator that enforces a maximum string or number length.
|
|
855
|
+
*
|
|
856
|
+
* Converts the value to string and checks if its length exceeds the specified maximum.
|
|
857
|
+
* Works with both string and number types.
|
|
858
|
+
*
|
|
859
|
+
* @param num - Maximum allowed length (inclusive)
|
|
860
|
+
* @returns Validator function
|
|
861
|
+
*
|
|
862
|
+
* @example
|
|
863
|
+
* ```typescript
|
|
864
|
+
* const control = signalForm({
|
|
865
|
+
* username: { value: 'verylongusername', validators: [signalFormValidators.maxLength(10)] }
|
|
866
|
+
* });
|
|
867
|
+
* // control.controls.username.errors() => { maxLength: 'To long' }
|
|
868
|
+
* ```
|
|
869
|
+
*/
|
|
870
|
+
declare function maxLength(num: number): ValidatorFn;
|
|
871
|
+
/**
|
|
872
|
+
* Validator that enforces a minimum string or number length.
|
|
873
|
+
*
|
|
874
|
+
* Converts the value to string and checks if its length is less than or equal to the specified minimum.
|
|
875
|
+
* Works with both string and number types.
|
|
876
|
+
*
|
|
877
|
+
* @param num - Minimum required length (inclusive)
|
|
878
|
+
* @returns Validator function
|
|
879
|
+
*
|
|
880
|
+
* @example
|
|
881
|
+
* ```typescript
|
|
882
|
+
* const control = signalForm({
|
|
883
|
+
* code: { value: 'ab', validators: [signalFormValidators.minLength(3)] }
|
|
884
|
+
* });
|
|
885
|
+
* // control.controls.code.errors() => { minLength: 'To short' }
|
|
886
|
+
* ```
|
|
887
|
+
*/
|
|
888
|
+
declare function minLength(num: number): ValidatorFn;
|
|
889
|
+
/**
|
|
890
|
+
* Validator that enforces a minimum numeric value.
|
|
891
|
+
*
|
|
892
|
+
* Checks if a numeric value is less than or equal to the specified minimum.
|
|
893
|
+
* Value is coerced to a number for comparison.
|
|
894
|
+
*
|
|
895
|
+
* @param num - Minimum allowed value (exclusive - value must be greater than this)
|
|
896
|
+
* @returns Validator function
|
|
897
|
+
*
|
|
898
|
+
* @example
|
|
899
|
+
* ```typescript
|
|
900
|
+
* const control = signalForm({
|
|
901
|
+
* age: { value: -5, validators: [signalFormValidators.min(0)] }
|
|
902
|
+
* });
|
|
903
|
+
* // control.controls.age.errors() => { minLength: 'To small' }
|
|
904
|
+
* ```
|
|
905
|
+
*/
|
|
906
|
+
declare function min(num: number): ValidatorFn;
|
|
907
|
+
/**
|
|
908
|
+
* Validator that enforces a maximum numeric value.
|
|
909
|
+
*
|
|
910
|
+
* Checks if a numeric value exceeds the specified maximum.
|
|
911
|
+
* Value is coerced to a number for comparison.
|
|
912
|
+
*
|
|
913
|
+
* @param num - Maximum allowed value (inclusive)
|
|
914
|
+
* @returns Validator function
|
|
915
|
+
*
|
|
916
|
+
* @example
|
|
917
|
+
* ```typescript
|
|
918
|
+
* const control = signalForm({
|
|
919
|
+
* age: { value: 150, validators: [signalFormValidators.max(120)] }
|
|
920
|
+
* });
|
|
921
|
+
* // control.controls.age.errors() => { minLength: 'To big' }
|
|
922
|
+
* ```
|
|
923
|
+
*/
|
|
924
|
+
declare function max(num: number): ValidatorFn;
|
|
925
|
+
/**
|
|
926
|
+
* Validator that checks if a value matches a specified regular expression pattern.
|
|
927
|
+
*
|
|
928
|
+
* Accepts either a RegExp object or a string pattern. String patterns are automatically
|
|
929
|
+
* wrapped with ^ and $ anchors to match the entire value.
|
|
930
|
+
*
|
|
931
|
+
* Skips validation for empty values (use with `required` if needed).
|
|
932
|
+
*
|
|
933
|
+
* @param valuePattern - Regular expression or pattern string to match against
|
|
934
|
+
* @returns Validator function
|
|
935
|
+
*
|
|
936
|
+
* @example
|
|
937
|
+
* ```typescript
|
|
938
|
+
* // Using regex
|
|
939
|
+
* const control1 = signalForm({
|
|
940
|
+
* code: { value: 'abc', validators: [signalFormValidators.pattern(/^[0-9]+$/)] }
|
|
941
|
+
* });
|
|
942
|
+
* // control1.controls.code.errors() => { pattern: 'RequiredPattern: ^[0-9]+$, ActualValue: abc' }
|
|
943
|
+
*
|
|
944
|
+
* // Using string pattern
|
|
945
|
+
* const control2 = signalForm({
|
|
946
|
+
* zipCode: { value: 'ABC', validators: [signalFormValidators.pattern('[0-9]{5}')] }
|
|
947
|
+
* });
|
|
948
|
+
* ```
|
|
949
|
+
*/
|
|
950
|
+
declare function pattern(valuePattern: string | RegExp): ValidatorFn;
|
|
951
|
+
/**
|
|
952
|
+
* Collection of built-in validators for signal-form controls.
|
|
953
|
+
*
|
|
954
|
+
* Provides common validation functions that can be used in the `validators` or `warnings`
|
|
955
|
+
* arrays of form controls. All validators skip empty values except `required`.
|
|
956
|
+
*
|
|
957
|
+
* @property required - Ensures the value is not empty (null, undefined, '', [], 0, empty Set)
|
|
958
|
+
* @property maxLength - Ensures string/number length doesn't exceed maximum
|
|
959
|
+
* @property minLength - Ensures string/number length meets minimum requirement
|
|
960
|
+
* @property min - Ensures numeric value is greater than minimum (exclusive)
|
|
961
|
+
* @property max - Ensures numeric value doesn't exceed maximum (inclusive)
|
|
962
|
+
* @property email - Validates email address format using Angular-compatible regex
|
|
963
|
+
* @property pattern - Validates value matches a regular expression pattern
|
|
964
|
+
*
|
|
965
|
+
* @example
|
|
966
|
+
* ```typescript
|
|
967
|
+
* const form = signalForm({
|
|
968
|
+
* email: {
|
|
969
|
+
* value: '',
|
|
970
|
+
* validators: [signalFormValidators.required, signalFormValidators.email]
|
|
971
|
+
* },
|
|
972
|
+
* age: {
|
|
973
|
+
* value: 25,
|
|
974
|
+
* validators: [signalFormValidators.min(0), signalFormValidators.max(120)],
|
|
975
|
+
* warnings: [signalFormValidators.max(100)] // Warning but doesn't invalidate
|
|
976
|
+
* },
|
|
977
|
+
* username: {
|
|
978
|
+
* value: '',
|
|
979
|
+
* validators: [
|
|
980
|
+
* signalFormValidators.required,
|
|
981
|
+
* signalFormValidators.minLength(3),
|
|
982
|
+
* signalFormValidators.maxLength(20),
|
|
983
|
+
* signalFormValidators.pattern(/^[a-zA-Z0-9_]+$/)
|
|
984
|
+
* ]
|
|
985
|
+
* }
|
|
986
|
+
* });
|
|
987
|
+
* ```
|
|
988
|
+
*/
|
|
989
|
+
declare const signalFormValidators: {
|
|
990
|
+
required: ValidatorFn;
|
|
991
|
+
maxLength: typeof maxLength;
|
|
992
|
+
minLength: typeof minLength;
|
|
993
|
+
min: typeof min;
|
|
994
|
+
max: typeof max;
|
|
995
|
+
email: ValidatorFn;
|
|
996
|
+
pattern: typeof pattern;
|
|
997
|
+
};
|
|
998
|
+
|
|
999
|
+
export { createSignalFormArray, createSignalFormControl, createSignalFormGroup, formArray, formControl, formGroup, isSignalFormArray, isSignalFormControl, isSignalFormGroup, signalForm, signalFormValidators };
|
|
1000
|
+
export type { FirstError, SignalForm, SignalFormArray, SignalFormArrayInput, SignalFormContext, SignalFormControl, SignalFormControlConfig, SignalFormControlInput, SignalFormControlLike, SignalFormDisableOptions, SignalFormDisabledFn, SignalFormErrorFor, SignalFormGroupInput, SignalFormInput, SignalFormInputs, SignalFormSetValueOptions, SignalFormValidationError, SignalFormValidatorFn, SignalFormValueFor };
|