igniteui-angular 22.2.0-rc.0 → 22.2.0-rc.1

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.
@@ -1301,18 +1301,31 @@ class NgControlAdapter {
1301
1301
  get invalid() {
1302
1302
  return !!this.ngControl.invalid;
1303
1303
  }
1304
+ get pending() {
1305
+ return !!this.ngControl.pending;
1306
+ }
1307
+ /** Derived, not read from `status`: the Signal Forms interop throws on a status it does not know. */
1308
+ get status() {
1309
+ if (this.disabled) {
1310
+ return 'disabled';
1311
+ }
1312
+ if (this.invalid) {
1313
+ return 'invalid';
1314
+ }
1315
+ return this.pending ? 'pending' : 'valid';
1316
+ }
1304
1317
  get touchedOrDirty() {
1305
1318
  const control = this.ngControl.control;
1306
1319
  return !!(control?.touched || control?.dirty);
1307
1320
  }
1308
1321
  /**
1309
- * Signal Forms expose no rule list. A field that is required, or was ever
1310
- * invalid or pending, is known to have rules; a rule satisfied from the
1311
- * start stays undetected.
1322
+ * Signal Forms expose no rule list. A field that is required, or was invalid or
1323
+ * pending since it was last pristine and untouched, is known to have rules;
1324
+ * a rule satisfied from that point on stays undetected.
1312
1325
  */
1313
1326
  get hasValidators() {
1314
1327
  if (this.backend === 'signal') {
1315
- return this.required || this.noteErrors();
1328
+ return this.required || this.sawErrors;
1316
1329
  }
1317
1330
  const control = this.ngControl.control;
1318
1331
  return !!(control?.validator || control?.asyncValidator);
@@ -1343,10 +1356,13 @@ class NgControlAdapter {
1343
1356
  */
1344
1357
  get statusChanges() {
1345
1358
  if (this.backend === 'signal') {
1346
- return this.watch(() => [
1347
- this.ngControl.valid, this.noteErrors(), this.ngControl.pending, this.required,
1348
- this.ngControl.disabled, this.ngControl.dirty, this.ngControl.touched
1349
- ]);
1359
+ return this.watch(() => {
1360
+ this.observeErrors();
1361
+ return [
1362
+ this.ngControl.valid, this.pending, this.required,
1363
+ this.ngControl.disabled, this.ngControl.dirty, this.ngControl.touched
1364
+ ];
1365
+ });
1350
1366
  }
1351
1367
  return this.ngControl.statusChanges;
1352
1368
  }
@@ -1378,11 +1394,14 @@ class NgControlAdapter {
1378
1394
  control.setValue(value);
1379
1395
  return 'accepted';
1380
1396
  }
1381
- /** Remembers that the field had rules. Returns the current invalid or pending state. */
1382
- noteErrors() {
1383
- const hasErrors = this.invalid || !!this.ngControl.pending;
1384
- this.sawErrors ||= hasErrors;
1385
- return hasErrors || this.sawErrors;
1397
+ /**
1398
+ * Records that the field has rules. A `[formField]` switch reuses the same interop
1399
+ * `NgControl`, so an untouched, pristine control drops earlier observations and keeps
1400
+ * only its current state, e.g. an empty field failing a custom rule before the first edit.
1401
+ */
1402
+ observeErrors() {
1403
+ const kept = this.touchedOrDirty && this.sawErrors;
1404
+ this.sawErrors = kept || this.invalid || this.pending;
1386
1405
  }
1387
1406
  // Signal-backed getters are reactive, so an effect over them replaces the missing observables.
1388
1407
  // A root effect runs before change detection, like an observable would; a view effect would