@fagon/ngx-intellitoolx 16.0.1 → 16.0.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.
package/README.md CHANGED
@@ -1,307 +1,386 @@
1
- # IntelliToolxHelper
1
+ # IntelliToolx
2
2
 
3
- Utility helpers for working with Angular Reactive Forms, deep comparisons, change detection, and common data transformations.
4
- Designed to simplify form state management, prevent accidental navigation, and normalize user input.
3
+ ![Angular](https://img.shields.io/badge/Angular-14%2B-red)
4
+ ![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue)
5
+ ![License](https://img.shields.io/badge/License-MIT-green)
6
+ ![Reactive Forms](https://img.shields.io/badge/Reactive%20Forms-Supported-orange)
7
+ ![Standalone Components](https://img.shields.io/badge/Standalone-Compatible-purple)
8
+
9
+ ## Overview
10
+
11
+ IntelliToolx is a comprehensive Angular utility library designed to simplify reactive form development, validation, and user experience.
12
+
13
+ It provides powerful helpers, reusable validators, smart error handling, UI components, and developer-friendly utilities that eliminate repetitive boilerplate and enforce consistent form behavior across applications.
14
+
15
+ Built with scalability, accessibility, and maintainability in mind, IntelliToolx helps teams build robust, user-friendly form workflows faster and with fewer bugs.
5
16
 
6
17
  ### Installation
7
18
 
8
- npm install intellitoolx-helper
19
+ ```bash
20
+ npm install intellitoolx
21
+ ```
22
+
23
+ # IntelliToolxHelper
24
+
25
+ Utility helpers for working with Angular Reactive Forms, deep comparisons, change detection, and common data transformations.
26
+ Designed to simplify form state management, prevent accidental navigation, and normalize user input.
9
27
 
10
- ## Import
28
+ ### Import
11
29
 
12
- import { IntelliToolxHelper } from 'intellitoolx-helper';
30
+ ```ts
31
+ import { IntelliToolxHelper } from "intellitoolx";
32
+ ```
13
33
 
14
- Methods
34
+ ## Methods
15
35
 
16
- ## captureInitialValue(form)
36
+ ### captureInitialFormValue(form)
17
37
 
18
38
  Captures and clones the initial value of a form and marks it as pristine.
19
39
 
20
- static captureInitialValue(form: AbstractControl): any
40
+ ```ts
41
+ static captureInitialFormValue(form: AbstractControl): any
42
+ ```
21
43
 
22
44
  Features
23
- Uses getRawValue() when available
24
- Marks form as pristine
25
- Returns a deep clone of the initial value
45
+
46
+ - Uses getRawValue() when available
47
+ - Marks form as pristine
48
+ - Returns a deep clone of the initial value
26
49
 
27
50
  Example
28
- const initial = IntelliToolxHelper.captureInitialValue(this.form);
29
51
 
30
- ## trimFormGroup(control)
52
+ ```ts
53
+ const initial = IntelliToolxHelper.captureInitialFormValue(this.form);
54
+ ```
55
+
56
+ ### trimFormGroup(control)
31
57
 
32
58
  Recursively trims whitespace from all string values in a form.
33
59
 
60
+ ```ts
34
61
  static trimFormGroup(control: AbstractControl): void
62
+ ```
35
63
 
36
64
  Supports
37
- FormGroup
38
- FormArray
39
- FormControl
65
+
66
+ - FormGroup
67
+ - FormArray
68
+ - FormControl
40
69
 
41
70
  Example
71
+
72
+ ```ts
42
73
  IntelliToolxHelper.trimFormGroup(this.form);
74
+ ```
43
75
 
44
- ## deepEqual(obj1, obj2)
76
+ ### deepEqual(obj1, obj2)
45
77
 
46
78
  Performs a deep comparison between two values.
47
79
 
80
+ ```ts
48
81
  static deepEqual(obj1: any, obj2: any): boolean
82
+ ```
49
83
 
50
84
  Special behavior
51
- Treats null, undefined, and "" as equal
52
- Normalizes numeric comparisons
53
- Compares File objects by metadata
54
- Supports nested objects & arrays
85
+
86
+ - Treats null, undefined, and "" as equal
87
+ - Normalizes numeric comparisons
88
+ - Compares File objects by metadata
89
+ - Supports nested objects & arrays
55
90
 
56
91
  Example
92
+
93
+ ```ts
57
94
  IntelliToolxHelper.deepEqual(a, b);
95
+ ```
58
96
 
59
- ## isEmpty(value)
97
+ ### isEmpty(value)
60
98
 
61
99
  Checks if a value is empty.
62
100
 
101
+ ```ts
63
102
  static isEmpty(value: any): boolean
103
+ ```
64
104
 
65
- Returns true for:
66
- null
67
- undefined
68
- empty string
69
- whitespace-only string
105
+ Returns true for: `null, undefined, empty string, whitespace-only string `
70
106
 
71
- ## clone(value)
107
+ ### clone(value)
72
108
 
73
109
  Creates a deep clone.
74
110
 
111
+ ```ts
75
112
  static clone(value: any): any
113
+ ```
76
114
 
77
115
  Uses structuredClone (Angular 14+ compatible).
78
116
 
79
- ## formHasChanges(initialValue, form)
117
+ ### formHasChanges(initialValue, form)
80
118
 
81
119
  Determines whether a form value has changed.
82
120
 
121
+ ```ts
83
122
  static formHasChanges(initialValue: any, form: AbstractControl): boolean
123
+ ```
84
124
 
85
125
  Example
126
+
127
+ ```ts
86
128
  if (IntelliToolxHelper.formHasChanges(initial, this.form)) {
87
- // prompt user
129
+ // prompt user
88
130
  }
131
+ ```
89
132
 
90
- ## confirmIfChanged(hasChanges, confirmHandler?)
133
+ ### confirmIfChanged(hasChanges, confirmHandler?)
91
134
 
92
135
  Shows confirmation if changes exist.
93
136
 
94
- static confirmIfChanged(
95
- hasChanges: boolean,
96
- confirmHandler?: ConfirmHandler
97
- ): Promise<boolean>
137
+ ```ts
138
+ static confirmIfChanged(hasChanges: boolean, confirmHandler?: ConfirmHandler): Promise<boolean>
139
+ ```
98
140
 
99
141
  Behavior
100
- Returns true if no changes
101
- Uses provided handler if available
102
- Falls back to browser confirm()
142
+
143
+ - Returns true if no changes
144
+ - Uses provided handler if available
145
+ - Falls back to browser confirm()
103
146
 
104
147
  Example
105
- const canLeave = await IntelliToolxHelper.confirmIfChanged(
106
- hasChanges,
107
- () => dialog.confirm()
108
- );
109
148
 
110
- ## registerBeforeUnload(shouldBlock, message?)
149
+ ```ts
150
+ const canLeave = await IntelliToolxHelper.confirmIfChanged(hasChanges, () => dialog.confirm());
151
+ ```
152
+
153
+ ### registerBeforeUnload(shouldBlock, message?)
111
154
 
112
155
  Prevents accidental page exit when changes exist.
113
156
 
114
- static registerBeforeUnload(
115
- shouldBlock: () => boolean,
116
- message?: string
117
- ): () => void
157
+ ```ts
158
+ static registerBeforeUnload(shouldBlock: () => boolean, message?: string): () => void
159
+ ```
118
160
 
119
- Returns
120
- Cleanup function to remove the listener.
161
+ Returns `Cleanup function to remove the listener.`
121
162
 
122
163
  Example
123
- const cleanup = IntelliToolxHelper.registerBeforeUnload(() =>
124
- this.form.dirty
125
- );
126
164
 
165
+ ```ts
166
+ const cleanup = IntelliToolxHelper.registerBeforeUnload(() => this.form.dirty);
127
167
  // later
128
168
  cleanup();
169
+ ```
129
170
 
130
- ## getFormControl(form, path)
171
+ ### getFormControl(form, path)
131
172
 
132
173
  Retrieves a nested FormControl using dot notation.
133
174
 
134
- static getFormControl<T>(
135
- form: AbstractControl,
136
- path: string
137
- ): FormControl<T> | null
175
+ ```ts
176
+ static getFormControl<T>(form: AbstractControl, path: string): FormControl<T> | null
177
+ ```
138
178
 
139
179
  Supports
140
- Nested FormGroups
141
- FormArrays using numeric indexes
180
+
181
+ - Nested FormGroups
182
+ - FormArrays using numeric indexes
142
183
 
143
184
  Example
144
- const control = IntelliToolxHelper.getFormControl(this.form, 'address.street');
145
- const item = IntelliToolxHelper.getFormControl(this.form, 'items.0.name');
146
185
 
147
- ## convertImageToBase64(file)
186
+ ```ts
187
+ const control = IntelliToolxHelper.getFormControl(this.form, "address.street");
188
+ const item = IntelliToolxHelper.getFormControl(this.form, "items.0.name");
189
+ ```
190
+
191
+ ### convertImageToBase64(file)
148
192
 
149
193
  Converts an image file to a Base64 string.
150
194
 
195
+ ```ts
151
196
  static convertImageToBase64(file: File): Promise<string>
197
+ ```
152
198
 
153
199
  Example
200
+
201
+ ```ts
154
202
  const base64 = await IntelliToolxHelper.convertImageToBase64(file);
203
+ ```
155
204
 
156
- ## replaceCharacter(text, replaceChar, replaceWithChar)
205
+ ### replaceCharacter(text, replaceChar, replaceWithChar)
157
206
 
158
207
  Replaces all occurrences of a character in a string.
159
208
 
160
- static replaceCharacter(
161
- text: any,
162
- replaceChar: string,
163
- replaceWithChar: string
164
- ): string
209
+ ```ts
210
+ static replaceCharacter(text: any, replaceChar: string, replaceWithChar: string): string
211
+ ```
165
212
 
166
213
  Example
167
- IntelliToolxHelper.replaceCharacter('1-2-3', '-', ':');
214
+
215
+ ```ts
216
+ IntelliToolxHelper.replaceCharacter("1-2-3", "-", ":");
168
217
  // 1:2:3
218
+ ```
169
219
 
170
- ## convertJsonStringToJson(value)
220
+ ### convertJsonStringToJson(value)
171
221
 
172
222
  Safely converts a JSON string into an object.
173
223
 
174
- static convertJsonStringToJson<T>(
175
- value: T | string | null | undefined
176
- ): T | null
224
+ ```ts
225
+ static convertJsonStringToJson<T>(value: T | string | null | undefined): T | null
226
+ ```
177
227
 
178
228
  Behavior
179
- Returns parsed object if valid JSON string
180
- Returns original object if already parsed
181
- Returns null if parsing fails
229
+
230
+ - Returns parsed object if valid JSON string
231
+ - Returns original object if already parsed
232
+ - Returns null if parsing fails
182
233
 
183
234
  Example
235
+
236
+ ```ts
184
237
  const data = IntelliToolxHelper.convertJsonStringToJson<MyType>(jsonString);
238
+ ```
185
239
 
186
- ### Usage Pattern (Recommended)
240
+ Usage Pattern (Recommended)
187
241
 
188
- initialValue = IntelliToolxHelper.captureInitialValue(this.form);
242
+ ```ts
243
+ initialValue = IntelliToolxHelper.captureInitialFormValue(this.form);
189
244
 
190
245
  save() {
191
- IntelliToolxHelper.trimFormGroup(this.form);
192
-
193
- if (!IntelliToolxHelper.formHasChanges(this.initialValue, this.form)) {
194
- return;
195
- }
246
+ IntelliToolxHelper.trimFormGroup(this.form);
196
247
 
197
- // proceed with save
248
+ if (!IntelliToolxHelper.formHasChanges(this.initialValue, this.form)) {
249
+ return;
250
+ }
251
+ // proceed with save
198
252
  }
253
+ ```
199
254
 
200
255
  # IntellitoolxRegExps
201
256
 
202
257
  A collection of commonly used regular expressions for validation in Angular and TypeScript applications.
203
258
 
204
- Designed for:
205
- Reactive Forms validation
206
- Input sanitization
207
- Reusable validation patterns
208
- Consistent form behavior across projects
259
+ 1. Designed for:
260
+ 2. Reactive Forms validation
261
+ 3. Input sanitization
262
+ 4. Reusable validation patterns
263
+ 5. Consistent form behavior across projects
209
264
 
210
- Import
211
- import { IntellitoolxRegExps } from 'intellitoolx-helper';
265
+ ### Import
266
+
267
+ ```ts
268
+ import { IntellitoolxRegExps } from "intellitoolx";
269
+ ```
212
270
 
213
- Available Regular Expressions
271
+ ## Available Regular Expressions
214
272
 
215
- ## EMAIL_REGEX
273
+ ### EMAIL_REGEX
216
274
 
217
- EMAIL*REGEX: /^(?=.{1,50}$)[a-zA-Z0-9.*%+-]+@[a-zA-Z0-9.-]+\.[A-Za-z]{2,}$/
275
+ `EMAIL*REGEX: /^(?=.{1,50}$)[a-zA-Z0-9.*%+-]+@[a-zA-Z0-9.-]+\.[A-Za-z]{2,}$/`
218
276
 
219
277
  Validates an email address with:
220
- Maximum length of 50 characters
221
- Standard email format
222
- Requires valid domain suffix (min 2 characters)
278
+
279
+ 1. Maximum length of 50 characters
280
+ 2. Standard email format
281
+ 3. Requires valid domain suffix (min 2 characters)
223
282
 
224
283
  Valid Examples
225
- test@example.com
226
- user.name@mail-domain.org
227
- info123@test.co
284
+
285
+ - test@example.com
286
+ - user.name@mail-domain.org
287
+ - info123@test.co
228
288
 
229
289
  Invalid Examples
230
- invalid-email
231
- user@
232
- @test.com
290
+
291
+ - invalid-email
292
+ - user@
293
+ - @test.com
233
294
 
234
295
  Usage (Angular Validator)
235
296
 
297
+ ```ts
236
298
  this.form = new FormGroup({
237
- email: new FormControl('', [
238
- Validators.pattern(IntellitoolxRegExps.EMAIL_REGEX),
239
- ]),
299
+ email: new FormControl("", [Validators.pattern(IntellitoolxRegExps.EMAIL_REGEX)]),
240
300
  });
301
+ ```
241
302
 
242
- ## NUMBER_REGEX
303
+ ### NUMBER_REGEX
243
304
 
244
- NUMBER_REGEX: /^\d+$/
305
+ `NUMBER_REGEX: /^\d+$/`
245
306
 
246
307
  Validates:
247
- Whole numbers only
248
- No decimals
249
- No negative values
250
- No spaces or characters
308
+
309
+ - Whole numbers only
310
+ - No decimals
311
+ - No negative values
312
+ - No spaces or characters
251
313
 
252
314
  Valid Examples
253
- 1, 25, 99999
315
+
316
+ - 1
317
+ - 25
318
+ - 99999
254
319
 
255
320
  Invalid Examples
256
- 1.5, -10, abc
257
321
 
258
- ## AMOUNT_REGEX
322
+ - 1.5
323
+ - -10
324
+ - abc
325
+
326
+ ### AMOUNT_REGEX
259
327
 
260
- AMOUNT_REGEX: /^\d+(\.\d{1,2})?$/
328
+ `AMOUNT_REGEX: /^\d+(\.\d{1,2})?$/`
261
329
 
262
330
  Validates monetary amounts:
263
- Whole numbers
264
- Optional decimal
265
- Maximum 2 decimal places
331
+
332
+ 1. Whole numbers
333
+ 2. Optional decimal
334
+ 3. Maximum 2 decimal places
266
335
 
267
336
  Valid Examples
268
- 10, 10.5, 10.50, 9999.99
337
+
338
+ - 10,
339
+ - 10.5
340
+ - 10.50
341
+ - 9999.99
269
342
 
270
343
  Invalid Examples
271
- 10., 10.999, abc
272
344
 
273
- ## DOMAIN_REGEX
345
+ - 10.
346
+ - 10.999
347
+ - abc
274
348
 
275
- DOMAIN_REGEX:
276
- /^(?=.{1,255}$)(https?|ftp):\/\/([\w.-]+)\.([a-z\.]{2,6})(:[0-9]{1,5})?(\/\S*)?$/
349
+ ### DOMAIN_REGEX
350
+
351
+ `DOMAIN_REGEX: /^(?=.{1,255}$)(https?|ftp):\/\/([\w.-]+)\.([a-z\.]{2,6})(:[0-9]{1,5})?(\/\S*)?$/`
277
352
 
278
353
  Validates full URLs with:
279
354
  http, https, or ftp protocol
280
355
 
281
356
  Valid domain
282
- Optional port
283
- Optional path
284
- Maximum length of 255 characters
357
+
358
+ 1. Optional port
359
+ 2. Optional path
360
+ 3. Maximum length of 255 characters
285
361
 
286
362
  Valid Examples
287
- https://example.com, http://sub.domain.org, https://example.com:8080/path, ftp://files.server.net
363
+
364
+ - https://example.com
365
+ - http://sub.domain.org
366
+ - https://example.com:8080/path
367
+ - ftp://files.server.net
288
368
 
289
369
  Invalid Examples
290
- example.com, http:/example.com, htp://domain.com
291
370
 
292
- ### Usage in Angular Reactive Forms
371
+ - example.com
372
+ - http:/example.com
373
+ - htp://domain.com
374
+
375
+ Usage in Angular Reactive Forms
293
376
 
377
+ ```ts
294
378
  this.form = new FormGroup({
295
- email: new FormControl('', [
296
- Validators.pattern(IntellitoolxRegExps.EMAIL_REGEX),
297
- ]),
298
- amount: new FormControl('', [
299
- Validators.pattern(IntellitoolxRegExps.AMOUNT_REGEX),
300
- ]),
301
- website: new FormControl('', [
302
- Validators.pattern(IntellitoolxRegExps.DOMAIN_REGEX),
303
- ]),
379
+ email: new FormControl("", [Validators.pattern(IntellitoolxRegExps.EMAIL_REGEX)]),
380
+ amount: new FormControl("", [Validators.pattern(IntellitoolxRegExps.AMOUNT_REGEX)]),
381
+ website: new FormControl("", [Validators.pattern(IntellitoolxRegExps.DOMAIN_REGEX)]),
304
382
  });
383
+ ```
305
384
 
306
385
  # IntellitoolxFormUpdateMessage
307
386
 
@@ -309,159 +388,187 @@ A lightweight Angular standalone component that displays a configurable warning
309
388
 
310
389
  Designed to improve user experience by clearly informing users why an action (such as saving) cannot proceed.
311
390
 
312
- ## Import
391
+ ### Import
392
+
393
+ ```ts
394
+ import { IntellitoolxFormUpdateMessage } from "intellitoolx";
395
+ ```
313
396
 
314
- import { IntellitoolxFormUpdateMessage } from 'intellitoolx-helper';
315
397
  Because it is standalone, import it directly:
316
398
 
399
+ ```ts
317
400
  @Component({
318
- standalone: true,
319
- imports: [IntellitoolxFormUpdateMessage],
401
+ standalone: true,
402
+ imports: [IntellitoolxFormUpdateMessage],
320
403
  })
404
+ ```
321
405
 
322
- ## Basic Usage
406
+ Basic Usage
323
407
 
408
+ ```
324
409
  <itx-form-update-message></itx-form-update-message>
410
+ ```
411
+
412
+ Default message:
325
413
 
326
- ### Default message:
414
+ `There are no changes to save. Please modify a field to continue.`
327
415
 
328
- There are no changes to save. Please modify a field to continue.
329
- With Configuration
416
+ ### With Configuration
330
417
 
331
418
  Customize text and styling using itxFormUpdateMessageConfig.
332
419
 
333
- <itx-form-update-message
334
- [itxFormUpdateMessageConfig]="updateMessageConfig"
420
+ ```html
421
+ <itx-form-update-message [itxFormUpdateMessageConfig]="updateMessageConfig"> </itx-form-update-message>
422
+ ```
335
423
 
336
- > </itx-form-update-message>
337
- > updateMessageConfig = {
338
- > message: 'Nothing changed yet.',
339
- > textColor: '#0c5460',
340
- > backgroundColor: '#d1ecf1',
341
- > borderColor: '#bee5eb',
342
- > };
424
+ ```ts
425
+ updateMessageConfig = {
426
+ message: "Nothing changed yet.",
427
+ textColor: "#0c5460",
428
+ backgroundColor: "#d1ecf1",
429
+ borderColor: "#bee5eb",
430
+ };
431
+ ```
343
432
 
344
- ## Configuration Interface
433
+ Configuration Interface
345
434
 
435
+ ```ts
346
436
  export interface IntellitoolxFormUpdateMessageConfig {
347
- message?: string;
348
- textColor?: string;
349
- backgroundColor?: string;
350
- borderColor?: string;
351
- padding?: string;
352
- iconAndMessageGap?: string;
353
- borderRadius?: string;
354
- fontWeight?: number | string;
355
- iconSize?: string;
437
+ message?: string;
438
+ textColor?: string;
439
+ backgroundColor?: string;
440
+ borderColor?: string;
441
+ padding?: string;
442
+ iconAndMessageGap?: string;
443
+ borderRadius?: string;
444
+ fontWeight?: number | string;
445
+ iconSize?: string;
356
446
  }
447
+ ```
357
448
 
358
449
  All properties are optional.
359
450
 
360
- ## Default Styling Behavior
361
-
451
+ Default Styling Behavior
362
452
  If no configuration is provided, the component uses accessible warning styles.
363
453
 
364
- Property Default
365
- text color #963C00
366
- background #fff3cd
367
- border #f3cd5a
368
- padding 1rem
369
- border radius 0.5rem
370
- gap 0.5rem
371
- font weight 400
372
- icon size 1rem
454
+ | Property | Default |
455
+ | ------------- | ------- |
456
+ | text color | #963C00 |
457
+ | background | #fff3cd |
458
+ | border | #f3cd5a |
459
+ | padding | 1rem |
460
+ | border radius | 0.5rem |
461
+ | gap | 0.5rem |
462
+ | font weight | 400 |
463
+ | icon size | 1rem |
464
+
373
465
  Accessibility
374
466
 
375
- Uses role="alert" to notify assistive technologies
376
- Icon is hidden from screen readers with aria-hidden="true"
377
- Provides clear visual contrast for warning context
467
+ - Uses role="alert" to notify assistive technologies
468
+ - Icon is hidden from screen readers with aria-hidden="true"
469
+ - Provides clear visual contrast for warning context
378
470
 
379
471
  Example: Show When No Changes Exist
380
- <itx-form-update-message
381
- \*ngIf="!formHasChanges"
472
+ formHasChanges = false;
382
473
 
383
- > </itx-form-update-message>
384
- > formHasChanges = false;
385
- > Example: Integrating With IntelliToolxHelper
386
- > hasChanges = IntelliToolxHelper.formHasChanges(this.initialValue, this.form);
387
- > <itx-form-update-message
388
- > *ngIf="!hasChanges"
389
- > </itx-form-update-message>
474
+ ```html
475
+ <itx-form-update-message *ngIf="!formHasChanges"> </itx-form-update-message>
476
+ ```
390
477
 
391
- ## Theming Examples
478
+ Example: Integrating With IntelliToolxHelper
392
479
 
480
+ ```ts
481
+ hasChanges = IntelliToolxHelper.formHasChanges(this.initialValue, this.form);
482
+ ```
483
+
484
+ ```html
485
+ <itx-form-update-message *ngIf="!hasChanges"> </itx-form-update-message>
486
+ ```
487
+
488
+ Theming Examples
393
489
  Success Style
490
+
491
+ ```ts
394
492
  updateMessageConfig = {
395
- message: 'No updates were made.',
396
- textColor: '#155724',
397
- backgroundColor: '#d4edda',
398
- borderColor: '#c3e6cb',
493
+ message: "No updates were made.",
494
+ textColor: "#155724",
495
+ backgroundColor: "#d4edda",
496
+ borderColor: "#c3e6cb",
399
497
  };
498
+ ```
400
499
 
401
500
  Minimal Style
501
+
502
+ ```ts
402
503
  updateMessageConfig = {
403
- backgroundColor: 'transparent',
404
- borderColor: '#ddd',
405
- textColor: '#555',
504
+ backgroundColor: "transparent",
505
+ borderColor: "#ddd",
506
+ textColor: "#555",
406
507
  };
508
+ ```
407
509
 
408
- ## When to Use
409
-
510
+ When to Use
410
511
  Use this component when:
411
- A save/update action is triggered without changes
412
- Preventing redundant submissions
413
- Improving form UX clarity
414
- Displaying inline form state feedback
512
+
513
+ 1. A save/update action is triggered without changes
514
+ 2. Preventing redundant submissions
515
+ 3. Improving form UX clarity
516
+ 4. Displaying inline form state feedback
415
517
 
416
518
  # IntellitoolxFormErrors
417
519
 
418
520
  A lightweight Angular standalone component for displaying reactive form validation errors with customizable and extensible error messages.
419
-
420
521
  Built to:
421
- standardize validation messages
422
- support component-level overrides
423
- allow global extension of error messages
424
- simplify template error handling
425
522
 
426
- Import
427
- import { IntellitoolxFormErrors } from 'intellitoolx-helper';
523
+ 1. standardize validation messages
524
+ 2. support component-level overrides
525
+ 3. allow global extension of error messages
526
+ 4. simplify template error handling
527
+
528
+ ### Import
529
+
530
+ ```ts
531
+ import { IntellitoolxFormErrors } from "intellitoolx";
532
+ ```
428
533
 
429
534
  You can import it directly into any component.
430
535
 
431
- ## Basic Usage
536
+ ### Basic Usage
432
537
 
433
- <input [formControl]="emailControl" />
434
- <itx-form-errors [control]="emailControl"></itx-form-errors>
538
+ ```html
539
+ <input [formControl]="emailControl" /> <itx-form-errors [control]="emailControl"></itx-form-errors>
540
+ ```
435
541
 
436
542
  Errors will display automatically when:
437
- control is touched
438
- control is invalid
439
543
 
440
- Default Supported Errors
544
+ - control is touched
545
+ - control is invalid
546
+
547
+ ### Default Supported Errors
548
+
441
549
  The component includes built-in messages for common validators:
442
550
 
443
- Error Key Message
444
- required This field is required
445
- email The email entered is invalid
446
- minlength You must enter at least X characters
447
- maxlength You must not enter more than X characters
448
- pattern Your entry must match the required pattern
449
- passwordMismatch Password and confirm password do not match
450
- futureDate Future date is not allowed
451
- duplicateEmail Each email must be unique
452
- maxWords Exceeded maximum number of words
453
- maxMonthYear Date is later than allowed
454
- minMonthYear Date is earlier than allowed
455
- exceededAllowedDateDifference Date difference can only be one month
456
- exceededLeastDateAllowed Start date cannot be greater than end date
457
-
458
- ## Adding Control Labels (User-Friendly Messages)
459
-
460
- <itx-form-errors
461
- [control]="amountControl"
462
- controlLabel="Amount"
463
-
464
- > </itx-form-errors>
551
+ | Error Key | Message |
552
+ | ----------------------------- | ------------------------------------------ |
553
+ | required | This field is required |
554
+ | email | The email entered is invalid |
555
+ | minlength | You must enter at least X characters |
556
+ | maxlength | You must not enter more than X characters |
557
+ | pattern | Your entry must match the required pattern |
558
+ | passwordMismatch | Password and confirm password do not match |
559
+ | futureDate | Future date is not allowed |
560
+ | duplicateEmail | Each email must be unique |
561
+ | maxWords | Exceeded maximum number of words |
562
+ | maxMonthYear | Date is later than allowed |
563
+ | minMonthYear | Date is earlier than allowed |
564
+ | exceededAllowedDateDifference | Date difference can only be one month |
565
+ | exceededLeastDateAllowed | Start date cannot be greater than end date |
566
+
567
+ ### Adding Control Labels (User-Friendly Messages)
568
+
569
+ ```html
570
+ <itx-form-errors [control]="amountControl" controlLabel="Amount"> </itx-form-errors>
571
+ ```
465
572
 
466
573
  Example output:
467
574
  Amount cannot be greater than 100
@@ -469,491 +576,570 @@ Amount cannot be greater than 100
469
576
  Component-Level Custom Messages
470
577
  Override messages for a specific field.
471
578
 
579
+ ```ts
472
580
  componentValidation = {
473
- required: { message: 'Email is mandatory' },
474
- minlength: { message: 'Too short' },
581
+ required: { message: "Email is mandatory" },
582
+ minlength: { message: "Too short" },
475
583
  };
584
+ ```
476
585
 
477
- <itx-form-errors
478
- [control]="emailControl"
479
- [componentValidation]="componentValidation"
480
-
481
- > </itx-form-errors>
586
+ ```html
587
+ <itx-form-errors [control]="emailControl" [componentValidation]="componentValidation"> </itx-form-errors>
588
+ ```
482
589
 
483
590
  ### Using Custom Validators with Messages
484
591
 
485
592
  If your validator returns an object:
486
- return { customMinValue: { message: 'Value is too small' } };
593
+
594
+ ```ts
595
+ return { customMinValue: { message: "Value is too small" } };
596
+ ```
487
597
 
488
598
  The component will display:
489
599
  Value is too small
490
600
 
491
- ## Extending Error Messages (Recommended)
601
+ ### Extending Error Messages (Recommended)
492
602
 
493
603
  Consumers can extend the component to add global or shared messages.
494
604
 
495
- ### Option 1 — Extend the Component
605
+ Option 1 — Extend the Component
496
606
 
497
607
  Create your own reusable error component:
498
608
 
499
- import { Component } from '@angular/core';
500
- import { IntellitoolxFormErrors } from 'intellitoolx-helper';
609
+ ```ts
610
+ import { Component } from "@angular/core";
611
+ import { IntellitoolxFormErrors } from "intellitoolx";
501
612
 
502
613
  @Component({
503
- selector: 'app-form-errors',
504
- standalone: true,
505
- imports: [IntellitoolxFormErrors],
506
- template: ` <itx-form-errors
507
- [control]="control"
508
- [componentValidation]="componentValidation"
509
- [controlLabel]="controlLabel"
510
- />
511
- `,
614
+ selector: "app-form-errors",
615
+ standalone: true,
616
+ imports: [IntellitoolxFormErrors],
617
+ template: ` <itx-form-errors [control]="control" [componentValidation]="componentValidation" [controlLabel]="controlLabel" /> `,
512
618
  })
513
619
  export class AppFormErrors extends IntellitoolxFormErrors {
514
- override errorMessages = {
515
- ...this.errorMessages,
516
- required: 'This field cannot be empty',
517
- phone: 'Phone number is invalid',
518
- usernameTaken: 'This username is already taken',
519
- };
620
+ override errorMessages = {
621
+ ...this.errorMessages,
622
+ required: "This field cannot be empty",
623
+ phone: "Phone number is invalid",
624
+ usernameTaken: "This username is already taken",
625
+ };
520
626
  }
627
+ ```
521
628
 
522
629
  Now use:
630
+
631
+ ```html
523
632
  <app-form-errors [control]="control"></app-form-errors>
633
+ ```
524
634
 
525
- ### Option 2 — Extend via Custom Validator Keys
635
+ Option 2 — Extend via Custom Validator Keys
526
636
 
527
637
  Return new error keys from validators:
528
638
 
639
+ ```ts
529
640
  return { usernameTaken: true };
641
+ ```
530
642
 
531
643
  Then provide the message:
532
644
 
645
+ ```ts
533
646
  componentValidation = {
534
- usernameTaken: { message: 'Username already exists' },
647
+ usernameTaken: { message: "Username already exists" },
535
648
  };
649
+ ```
536
650
 
537
- ### Option 3 — Global Shared Messages Service (Advanced)
651
+ Option 3 — Global Shared Messages Service (Advanced)
538
652
 
539
653
  Create a shared constant:
540
654
 
655
+ ```ts
541
656
  export const APP_ERROR_MESSAGES = {
542
- required: 'Required field',
543
- email: 'Invalid email address',
657
+ required: "Required field",
658
+ email: "Invalid email address",
544
659
  };
660
+ ```
545
661
 
546
662
  Then extend:
663
+
664
+ ```ts
547
665
  override errorMessages = {
548
666
  ...APP_ERROR_MESSAGES,
549
667
  };
668
+ ```
550
669
 
551
- ## Supported Error Value Types
670
+ ### Supported Error Value Types
552
671
 
553
672
  The component intelligently handles different validator outputs:
554
673
 
555
- Boolean
556
- { required: true }
557
- uses default or custom message
558
-
559
- String
560
- { customError: 'Invalid value provided' }
561
- → displays string directly
562
-
563
- Object
564
- { minlength: { requiredLength: 5 } }
565
- → dynamic message rendering
674
+ - Boolean { required: true } → uses default or custom message
675
+ - String { customError: 'Invalid value provided' } → displays string directly
676
+ - Object { minlength: { requiredLength: 5 } } → dynamic message rendering
566
677
 
567
678
  Built-in Smart Messages
568
- Pattern Errors
569
679
 
570
- ## Displays:
680
+ - Pattern Errors Display: `Please provide a valid {controlLabel}`
681
+ - Min / Max Validators Display: `Age cannot be less than 18` / `Price cannot be greater than 100`
682
+ - Ngb Date Errors Display: `Invalid date format provided`
571
683
 
572
- Please provide a valid {controlLabel}
573
- Min / Max Validators
574
- Age cannot be less than 18
575
- Price cannot be greater than 100
576
- Ngb Date Errors
577
- Invalid date format provided
684
+ Best Practices
578
685
 
579
- ### Best Practices
686
+ - Always provide controlLabel for better UX
687
+ - Use componentValidation for field-specific overrides
688
+ - Extend the component for app-wide consistency
689
+ - Return structured error objects from custom validators
690
+ - Keep error keys consistent across the application
580
691
 
581
- Always provide controlLabel for better UX
582
- ✔ Use componentValidation for field-specific overrides
583
- ✔ Extend the component for app-wide consistency
584
- ✔ Return structured error objects from custom validators
585
- ✔ Keep error keys consistent across the application
692
+ ### Example (Full Integration)
586
693
 
587
- Example (Full Integration)
694
+ ```html
588
695
  <input formControlName="email" />
589
696
 
590
- <app-form-errors
591
- [control]="form.controls.email"
592
- controlLabel="Email Address"
593
-
594
- > </app-form-errors>
697
+ <app-form-errors [control]="form.controls.email" controlLabel="Email Address"> </app-form-errors>
698
+ ```
595
699
 
596
700
  # RequiredMarkerDirective
597
701
 
598
702
  An Angular standalone directive that automatically adds a visual required marker to form labels when the associated form control has a required validator.
599
703
  This ensures consistent UX and eliminates manual asterisk management.
600
704
 
601
- ## Import
705
+ ### Import
602
706
 
603
- import { RequiredMarkerDirective } from 'intellitoolx-helper';
707
+ ```ts
708
+ import { RequiredMarkerDirective } from "intellitoolx";
709
+ ```
604
710
 
605
711
  Because it is standalone, import it directly:
606
712
 
713
+ ```ts
607
714
  @Component({
608
- standalone: true,
609
- imports: [RequiredMarkerDirective],
715
+ standalone: true,
716
+ imports: [RequiredMarkerDirective],
610
717
  })
718
+ ```
611
719
 
612
- ## Basic Usage
720
+ ### Basic Usage
613
721
 
614
722
  Add the directive to a <label> element.
615
723
 
724
+ ```html
616
725
  <label for="email" itxRequired>Email</label>
726
+
617
727
  <input id="email" formControlName="email" />
728
+ ```
618
729
 
619
730
  If the control has Validators.required, the output becomes:
620
- Email \*
731
+ Email\*
621
732
 
622
- ## How It Works
733
+ ### How It Works
623
734
 
624
- Reads the label’s for attribute.
625
- Finds the matching control inside the parent FormGroup.
626
- Checks for Validators.required.
627
- Adds or removes the required marker dynamically.
628
- Updates when value or status changes.
629
-
630
- ## Dynamic Updates
735
+ - Reads the label’s for attribute.
736
+ - Finds the matching control inside the parent FormGroup.
737
+ - Checks for Validators.required.
738
+ - Adds or removes the required marker dynamically.
739
+ - Updates when value or status changes.
631
740
 
741
+ Dynamic Updates
632
742
  If required validation is added or removed at runtime:
743
+
744
+ ```ts
633
745
  control.setValidators([Validators.required]);
634
746
  control.updateValueAndValidity();
747
+ ```
748
+
635
749
  The label updates automatically.
636
750
 
637
- ## Default Marker Behavior
751
+ ### Default Marker Behavior
638
752
 
639
- Property Default
640
- marker sign \*
641
- color red
642
- spacing 0.25rem
643
- position after label text
644
- Global Configuration
753
+ | Property | Default |
754
+ | -------------------- | ------- |
755
+ | marker sign | \* |
756
+ | color | red |
757
+ | spacing | 0.25rem |
758
+ | position after label | text |
645
759
 
646
- ## You can configure marker appearance globally using the provided injection token.
760
+ ### Global Configuration
647
761
 
762
+ You can configure marker appearance globally using the provided injection token.
648
763
  Step 1 — Provide Configuration
649
- import { REQUIRED_MARKER_GLOBAL_CONFIG } from 'intellitoolx-helper';
764
+
765
+ ```ts
766
+ import { REQUIRED_MARKER_GLOBAL_CONFIG } from "intellitoolx";
650
767
 
651
768
  providers: [
652
- {
653
- provide: REQUIRED_MARKER_GLOBAL_CONFIG,
654
- useValue: {
655
- sign: '*',
656
- color: '#d9534f',
657
- spacing: '4px',
658
- position: 'after', // 'before' | 'after'
659
- },
660
- },
769
+ {
770
+ provide: REQUIRED_MARKER_GLOBAL_CONFIG,
771
+ useValue: {
772
+ sign: "*",
773
+ color: "#d9534f",
774
+ spacing: "4px",
775
+ position: "after", // 'before' | 'after'
776
+ },
777
+ },
661
778
  ];
779
+ ```
662
780
 
663
781
  Configuration Options
782
+
783
+ ```ts
664
784
  export interface ResolvedRequiredMarkerConfig {
665
- sign: string;
666
- color: string;
667
- spacing: string;
668
- position: 'before' | 'after';
785
+ sign: string;
786
+ color: string;
787
+ spacing: string;
788
+ position: "before" | "after";
669
789
  }
790
+ ```
670
791
 
671
792
  Positioning the Marker
672
- After (default)
673
- Email \*
674
- Before
675
- position: 'before'
676
-
677
- - Email
793
+ After (default) `Email \*`
794
+ Before position: 'before' `\* Email`
678
795
 
679
796
  Preserves Additional Label Text
680
797
  The directive preserves text in parentheses or suffix content.
798
+
799
+ ```html
681
800
  <label for="dob" itxRequired>Date of Birth (optional)</label>
801
+ ```
682
802
 
683
- Output when required:
684
- Date of Birth \* (optional)
803
+ Output when required: `Date of Birth \* (optional)`
685
804
  Works With Nested Form Groups
686
- Ensure the for attribute matches the control name.
805
+ Ensure the `for` attribute matches the control name.
806
+
807
+ ```html
687
808
  <label for="address.street" itxRequired>Street</label>
809
+
688
810
  <input formControlName="street" />
811
+ ```
689
812
 
690
- ## Requirements
813
+ ### Requirements
691
814
 
692
- Must be used inside a form with FormGroupDirective
693
- Label for attribute must match control name
815
+ - Must be used inside a form with FormGroupDirective
816
+ - Label for attribute must match control name
694
817
 
695
- ## Common Mistakes
818
+ ### Common Mistakes
696
819
 
697
- Missing for attribute
698
- Label not associated with control
699
- Control name mismatch
820
+ - Missing for attribute
821
+ - Label not associated with control
822
+ - Control name mismatch
700
823
 
701
824
  Example (Complete)
702
825
 
826
+ ```html
703
827
  <form [formGroup]="form">
704
828
  <label for="email" itxRequired>Email</label>
705
829
  <input id="email" formControlName="email" />
706
830
  </form>
707
- email: new FormControl('', Validators.required);
831
+ ```
832
+
833
+ ```ts
834
+ email: new FormControl("", Validators.required);
835
+ ```
708
836
 
709
837
  # JsonParsePipe
710
838
 
711
839
  An Angular standalone pipe that safely parses JSON strings into JavaScript objects.
840
+ Built on top of `IntelliToolxHelper.convertJsonStringToJson`, this pipe prevents template errors when dealing with dynamic or stringified JSON data.
712
841
 
713
- Built on top of IntelliToolxHelper.convertJsonStringToJson, this pipe prevents template errors when dealing with dynamic or stringified JSON data.
714
-
715
- ## Import
842
+ ### Import
716
843
 
717
- import { JsonParsePipe } from 'intellitoolx-helper';
844
+ ```ts
845
+ import { JsonParsePipe } from "intellitoolx";
846
+ ```
718
847
 
719
848
  Because it is standalone, import it directly:
720
849
 
850
+ ```ts
721
851
  @Component({
722
- standalone: true,
723
- imports: [JsonParsePipe],
852
+ standalone: true,
853
+ imports: [JsonParsePipe],
724
854
  })
855
+ ```
725
856
 
726
- ## Usage
857
+ ### Usage
727
858
 
728
859
  Basic Example
860
+
861
+ ```
729
862
  {{ jsonString | jsonParse | json }}
863
+ ```
730
864
 
731
865
  Input
866
+
867
+ ```ts
732
868
  jsonString = '{"name":"John","age":30}';
869
+ ```
733
870
 
734
871
  Output
872
+
873
+ ```json
735
874
  {
736
- "name": "John",
737
- "age": 30
875
+ "name": "John",
876
+ "age": 30
738
877
  }
878
+ ```
739
879
 
740
- ## When to Use
880
+ ### When to Use
741
881
 
742
882
  Use jsonParse when:
743
- API responses contain stringified JSON
744
- Form values store serialized objects
745
- LocalStorage data needs parsing
746
- Preventing template crashes from invalid JSON
747
883
 
748
- ## Behavior
884
+ - API responses contain stringified JSON
885
+ - Form values store serialized objects
886
+ - LocalStorage data needs parsing
887
+ - Preventing template crashes from invalid JSON
888
+
889
+ ### Behavior
749
890
 
750
891
  The pipe safely handles multiple input types:
751
892
 
752
- Input Result
753
- Valid JSON string Parsed object
754
- Invalid JSON string null
755
- Object Returned unchanged
756
- null / undefined null
893
+ | Input | Result |
894
+ | ------------------------ | --------- |
895
+ | Valid JSON string Parsed | object |
896
+ | Invalid JSON string | null |
897
+ | Object Returned | unchanged |
898
+ | null / undefined | null |
757
899
 
758
900
  Examples
759
901
  Parse API Data
760
902
 
761
- <div *ngIf="user.data | jsonParse as parsed">
762
- {{ parsed.name }}
763
- </div>
903
+ ```html
904
+ <div *ngIf="user.data | jsonParse as parsed">{{ parsed.name }}</div>
905
+ ```
764
906
 
765
907
  Parse Stored JSON
908
+
909
+ ```
766
910
  {{ localStorageValue | jsonParse | json }}
911
+ ```
767
912
 
768
913
  Safe Access with Optional Chaining
914
+
915
+ ```
769
916
  {{ (settings | jsonParse)?.theme }}
917
+ ```
770
918
 
771
919
  Equivalent TypeScript Logic
772
920
 
773
921
  The pipe internally performs:
922
+
923
+ ```ts
774
924
  IntelliToolxHelper.convertJsonStringToJson(value);
925
+ ```
775
926
 
776
927
  Error Safety
928
+
777
929
  Unlike JSON.parse() directly in templates, this pipe:
778
- prevents runtime template errors
779
- avoids breaking change detection
780
- returns null on parsing failure
930
+
931
+ - prevents runtime template errors
932
+ - avoids breaking change detection
933
+ - returns null on parsing failure
781
934
 
782
935
  For large datasets or repeated bindings:
783
936
  Prefer parsing in the component
937
+
938
+ ```ts
784
939
  parsedData = IntelliToolxHelper.convertJsonStringToJson(data);
940
+ ```
785
941
 
786
942
  # IntelliToolx Validators
787
943
 
788
944
  A set of reusable Angular Reactive Form validators designed for common business rules such as amount limits, password matching, word limits, and duplicate detection.
789
-
790
- These validators integrate seamlessly with Angular forms and work perfectly with IntellitoolxFormErrors for displaying user-friendly messages.
945
+ These validators integrate seamlessly with Angular forms and work perfectly with `IntellitoolxFormErrors` for displaying user-friendly messages.
791
946
 
792
947
  Import
793
- import {
794
- customMaxAmountValidator,
795
- customMinAmountValidator,
796
- MaxWordsValidator,
797
- PasswordMismatchValidator,
798
- uniqueEmailsValidator
799
- } from 'intellitoolx-helper';
800
948
 
801
- ## Validators Overview
949
+ ```ts
950
+ import { customMaxAmountValidator, customMinAmountValidator, maxWordsValidator, passwordMismatchValidator, uniqueEmailsValidator } from "intellitoolx";
951
+ ```
802
952
 
803
- Validator Purpose
804
- customMaxAmountValidator Enforces maximum numeric value
805
- customMinAmountValidator Enforces minimum numeric value
806
- MaxWordsValidator Limits number of words
807
- PasswordMismatchValidator Ensures password fields match
808
- uniqueEmailsValidator Prevents duplicate emails in FormArray
953
+ ### Validators Overview
809
954
 
810
- ## customMaxAmountValidator(maxValue)
955
+ | Validator | Purpose |
956
+ | ------------------------- | -------------------------------------- |
957
+ | customMaxAmountValidator | Enforces maximum numeric value |
958
+ | customMinAmountValidator | Enforces minimum numeric value |
959
+ | maxWordsValidator | Limits number of words |
960
+ | passwordMismatchValidator | Ensures password fields match |
961
+ | uniqueEmailsValidator | Prevents duplicate emails in FormArray |
962
+
963
+ ### customMaxAmountValidator(maxValue)
811
964
 
812
965
  Ensures a numeric value does not exceed a specified maximum.
966
+
967
+ ```ts
813
968
  customMaxAmountValidator(maxValue: number): ValidatorFn
969
+ ```
814
970
 
815
971
  Example
816
- amount = new FormControl('', [
817
- customMaxAmountValidator(1000)
818
- ]);
972
+
973
+ ```ts
974
+ amount = new FormControl("", [customMaxAmountValidator(1000)]);
975
+ ```
819
976
 
820
977
  Error Output
978
+
979
+ ```json
821
980
  {
822
- customMaxValue: {
823
- requiredMin: 1000,
824
- actual: 1200,
825
- message: "The value must not exceed 1000.00"
826
- }
981
+ "customMaxValue": {
982
+ "requiredMin": 1000,
983
+ "actual": 1200,
984
+ "message": "The value must not exceed 1000.00"
985
+ }
827
986
  }
987
+ ```
828
988
 
829
989
  Notes
830
- Accepts numeric values only
831
- Returns a formatted error message
832
- Works with IntellitoolxFormErrors automatically
833
990
 
834
- ## customMinAmountValidator(minValue)
991
+ - Accepts numeric values only
992
+ - Returns a formatted error message
993
+ - Works with IntellitoolxFormErrors automatically
994
+
995
+ ### customMinAmountValidator(minValue)
835
996
 
836
997
  Ensures a numeric value is at least the specified minimum.
998
+
999
+ ```ts
837
1000
  customMinAmountValidator(minValue: number): ValidatorFn
1001
+ ```
838
1002
 
839
1003
  Example
840
- amount = new FormControl('', [
841
- customMinAmountValidator(10)
842
- ]);
1004
+
1005
+ ```ts
1006
+ amount = new FormControl("", [customMinAmountValidator(10)]);
1007
+ ```
1008
+
843
1009
  Error Output
1010
+
1011
+ ```json
844
1012
  {
845
- customMinValue: {
846
- requiredMin: 10,
847
- actual: 5,
848
- message: "The value must be at least 10.00"
849
- }
1013
+ "customMinValue": {
1014
+ "requiredMin": 10,
1015
+ "actual": 5,
1016
+ "message": "The value must be at least 10.00"
1017
+ }
850
1018
  }
1019
+ ```
851
1020
 
852
- ## MaxWordsValidator(maxWords)
1021
+ ### maxWordsValidator(maxWords)
853
1022
 
854
1023
  Limits the number of words in a text input.
855
- MaxWordsValidator(maxWords: number): ValidatorFn
1024
+ maxWordsValidator(maxWords: number): ValidatorFn
856
1025
 
857
1026
  Example
858
- description = new FormControl('', [
859
- MaxWordsValidator(20)
860
- ]);
861
1027
 
862
- ### Behavior
1028
+ ```ts
1029
+ description = new FormControl("", [maxWordsValidator(20)]);
1030
+ ```
1031
+
1032
+ Behavior
863
1033
 
864
- Ignores extra whitespace
865
- Counts words separated by spaces
1034
+ - Ignores extra whitespace
1035
+ - Counts words separated by spaces
866
1036
 
867
1037
  Error Output
1038
+
1039
+ ```json
868
1040
  {
869
- maxWords: {
870
- actual: 25,
871
- max: 20
872
- }
1041
+ "maxWords": {
1042
+ "actual": 25,
1043
+ "max": 20
1044
+ }
873
1045
  }
1046
+ ```
874
1047
 
875
- ## PasswordMismatchValidator(controlName, matchingControlName)
1048
+ ### passwordMismatchValidator(controlName, matchingControlName)
876
1049
 
877
1050
  Validates that two form fields match (commonly used for password confirmation).
878
- PasswordMismatchValidator(
879
- controlName: string,
880
- matchingControlName: string
1051
+
1052
+ ```ts
1053
+ passwordMismatchValidator(
1054
+ controlName: string,
1055
+ matchingControlName: string
881
1056
  )
1057
+ ```
882
1058
 
883
1059
  Example
1060
+
1061
+ ```ts
884
1062
  this.form = new FormGroup(
885
- {
886
- password: new FormControl(''),
887
- confirmPassword: new FormControl('')
888
- },
889
- {
890
- validators: PasswordMismatchValidator('password', 'confirmPassword')
891
- }
1063
+ {
1064
+ password: new FormControl(""),
1065
+ confirmPassword: new FormControl(""),
1066
+ },
1067
+ {
1068
+ validators: passwordMismatchValidator("password", "confirmPassword"),
1069
+ },
892
1070
  );
1071
+ ```
893
1072
 
894
1073
  Error Output
1074
+
1075
+ ```
895
1076
  { passwordMismatch: true }
1077
+ ```
896
1078
 
897
1079
  Notes
898
- Error is applied to the matching control
899
- Ideal for password confirmation fields
900
1080
 
901
- ## uniqueEmailsValidator()
1081
+ - Error is applied to the matching control
1082
+ - Ideal for password confirmation fields
1083
+
1084
+ ### uniqueEmailsValidator()
902
1085
 
903
1086
  Ensures all email addresses inside a FormArray are unique.
1087
+
1088
+ ```ts
904
1089
  uniqueEmailsValidator(): ValidatorFn
1090
+ ```
905
1091
 
906
1092
  Example
1093
+
1094
+ ```ts
907
1095
  this.form = new FormGroup({
908
- contacts: new FormArray([
909
- new FormGroup({
910
- email: new FormControl('')
911
- })
912
- ])
1096
+ contacts: new FormArray([
1097
+ new FormGroup({
1098
+ email: new FormControl(""),
1099
+ }),
1100
+ ]),
913
1101
  });
914
1102
 
915
1103
  this.contacts.setValidators(uniqueEmailsValidator());
1104
+ ```
916
1105
 
917
- ### Behavior
1106
+ Behavior
918
1107
 
919
- Ignores case and whitespace
920
- Flags duplicates automatically
921
- Updates errors dynamically
1108
+ - Ignores case and whitespace
1109
+ - Flags duplicates automatically
1110
+ - Updates errors dynamically
922
1111
 
923
- Error Output (control level)
924
- { duplicateEmail: true }
925
- Error Output (form array level)
926
- { duplicateEmails: true }
1112
+ Error Output (control level) `{ duplicateEmail: true }`
1113
+ Error Output (form array level) `{ duplicateEmails: true }`
927
1114
 
928
1115
  ### Integration with IntellitoolxFormErrors
929
1116
 
930
1117
  These validators return error keys compatible with the error component:
931
- Validator Error Key
932
- customMaxAmountValidator customMaxValue
933
- customMinAmountValidator customMinValue
934
- MaxWordsValidator maxWords
935
- PasswordMismatchValidator passwordMismatch
936
- uniqueEmailsValidator duplicateEmail
937
1118
 
938
- ### Best Practices
1119
+ | Validator Error | Key |
1120
+ | ------------------------- | ---------------- |
1121
+ | customMaxAmountValidator | customMaxValue |
1122
+ | customMinAmountValidator | customMinValue |
1123
+ | maxWordsValidator | maxWords |
1124
+ | passwordMismatchValidator | passwordMismatch |
1125
+ | uniqueEmailsValidator | duplicateEmail |
1126
+
1127
+ Best Practices
939
1128
 
940
- Use with Reactive Forms only
941
- Combine with required validators when necessary
942
- Provide control labels for better error messages
943
- Normalize numeric inputs before validation
944
- Use FormArray validators for dynamic lists
1129
+ - Use with Reactive Forms only
1130
+ - Combine with required validators when necessary
1131
+ - Provide control labels for better error messages
1132
+ - Normalize numeric inputs before validation
1133
+ - Use FormArray validators for dynamic lists
945
1134
 
946
1135
  ### Complete Example
947
1136
 
1137
+ ```ts
948
1138
  this.form = new FormGroup({
949
- amount: new FormControl('', [
950
- customMinAmountValidator(10),
951
- customMaxAmountValidator(1000),
952
- ]),
953
- description: new FormControl('', [
954
- MaxWordsValidator(20)
955
- ]),
1139
+ amount: new FormControl("", [customMinAmountValidator(10), customMaxAmountValidator(1000)]),
1140
+ description: new FormControl("", [maxWordsValidator(20)]),
956
1141
  });
1142
+ ```
957
1143
 
958
1144
  License
959
1145
  MIT