@ardium-pl/devkit 8.3.2

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.
Files changed (82) hide show
  1. package/README.md +25 -0
  2. package/fesm2022/ardium-pl-devkit.mjs +3874 -0
  3. package/fesm2022/ardium-pl-devkit.mjs.map +1 -0
  4. package/index.d.ts +5 -0
  5. package/lib/click-outside/click-outside.directive.d.ts +14 -0
  6. package/lib/click-outside/click-outside.module.d.ts +8 -0
  7. package/lib/click-outside/index.d.ts +2 -0
  8. package/lib/coercion/array.d.ts +21 -0
  9. package/lib/coercion/boolean.d.ts +6 -0
  10. package/lib/coercion/date.d.ts +5 -0
  11. package/lib/coercion/index.d.ts +4 -0
  12. package/lib/coercion/number.d.ts +20 -0
  13. package/lib/dom-boxes/dom-boxes.d.ts +7 -0
  14. package/lib/dom-boxes/index.d.ts +1 -0
  15. package/lib/escape-html/escape-html.d.ts +1 -0
  16. package/lib/escape-html/escape-html.module.d.ts +8 -0
  17. package/lib/escape-html/escape-html.pipe.d.ts +7 -0
  18. package/lib/escape-html/index.d.ts +3 -0
  19. package/lib/file-pipes/file-pipes.defaults.d.ts +8 -0
  20. package/lib/file-pipes/file-pipes.module.d.ts +10 -0
  21. package/lib/file-pipes/fileext.pipe.d.ts +39 -0
  22. package/lib/file-pipes/filename.pipe.d.ts +38 -0
  23. package/lib/file-pipes/filesize.pipe.d.ts +50 -0
  24. package/lib/file-pipes/index.d.ts +5 -0
  25. package/lib/file-system/file-system.service.d.ts +69 -0
  26. package/lib/file-system/file-system.types.d.ts +186 -0
  27. package/lib/file-system/index.d.ts +2 -0
  28. package/lib/find-functions/find-suggestion.d.ts +3 -0
  29. package/lib/find-functions/index.d.ts +1 -0
  30. package/lib/forms/index.d.ts +1 -0
  31. package/lib/forms/track-form-control/index.d.ts +1 -0
  32. package/lib/forms/track-form-control/track-form-control.d.ts +83 -0
  33. package/lib/hold/hold.defaults.d.ts +9 -0
  34. package/lib/hold/hold.directive.d.ts +24 -0
  35. package/lib/hold/hold.module.d.ts +8 -0
  36. package/lib/hold/index.d.ts +3 -0
  37. package/lib/http-service/_types.d.ts +20 -0
  38. package/lib/http-service/_utils.d.ts +1 -0
  39. package/lib/http-service/http.service.d.ts +2574 -0
  40. package/lib/http-service/index.d.ts +1 -0
  41. package/lib/infinite-scroll/index.d.ts +3 -0
  42. package/lib/infinite-scroll/infinite-scroll.defaults.d.ts +8 -0
  43. package/lib/infinite-scroll/infinite-scroll.directive.d.ts +24 -0
  44. package/lib/infinite-scroll/infinite-scroll.module.d.ts +8 -0
  45. package/lib/keyboard/index.d.ts +2 -0
  46. package/lib/keyboard/keyboard.service.d.ts +60 -0
  47. package/lib/keyboard/keyboard.types.d.ts +13 -0
  48. package/lib/keyboard/types-internal.d.ts +20 -0
  49. package/lib/keyboard/utils.d.ts +3 -0
  50. package/lib/relative-pos/index.d.ts +1 -0
  51. package/lib/relative-pos/relative-pos.d.ts +24 -0
  52. package/lib/signals/array/array-signal.d.ts +123 -0
  53. package/lib/signals/array/index.d.ts +1 -0
  54. package/lib/signals/counter/counter-signal.d.ts +67 -0
  55. package/lib/signals/counter/index.d.ts +1 -0
  56. package/lib/signals/debounced/debounced-signal.d.ts +15 -0
  57. package/lib/signals/debounced/index.d.ts +1 -0
  58. package/lib/signals/map/index.d.ts +1 -0
  59. package/lib/signals/map/map-signal.d.ts +97 -0
  60. package/lib/signals/persistent/index.d.ts +1 -0
  61. package/lib/signals/persistent/persistent-signal.d.ts +106 -0
  62. package/lib/signals/query-param/index.d.ts +1 -0
  63. package/lib/signals/query-param/query-param-signal.d.ts +35 -0
  64. package/lib/signals/queue/index.d.ts +1 -0
  65. package/lib/signals/queue/queue-signal.d.ts +77 -0
  66. package/lib/signals/set/index.d.ts +1 -0
  67. package/lib/signals/set/set-signal.d.ts +76 -0
  68. package/lib/signals/stack/index.d.ts +1 -0
  69. package/lib/signals/stack/stack-signal.d.ts +77 -0
  70. package/lib/signals/throttled/index.d.ts +1 -0
  71. package/lib/signals/throttled/throttled-signal.d.ts +15 -0
  72. package/lib/signals/tuple/index.d.ts +1 -0
  73. package/lib/signals/tuple/tuple-signal.d.ts +60 -0
  74. package/lib/validators/index.d.ts +1 -0
  75. package/lib/validators/validators.d.ts +612 -0
  76. package/lib/viewport-observer/index.d.ts +3 -0
  77. package/lib/viewport-observer/utils.d.ts +15 -0
  78. package/lib/viewport-observer/viewport-observer-ref.d.ts +47 -0
  79. package/lib/viewport-observer/viewport-observer.defaults.d.ts +7 -0
  80. package/lib/viewport-observer/viewport-observer.service.d.ts +23 -0
  81. package/package.json +30 -0
  82. package/public-api.d.ts +26 -0
@@ -0,0 +1,612 @@
1
+ import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';
2
+ export declare class ExtValidators {
3
+ /**
4
+ * Validator that requires the control's value to contain a certain substring.
5
+ *
6
+ * @param seed The substring that the control's value should contain.
7
+ * @returns A validator function that returns an error map with the `contains` property if the validation check fails, otherwise `null`.
8
+ *
9
+ * @example
10
+ *
11
+ * ```ts
12
+ * const control = new FormControl('ng', ExtValidators.contains('angular'));
13
+ * console.log(control.errors);
14
+ * // { contains: { actualValue: 'ng', shouldContain: 'angular' } }
15
+ *
16
+ * const control = new FormControl('I love angular', ExtValidators.contains('angular'));
17
+ * console.log(control.errors);
18
+ * // null
19
+ * ```
20
+ */
21
+ static contains(seed: string): ValidatorFn;
22
+ /**
23
+ * Validator that requires the control's value to not contain a certain substring.
24
+ *
25
+ * @param seed The substring that the control's value should not contain.
26
+ * @returns A validator function that returns an error map with the `notContains` property if the validation check fails, otherwise `null`.
27
+ *
28
+ * @example
29
+ *
30
+ * ```ts
31
+ * const control = new FormControl('angular', ExtValidators.notContains('ng'));
32
+ * console.log(control.errors);
33
+ * // { notContains: { actualValue: 'angular', shouldNotContain: 'ng' } }
34
+ *
35
+ * const control = new FormControl('angular', ExtValidators.notContains('react'));
36
+ * console.log(control.errors);
37
+ * // null
38
+ * ```
39
+ */
40
+ static notContains(seed: string): ValidatorFn;
41
+ /**
42
+ * Validator that requires the control's value to be in lowercase.
43
+ *
44
+ * @returns An error map with the `lowercase` property if the validation check fails, otherwise `null`.
45
+ *
46
+ * @example
47
+ *
48
+ * ```ts
49
+ * const control = new FormControl('Angular', ExtValidators.lowercase);
50
+ * console.log(control.errors);
51
+ * // { lowercase: { actualValue: 'Angular' } }
52
+ *
53
+ * const control = new FormControl('angular', ExtValidators.lowercase);
54
+ * console.log(control.errors);
55
+ * // null
56
+ * ```
57
+ */
58
+ static lowercase(control: AbstractControl): ValidationErrors | null;
59
+ /**
60
+ * Validator that requires the control's value to be in uppercase.
61
+ *
62
+ * @returns An error map with the `uppercase` property if the validation check fails, otherwise `null`.
63
+ *
64
+ * @example
65
+ *
66
+ * ```ts
67
+ * const control = new FormControl('Angular', ExtValidators.uppercase);
68
+ * console.log(control.errors);
69
+ * // { uppercase: { actualValue: 'Angular' } }
70
+ *
71
+ * const control = new FormControl('ANGULAR', ExtValidators.uppercase);
72
+ * console.log(control.errors);
73
+ * // null
74
+ * ```
75
+ */
76
+ static uppercase(control: AbstractControl): ValidationErrors | null;
77
+ /**
78
+ * Validator that wraps the built-in `Validators.pattern` but allows specifying a custom error name instead of the default `pattern` key.
79
+ *
80
+ * @param name The error name to use when the validation fails.
81
+ * @param pattern A string or RegExp to test the control's value against.
82
+ * @returns A `ValidatorFn` that returns an error map with the given `name` when the value does not match the pattern.
83
+ *
84
+ * @example
85
+ *
86
+ * ```ts
87
+ * const control = new FormControl('abc-123', ExtValidators.namedPattern('sku', /^[A-Z]{3}-\d{3}$/));
88
+ * console.log(control.errors);
89
+ * // { sku: { actualValue: 'abc-123' } }
90
+ *
91
+ * const control = new FormControl('ABC-123', ExtValidators.namedPattern('sku', /^[A-Z]{3}-\d{3}$/));
92
+ * console.log(control.errors);
93
+ * // null
94
+ * ```
95
+ */
96
+ static namedPattern(name: string, pattern: string | RegExp): ValidatorFn;
97
+ /**
98
+ * Validator that requires the control's numeric value to be divisible by the given divisor.
99
+ *
100
+ * - Accepts numbers or numeric strings (uses `parseFloat`).
101
+ * - Does not validate `null`/`undefined` values to allow optional controls.
102
+ * - If `divisor` is `null`/`undefined`/`0`, validation is skipped and `null` is returned.
103
+ *
104
+ * @param divisor The number the control's value must be divisible by.
105
+ * @returns A validator function that returns `{ divisibleBy: { divisor, actual } }` when invalid, otherwise `null`.
106
+ *
107
+ * @example
108
+ *
109
+ * ```ts
110
+ * const control = new FormControl('12', ExtValidators.divisibleBy(5));
111
+ * console.log(control.errors);
112
+ * // { divisibleBy: { divisor: 5, actual: '12' } }
113
+ *
114
+ * const control = new FormControl('15', ExtValidators.divisibleBy(5));
115
+ * console.log(control.errors);
116
+ * // null
117
+ * ```
118
+ */
119
+ static divisibleBy(divisor: number): ValidatorFn;
120
+ /**
121
+ * Validator that requires the control's value to contain only ASCII characters.
122
+ *
123
+ * @param control The form control to validate.
124
+ * @returns `null` when valid (or when value is not a string), otherwise `{ ascii: { actualValue } }`.
125
+ *
126
+ * @example
127
+ *
128
+ * ```ts
129
+ * const control = new FormControl('Zażółć', ExtValidators.ascii);
130
+ * console.log(control.errors);
131
+ * // { ascii: { actualValue: 'Zażółć' } }
132
+ *
133
+ * const control = new FormControl('Hello!', ExtValidators.ascii);
134
+ * console.log(control.errors);
135
+ * // null
136
+ * ```
137
+ */
138
+ static ascii(control: AbstractControl): ValidationErrors | null;
139
+ /**
140
+ * Validator that requires the control's value to be valid Base64 (RFC 4648-style alphabet).
141
+ *
142
+ * Notes:
143
+ * - This checks *format* (characters + padding), not whether the decoded bytes are meaningful.
144
+ * - Non-string / empty values are not validated to allow optional controls.
145
+ *
146
+ * @param control The form control to validate.
147
+ * @returns `null` when valid (or when value is not a string), otherwise `{ base64: { actualValue } }`.
148
+ *
149
+ * @example
150
+ *
151
+ * ```ts
152
+ * const control = new FormControl('hello world', ExtValidators.base64);
153
+ * console.log(control.errors);
154
+ * // { base64: { actualValue: 'hello world' } }
155
+ *
156
+ * const control = new FormControl('aGVsbG8=', ExtValidators.base64);
157
+ * console.log(control.errors);
158
+ * // null
159
+ * ```
160
+ */
161
+ static base64(control: AbstractControl): ValidationErrors | null;
162
+ /**
163
+ * Validator that requires the control's value to be a hexadecimal string.
164
+ *
165
+ * - Accepts upper and lower case characters.
166
+ * - Does not allow `0x` prefix (pure hex digits only).
167
+ *
168
+ * @param control The form control to validate.
169
+ * @returns `null` when valid (or when value is not a string), otherwise `{ hex: { actualValue } }`.
170
+ *
171
+ * @example
172
+ *
173
+ * ```ts
174
+ * const control = new FormControl('0xdeadbeef', ExtValidators.hex);
175
+ * console.log(control.errors);
176
+ * // { hex: { actualValue: '0xdeadbeef' } }
177
+ *
178
+ * const control = new FormControl('deadBEEF', ExtValidators.hex);
179
+ * console.log(control.errors);
180
+ * // null
181
+ * ```
182
+ */
183
+ static hex(control: AbstractControl): ValidationErrors | null;
184
+ /**
185
+ * Validator that requires the control's value to be an octal string (digits 0-7 only).
186
+ *
187
+ * @param control The form control to validate.
188
+ * @returns `null` when valid (or when value is not a string), otherwise `{ octal: { actualValue } }`.
189
+ *
190
+ * @example
191
+ *
192
+ * ```ts
193
+ * const control = new FormControl('128', ExtValidators.octal);
194
+ * console.log(control.errors);
195
+ * // { octal: { actualValue: '128' } }
196
+ *
197
+ * const control = new FormControl('755', ExtValidators.octal);
198
+ * console.log(control.errors);
199
+ * // null
200
+ * ```
201
+ */
202
+ static octal(control: AbstractControl): ValidationErrors | null;
203
+ /**
204
+ * Validator that requires the control's value to be a binary string (digits 0-1 only).
205
+ *
206
+ * @param control The form control to validate.
207
+ * @returns `null` when valid (or when value is not a string), otherwise `{ binary: { actualValue } }`.
208
+ *
209
+ * @example
210
+ *
211
+ * ```ts
212
+ * const control = new FormControl('10201', ExtValidators.binary);
213
+ * console.log(control.errors);
214
+ * // { binary: { actualValue: '10201' } }
215
+ *
216
+ * const control = new FormControl('101010', ExtValidators.binary);
217
+ * console.log(control.errors);
218
+ * // null
219
+ * ```
220
+ */
221
+ static binary(control: AbstractControl): ValidationErrors | null;
222
+ /**
223
+ * Validator that requires the control's value to be a valid IP address.
224
+ *
225
+ * @param ipType The required IP version (`4` for IPv4, `6` for IPv6).
226
+ * @returns A validator function that returns `{ ipAddress: { requiredType, actualValue } }` when invalid, otherwise `null`.
227
+ *
228
+ * @example
229
+ *
230
+ * ```ts
231
+ * const control = new FormControl('999.1.2.3', ExtValidators.ipAddress(4));
232
+ * console.log(control.errors);
233
+ * // { ipAddress: { requiredType: 'IPv4', actualValue: '999.1.2.3' } }
234
+ *
235
+ * const control = new FormControl('127.0.0.1', ExtValidators.ipAddress(4));
236
+ * console.log(control.errors);
237
+ * // null
238
+ * ```
239
+ *
240
+ * ```ts
241
+ * const control = new FormControl('not-an-ip', ExtValidators.ipAddress(6));
242
+ * console.log(control.errors);
243
+ * // { ipAddress: { requiredType: 'IPv6', actualValue: 'not-an-ip' } }
244
+ *
245
+ * const control = new FormControl('::1', ExtValidators.ipAddress(6));
246
+ * console.log(control.errors);
247
+ * // null
248
+ * ```
249
+ */
250
+ static ipAddress(ipType: 4 | 6 | 'any'): ValidatorFn;
251
+ /**
252
+ * Validator that requires the control's value to be a UUID string.
253
+ *
254
+ * Notes:
255
+ * - This validates the canonical 8-4-4-4-12 hex format.
256
+ * - It does not enforce UUID version/variant bits (it accepts any hex in those positions).
257
+ *
258
+ * @param control The form control to validate.
259
+ * @returns `null` when valid (or when value is not a string), otherwise `{ uuid: { actualValue } }`.
260
+ *
261
+ * @example
262
+ *
263
+ * ```ts
264
+ * const control = new FormControl('550e8400-e29b-41d4-a716-44665544ZZZZ', ExtValidators.uuid);
265
+ * console.log(control.errors);
266
+ * // { uuid: { actualValue: '550e8400-e29b-41d4-a716-44665544ZZZZ' } }
267
+ *
268
+ * const control = new FormControl('550e8400-e29b-41d4-a716-446655440000', ExtValidators.uuid);
269
+ * console.log(control.errors);
270
+ * // null
271
+ * ```
272
+ */
273
+ static uuid(control: AbstractControl): ValidationErrors | null;
274
+ /**
275
+ * Validator that requires the control's value to be a hex color.
276
+ *
277
+ * Accepts:
278
+ * - `#RGB` / `RGB`
279
+ * - `#RRGGBB` / `RRGGBB`
280
+ *
281
+ * @param control The form control to validate.
282
+ * @returns `null` when valid (or when value is not a string), otherwise `{ hexColor: { actualValue } }`.
283
+ *
284
+ * @example
285
+ *
286
+ * ```ts
287
+ * const control = new FormControl('#12FG00', ExtValidators.hexColor);
288
+ * console.log(control.errors);
289
+ * // { hexColor: { actualValue: '#12FG00' } }
290
+ *
291
+ * const control = new FormControl('#ff00aa', ExtValidators.hexColor);
292
+ * console.log(control.errors);
293
+ * // null
294
+ * ```
295
+ */
296
+ static hexColor(control: AbstractControl): ValidationErrors | null;
297
+ /**
298
+ * Validator that requires the control's value to be an `rgb(r, g, b)` CSS color string.
299
+ *
300
+ * Constraints:
301
+ * - `r`, `g`, `b` must be integers in the range 0..255
302
+ * - Whitespace is allowed
303
+ *
304
+ * @param control The form control to validate.
305
+ * @returns `null` when valid (or when value is not a string), otherwise `{ rgbColor: { actualValue } }`.
306
+ *
307
+ * @example
308
+ *
309
+ * ```ts
310
+ * const control = new FormControl('rgb(256, 0, 0)', ExtValidators.rgbColor);
311
+ * console.log(control.errors);
312
+ * // { rgbColor: { actualValue: 'rgb(256, 0, 0)' } }
313
+ *
314
+ * const control = new FormControl('rgb(255, 0, 128)', ExtValidators.rgbColor);
315
+ * console.log(control.errors);
316
+ * // null
317
+ * ```
318
+ */
319
+ static rgbColor(control: AbstractControl): ValidationErrors | null;
320
+ /**
321
+ * Validator that requires the control's value to be an `hsl(h, s%, l%)` CSS color string.
322
+ *
323
+ * Constraints:
324
+ * - `h` (hue) must be an integer in the range 0..360
325
+ * - `s` and `l` must be percentages in the range 0..100
326
+ * - Whitespace is allowed
327
+ *
328
+ * @param control The form control to validate.
329
+ * @returns `null` when valid (or when value is not a string), otherwise `{ hslColor: { actualValue } }`.
330
+ *
331
+ * @example
332
+ *
333
+ * ```ts
334
+ * const control = new FormControl('hsl(361, 50%, 40%)', ExtValidators.hslColor);
335
+ * console.log(control.errors);
336
+ * // { hslColor: { actualValue: 'hsl(361, 50%, 40%)' } }
337
+ *
338
+ * const control = new FormControl('hsl(210, 50%, 40%)', ExtValidators.hslColor);
339
+ * console.log(control.errors);
340
+ * // null
341
+ * ```
342
+ */
343
+ static hslColor(control: AbstractControl): ValidationErrors | null;
344
+ /**
345
+ * Validator factory for password-like rules.
346
+ *
347
+ * You can combine any subset of rules. Only rules that are enabled will be validated.
348
+ *
349
+ * Returned error shape:
350
+ * - `null` when valid
351
+ * - `{ password: { ...details } }` when invalid, where `details` may include:
352
+ * - `minLength` / `maxLength` objects with required/actual lengths
353
+ * - boolean flags: `requireNumbers`, `requireUppercase`, `requireLowercase`, `requireSpecialCharacters`
354
+ *
355
+ * Notes:
356
+ * - Special character set is: `[!@#$%^&*(),.?":{}|<>]`
357
+ * - Non-string / empty values are not validated to allow optional controls.
358
+ *
359
+ * @param rules Password rules configuration.
360
+ * @returns A validator function that returns a `password` error map when validation fails, otherwise `null`.
361
+ *
362
+ * @example
363
+ *
364
+ * Negative example (produces an error and shows the nested details):
365
+ *
366
+ * ```ts
367
+ * const control = new FormControl('password', ExtValidators.password({
368
+ * minLength: 8,
369
+ * requireNumbers: true,
370
+ * requireUppercase: true,
371
+ * requireSpecialCharacters: true,
372
+ * }));
373
+ *
374
+ * console.log(control.errors);
375
+ * // {
376
+ * // password: {
377
+ * // requireNumbers: true,
378
+ * // requireUppercase: true,
379
+ * // requireSpecialCharacters: true
380
+ * // }
381
+ * // }
382
+ *
383
+ * const control = new FormControl('P@ssw0rd!', ExtValidators.password({
384
+ * minLength: 8,
385
+ * requireNumbers: true,
386
+ * requireUppercase: true,
387
+ * requireSpecialCharacters: true,
388
+ * }));
389
+ *
390
+ * console.log(control.errors);
391
+ * // null
392
+ * ```
393
+ */
394
+ static password(rules: {
395
+ minLength?: number;
396
+ maxLength?: number;
397
+ requireNumbers?: boolean;
398
+ requireUppercase?: boolean;
399
+ requireLowercase?: boolean;
400
+ requireSpecialCharacters?: boolean;
401
+ }): ValidatorFn;
402
+ /**
403
+ * Validator that requires the control's value (an array) to contain a specific element.
404
+ *
405
+ * Non-array values are ignored to avoid false positives.
406
+ *
407
+ * @param seed The element that must exist in the array (uses `Array.prototype.includes`).
408
+ * @returns A validator function that returns `{ arrayContains: { actualValue, shouldContain } }` when invalid, otherwise `null`.
409
+ *
410
+ * @example
411
+ *
412
+ * ```ts
413
+ * const control = new FormControl(['a', 'b'], ExtValidators.arrayContains('c'));
414
+ * console.log(control.errors);
415
+ * // { arrayContains: { actualValue: ['a', 'b'], shouldContain: 'c' } }
416
+ *
417
+ * const control = new FormControl(['a', 'b', 'c'], ExtValidators.arrayContains('c'));
418
+ * console.log(control.errors);
419
+ * // null
420
+ * ```
421
+ */
422
+ static arrayContains(seed: any): ValidatorFn;
423
+ /**
424
+ * Validator that requires the control's value (an array) to *not* contain a specific element.
425
+ *
426
+ * Non-array values are ignored to avoid false positives.
427
+ *
428
+ * @param seed The element that must not exist in the array (uses `Array.prototype.includes`).
429
+ * @returns A validator function that returns `{ arrayNotContains: { actualValue, shouldNotContain } }` when invalid, otherwise `null`.
430
+ *
431
+ * @example
432
+ *
433
+ * ```ts
434
+ * const control = new FormControl(['a', 'b'], ExtValidators.arrayNotContains('b'));
435
+ * console.log(control.errors);
436
+ * // { arrayNotContains: { actualValue: ['a', 'b'], shouldNotContain: 'b' } }
437
+ *
438
+ * const control = new FormControl(['a', 'b'], ExtValidators.arrayNotContains('c'));
439
+ * console.log(control.errors);
440
+ * // null
441
+ * ```
442
+ */
443
+ static arrayNotContains(seed: any): ValidatorFn;
444
+ /**
445
+ * Validator that requires the control's value (an array) to contain only unique items.
446
+ *
447
+ * Uses a `Set` to compare uniqueness (`Set.size === array.length`).
448
+ *
449
+ * @param control The form control to validate.
450
+ * @returns `null` when valid (or when value is not an array), otherwise `{ arrayUnique: { actualValue } }`.
451
+ *
452
+ * @example
453
+ *
454
+ * ```ts
455
+ * const control = new FormControl([1, 1, 2], ExtValidators.arrayUnique);
456
+ * console.log(control.errors);
457
+ * // { arrayUnique: { actualValue: [1, 1, 2] } }
458
+ *
459
+ * const control = new FormControl([1, 2, 3], ExtValidators.arrayUnique);
460
+ * console.log(control.errors);
461
+ * // null
462
+ * ```
463
+ */
464
+ static arrayUnique(control: AbstractControl): ValidationErrors | null;
465
+ /**
466
+ * Validator factory that requires uploaded file(s) to be at most the given size.
467
+ *
468
+ * Supported control value shapes:
469
+ * - a single `File`
470
+ * - an array of files (typically `File[]`)
471
+ *
472
+ * Non-file values (or arrays with no `File` instances) are ignored to avoid false positives.
473
+ *
474
+ * Error shape:
475
+ * - If a single `File` was provided: `{ fileMaxSize: { requiredMaxSize, actualSize } }`
476
+ * - If an array was provided: `{ fileMaxSize: { requiredMaxSize, actualSizes } }` where `actualSizes` are the sizes of invalid files
477
+ *
478
+ * @param maxSizeInBytes Maximum allowed size in bytes.
479
+ * @returns A validator function that returns a `fileMaxSize` error map when invalid, otherwise `null`.
480
+ *
481
+ * @example
482
+ *
483
+ * Negative example (single file; produces an error):
484
+ *
485
+ * ```ts
486
+ * const big = new File([new Uint8Array(10)], 'big.txt'); // example only
487
+ * Object.defineProperty(big, 'size', { value: 10_000_000 }); // force size for demo
488
+ *
489
+ * const control = new FormControl<File | null>(big, ExtValidators.fileMaxSize(1_000));
490
+ * console.log(control.errors);
491
+ * // { fileMaxSize: { requiredMaxSize: 1000, actualSize: 10000000 } }
492
+ * ```
493
+ *
494
+ * Negative example (array; produces an error with `actualSizes`):
495
+ *
496
+ * ```ts
497
+ * const f1 = new File([new Uint8Array(1)], 'a.txt');
498
+ * const f2 = new File([new Uint8Array(1)], 'b.txt');
499
+ * Object.defineProperty(f1, 'size', { value: 500 });
500
+ * Object.defineProperty(f2, 'size', { value: 1500 });
501
+ *
502
+ * const control = new FormControl<File[]>([f1, f2], ExtValidators.fileMaxSize(1000));
503
+ * console.log(control.errors);
504
+ * // { fileMaxSize: { requiredMaxSize: 1000, actualSizes: [1500] } }
505
+ *
506
+ * const f = new File([new Uint8Array(1)], 'ok.txt');
507
+ * Object.defineProperty(f, 'size', { value: 500 });
508
+ *
509
+ * const control = new FormControl<File | null>(f, ExtValidators.fileMaxSize(1000));
510
+ * console.log(control.errors);
511
+ * // null
512
+ * ```
513
+ */
514
+ static fileMaxSize(maxSizeInBytes: number): ValidatorFn;
515
+ /**
516
+ * Validator factory that requires uploaded file(s) to be at least the given size.
517
+ *
518
+ * Supported control value shapes:
519
+ * - a single `File`
520
+ * - an array of files (typically `File[]`)
521
+ *
522
+ * Non-file values (or arrays with no `File` instances) are ignored to avoid false positives.
523
+ *
524
+ * Error shape:
525
+ * - If a single `File` was provided: `{ fileMinSize: { requiredMinSize, actualSize } }`
526
+ * - If an array was provided: `{ fileMinSize: { requiredMinSize, actualSizes } }` where `actualSizes` are the sizes of invalid files
527
+ *
528
+ * @param minSizeInBytes Minimum allowed size in bytes.
529
+ * @returns A validator function that returns a `fileMinSize` error map when invalid, otherwise `null`.
530
+ *
531
+ * @example
532
+ *
533
+ * Negative example (single file; produces an error):
534
+ *
535
+ * ```ts
536
+ * const tiny = new File([new Uint8Array(1)], 'tiny.txt');
537
+ * Object.defineProperty(tiny, 'size', { value: 50 });
538
+ *
539
+ * const control = new FormControl<File | null>(tiny, ExtValidators.fileMinSize(100));
540
+ * console.log(control.errors);
541
+ * // { fileMinSize: { requiredMinSize: 100, actualSize: 50 } }
542
+ * ```
543
+ *
544
+ * Negative example (array; produces an error with `actualSizes`):
545
+ *
546
+ * ```ts
547
+ * const f1 = new File([new Uint8Array(1)], 'a.txt');
548
+ * const f2 = new File([new Uint8Array(1)], 'b.txt');
549
+ * Object.defineProperty(f1, 'size', { value: 50 });
550
+ * Object.defineProperty(f2, 'size', { value: 200 });
551
+ *
552
+ * const control = new FormControl<File[]>([f1, f2], ExtValidators.fileMinSize(100));
553
+ * console.log(control.errors);
554
+ * // { fileMinSize: { requiredMinSize: 100, actualSizes: [50] } }
555
+ *
556
+ * const ok = new File([new Uint8Array(1)], 'ok.txt');
557
+ * Object.defineProperty(ok, 'size', { value: 150 });
558
+ *
559
+ * const control = new FormControl<File | null>(ok, ExtValidators.fileMinSize(100));
560
+ * console.log(control.errors);
561
+ * // null
562
+ * ```
563
+ */
564
+ static fileMinSize(minSizeInBytes: number): ValidatorFn;
565
+ /**
566
+ * Validator factory that requires uploaded file(s) to have an allowed extension.
567
+ *
568
+ * Supported control value shapes:
569
+ * - a single `File`
570
+ * - an array of files (typically `File[]`)
571
+ *
572
+ * Notes:
573
+ * - Extension is derived from the last `.` in the filename: `file.name.split('.').pop()`
574
+ * - The extracted extension is lowercased before checking.
575
+ * - `allowedExtensions` should be provided in lowercase to match the comparison.
576
+ *
577
+ * Error shape:
578
+ * - If a single `File` was provided: `{ fileExtension: { allowedExtensions, actualExtension } }`
579
+ * - If an array was provided: `{ fileExtension: { allowedExtensions, invalidFiles } }`
580
+ *
581
+ * @param allowedExtensions A list of allowed extensions (without dots), e.g. `['png', 'jpg', 'pdf']`.
582
+ * @returns A validator function that returns a `fileExtension` error map when invalid, otherwise `null`.
583
+ *
584
+ * @example
585
+ *
586
+ * Negative example (single file; produces an error):
587
+ *
588
+ * ```ts
589
+ * const file = new File([new Uint8Array(1)], 'report.exe');
590
+ * const control = new FormControl<File | null>(file, ExtValidators.fileExtension(['pdf', 'docx']));
591
+ * console.log(control.errors);
592
+ * // { fileExtension: { allowedExtensions: ['pdf', 'docx'], actualExtension: 'exe' } }
593
+ * ```
594
+ *
595
+ * Negative example (array; produces an error with invalid file names):
596
+ *
597
+ * ```ts
598
+ * const a = new File([new Uint8Array(1)], 'a.png');
599
+ * const b = new File([new Uint8Array(1)], 'b.exe');
600
+ *
601
+ * const control = new FormControl<File[]>([a, b], ExtValidators.fileExtension(['png', 'jpg']));
602
+ * console.log(control.errors);
603
+ * // { fileExtension: { allowedExtensions: ['png', 'jpg'], invalidFiles: ['b.exe'] } }
604
+ *
605
+ * const file = new File([new Uint8Array(1)], 'photo.jpg');
606
+ * const control = new FormControl<File | null>(file, ExtValidators.fileExtension(['png', 'jpg']));
607
+ * console.log(control.errors);
608
+ * // null
609
+ * ```
610
+ */
611
+ static fileExtension(allowedExtensions: string[]): ValidatorFn;
612
+ }
@@ -0,0 +1,3 @@
1
+ export * from './viewport-observer-ref';
2
+ export * from './viewport-observer.defaults';
3
+ export * from './viewport-observer.service';
@@ -0,0 +1,15 @@
1
+ import { MonoTypeOperatorFunction } from 'rxjs';
2
+ /**
3
+ * Custom RxJS operator that throttles incoming values but saves the last one when (emitted when the throttle duration ends). A combination of throttleTime and debounceTime.
4
+ * @param duration the throttle duration
5
+ * @returns an RxJS operator function
6
+ */
7
+ export declare function throttleSaveLast<T>(duration: number): MonoTypeOperatorFunction<T>;
8
+ /**
9
+ * Requires that at least one property from the given object is defined.
10
+ *
11
+ * @copyright Copied from [Microsoft Learn](https://learn.microsoft.com/en-us/javascript/api/@azure/keyvault-certificates/requireatleastone).
12
+ */
13
+ export type RequireAtLeastOne<T> = {
14
+ [K in keyof T]-?: Required<Pick<T, K>> & Partial<Pick<T, Exclude<keyof T, K>>>;
15
+ }[keyof T];
@@ -0,0 +1,47 @@
1
+ import { ElementRef, Signal } from '@angular/core';
2
+ import { Observable } from 'rxjs';
3
+ import { RequireAtLeastOne } from './utils';
4
+ declare enum ViewportRelation {
5
+ Above = "above",
6
+ PartiallyAbove = "partially-above",
7
+ Inside = "inside",
8
+ PartiallyBelow = "partially-below",
9
+ Below = "below",
10
+ InsideButTooLarge = "inside-too-large",
11
+ Undefined = "undefined"
12
+ }
13
+ export interface ArdViewportObserverConfig {
14
+ margin: number | RequireAtLeastOne<{
15
+ top: number;
16
+ bottom: number;
17
+ }>;
18
+ throttleTime: number;
19
+ }
20
+ export declare class ArdViewportObserverRef {
21
+ private readonly update$;
22
+ readonly element: HTMLElement;
23
+ constructor(element: HTMLElement | ElementRef<HTMLElement>, update$: Observable<void>, config: ArdViewportObserverConfig);
24
+ private readonly _throttleTime;
25
+ private readonly _margins;
26
+ readonly margins: {
27
+ readonly top: Signal<number>;
28
+ readonly bottom: Signal<number>;
29
+ };
30
+ private readonly _scrollSubscription;
31
+ private readonly _rawPosition;
32
+ readonly position: Signal<{
33
+ top: number;
34
+ bottom: number;
35
+ } | undefined>;
36
+ readonly viewportRelation: Signal<ViewportRelation | undefined>;
37
+ readonly isInViewport: Signal<boolean | undefined>;
38
+ private _updateViewportRelation;
39
+ private _getNewRelation;
40
+ private readonly _isDestroyed;
41
+ readonly isDestroyed: Signal<boolean>;
42
+ recheck(): void;
43
+ destroy(): void;
44
+ setMargin(topAndBottom: number): ArdViewportObserverRef;
45
+ setMargin(top: number, bottom: number): ArdViewportObserverRef;
46
+ }
47
+ export {};
@@ -0,0 +1,7 @@
1
+ import { InjectionToken, Provider } from '@angular/core';
2
+ import { ArdViewportObserverConfig } from './viewport-observer-ref';
3
+ export interface ArdViewportObserverDefaults extends Required<ArdViewportObserverConfig> {
4
+ margin: Required<Exclude<ArdViewportObserverConfig['margin'], undefined>>;
5
+ }
6
+ export declare const ARD_VIEWPORT_OBSERVER_DEFAULTS: InjectionToken<ArdViewportObserverDefaults>;
7
+ export declare function provideViewportObserverDefaults(config: Partial<ArdViewportObserverDefaults>): Provider;