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