Commit graph

632 commits

Author SHA1 Message Date
Matthieu Riegler
15d4bd58d1 fix(forms): interop supports CVAs with signals (#64618)
The directive implemnetation might set CVA values during the template evaluation. Since the template is a reactive context we need to untrack when setting the CVA values to prevent writing to signals in a reactive context.

fixes #64614

PR Close #64618
2025-10-24 09:31:39 +02:00
Miles Malerba
515c2949d8 test(forms): test reactive iteration over array field (#64113)
Adds a test that verifies @for iteration over an array field is actually
reactive to new items being added to the array.

PR Close #64113
2025-10-24 09:29:29 +02:00
Miles Malerba
ef34e39b2a refactor(forms): rename files related to metadata (#64603)
Renames some files to reflect the property => metadata name change

PR Close #64603
2025-10-23 18:13:16 +02:00
Miles Malerba
884765be56 refactor(forms): rename field state related to metdata (#64603)
Renames the field state related to metadata to reflect the new
"metadata" name. In particular:
- `property(...)` is renamed to `metadata(...)`
- `hasProperty(...)` is renamed to `hasMetadata(...)`

PR Close #64603
2025-10-23 18:13:16 +02:00
Miles Malerba
b29e6469ed refactor(forms): rename logic functions related to metadata (#64603)
Renames logic functions related to metadata to align with the new
"metadata" name. Notably:
- `property(...)` => `metadata(...)`
- `aggregateProperty(...)` => `aggregateMetadata(...)`

PR Close #64603
2025-10-23 18:13:16 +02:00
Miles Malerba
ef37ecf444 refactor(forms): rename Property and AggregateProperty (#64603)
These have been renamed to `MetadataKey` and `AggregateMetadataKey`
respectively. The team consensus is that the term "property" is so
overloaded that it makes the topic difficult to explain & discuss, hence
the rename.

PR Close #64603
2025-10-23 18:13:16 +02:00
kirjs
a3e91b2e96 refactor(forms): Add a test better documenting behavior of the error function in built-in validators (#63993)
We will need to find a better way to name it.

PR Close #63993
2025-10-22 18:27:37 +00:00
Leon Senft
fd9af2afaf fix(forms): only propagate schema defined properties from field to control (#64446)
Prior to this change, `FieldState` defined a signal for each built-in
property. This unfortunately meant that the `Field` directive had no way
of knowing which property had actually been defined in the schema, and
would thus attempt to propagate them all to the bound form control. This
meant that the default values of these signals would override the
default or template defined values of these control properties.

Now these properties are `undefined` by default, and only initialized if
defined in the schema. Thus the `Field` directive will not attempt to
bind any properties that aren't explicitly managed by the schema.

PR Close #64446
2025-10-21 17:38:34 +00:00
Leon Senft
4261a8c583 refactor(forms): use FormValueControl instead of FormUiControl (#64446)
`FormUiControl` is the base type used for shared properties of
`FormValueControl` and `FormCheckboxControl`.

PR Close #64446
2025-10-21 17:38:34 +00:00
Leon Senft
6fca0e03ff test(forms): propagate pattern property to custom control input (#64446)
Note that unlike the other built-in properties, `pattern` is not
propagated to native controls so the lack of symmetry with other
property tests is intentional.

PR Close #64446
2025-10-21 17:38:34 +00:00
cexbrayat
9c5e969f51 fix(forms): bind invalid input in custom controls (#64526)
FormUiControl has an `invalid` input signal, but it was not bound by the control instructions.

PR Close #64526
2025-10-21 17:37:58 +00:00
cexbrayat
bc9c814ca7 refactor(forms): remove Mutable from signal forms public API (#64436)
The `Mutable` type is only used internally in the `addDefaultField` function, so it can be avoided to be publicly exposed.

PR Close #64436
2025-10-20 21:20:11 +00:00
Kristiyan Kostadinov
c2d376b85a feat(core): make SimpleChanges generic (#64535)
Currently it's easy to make a mistake when accessing properties on `SimpleChanges`, because the keys aren't typed. These changes add an optional generic to the interface so that users can get a compilation error if they make a typo.

A few things to note:
1. The generic argument is optional and we revert to the old behavior if one isn't passed for backwards compatibility.
2. All of the keys are optional, because they aren't guaranteed to be present for any `ngOnChanges` invocation.
3. We unwrap the values of input signals to match the behavior at runtime.

Fixes #17560.

PR Close #64535
2025-10-20 17:49:39 +00:00
Leon Senft
505bde1fed fix(forms): mark field as dirty when value is changed by ControlValueAccessor (#64471)
This corresponds with fixes made for native and custom signal form
controls: https://github.com/angular/angular/pull/64483.

PR Close #64471
2025-10-20 15:35:42 +00:00
Leon Senft
a0f3960270 refactor(forms): prefix framework-private methods on Field with ɵ (#64471)
These methods are only intended to be used internally within framework
instructions. Prefix them with `ɵ` to indicate that they are
framework-private and should not be called from user code.

PR Close #64471
2025-10-20 15:35:42 +00:00
Leon Senft
94b0afec00 fix(forms): implement interoperability between signal forms and reactive forms (#64471)
Add support for interoperability between signal forms and reactive forms that
commit effccffde0 had removed.

A signal forms field can once again be bound to any element or component with a
`ControlValueAccessor`.

PR Close #64471
2025-10-20 15:35:42 +00:00
Leon Senft
3529877772 fix(forms): mark field as dirty when value is changed by a bound control (#64483)
Fix https://github.com/angular/angular/issues/64465.
Fix https://github.com/angular/angular/issues/63623.

PR Close #64483
2025-10-17 16:02:16 +00:00
Leon Senft
348a8f3195 test(forms): remove redundant test cases (#64483)
These were made redundant by https://github.com/angular/angular/pull/63884.

PR Close #64483
2025-10-17 16:02:16 +00:00
Leon Senft
e9740662c3 test(forms): field directive marks field as touched on 'blur' events (#64485)
This was implemented but missing a test case.

PR Close #64485
2025-10-17 14:53:02 +00:00
Joey Perrott
13e18cafff build: migrate vscode extension into repo (#63924) (#64049)
Migrate the vscode extension for angular into this repository.

PR Close #63924

PR Close #64049
2025-10-15 10:37:02 -07:00
Kristiyan Kostadinov
ab415f3d7f fix(core): control not recognized when input has directive injecting ViewContainerRef (#64368)
When a directive injects a `ViewContainerRef`, the runtime inserts a container that was throwing off the logic that recognizes native controls.

These changes switch to check if the node is a native control through the `TNode`. This also makes it a bit less prone to breaking during SSR.

Fixes #64362.

PR Close #64368
2025-10-14 09:29:58 -07:00
Leon Senft
32f86d35f7 perf(forms): optimize [field] binding instructions (#64351)
Caches information about the kind of form control that a `TNode`
represents in `TNodeFlags`. This avoids redundant computations on
subsequent template create and update passes.

Renames the `INVALID_CONTROL_HOST` error code to
`INVALID_FIELD_DIRECTIVE_HOST` for clarity and adds a test for it.

PR Close #64351
2025-10-13 13:02:17 -07:00
Miles Malerba
2fdd4da2a8 refactor(forms): rename the control directive to the field directive (#64300)
Renames the control directive and the input that users set to bind a
field to a UI control.

Previously users would do:

```
<input [control]="someField">
```

Now users will do:

```
<input [filed]="someField">
```

PR Close #64300
2025-10-13 08:59:13 -07:00
Miles Malerba
0acc91ef51 refactor(forms): move files in preparation for rename (#64300)
Renames several files related to the "control" directive to reflect its
new name, the "field" directive

PR Close #64300
2025-10-13 08:59:13 -07:00
SkyZeroZx
479ffc1d4e docs: Documents utility functions for narrowing form control types (#64373)
PR Close #64373
2025-10-13 08:32:29 -07:00
Matthieu Riegler
2ecbc4e643 docs: add a callout that adding/removing to formArray doesn't not mark dirty (#64337)
fixes #36788

PR Close #64337
2025-10-10 08:13:55 -07:00
SkyZeroZx
a397ca35fa docs: Add unified control state change events (#64279)
PR Close #64279
2025-10-10 06:42:34 -07:00
Leon Senft
4c264c949a test(forms): make custom controls in test implement FormUiControl (#63884)
Fix type issues revealed by implementing the expected interface.

PR Close #63884
2025-10-09 05:15:21 -07:00
Leon Senft
71e8672837 fix(forms): test that minLength/maxLength properties are propagated to controls (#63884)
Ensure that minLength and maxLength are only bound to native input elements that
support them.

PR Close #63884
2025-10-09 05:15:21 -07:00
Leon Senft
acd7c83597 fix(forms): test that min/max properties are propagated to controls (#63884)
Fix a bug where the min property of a form field was not correctly
propagated to custom controls. Also ensure that min and max are only
bound to native input elements that support them.

PR Close #63884
2025-10-09 05:15:21 -07:00
Leon Senft
f4d1017c25 fix(forms): test that common field states are propagated to controls (#63884)
Fix several typos caught by the added test cases:

* `disabled` attribute for native controls
* `readonly` property for custom controls

Note that the `name` test cases have been marked `pending()` due to
https://github.com/angular/angular/issues/63882.

PR Close #63884
2025-10-09 05:15:21 -07:00
Leon Senft
effccffde0 refactor(core): add framework support for binding form controls (#63773)
Move most of the implementation of the `Control` directive into core
framework instructions. This allows field state changes to be propagated
to their corresponding UI controls directly during execution of a
template update block, instead of relying on `effect()`s to synchronize
each change later during the update (and too late in the case of
required inputs).

* Define a private API in `@angular/core` for signal forms to implement:
  * `ɵControl` for the `Control` directive.
  * `ɵFieldState` for the control's associated `FieldState`.
* Emit specialized instructions when compiling a `[control]` binding:
  * `ɵɵcontrolCreate` sets up the `ɵControl` directive if present,
    determines whether it's bound to a native control element or a
    custom control component, and adds the appropriate event listeners
    to notify the `ɵFieldState` of UI changes.
  * `ɵɵcontrol` propagates changes from `ɵFieldState` properties to their
    corresponding UI control properties (in additional to binding the `control`
    property itself).

PR Close #63773
2025-10-04 13:21:55 -07:00
Miles Malerba
34dd3f647a refactor(forms): rename Field to FieldTree (#64214)
There are two primary reasons for this renaming:
1. It better reflects the actual nature of the proxy object, namely that
   the form is represented as a tree, and that this object is used for
   navigating the tree structure (while `FieldState` is used for getting
   the state at a particular point in the structure).
2. This frees up the name `Field` to be used for the directive that
   binds a `FieldTree` to a UI control.

PR Close #64214
2025-10-03 07:59:31 -07:00
Miles Malerba
823384207b refactor(forms): Add a lightweight DI token for Control (#64188)
This will allow optionally injecting the Control directive without
importing the full directive.

PR Close #64188
2025-10-02 07:45:29 -07:00
Matthieu Riegler
e2fd79bfdb docs: add warning to AbstractControl.setErrors (#64063)
fixes #38191

PR Close #64063
2025-09-25 16:29:52 -04:00
Matthieu Riegler
c0d88c37c9 fix(forms): Emit FormResetEvent when resetting control (#64024)
Prior to this change, the event was emitted by the Form Directive. With the change, it is now emitted at the control level.

fixes #58894

PR Close #64024
2025-09-24 16:48:32 +00:00
Matthieu Riegler
3d1e8fa08b docs: add types category for signal forms API entries (#63967)
PR Close #63967
2025-09-22 22:47:38 +00:00
Kristiyan Kostadinov
f5b50ec20d refactor: clean up explicit standalone flags from tests (#63963)
Since standalone is the default, we can dropn the `standalone: true` flags from our tests.

PR Close #63963
2025-09-22 14:27:34 +00:00
Matthieu Riegler
c50d659509 refactor(core): protect InjectionToken usage of ngDevMode (#63875)
Since those are top level APIs, `ngDevMode` might not be available at runtime if they're invoked before the variable is set.

fixes #62796

PR Close #63875
2025-09-19 21:27:45 +00:00
Matthieu Riegler
e835c359f7 docs: Add categories to form apis (#63938)
PR Close #63938
2025-09-19 20:21:16 +00:00
kirjs
b60d5e49b1 refactor(forms): get rid of watFor in validation status spec (#63948)
It was flaky, and now it is not flaky

PR Close #63948
2025-09-19 17:59:32 +00:00
Jessica Janiuk
db8f716a0e Revert "docs: Add categories to form apis (#63938)" (#63950)
This reverts commit 0c4feb8e9e.

PR Close #63950
2025-09-19 17:58:10 +00:00
Matthieu Riegler
0c4feb8e9e docs: Add categories to form apis (#63938)
PR Close #63938
2025-09-19 17:02:57 +00:00
SkyZeroZx
d201cd2c2b feat(forms): Prevents marking fields as touched/dirty when state is hidden/readonly/disabled (#63633)
Ensures fields that are hidden, disabled, or readonly cannot be marked as touched or dirty, improving form state integrity

PR Close #63633
2025-09-15 16:52:15 +00:00
Andrew Scott
c3576506b3 refactor(core): Update tests for zoneless by default (#63668)
This updates tests and examples only to prepare for zoneless by default.

These changes were identified and made as part of #63382. Anything that
failed gets `provideZoneChangeDetection` unless the fixes were easily
and quickly determined.

It also adds the zoneless provider to the `initTestEnvironment` calls
for tests in this repo to prevent regressions before #63382 is merged.

PR Close #63668
2025-09-09 14:41:56 -07:00
Miles Malerba
00a1806eaa refactor(forms): add validateStandardSchema to public api (#63616)
Add `validateStandardSchema` which was accidentally omitted from the
public api.

PR Close #63616
2025-09-08 13:58:55 -07:00
Miles Malerba
1233f7319d refactor(forms): move control directive under api (#63616)
Moves the control directive under api/ since it is part of the public
API. Also removes the interop abstract control from the public API

PR Close #63616
2025-09-08 13:58:55 -07:00
Miles Malerba
6d3f6542b4 refactor(forms): mark all signal forms apis as experimental (#63616)
Ensure that each public API symbol in @angular/forms/signals is marked
as `@experimental`

PR Close #63616
2025-09-08 13:58:55 -07:00
Miles Malerba
bacda4f41b refactor(forms): add support for binding number fields to date inputs (#63585)
In addition to `value` and `valueAsDate`, the date type fields work with
`valueAsNumber` as well, treating it as epoch miliseconds.

PR Close #63585
2025-09-05 14:00:34 -07:00
Miles Malerba
681b13c40f refactor(forms): add support for more input types (#63585)
Adds additional handling for input types that handle numbers:
- number
- range
- datetime-local

As well as input types that handle dates:
- date
- month
- week
- time
- *not* datetime-local which does not allow setting valueAsDate

This PR allows binding either a `Field<string>` or `Field<number>` to
the number type inputs and a `Field<string>`, `Field<numebr>`, or
`Field<Date | null>` to the date type inputs. Binding uses the
corresponding `.value`, `.valueAsNumber`, or `.valueAsDate` according to
the type of the `Field`.

When reading new values out of the input, the `Control` directive will
read the property that aligns with the type of the existing value in the
`Field` and write back the same type.

PR Close #63585
2025-09-05 14:00:34 -07:00