@arsedizioni/ars-utils 22.0.43 → 22.0.47
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/fesm2022/arsedizioni-ars-utils-core.mjs +37 -21
- package/fesm2022/arsedizioni-ars-utils-core.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-ui.mjs +58 -4
- package/fesm2022/arsedizioni-ars-utils-ui.mjs.map +1 -1
- package/package.json +1 -1
- package/types/arsedizioni-ars-utils-clipper.ui.d.ts +1 -1
- package/types/arsedizioni-ars-utils-core.d.ts +15 -14
- package/types/arsedizioni-ars-utils-ui.d.ts +48 -22
|
@@ -198,7 +198,9 @@ class DateFnsAdapter extends DateAdapter {
|
|
|
198
198
|
if (typeof value === 'string' && value.length > 0) {
|
|
199
199
|
const iso8601Date = parseISO(value);
|
|
200
200
|
if (this.isValid(iso8601Date)) {
|
|
201
|
-
|
|
201
|
+
const t = new TZDate(iso8601Date, 'Europe/Rome');
|
|
202
|
+
t.setHours(12, 0, 0, 0);
|
|
203
|
+
return t;
|
|
202
204
|
}
|
|
203
205
|
const formats = Array.isArray(parseFormat) ? parseFormat : [parseFormat];
|
|
204
206
|
if (!formats.length) {
|
|
@@ -209,13 +211,17 @@ class DateFnsAdapter extends DateAdapter {
|
|
|
209
211
|
locale: this.locale
|
|
210
212
|
});
|
|
211
213
|
if (this.isValid(fromFormat)) {
|
|
212
|
-
|
|
214
|
+
const t = new TZDate(fromFormat, 'Europe/Rome');
|
|
215
|
+
t.setHours(12, 0, 0, 0);
|
|
216
|
+
return t;
|
|
213
217
|
}
|
|
214
218
|
}
|
|
215
219
|
return this.invalid();
|
|
216
220
|
}
|
|
217
221
|
else if (typeof value === 'number') {
|
|
218
|
-
|
|
222
|
+
const t = new TZDate(new Date(value), 'Europe/Rome');
|
|
223
|
+
t.setHours(12, 0, 0, 0);
|
|
224
|
+
return t;
|
|
219
225
|
}
|
|
220
226
|
else if (value instanceof Date) {
|
|
221
227
|
return this.clone(value);
|
|
@@ -2162,6 +2168,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
|
|
|
2162
2168
|
* The host control is re-validated whenever the OTHER control's value changes:
|
|
2163
2169
|
* without this, typing a new password AFTER the confirmation field was filled
|
|
2164
2170
|
* left the form incorrectly valid (the classic password/confirm bug).
|
|
2171
|
+
*
|
|
2172
|
+
* IMPORTANT (reciprocal-binding safety): the re-validation triggered from the
|
|
2173
|
+
* other control's `valueChanges` runs with `{ emitEvent: false }`. Calling
|
|
2174
|
+
* Angular's `onValidatorChange` instead would re-emit valueChanges, so a
|
|
2175
|
+
* reciprocal setup (A [equals]=B and B [equals]=A) would overflow the stack.
|
|
2165
2176
|
*/
|
|
2166
2177
|
class EqualsValidatorDirective {
|
|
2167
2178
|
constructor() {
|
|
@@ -2169,21 +2180,18 @@ class EqualsValidatorDirective {
|
|
|
2169
2180
|
this.equals = input(undefined, /* @ts-ignore */
|
|
2170
2181
|
...(ngDevMode ? [{ debugName: "equals" }] : /* istanbul ignore next */ []));
|
|
2171
2182
|
// Re-subscribe whenever the [equals] binding points to a different control,
|
|
2172
|
-
// and
|
|
2183
|
+
// and re-validate the host on every change of the other control.
|
|
2173
2184
|
effect(() => {
|
|
2174
2185
|
const other = this.equals();
|
|
2175
2186
|
this.subscription?.unsubscribe();
|
|
2176
|
-
this.subscription = other?.valueChanges.subscribe(() =>
|
|
2187
|
+
this.subscription = other?.valueChanges.subscribe(() =>
|
|
2188
|
+
// emitEvent:false breaks the reciprocal valueChanges loop (see class doc).
|
|
2189
|
+
this.hostControl?.updateValueAndValidity({ emitEvent: false }));
|
|
2190
|
+
// Re-validate the host when the bound control itself is swapped.
|
|
2191
|
+
this.hostControl?.updateValueAndValidity({ emitEvent: false });
|
|
2177
2192
|
});
|
|
2178
2193
|
inject(DestroyRef).onDestroy(() => this.subscription?.unsubscribe());
|
|
2179
2194
|
}
|
|
2180
|
-
/**
|
|
2181
|
-
* Registers the callback Angular invokes to re-run this validator.
|
|
2182
|
-
* @param fn - The revalidation callback provided by the forms API.
|
|
2183
|
-
*/
|
|
2184
|
-
registerOnValidatorChange(fn) {
|
|
2185
|
-
this.onValidatorChange = fn;
|
|
2186
|
-
}
|
|
2187
2195
|
/**
|
|
2188
2196
|
* Validates that the host control value equals the bound control's value.
|
|
2189
2197
|
* Returns `null` (valid) when no control is bound.
|
|
@@ -2191,6 +2199,7 @@ class EqualsValidatorDirective {
|
|
|
2191
2199
|
* @returns `null` when valid, `{ equals: ... }` otherwise.
|
|
2192
2200
|
*/
|
|
2193
2201
|
validate(control) {
|
|
2202
|
+
this.hostControl = control;
|
|
2194
2203
|
const eq = this.equals();
|
|
2195
2204
|
if (!eq)
|
|
2196
2205
|
return null;
|
|
@@ -2405,6 +2414,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
|
|
|
2405
2414
|
*
|
|
2406
2415
|
* The host control is re-validated whenever the OTHER control's value changes,
|
|
2407
2416
|
* so editing either field keeps both error states consistent.
|
|
2417
|
+
*
|
|
2418
|
+
* IMPORTANT (reciprocal-binding safety): the re-validation triggered from the
|
|
2419
|
+
* other control's `valueChanges` is run with `{ emitEvent: false }`. Using
|
|
2420
|
+
* Angular's `onValidatorChange` here instead would call `host.updateValueAndValidity()`
|
|
2421
|
+
* WITH events, so a reciprocal setup (A [notEqual]=B and B [notEqual]=A) would
|
|
2422
|
+
* ping-pong valueChanges between the two controls and overflow the stack.
|
|
2408
2423
|
*/
|
|
2409
2424
|
class NotEqualValidatorDirective {
|
|
2410
2425
|
constructor() {
|
|
@@ -2414,17 +2429,15 @@ class NotEqualValidatorDirective {
|
|
|
2414
2429
|
effect(() => {
|
|
2415
2430
|
const other = this.notEqual();
|
|
2416
2431
|
this.subscription?.unsubscribe();
|
|
2417
|
-
this.subscription = other?.valueChanges.subscribe(() =>
|
|
2432
|
+
this.subscription = other?.valueChanges.subscribe(() =>
|
|
2433
|
+
// Re-validate the host WITHOUT emitting valueChanges, otherwise a
|
|
2434
|
+
// reciprocal binding would loop forever (see class doc).
|
|
2435
|
+
this.hostControl?.updateValueAndValidity({ emitEvent: false }));
|
|
2436
|
+
// Re-validate the host when the bound control itself is swapped.
|
|
2437
|
+
this.hostControl?.updateValueAndValidity({ emitEvent: false });
|
|
2418
2438
|
});
|
|
2419
2439
|
inject(DestroyRef).onDestroy(() => this.subscription?.unsubscribe());
|
|
2420
2440
|
}
|
|
2421
|
-
/**
|
|
2422
|
-
* Registers the callback Angular invokes to re-run this validator.
|
|
2423
|
-
* @param fn - The revalidation callback provided by the forms API.
|
|
2424
|
-
*/
|
|
2425
|
-
registerOnValidatorChange(fn) {
|
|
2426
|
-
this.onValidatorChange = fn;
|
|
2427
|
-
}
|
|
2428
2441
|
/**
|
|
2429
2442
|
* Validates that the host control value is not equal to the bound control's value.
|
|
2430
2443
|
* Also clears the `notequal` error on the other control when the host becomes valid.
|
|
@@ -2433,6 +2446,7 @@ class NotEqualValidatorDirective {
|
|
|
2433
2446
|
* @returns `null` when valid, `{ notequal: true }` otherwise.
|
|
2434
2447
|
*/
|
|
2435
2448
|
validate(control) {
|
|
2449
|
+
this.hostControl = control;
|
|
2436
2450
|
const notEqual = this.notEqual();
|
|
2437
2451
|
if (!notEqual)
|
|
2438
2452
|
return null;
|
|
@@ -2443,7 +2457,9 @@ class NotEqualValidatorDirective {
|
|
|
2443
2457
|
}
|
|
2444
2458
|
else if (notEqual.hasError('notequal')) {
|
|
2445
2459
|
const { notequal: _removed, ...rest } = notEqual.errors ?? {};
|
|
2446
|
-
|
|
2460
|
+
// emitEvent:false on both: clearing the partner's error must not feed
|
|
2461
|
+
// back through valueChanges/statusChanges into this validator.
|
|
2462
|
+
notEqual.setErrors(Object.keys(rest).length > 0 ? rest : null, { emitEvent: false });
|
|
2447
2463
|
notEqual.updateValueAndValidity({ onlySelf: true, emitEvent: false });
|
|
2448
2464
|
notEqual.markAsTouched();
|
|
2449
2465
|
notEqual.markAsDirty();
|