Commit Graph

15031 Commits

Author SHA1 Message Date
Alex Rickabaugh 24e52d450d feat(forms): add debounce option to validateAsync and validateHttp
This adds support for a `debounce` option to the `validateAsync` and `validateHttp` functions.
This allows developers to debounce the triggering of async validators to improve performance.

A `DebounceTimer` type was also added to `@angular/core` to represent the wait condition parameters uniformly.
2026-03-25 14:17:52 -07:00
Leon Senft b5af15a332 test(forms): support directive composition with FormField
Support composing the `FormField` directive with custom controls:
2026-03-25 13:35:02 -07:00
Angular Robot 0007723a03 build: update cross-repo angular dependencies
See associated pull request for more information.
2026-03-25 13:32:59 -07:00
Alan Agius b40d11eec4 build: consolidate domino bundling in platform-server
Move the domino bundling logic and related shims into a centralized third_party directory within packages/platform-server. This avoids duplication of the bundling logic and ensures consistent shimming across the platform-server package and its entry points.

Following a conversation with OSS licensing, this change also includes the domino LICENSE file in the generated npm package to comply with licensing requirements for bundled third-party code.

```
├── fesm2022
│   ├── init.mjs
│   ├── init.mjs.map
│   ├── platform-server.mjs
│   ├── platform-server.mjs.map
│   ├── _server-chunk.mjs
│   ├── _server-chunk.mjs.map
│   ├── testing.mjs
│   └── testing.mjs.map
├── LICENSE
├── package.json
├── README.md
├── third_party
│   └── domino
│       ├── bundled-domino.d.ts
│       ├── bundled-domino.mjs
│       ├── bundled-domino.mjs.map
│       └── LICENSE
└── types
    ├── init.d.ts
    ├── platform-server.d.ts
    └── testing.d.ts
```
2026-03-25 13:31:05 -07:00
Andrew Scott eecfa4c909 refactor(language-service): Export template target from API
allows template target to be used in other tooling
2026-03-25 13:07:42 -07:00
Matthieu Riegler cf3b7fe489 refactor(core): remove todo
This TODO hinted that we also needed to remove a g3 patch.
2026-03-25 13:02:23 -07:00
Alex Rickabaugh 16adbbf423 fix(core): ensure custom controls resolve transitive host directives
Custom controls can be modeled using a set of host directives to alias
and expose value and valueChange (or checked/checkedChange) bindings,
as well as native attributes like disabled.

This commit updates initializeCustomControlStatus to correctly identify
host components using mapped inputs/outputs, even when those inputs are
exposed via transitive host directives. It also updates
customControlHasInput so that the custom control presence check correctly
evaluates the exposed inputs across all applied host directives, caching
the result to optimize performance on hot code paths.
2026-03-25 13:00:46 -07:00
Kristiyan Kostadinov 3382e8a34b refactor(compiler-cli): generalize out of band diagnostics recorder
Currently the `OutOfBandDiagnosticRecorder` is tied to producing TypeScript diagnostics, however some of our use cases might call for a different form.

These changes decouple the recorder from TypeScript and make the diagnostic type generic.
2026-03-25 12:59:11 -07:00
Kristiyan Kostadinov 9ee4f83705 build: update to TypeScript 6 stable
Updates the repo to the stable version of TypeScript 6.
2026-03-25 12:57:49 -07:00
Matthieu Riegler eae8f7e30b feat(core): Set default Component changeDetection strategy to OnPush
The default change detection strategy is now OnPush.

BREAKING CHANGE: Component with undefined `changeDetection` property are now `OnPush` by default. Specify `changeDetection: ChangeDetectionStrategy.Eager` to keep the previous behavior.
2026-03-24 16:25:02 -07:00
Kristiyan Kostadinov d9712e605e refactor(core): expand input flags type
Expands the type for the input flags in definitions since the current one prevents some of the generated code from compiling.
2026-03-24 15:18:28 -07:00
Alex Rickabaugh 709f5a390c feat(forms): add FieldState.getError()
Added a `getError(kind: string)` method to `FieldState` that returns the first validation error of a given kind, or `undefined` if no such error exists. This method is reactive and will re-evaluate when errors change.

Fixes #63905

Also updated public API goldens and added unit tests.
2026-03-24 15:07:55 -07:00
Alex Rickabaugh ee8d2098cb fix(forms): change FieldState optional properties to non-optional | undefined
This improves compatibility with TypeScript's exactOptionalPropertyTypes.

Fixes #67246
2026-03-24 14:51:31 -07:00
SkyZeroZx 1782114862 refactor(router): expose ComponentInputBindingOptions in public API
Expose  `ComponentInputBindingOptions` as part of the public API
2026-03-24 14:48:52 -07:00
Matthieu Riegler 8bc31a515f feat(core): Allow other expression for exhaustive typechecking
When the switched expression is nested within a union, exhaustive typechecking needs to know which expression to check.
This change adds the possibility of specifying the expression to check:

```
@Component({
  selector: 'app-root',
  imports: [],
  template: `
    @switch (state.mode) {
      @case ('show') { {{ state.menu }}; }
      @case ('hide') {}
      @default never(state);
    }
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class App {
  state!: { mode: 'hide' } | { mode: 'show'; menu: number };;
}
```

fixes #67406
2026-03-24 14:42:28 -07:00
Leon Senft 0eeb1b5f03 fix(forms): allow FormRoot to be used without submission options (#67727)
The `[formRoot]` directive will no longer call `submit()` if the bound
form doesn't define its own submission options. This allows the
directive to be used solely for the default behavior it provides:
setting `novalidate` on the `<form>` and calling `preventDefault()` on
the `submit` event.

Fix #67367

PR Close #67727
2026-03-23 15:41:19 -07:00
Leon Senft f4a5b42ebe refactor(forms): rename directive files for consistency (#67727)
- **FormField**:  `form_field_directive.ts` -> `form_field.ts`
- **FormRoot**:   `ng_signal_form.ts`       -> `form_root.ts`

PR Close #67727
2026-03-23 15:41:19 -07:00
SkyZeroZx 26afb736b7 docs: Update provideZonelessChangeDetection tsdocs 2026-03-23 14:48:02 -07:00
Matthieu Riegler f46e8bd440 refactor(compiler): remove fullTemplateTypeCheck compiler option.
The option was deprecated back in v13. Users should use `strictTemplates: true`.
2026-03-23 11:33:15 -07:00
Modeste ASSIONGBON 2615f35da9 docs: fix js doc of signal forms ignoreValidators option. 2026-03-23 11:21:16 -07:00
SkyZeroZx 1f9a42bb42 refactor(http): Make Fetch API the default in HttpBackend
Updates the `HttpBackend` default provider to `FetchBackend`.

Also updates related warning messages to reflect the new default behavior.
2026-03-23 11:20:39 -07:00
Pushkar-Mahajan4 1128e78913 docs: fix typo in Input decorator 2026-03-23 11:19:46 -07:00
Kristiyan Kostadinov 63ac1bd2fd refactor(compiler-cli): decouple host element creation logic from TypeScript
Reworks the logic for constructing a `HostElement` node so that we can reuse it without depending on TypeScript APIs.
2026-03-23 11:16:39 -07:00
Matthieu Riegler d2054c7c1a refactor: prepare for required changeDetection prop on G3.
We'll make this a G3 only change to prevent backsliding during the transition period.
2026-03-20 15:52:38 -07:00
Angular Robot 621c9083de build: update cross-repo angular dependencies
See associated pull request for more information.
2026-03-20 15:22:17 -07:00
splincode c5da47f63f refactor: replace any with stricter types in common and core
- `JsonPipe.transform`: `any` → `unknown`
- `renderStringify`: `any` → `unknown`
- `NgLocalization.getPluralCategory`: `any` → `number`
2026-03-20 15:20:43 -07:00
Kristiyan Kostadinov 96be4f429b fix(compiler): abstract emitter producing incorrect code for dynamic imports
Fixes that the abstract emitter wasn't adding quotes around the URL of a dynamic import.
2026-03-20 15:18:29 -07:00
Kristiyan Kostadinov 5e99ae9f00 fix(core): widen type for directive inputs/outputs
Currently the directive inputs and outputs are typed to match the members of the class. We can't guarantee that when generating code, because of cases like `model` where an output is generated implicitly.

These changes widen the type to be any string.
2026-03-20 15:18:29 -07:00
Kristiyan Kostadinov 22f8b0a500 fix(core): resolver function not matching expected type
Fixes that the `ɵɵresolveWindow` function wasn't match the type expected by `ɵɵlistener`. I've also added explicit type annotations to make cases like this easier to catch.
2026-03-20 15:18:29 -07:00
Matt Lewis 5a712d42d1 fix(compiler): prevent shimCssText from adding extra blank lines per CSS comment
The comment placeholder restoration in `shimCssText` appended an unconditional
`+ '\n'` to each non-hash comment replacement. Because `_commentRe` does not
consume the newline that follows a comment in the source, that newline already
remains in `cssText`. The extra `'\n'` was therefore inserted on top of the
existing one, shifting every line after each comment down by one. In files with
many comments (e.g. large SCSS preambles) this shifts all subsequent CSS rules
far enough that the CSS sourcemap — generated before `shimCssText` runs —
points to completely wrong source locations in browser DevTools.

The fix is to drop the `+ '\n'`; internal newlines within a multi-line comment
are still preserved via `_newLinesRe`, and the trailing newline that follows the
comment in `cssText` is already present without any extra injection.
2026-03-20 15:17:31 -07:00
Alex Rickabaugh df8b020299 fix(forms): clear native date inputs correctly in signal forms when changed via native UI
When a native date input gets cleared manually by a user via the internal browser
UI, the element changes from invalid to valid, but no `input` event is emitted.

This commit introduces `InputValidityMonitor`, an injectable service that
intercepts these edge-case native status changes. The monitor dynamically
installs CSP-compliant styles appending specific animation keyframes for
`:valid` and `:invalid` pseudoclasses on native form controls. By attaching an
`animationstart` listener, Angular intercepts these changes immediately and
re-invokes the parser.

Fixes #67300
2026-03-20 15:10:26 -07:00
Alex Rickabaugh 98c5afdb02 perf(forms): lazily instantiate signal form fields
Currently, Signal Forms eagerly instantiates all nodes in the form tree because `childrenMap` iterates over the `value` and creates a `FieldNode` for every property. This ensures validation side-effects are run early, but creates pure overhead for fields without validation logic unless explicitly accessed.

This commit makes `childrenMap` lazy by default, skipping materialization for children without schema logic. This is achieved by introducing `hasLogicRules()` and `anyChildHasLogic()` across the `LogicNode` hierarchy. Fields are now only instantiated when a direct read occurs via `getChild()` (which calls the new `ensureChildrenMap()`) or if their subtree requires eager evaluation due to existing validation rules.

Fixes #67212
2026-03-20 15:09:26 -07:00
Alex Rickabaugh 50e599e73e fix(core): lazy-initialize debounced state to prevent computation cycle
When building a debounced resource, we previously eagerly started tracking the 'source' signal state by instantiating a regular signal. However, if this 'debounced' primitive is initialized in a computation reactive graph (like signal forms 'validateAsync'), reading the current UI source dependency eagerly can induce a cycle if we haven't finished calculating the graph node yet.

This fix uses a 'linkedSignal' block to define the eager 'source' instead. Because linkedSignals are lazy by default, this bypasses the initial eager evaluation, allowing the containing reactive graph to finish forming first without losing our timing logic inside the ambient effect().
2026-03-19 16:18:38 -07:00
Matthieu Riegler e01573fbca docs: Add callout about the Component interface. 2026-03-19 16:14:18 -07:00
Matthieu Riegler f99e7ed20f refactor(platform-browser): remove Hammer integration
The integration was deprecated in v20 and will now be removed.

BREAKING CHANGE: Hammer.js integration has been removed. Use your own implementation.
2026-03-19 16:13:20 -07:00
SkyZeroZx ca67828ee2 refactor(compiler-cli): introduce NG8023 compile-time diagnostic for duplicate selectors
Add NG8023 extended diagnostic to report duplicate component selectors
during compilation.

This replaces the former NG0300 runtime error, ensuring the failure
occurs at build time instead of runtime.

Closes  angular#48377

BREAKING CHANGE: Elements with multiple matching selectors will now throw at compile time.
2026-03-19 16:12:02 -07:00
Jessica Janiuk dfa149dc68 fix(core): fixes a regression with animate.leave and reordering
This fixes a regression bug that resulted in reordered elements not getting properly removed from the DOM. Reused nodes were not being cleared out in this situation.

fixes: #67728
2026-03-19 15:51:57 -07:00
Alex Rickabaugh 41b1410cb8 feat(forms): support binding number|null to <input type="text">
`<input type="number">` often does not provide the desired user experience when editing numbers in
a form. MDN even [describes](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input/number#using_number_inputs)
how text inputs should be used in many cases instead, via `<input type="text" inputmode="numeric">`
or similar configurations. Previously, this did not work with Signal Forms without a custom input
component/directive.

This PR builds support for binding `number|null` models directly to `<input type="text">` native
controls via `[formField]`. When a model has a number or `null` value, signal forms will preserve
that status when the user makes edits/changes. Empty string values are converted to `null`, other
values are parsed as numbers, and a parse error is raised when a non-numeric value is entered.

Note that it's up to the UI developer to configure additional UI affordances such as setting an
appropriate `inputmode`, rejecting non-numeric keypresses, etc.

Fixes #66903
Fixes #66157
2026-03-19 15:26:34 -07:00
Matthieu Riegler e850643b1b feat(compiler): Support comments in html element.
```
      <div
        // comment 0
        /* comment 1 */
        attr1="value1"
        /*
           comment 2
           spanning multiple lines
        */
        attr2="value2"
      ></div>
```
2026-03-19 15:25:17 -07:00
Alex Rickabaugh 74f76d8075 feat(forms): add reloadValidation to Signal Forms to manually trigger async validation
This commit introduces a formal mechanism to manually re-trigger
asynchronous validations in Signal Forms, addressing #66994.

It exposes a `reloadValidation` method on the `FieldState` interface
that recursively cascades down the form tree and invokes the underlying
`ResourceRef`'s `reload()` method for any metadata keys tagged with the
internal `IS_ASYNC_VALIDATION_RESOURCE` symbol.

Fixes #66994
2026-03-19 15:22:13 -07:00
SkyZeroZx c1312da183 fix(common): avoid redundant image fetch on destroy with auto sizes
prevents browsers from re-fetch image during DOM teardown
when using `sizes="auto"` with lazy loading.

Fixes angular#67055
2026-03-19 15:21:16 -07:00
aparziale a73b4b7c30 fix(migrations): inject migration not work in multi-project workspace with option path
Fix inject migration in multi-project workspace. The inject migration doesn't work when targeting one of the projects due to either not finding any files in other projects or considering them external thus it throws a SchematicsException

Fixes: #66074
2026-03-19 15:20:40 -07:00
Angular Robot c9e6263e0e build: update cross-repo angular dependencies
See associated pull request for more information.
2026-03-19 15:04:54 -07:00
Kristiyan Kostadinov 468874d6e0 refactor(compiler): emit types from abstract emitter
Adds an opt-in flag to emit type information through the base abstract emitter.
2026-03-18 14:05:18 -06:00
Kristiyan Kostadinov a946e26850 refactor(compiler): move more logic into abstract emitter
Moves the logic for constructing more AST nodes into the `AbstractEmitterVisitor` so it's easier to implement.

Also cleans up the visitor a bit.
2026-03-18 14:05:18 -06:00
Kristiyan Kostadinov 71cee58e89 refactor(compiler): add opt out for printing comments
Allows for consumers of the `AbstractEmitterVisitor` to determine whether comments should be printed.
2026-03-18 14:05:18 -06:00
Kristiyan Kostadinov a3fb4a5f70 refactor(compiler): clean up unused parameter
Cleans up the `escapeDollarInStrings` parameter in various places since it isn't passed anywhere.
2026-03-18 14:05:18 -06:00
Kristiyan Kostadinov c457b9b5b4 refactor(compiler): add ts-ignore comment on factory functions
Adds a `ts-ignore` comment to thew instantiation expressions in factories, because in some compilation modes we can't guarantee that they'll compile.
2026-03-18 14:05:18 -06:00
Jessica Janiuk 890c97301f Revert "refactor(core): Ensure determineLongestAnimation is run synchronously after style applies"
This reverts commit 318ade062e.
2026-03-18 11:30:35 -06:00
Yenya030 57a07d0058 refactor(service-worker): remove unnecessary cast in mock redirect check
Use the typed Response.redirected property directly in the service-worker test mock instead of casting to any.
2026-03-18 11:26:21 -06:00