@angular/forms 21.0.0-next.3 → 21.0.0-next.4

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.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v21.0.0-next.3
2
+ * @license Angular v21.0.0-next.4
3
3
  * (c) 2010-2025 Google LLC. https://angular.io/
4
4
  * License: MIT
5
5
  */
@@ -1857,15 +1857,15 @@ class Control {
1857
1857
  }
1858
1858
  };
1859
1859
  }
1860
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0-next.3", ngImport: i0, type: Control, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1861
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.0-next.3", type: Control, isStandalone: true, selector: "[control]", inputs: { _field: ["control", "_field"] }, providers: [
1860
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0-next.4", ngImport: i0, type: Control, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1861
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.0-next.4", type: Control, isStandalone: true, selector: "[control]", inputs: { _field: ["control", "_field"] }, providers: [
1862
1862
  {
1863
1863
  provide: NgControl,
1864
1864
  useFactory: () => inject(Control).ngControl,
1865
1865
  },
1866
1866
  ], ngImport: i0 });
1867
1867
  }
1868
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0-next.3", ngImport: i0, type: Control, decorators: [{
1868
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0-next.4", ngImport: i0, type: Control, decorators: [{
1869
1869
  type: Directive,
1870
1870
  args: [{
1871
1871
  selector: '[control]',
@@ -2619,14 +2619,12 @@ class FieldNodeState {
2619
2619
  * Marks this specific field as touched.
2620
2620
  */
2621
2621
  markAsTouched() {
2622
- // TODO: should this be noop for fields that are hidden/disabled/readonly
2623
2622
  this.selfTouched.set(true);
2624
2623
  }
2625
2624
  /**
2626
2625
  * Marks this specific field as dirty.
2627
2626
  */
2628
2627
  markAsDirty() {
2629
- // TODO: should this be noop for fields that are hidden/disabled/readonly
2630
2628
  this.selfDirty.set(true);
2631
2629
  }
2632
2630
  /**
@@ -2650,20 +2648,24 @@ class FieldNodeState {
2650
2648
  * Whether this field is considered dirty.
2651
2649
  *
2652
2650
  * A field is considered dirty if one of the following is true:
2653
- * - It was directly dirtied
2651
+ * - It was directly dirtied and is interactive
2654
2652
  * - One of its children is considered dirty
2655
2653
  */
2656
2654
  dirty = computed(() => {
2657
- return reduceChildren(this.node, this.selfDirty(), (child, value) => value || child.nodeState.dirty(), shortCircuitTrue);
2655
+ const selfDirtyValue = this.selfDirty() && !this.isNonInteractive();
2656
+ return reduceChildren(this.node, selfDirtyValue, (child, value) => value || child.nodeState.dirty(), shortCircuitTrue);
2658
2657
  }, ...(ngDevMode ? [{ debugName: "dirty" }] : []));
2659
2658
  /**
2660
2659
  * Whether this field is considered touched.
2661
2660
  *
2662
2661
  * A field is considered touched if one of the following is true:
2663
- * - It was directly touched
2662
+ * - It was directly touched and is interactive
2664
2663
  * - One of its children is considered touched
2665
2664
  */
2666
- touched = computed(() => reduceChildren(this.node, this.selfTouched(), (child, value) => value || child.nodeState.touched(), shortCircuitTrue), ...(ngDevMode ? [{ debugName: "touched" }] : []));
2665
+ touched = computed(() => {
2666
+ const selfTouchedValue = this.selfTouched() && !this.isNonInteractive();
2667
+ return reduceChildren(this.node, selfTouchedValue, (child, value) => value || child.nodeState.touched(), shortCircuitTrue);
2668
+ }, ...(ngDevMode ? [{ debugName: "touched" }] : []));
2667
2669
  /**
2668
2670
  * The reasons for this field's disablement. This includes disabled reasons for any parent field
2669
2671
  * that may have been disabled, indirectly causing this field to be disabled as well.
@@ -2709,6 +2711,14 @@ class FieldNodeState {
2709
2711
  }
2710
2712
  return `${parent.name()}.${this.node.structure.keyInParent()}`;
2711
2713
  }, ...(ngDevMode ? [{ debugName: "name" }] : []));
2714
+ /** Whether this field is considered non-interactive.
2715
+ *
2716
+ * A field is considered non-interactive if one of the following is true:
2717
+ * - It is hidden
2718
+ * - It is disabled
2719
+ * - It is readonly
2720
+ */
2721
+ isNonInteractive = computed(() => this.hidden() || this.disabled() || this.readonly(), ...(ngDevMode ? [{ debugName: "isNonInteractive" }] : []));
2712
2722
  }
2713
2723
 
2714
2724
  /**