Commit Graph

22 Commits

Author SHA1 Message Date
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 3d1e8fa08b docs: add types category for signal forms API entries (#63967)
PR Close #63967
2025-09-22 22:47:38 +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
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
Miles Malerba db95a5c763 refactor(forms): loosen the error and disabled type on FormUiControl (#63455)
This allows passing errors and disabled reasons that did not originate
from `@angular/forms/signals` in case the the control is being used
separately from the forms system

PR Close #63455
2025-08-29 14:44:13 -07:00
Miles Malerba 10ef96adb3 fix(forms): consistent treatment of empty (#63456)
Removes custom handling of emptiness in several of the validators and
replaces it with a common `isEmpty` check. The common empty check
considered the following values to be empty: `null`, `undefined`, `''`,
`false`, `NaN`

Generally most validators should treat an empty value as valid. This
aligns with both the behavior or native HTML validators and reactive
forms validators.

As an example, consider an optional email field. If the email validator
considered empty string to be an invalid email, there would be no way
for the user to not enter it.

There are several exceptions to this rule:
- `required` whose entire purpose is to ensure that the field is *not*
  empty
- `validateStandardSchema` which should subject all values including
  empty ones to the specified standard schema. It is up to the schema to
  decide whether an empty value is valid or not
- `validate`/`validateAsync` which leaves it up to the user's custom
  validation logic to decide if an empty value is valid.

PR Close #63456
2025-08-29 14:43:03 -07:00
Miles Malerba 862495c238 build: configure signal forms for release (#63458)
Configures signal forms to release as `@angular/forms/signals`

PR Close #63458
2025-08-29 14:31:35 -07:00
Matthieu Riegler 2f5f975cb5 refactor(forms): fix dependencies (#63451)
common/http was missing

PR Close #63451
2025-08-28 09:43:39 -07:00
Miles Malerba b8314bd340 feat(forms): add experimental signal-based forms (#63408)
This commit introduces an experimental version of a new signal-based forms API for Angular. This new API aims to explore how signals can be leveraged to create a more declarative, intuitive, and reactive way of handling forms.

The primary goals of this new signal-based approach are:

*   **Signal-centric Design:** Place signals at the core of the forms experience, enabling a truly reactive programming model for form state and logic.
*   **Declarative Logic:** Allow developers to define form behavior, such as validation and conditional fields, declaratively using TypeScript. This moves logic out of the template and into a typed, testable schema.
*   **Developer-Owned Data Model:** The library does not maintain a copy of data in a form model, but instead read and write it via a developer-provided `WritableSignal`, eliminating the need for applications to synchronize their data with the form system.
*   **Interoperability:** A key design goal is seamless interoperability with existing reactive forms, allowing for incremental adoption.
*   **Bridging Template and Reactive Forms:** This exploration hopes to close the gap between template and reactive forms, offering a unified and more powerful approach that combines the best aspects of both.

This initial version of the experimental API includes the core building blocks, such as the `form()` function, `Field` and `FieldState` objects, and a `[control]` directive for binding to UI elements. It also introduces a schema-based system for defining validation, conditional logic, and other form behaviors.

Note: This is an early, experimental API. It is not yet complete and is subject to change based on feedback and further exploration.

Co-authored-by: Kirill Cherkashin <kirts@google.com>
Co-authored-by: Alex Rickabaugh <alxhub@users.noreply.github.com>
Co-authored-by: Leon Senft <leonsenft@users.noreply.github.com>
Co-authored-by: Dylan Hunn <dylhunn@gmail.com>
Co-authored-by: Michael Small <michael-small@users.noreply.github.com>

PR Close #63408
2025-08-28 09:02:43 -07:00