Compare commits

...

678 Commits

Author SHA1 Message Date
Alex Rickabaugh 5a214653a8 release: cut the v21.0.5 release 2025-12-11 15:41:58 -08:00
Miles Malerba 4fd2b722b4 fix(forms): fix signal forms type error
Removes the `implements` clause on the `Field` directive since it is
causing type errors for people.

(cherry picked from commit d0097f7d0c)
2025-12-11 15:33:17 -08:00
SkyZeroZx 69d243abb7 fix(core): avoid false-positive deprecation when using InjectionToken with factory only
Prevents the deprecation warning that was incorrectly triggered when
defining an InjectionToken with only a `factory`, which correctly
defaults to the `root` scope.

(cherry picked from commit 4f6014a756)
2025-12-11 11:20:17 -08:00
Alex Rickabaugh fa4e6e6763 release: cut the v21.0.4 release 2025-12-10 16:49:04 -08:00
Angular Robot c937da491c build: update cross-repo angular dependencies
See associated pull request for more information.
2025-12-10 16:42:43 -08:00
jnizet 67a5a65a24 docs: fix typos and clarify root effect
(cherry picked from commit c63ef9cb6a)
2025-12-10 12:41:04 -08:00
Chathulanka Gamage 8a31eb8fb8 docs: update control-flow.md to replace else-if with else if
fix incorrect hyphenated form "else-if" and update documentation to match correct syntax "else if"

(cherry picked from commit 7674ada620)
2025-12-10 12:39:25 -08:00
Angular Robot fe581f38fd build: update pnpm to v10.25.0
See associated pull request for more information.
2025-12-10 12:36:08 -08:00
Michael Small de6dc043fb docs: add 'new' to page 'Side effects for non-reactive APIs'
(cherry picked from commit 3ab17876ba)
2025-12-10 12:27:30 -08:00
Matthieu Riegler f20d301bdc refactor: spread rules with glob syntax
prettierignore does not support the glob syntax for multiple extensions.

(cherry picked from commit c429e701fc)
2025-12-10 12:26:57 -08:00
Matthieu Riegler 42c89f1c98 docs: add the version of angular being used to the footer
Include the version of angular being used for the build in the footer of the application

This is a backport of #64863
2025-12-10 12:24:50 -08:00
SkyZeroZx 6930a2e8c8 docs: update forwardRef usage with signals and add HostListener note
(cherry picked from commit bff2dcb93c)
2025-12-10 12:23:33 -08:00
Angular Robot 68a98118d2 build: lock file maintenance
See associated pull request for more information.
2025-12-10 12:22:25 -08:00
Andrew Scott 497c0e36ab refactor(core): Add transition.to property to FakeNavigation
This matches the upstream changes in https://github.com/whatwg/html/commit/f19930f98afeb7565cfc1cbc6a1d4a2086535bca

(cherry picked from commit 5988bdedae)
2025-12-10 10:18:13 -08:00
diegoinost02 7fde186157 docs(forms): document array item validation in Signal Forms
(cherry picked from commit 9dd08c571a)
2025-12-10 10:17:33 -08:00
diegoinost02 8c8bd3e856 docs(forms): add signal forms documentation for validating array items
(cherry picked from commit e6865af8f1)
2025-12-10 10:17:33 -08:00
SkyZeroZx 49fca78f27 docs(docs-infra): Fixes the visibility of the copy link button in API documentation headings
Fixes the visibility of the copy link button in API documentation headings.
The button now appears on hover, improving the user experience.

(cherry picked from commit 15e3407dab)
2025-12-10 10:16:04 -08:00
Shuaib Hasan Akib 2dd971b73e docs: hide menu icons from screen readers in aria example
Add aria-hidden="true" to decorative icon elements in the ARIA menu documentation
example to prevent screen readers from announcing both icon names and labels.
This improves the accessibility experience by ensuring only meaningful text
is announced to screen reader users.

Fixes: #65768
(cherry picked from commit 1c6049584e)
2025-12-10 10:09:41 -08:00
Matthieu Riegler cbb10179c8 fix(forms): allow resetting with empty string
Both empty string and null values should be accepted when resetting

fixes #65949

(cherry picked from commit 14713d0992)
2025-12-10 10:04:58 -08:00
Shuaib Hasan Akib 834593b9c0 docs: use fenced code blocks and format examples
Replaces custom docs-code blocks with fenced Markdown code blocks and reformats examples to improve readability, consistency, and copy-paste behavior.

(cherry picked from commit d0a34a6ca5)
2025-12-10 09:35:56 -08:00
Shuaib Hasan Akib ac6f34a43b fix(docs-infra): parse linenums attribute from triple backtick metadata
The triple backtick code block parser now extracts the linenums attribute
from metadata and applies it to enable line number display in code examples

(cherry picked from commit 1f29577077)
2025-12-10 09:31:48 -08:00
Andrew Scott 01ab257da4 refactor(core): match spec updates for FakeNavigation
Updates FakeNavigation based on updates in https://github.com/whatwg/html/pull/11952

(cherry picked from commit d355205198)
2025-12-10 08:19:28 -08:00
Matthieu Riegler 84f397c831 refactor(core): Support Error like object for on resource errors.
Error like object will be treated as errors.

Related to #61861

(cherry picked from commit 835a643161)
2025-12-10 08:18:24 -08:00
Joey Perrott 96bb4c6ae3 build: add the ignore all rc files flag when running bazel info
Due to a bug in bazel we need to ignore all of the rc files when running bazel info commands

(cherry picked from commit 9ace7d7a0d)
2025-12-09 13:44:49 -08:00
Matthieu Riegler 4043ec5bdd docs: create a separate effect guide
This also includes details about `afterRenderEffect`

WIP.

fixes #63757

(cherry picked from commit 827f5a6fd5)
2025-12-09 13:11:05 -08:00
Kristiyan Kostadinov 65297c6201 fix(compiler-cli): expand type for native controls with a dynamic type
We recently allowed users to have a dynamic input `type` with signal forms, but the logic that infers the value type falls back to `string` even though in theory it can be any of the other types.

These changes expand the inferred type to `string | number | boolean | Date | null` if we detect a dynamic `type` binding.

(cherry picked from commit 8a3f3a91cf)
2025-12-09 13:01:35 -08:00
kirjs 6d7475582f fix(forms): Reuse key in parent in compat structure
This fixes the "Compat nodes do not use keyInParent." error when trying to bind compatField.

(cherry picked from commit 179b4cba67)
2025-12-09 12:59:27 -08:00
arturovt bb0061ba63 refactor(core): wrap operationsCounter calls with ngDevMode checks
Wrap operationsCounter method calls (recordCreate, recordDestroy, reset)
with ngDevMode guards to ensure they are tree-shaken in production builds.

This aligns with the existing pattern where operationsCounter is only
initialized in development mode, and eliminates unnecessary method call
overhead in production.

The optional chaining (?.) is retained as TypeScript doesn't narrow types
based on ngDevMode checks, but the entire expression will be removed during
production builds.

(cherry picked from commit 80dbd74ae8)
2025-12-09 10:38:44 -08:00
Matthieu Riegler ffad78360f refactor(core): add dedicated deprecated signatures for providedIn: any / NgModule.
Those were deprecated by #47616 back in v15.

fixes #65923

(cherry picked from commit 8199945637)
2025-12-09 10:38:14 -08:00
Angular Robot 4bfee61aa7 docs: update cross-repo adev docs
Updated Angular adev cross repo docs files.
2025-12-09 10:37:00 -08:00
Miles Malerba f254ff4f2e feat(forms): expose element on signal forms Field directive
This allows for easier focusing of the relevant element based on the
`field` property of a `ValidationError`

(cherry picked from commit aff8b248b3)
2025-12-09 09:47:56 -08:00
Andrew Scott 91532626a9 docs: Update tutorial last step to use markForCheck
Ideally this tutorial would have used signals but didn't. That's a bigger change than
we are able to make right now and there are other things we would like
to update at the same time. This fix is a temporary patch to the
existing content until there is time to redo the tutorial and videos
entirely.

fixes #65863

(cherry picked from commit 200d923436)
2025-12-09 09:39:37 -08:00
Angular Robot d8162373d7 build: update cross-repo angular dependencies
See associated pull request for more information.
2025-12-09 09:28:32 -08:00
SkyZeroZx 5d73893219 docs(docs-infra): Refactors tutorial generation and updates ng-container docs
Updates the `ng-container` documentation page to use the correct `angular-html` code format and removes an unused CLI documentation file.

(cherry picked from commit 9a6b8e0315)
2025-12-09 09:25:34 -08:00
Kristiyan Kostadinov f901cc9eb3 perf(compiler): chain query creation instructions
We always emit the query creation instructions in a group which makes them good candidates for chaining.

(cherry picked from commit ae1c0dc490)
2025-12-09 09:24:41 -08:00
Andrew Scott a41b0ce025 fix(vscode-extension): Show warning if multiple versions of Angular are detected in workspace
This shows a more prominent warning when multiple versions of Angular
are detected in the workspace and we are forced to choose one to use for
the language server. This also logs those versions with their locations
and directs the user to view the output panel.

fixes #65466

(cherry picked from commit c9dfc6c484)
2025-12-09 09:23:52 -08:00
Matthieu Riegler 182116582e docs(docs-infra): prefer/avoid code block styling
fixes #65866

(cherry picked from commit 3411638f65)
2025-12-09 09:23:17 -08:00
Miles Malerba 5880fbc73c feat(forms): redo the signal forms metadata API
This PR makes a number of changes to the metadata API to address design
flaws in the previous API. Some of the changes include:

- Replaces the previous `MetadataKey` and `AggregateMetadataKey` with a
  single unified `MetadataKey` that is used for all metadata.
- The new `MetadataKey` is only defined for fields that explicitly set
  it in their schema logic
- All metadata now has reducer / aggregate behavior
- The new `MetadataKey` has an option to create a managed key which
  wraps the result of its computed aggregate into some other structure
  such as a `Resource` or `linkedSignal`
- There are now two APIs to create metadata keys
  - `createMetadataKey` for pure computed metadata
  - `createManagedMetadataKey` for metadata that manages its computation
    internally

(cherry picked from commit ebc5c2b083)
2025-12-09 09:21:45 -08:00
Joey Perrott 53f752e7a3 build: update repository to use node 22.21.1 in bazel
The repository was updated to use node 22.21.1 via nvm, but bazel had not been updated to match

(cherry picked from commit 349133374f)
2025-12-09 09:19:19 -08:00
Shuaib Hasan Akib d9522d9033 docs(docs-infra): hide trailing empty line in code examples
Add CSS rule to hide the last empty line in code blocks to prevent displaying
unnecessary empty lines when source files end with a newline character.
The empty line remains in the DOM for proper copy-paste functionality.

(cherry picked from commit 4b9fffaa79)
2025-12-09 09:17:46 -08:00
Gouvernathor 1a4ce250e7 docs(common): Explain how ::ng-deep works
Co-authored-by: Matthieu Riegler <kyro38@gmail.com>
(cherry picked from commit 5607f513a7)
2025-12-09 09:16:51 -08:00
cexbrayat 55fc677cef fix(forms): add signals for dirty, hidden, and pending states in custom controls
FormUiControl states that hidden, pending and dirty will be bind in custom controls, but this is currently not the case.

Fixes #65575

(cherry picked from commit 9fe9566581)
2025-12-08 10:30:48 -08:00
Anuj Chhajed 288238abef refactor(core): correct all typeof ngDevMode comparison patterns introduced by #63875
This change replaces all remaining occurrences of `typeof ngDevMode !== undefined`
with the correct `typeof ngDevMode !== 'undefined'` form. This aligns the codebase
with JavaScript typeof semantics and maintains consistency with other Angular code.

(cherry picked from commit 96b79fc393)
2025-12-08 10:30:06 -08:00
Miles Malerba a4c436a058 refactor: followup cleanup for #65758 fallout
Fixes some issues left behind by recent refactor

(cherry picked from commit efde94a525)
2025-12-08 10:28:04 -08:00
mahmoudaboueleneen 7c82f4e410 docs: fix typo in 'components' word in host elements guide
(cherry picked from commit bad758d4ea)
2025-12-08 10:24:10 -08:00
Shuaib Hasan Akib 55709c1de6 refactor(core): use proper type for stringifyTypeFromDebugify parameter
Replace the 'any' type with ClassDebugInfo for the debugInfo parameter in
stringifyTypeFromDebugInfo function. This removes the TODO comment that was
tracking the need for proper typing without creating circular dependencies.

The change improves type safety while avoiding circular imports since
stringify_utils.ts doesn't export anything that definition.ts imports.

(cherry picked from commit 5fd75410a9)
2025-12-08 10:23:21 -08:00
Joey Perrott ed7db0e0a2 build: update to bazel version 8.4.2
Update bazel to use version 8.4.2

(cherry picked from commit aa92f19307)
2025-12-08 10:22:04 -08:00
Alan Agius f18af4b0db build: ignore adev generated content JSON files in Prettier
These files are auto generated.

(cherry picked from commit 22eda59a31)
2025-12-08 10:20:34 -08:00
Matthieu Riegler 10bdae9098 build: enable angular formatting on all html files
This should also be safe on any html file that isn't an angular template

(cherry picked from commit 9d1d742f1b)
2025-12-08 10:19:50 -08:00
Alessio Pelliccione 7f967997fb feat(docs-infra): add complexity level badge
Introduces the new complexity badge in recommendation cards.
The implementation utilizes CSS variables and `color-mix` to efficiently
handle color themes (Basic, Medium, Advanced) and dark mode support.

Closes #65378

(cherry picked from commit 253dc95d63)
2025-12-08 10:05:51 -08:00
Angular Robot b2ea55c969 build: update cross-repo angular dependencies
See associated pull request for more information.
2025-12-08 09:36:30 -08:00
SkyZeroZx 7ab88c1697 docs: add attribute binding reference in accessibility guide
(cherry picked from commit 70e024ea80)
2025-12-08 09:24:30 -08:00
Shuaib Hasan Akib 46f7986a02 docs: add missing page title to update guide
Fixes the missing page title so the update guide displays a proper heading.

(cherry picked from commit c9cba99407)
2025-12-08 09:23:28 -08:00
SkyZeroZx 3c8b3ac07b docs: Updates tutorial syntaxis highlight
(cherry picked from commit ccf31349c5)
2025-12-08 09:21:48 -08:00
Angular Robot f253f1200d build: update bazel dependencies
See associated pull request for more information.
2025-12-08 09:13:52 -08:00
SkyZeroZx 71568e069c docs: add documentation HOST_TAG_NAME
(cherry picked from commit 6f2ef918e3)
2025-12-08 09:08:55 -08:00
Jessica Janiuk 0352d552a1 docs: Update contributing guidelines
This commit updates the CONTRIBUTING.md file to provide clearer
guidelines for new contributors, including sections on code style,
testing, and the pull request process.

(cherry picked from commit ce4ddf4b47)
2025-12-08 09:06:31 -08:00
Miles Malerba 195c574ca1 test: fix broken adev tests
Fixes a broken adev tests and enables another one that seems to work
fine now

(cherry picked from commit cda56db20f)
2025-12-08 09:04:55 -08:00
SkyZeroZx 56418b108e docs: add documentation for HTTP_TRANSFER_CACHE_ORIGIN_MAP
(cherry picked from commit 7e1e396a00)
2025-12-08 09:00:13 -08:00
SkyZeroZx 5b911d6025 docs(docs-infra): fix hideCopy option to code snippets
Adds the ability to hide the copy button on code snippets.

Updates documentation to use the new `hideCopy` option with the new
markdown code fence syntax.

(cherry picked from commit a4563044ad)
2025-12-08 08:48:25 -08:00
Shuaib Hasan Akib b8ed18c527 docs: fix lazy loading documentation reference
Updates broken or outdated references in the lazy loading guide.

Fixes: #65906
(cherry picked from commit 45aa63308e)
2025-12-08 08:47:45 -08:00
Alan Agius 8bedd996ac build: format manifest files after updating its version
This commit run the formatter during the release.

(cherry picked from commit d2ac93d5ca)
2025-12-08 08:44:01 -08:00
Alan Agius 79ebbf7e36 refactor: move Prettier ignore rules from ng-dev config to .prettierignore
This moves all prettier ignore rules to the prettier config

(cherry picked from commit 52aac81829)
2025-12-08 08:43:11 -08:00
Matthieu Riegler 5d8adf2105 docs(docs-infra): fix next version dropdown
fixes #65912

(cherry picked from commit 13bc1bc721)
2025-12-08 08:42:24 -08:00
Matthieu Riegler bd4cfc88ef docs(docs-infra): expose VERSION from @angular/upgrade
The missing src was responsible for not exposing the symbols during the doc extraction.

fixes #65916

(cherry picked from commit 81cf319534)
2025-12-08 08:41:40 -08:00
kirjs 28e7546edc feat(docs-infra): forward preview error locations
Intercept the WebContainer preview overlay open-in-editor requests and relay them to the editor via postMessage so errors open the matching file.

(cherry picked from commit 789f91bd4f)
2025-12-04 11:45:56 -08:00
kirjs 3d58d10e68 feat(docs-infra): allow navigating to editor error locations
This shows up in a little pop-up, and is clickable now, and leads to exact line

(cherry picked from commit 21b995f4b7)
2025-12-04 11:45:56 -08:00
diegoinost02 ba61579cb7 docs: clarify linkedSignal update behavior
Updates the linkedSignal documentation to specify that it updates its value when the source changes or when any signal referenced in the computation changes, ensuring the description accurately reflects its behavior.

(cherry picked from commit e311f3df72)
2025-12-04 11:42:51 -08:00
Shuaib Hasan Akib ab38d91891 docs: update rxResource changes in updated page
Add both `request` and `loader` changes in rxResource section

(cherry picked from commit abcd6b5bfb)
2025-12-04 11:41:41 -08:00
SkyZeroZx 36cffc72d3 docs: update zone pollution guide highlight syntax
(cherry picked from commit 3adb091c1a)
2025-12-04 11:40:07 -08:00
Kirill Cherkashin 7de8558219 refactor(forms): Break logic.ts into separate files
This would make it easier to navigate

(cherry picked from commit 5be33048cc)
2025-12-04 11:33:26 -08:00
Nakul Sharma d40a517c0f refactor(core): use getComponentDef in stringify_utils
- Use getComponentDef in debugStringifyTypeForError to clean up TODO
- Remove outdated comment from stringify_utils

(cherry picked from commit 0bb8924ab6)
2025-12-04 11:32:17 -08:00
Joey Perrott c3bd22d10d build: update cross-repo angular dependencies
See associated pull request for more information.
2025-12-04 11:26:14 -08:00
Alex Rickabaugh bf1c12cd93 fix(forms): memoize reads of child fields in signal forms (#65802)
Previously, navigating a `FieldTree` in signal forms involved reactive reads
of the value of the parent field(s), both directly and via `.childrenMap()`.

This meant that on _any_ change to the value of a field, reactive
notifications would trigger updates of computeds, reruns of effects, etc.
So for example, this effect would run on every change to the form:

```ts
const f = form(signal({data: 'abc', unrelated: 0}));
effect(() => {
  // accessing f.data incurs a dependency on f().value() which changes
  // on every change in the whole form
  console.log(f.data().value());
});
```

This is deeply counterintuitive and troublesome when attempting to write
effect logic, and also results in `computed`s unnecessarily updating.

This change introduces the concept of a "reader" computed, which memoizes
the access of a field at a given key via the reactive graph. With this, the
same `f.data` access above now depends on the `data` reader in `f` only,
which is effectively a constant computed. As a result, the effect only
reruns on changes to `data`'s value, as intended.

PR Close #65802
2025-12-03 12:52:43 -08:00
Alex Rickabaugh 2c12661620 refactor(forms): simplify child field creation (#65802)
Previously, several values were being passed into the creation of
`FieldNodeStructure`s that were only used in the creation of child nodes.
Separately, we also passed a `createChildNode` function which these values
were passed back into.

Instead, this moves the small bit of logic from structure.ts behind the
`createChildNode` callback, which reduces the passing of values back-and-
forth and gives `createChildNode` a much more suitable signature.

PR Close #65802
2025-12-03 12:52:43 -08:00
cexbrayat 565c022a87 build: disable assistant_to_the_branch_manager on forks
It currently fails as it is triggered on push, but requires an angular-robot-key that forks don't have.

(cherry picked from commit fc23fcdd3b)
2025-12-03 12:33:18 -08:00
Angular Robot 4e19d6c072 docs: update cross-repo adev docs
Updated Angular adev cross repo docs files.
2025-12-03 12:32:36 -08:00
Joey Perrott fbc43f9272 build: use mjs files for ng-dev configuration
In preperation for ng-dev requiring mjs files for configuration, switch over our usage
2025-12-03 12:30:55 -08:00
Joey Perrott 34caae5978 ci: use defined ng-dev config for deploying docs site
Use the repo defined ng-dev configuration for deploying the docs site

(cherry picked from commit eebcaf49f1)
2025-12-03 11:26:10 -08:00
Shuaib Hasan Akib 2e5d187120 fix(docs-infra): prevent readonly TypeScript keyword from being linked
This updates the docs infrastructure to avoid incorrectly linking the `readonly` keyword in TypeScript examples.

Fixes #65632

(cherry picked from commit 7f8ffa3304)
2025-12-03 16:30:55 +01:00
Pawel Kozlowski c355ffd99e release: cut the v21.0.3 release 2025-12-03 16:18:30 +01:00
SkyZeroZx 6b4ab876e8 feat(forms): Allows transforms on FormUiControl signals
Extends the `FormUiControl` interface to allow `InputSignalWithTransform` in addition to `InputSignal` for its properties.

Fixes #65756

(cherry picked from commit 7d1e502345)
2025-12-03 15:13:06 +01:00
Leon Senft 609699ae17 perf(core): tree shake unused dynamic [field] binding instructions (#65599)
Move the instructions used to dynamically bind a `Field` directive to a
form control onto the `Field` itself. This way the instructions are only
retained if the app uses the `Field` directive.

PR Close #65599
2025-12-03 15:10:50 +01:00
Leon Senft a5dbd4b382 fix(forms): support dynamic [field] bindings (#65599)
Support binding a `Field` directive to a component created dynamically
with `createComponent()`.

Fix #64632

PR Close #65599
2025-12-03 15:10:49 +01:00
Kristiyan Kostadinov 4bb085311e fix(core): unable to inject viewProviders when host directive with providers is present
When registering providers, the DI system assumes that `viewProviders` are registered before plain `providers`. This was reinforced by components always being first in the array of directive matches, only one component being allowed per node and the fact that only components can have `viewProviders`.

This breaks down if there are host directives with `providers` on the component, because they'll execute earlier, throwing off the order of operations.

These changes fix the issue by separating out the resolvers for `viewProviders` and plain `providers` and explicitly running the component's `viewProviders` resolver before any others. This also has the benefit of not attempting to resolve `viewProviders` for directives which are guaranteed not to have them.

Fixes #65724.

(cherry picked from commit 886cf6c452)
2025-12-03 15:09:53 +01:00
Angular Robot 6491df9175 build: lock file maintenance
See associated pull request for more information.
2025-12-03 13:24:37 +01:00
Alan Agius 20474d3f0f fix(http): enable XSRF protection for same-origin absolute URLs
Previously, the XSRF interceptor only added the XSRF token to requests with relative URLs.
This commit updates the interceptor to also add the token to requests with absolute URLs, provided they match the current origin.

(cherry picked from commit 0659d11c85)
2025-12-03 12:19:46 +01:00
Kristiyan Kostadinov 1f1856e897 fix(compiler-cli): check that field radio button values are strings
Adds some type checking code which verifies that the bound `value` on a `Field` radio button is a string.

Fixes #65726.

(cherry picked from commit 6773d3b97d)
2025-12-03 12:19:01 +01:00
arturovt 48b89f9fbe fix(router): handle errors from view transition finished promise
This commit adds a `.catch()` handler to `transition.finished` from `document.startViewTransition` to prevent unhandled promise rejections. The finished promise can reject with `TimeoutError` or `InvalidStateError` when transitions fail during or after the animation phase.

Based on the Blink source code, the `finished` promise can reject with:
* `TimeoutError`: "Transition was aborted because of timeout in DOM update"
* `InvalidStateError`: "Transition was aborted because of invalid state"

This may happen when the DOM update phase exceeds the browser's internal timeout threshold.

(cherry picked from commit b74a0693f2)
2025-12-03 12:17:02 +01:00
Joey Perrott 0f50ea8f97 docs: prevent showing typescript diagnostic errors until the node runtime reaches a ready state
Prevent the overlay box showing diagnostics errors until after the initial setup of the node runtime is completed.

Fixes #52649

(cherry picked from commit 819b640c2d)
2025-12-03 11:54:58 +01:00
Pawel Kozlowski c112ef1808 Revert "build: update cross-repo angular dependencies"
This reverts commit 82d616b681.
2025-12-03 11:34:40 +01:00
Pawel Kozlowski 2a459a0e3f Revert "build: update bazel dependencies"
This reverts commit 42fbb64aec.
2025-12-03 11:34:40 +01:00
Angular Robot 42fbb64aec build: update bazel dependencies
See associated pull request for more information.
2025-12-03 10:12:32 +01:00
Joey Perrott 82d616b681 build: update cross-repo angular dependencies
See associated pull request for more information.
2025-12-03 10:09:29 +01:00
Joey Perrott 8e837cc226 docs: rename visibleRegion to region
Use the attribute region instead of visibleRegion

(cherry picked from commit 34bedae101)
2025-12-03 10:06:06 +01:00
Joey Perrott 76f784c340 refactor(docs-infra): extract only the visibleRegion
Previously we extracted the regions and only made the visible region visible on the page, but since there is not a need for the
non-visible code to be presented, we don't need to include it in the generated code snippets.

(cherry picked from commit 9b3b5fb4cf)
2025-12-03 10:06:05 +01:00
Kirill Cherkashin e95d2e3a34 docs: Update adev/src/content/guide/forms/signals/models.md
Co-authored-by: Matthieu Riegler <kyro38@gmail.com>
(cherry picked from commit 29223c440f)
2025-12-02 19:30:57 +01:00
kirjs 1ee0ff8cfb docs(forms): Polish the docs
- Recommend using form/fields to set the value
- Drop "Dynamic field addition" section as for the above reason

(cherry picked from commit 1fd8303659)
2025-12-02 19:30:57 +01:00
Andrew Scott c2a8934d12 Revert "refactor(router): compress synchronous end to router navigation to single operator"
This reverts commit 71362733cf.
2025-12-02 19:13:07 +01:00
Andrew Scott 71362733cf refactor(router): compress synchronous end to router navigation to single operator
The end of the Router navigation is a block of synchronous logic that
can be compressed into a single operator rather than splitting it across
several, making it harder to step through. The only benefit from the
split is automatic unsubscribe/cancellation, which we can replicate
with an additional 'shouldContinue' check before proceeding.

(cherry picked from commit b7d21e209a)
2025-12-02 16:44:06 +01:00
Kristiyan Kostadinov 5a80a48e96 fix(compiler-cli): avoid allocating an object for signals in production mode
Currently when the signal debug name transform sees something like `const foo = signal(0);`, it transforms the signal into `signal(0, {...(ngDevMode ? { debugName: 'foo' } : {})})`. After minification this becomes `signal(0, {})` which will allocate memory for the empty object literal.

These changes rework the logic to produce `signal(0, ...(ngDevMode ? [{ debugName: 'foo' }] : []))` which will be fully tree shaken away to `signal(0)`.

(cherry picked from commit e30e61b789)
2025-12-02 15:06:55 +01:00
Jessica Janiuk 8c3304c766 fix(core): run animation queue in environment injector context
In the case that a component injector is destroyed before the animation
queue runs, the animation queue would fail to run because it was using a
destroyed injector. This commit changes the animation queue to run in the
context of the EnvironmentInjector, which is not destroyed until the app
is destroyed.

fixes: #65628
(cherry picked from commit d8ab83ca82)
2025-12-02 15:05:21 +01:00
Matthieu Riegler 017672f742 refactor(compiler): Generate the controlCreate instruction after the native element has been created
This is necessary to exclude a race condition where the MutationObserver initialized by the instruction fired before the inputs are binded.

fixes #65678

(cherry picked from commit f35b2ef47c)
2025-12-02 12:59:53 +01:00
Matthieu Riegler 8e0df4083d docs(docs-infra): Show examples on function overloads
(cherry picked from commit a784995a98)
2025-12-02 12:13:16 +01:00
Georgi Serev c0e0010bb9 fix(devtools): hide profiler node details when the frame is changed
Hide the details panel when the user selects a new frame.

(cherry picked from commit 2eaa4d54ad)
2025-12-02 12:05:58 +01:00
Joey Perrott 53e0aaba4e refactor(docs-infra): move header id tracking into RendererContext
Move the header id tracking into the renderer context rather than a global state.  Since the RendererContext is
initialized for each execution of the marked parser, we can store the context of which header ids have been seen within
a single page there which allows us to run these parse interactions in parallel.

(cherry picked from commit a16a70ca74)
2025-12-02 12:03:39 +01:00
Joey Perrott 5ec3bd9c55 refactor(docs-infra): transform all headings using the built in transformer
Rather than manually calling the transformer we use for headings from within a render function, we now properly call into the Renderer to do them
via the tokens they are require instead.  This is being done to allow us to have a per Renderer instance of state instead of a global state, which will
allow us to run marked async and hopefully speed up the pipeline

(cherry picked from commit 8b296543ae)
2025-12-02 12:03:38 +01:00
Tim Deschryver efe4b72abb docs: fix documentation link for currentNavigation method
(cherry picked from commit 680de24c3c)
2025-12-02 12:02:28 +01:00
SkyZeroZx ea45b4d54c docs: add platform-specific implementation and helpers
(cherry picked from commit 0c7508bf56)
2025-12-02 12:00:05 +01:00
Angular Robot 2935fef3af build: update cross-repo angular dependencies
See associated pull request for more information.
2025-12-02 10:47:29 +01:00
SkyZeroZx 35b39bd86f docs: improve formatting and fixed numeration issue in attribute directives guide
(cherry picked from commit 03c04d4c83)
2025-12-02 10:45:51 +01:00
SkyZeroZx 893fbdfb04 docs: update syntax highlighting in component documentation
(cherry picked from commit 7fd5890d48)
2025-12-02 10:38:20 +01:00
Gaston f368ab957c docs: add FormArrayDirective documentation to reactive forms guide
Update adev/src/content/guide/forms/reactive-forms.md

Co-authored-by: Matthieu Riegler <kyro38@gmail.com>
(cherry picked from commit da99b5d1d0)
2025-12-02 10:36:17 +01:00
Matthieu Riegler 7f289bdc3a docs: fix submit example
`async` keyword is required for the `submit` callback

(cherry picked from commit bc93b398af)
2025-12-02 10:35:10 +01:00
Angular Robot 706d7620e8 build: update cross-repo angular dependencies
See associated pull request for more information.
2025-12-01 19:36:18 +01:00
SkyZeroZx b4c8c939b0 docs: update notes to use consistent formatting in various guides
(cherry picked from commit aea2465a59)
2025-12-01 19:33:36 +01:00
Angular Robot 48008c2f6f docs: update cross-repo adev docs
Updated Angular adev cross repo docs files.
2025-12-01 19:30:14 +01:00
Shuaib Hasan Akib 8ab759497c docs: format typescript examples and replace <docs-code> with fenced code blocks
Replaced <docs-code language="typescript"  to improved
readability and consistency across documentation.

(cherry picked from commit 3731f07579)
2025-12-01 19:20:23 +01:00
SkyZeroZx dad3d7900f feat(docs-infra): Adds copy link to anchor functionality
Enables copying a direct link to any section by clicking its anchor. Also updates the aria-label to remove the code tag

(cherry picked from commit 4e89bc6244)
2025-12-01 19:19:35 +01:00
Angular Robot c139b35d5d build: update rules_angular digest to 9409450
See associated pull request for more information.
2025-12-01 19:18:09 +01:00
til0r ed32e8c364 docs: fix npm link URL in creating-libraries guide
- Update `npm link` to the official docs URL.
- Keep `pnpm link` reference intact

(cherry picked from commit 721080aaa9)
2025-12-01 18:58:37 +01:00
Pratyush Swain fe863aad05 docs(docs-infra): update NG0910 documentation with new control flow
(cherry picked from commit 27d1ccb2df)
2025-12-01 18:54:02 +01:00
Shuaib Hasan Akib 7efcd9ad4c docs: link inject function to its API reference
Replaced plain code-form usage of `inject` with a link to the
API docs (`/api/core/inject`) to improve navigation and
help readers access detailed reference information more easily.

(cherry picked from commit 7b33554d24)
2025-12-01 18:53:08 +01:00
aparziale 4d036fcc41 docs(docs-infra): Fix Incorrect indentation
Fix Incorrect indentation in hierarchical dependency injection guide

Fix #65722

(cherry picked from commit a850987519)
2025-12-01 18:52:20 +01:00
Shuaib Hasan Akib 74cbe36fa6 docs: update examples to use self-closing tags for consistency with recommended practices
Updated various template examples to use self-closing component tags
(e.g., `<my-comp />`) instead of the expanded form (`<my-comp></my-comp>`),
improving consistency across the documentation and aligning with current
Angular style recommendations.

(cherry picked from commit a464406ebf)
2025-12-01 18:50:54 +01:00
aparziale ce961fe5c0 docs(docs-infra): Fix Drag handle SVG is not visible
Fix Drag handle SVG is not visible. The css style overrides the default behavior

Fixes #65545

(cherry picked from commit 7a39565916)
2025-12-01 18:49:10 +01:00
SkyZeroZx b7ccb308b8 docs(docs-infra): Improves symbol linking for Angular Aria selectors
Improves the symbol linking logic to handle Angular component selectors (e.g., ngCombobox). It attempts to convert Angular selector patterns to their corresponding class names, improving navigation to Angular API documentation.

(cherry picked from commit 2d854e01bc)
2025-12-01 18:47:23 +01:00
galmi bc6cb6830e docs(forms): fix links in signal forms guides and use docs-pill-row links for next steps
(cherry picked from commit 726dfad9db)
2025-12-01 18:46:22 +01:00
Shuaib Hasan Akib cb2847c8d9 fix(docs-infra): truncate long TOC items and add title tooltips
Long TOC entries now truncate with …, and a title attribute is added to display the full label on hover.

Fixes: #65727
(cherry picked from commit 313454bf17)
2025-12-01 18:43:50 +01:00
Ben Hong 8cfe9d8100 docs: update aria listbox selection mode section
(cherry picked from commit 7ea5b66a70)
2025-12-01 18:41:57 +01:00
Kristiyan Kostadinov c46f65df39 docs: fix up font in drag drop examples
Fixes that the CDK drag&drop examples were using a serif font.

(cherry picked from commit 649e2ec1d4)
2025-12-01 18:40:38 +01:00
aparziale 505e1a1f6b docs(docs-infra): fix content projection documentation
Fixed documentation issues in content projection examples.
- Component decorator without '@'
- Self-closing tag for ng-content

Fix #65675

(cherry picked from commit f18dd5e54c)
2025-12-01 18:38:20 +01:00
kirjs 9aab858871 feat(docs-infra): prevent browser save dialog in adev code editor
Add Cmd+S/Ctrl+S keyboard shortcut to the adev code editor that prevents
the annoying browser save dialog from appearing. The shortcut is a no-op
since the editor already has auto-save functionality that persists changes
after 500ms of inactivity.

(cherry picked from commit cb04cee7b2)
2025-12-01 18:36:06 +01:00
Kristiyan Kostadinov 8c4a1524da release: cut the v21.0.2 release 2025-12-01 12:51:18 +01:00
Alan Agius 78fd159b78 fix(compiler): prevent XSS via SVG animation attributeName and MathML/SVG URLs
This commit implements a security fix to prevent XSS vulnerabilities where SVG animation elements (`<animate>`, `<set>`, etc.) could be used to modify the `href` or `xlink:href` attributes of other elements to `javascript:` URLs.

(cherry picked from commit 1c6b0704fb)
2025-12-01 10:27:00 +01:00
SkyZeroZx fec1f1ae5f docs: update code snippets in reference doocumentation
(cherry picked from commit 8f3fdc3e80)
2025-11-26 16:01:17 -05:00
Matthieu Riegler a4084154f2 refactor(migrations): don't migration the server bootstrapApplicaiton on zoneless apps.
With the change we specifically analyse `boostrapApplication` with a config that uses `mergeApplicationConfig`.

fixes #65408

(cherry picked from commit c1dfd9cde6)
2025-11-26 15:58:57 -05:00
aparziale 99b6341ca5 docs(docs-infra): fix form custom control example uses syntax
Fixed form custom control example uses non-working syntax in template

Fix #65647

(cherry picked from commit a3fb41e797)
2025-11-26 15:48:20 -05:00
Matthieu Riegler 4207d89455 docs(docs-infra): fix visible lines/regions
fixes #65552

(cherry picked from commit 1c3868198e)
2025-11-26 13:43:40 -05:00
Matthieu Riegler 1260d1ac6d refactor(devtools): Use the same error message as the signal custom formatter for signal errors
When signals throw errors on read, the devtools will show the same error message as the signal custom formatter.
We also don't log errors anymore to the console as those might be surprising to see as errors and are buggy behavior of the devtools.

(cherry picked from commit a0930e166c)
2025-11-26 13:11:10 -05:00
Matthieu Riegler 151616dd7c refactor(core): show error message on signal error
When a signal throws an error on read. The formatter will show the error message.

(cherry picked from commit 5b720aa2eb)
2025-11-26 13:11:10 -05:00
Leon Senft 0ae14cb746 test(core): test bundling of dynamic component creation and bindings
Add test coverage for bundling dynamic component creation API like
`createComponent()` and `inputBinding()`. This will be used to test that
Signal Forms related features for #64632 can be tree-shaken when unused.

(cherry picked from commit add8c41e5b)
2025-11-26 11:57:18 -05:00
SkyZeroZx 10201b6873 docs(docs-infra): renders inline code snippets in docs pills
Improves the rendering of `DocsPillRow` to correctly display inline code snippets (using backticks) within the pill labels.

(cherry picked from commit ef034c15c1)
2025-11-25 18:30:09 -05:00
kirjs 47a739611a release: cut the v21.0.1 release 2025-11-25 15:04:58 -05:00
Alan Agius 3240d856d9 fix(http): prevent XSRF token leakage to protocol-relative URLs
The XSRF interceptor previously failed to detect protocol-relative URLs (starting with `//`) as absolute URLs. This allowed requests to such URLs to include the XSRF token, potentially leaking it to external domains.

This change updates the interceptor to correctly identify protocol-relative URLs as absolute and exclude them from receiving the XSRF token.

(cherry picked from commit 40790ef980)
2025-11-25 13:47:29 -05:00
Alan Agius 908b5a41a3 refactor: replace getDocument() with inject(DOCUMENT)
This replaces `getDocument()` with `inject(DOCUMENT)` across hydration and transfer state logic.

(cherry picked from commit 400fc82c43)
2025-11-25 13:05:01 -05:00
Kristiyan Kostadinov 6b20adff62 refactor: add mark for signal forms
Adds a mark for signal forms so we can track adoption. Also moves the call for `@let` into `declareLet` since we don't need it to fire as often as in `storeLet`.

(cherry picked from commit c994267f17)
2025-11-25 13:03:46 -05:00
Alan Agius 49ad7c6508 fix(core): use injected DOCUMENT for CSP_NONCE
This ensures that the right document is used and that `CSP_NONCE` can be used in `provideAppInitializer` and `provideEnvironmentInitializer`.

Closes #65624

(cherry picked from commit 3b1fa8235b)
2025-11-25 11:39:23 -05:00
AntonChesnokov 8d3a89a477 fix(compiler-cli): escape angular control flow in jsdoc
Escape @-prefixed template control flow constructs during doc extraction so JSDoc parsing keeps description text intact. Add regression coverage for @for snippets.

(cherry picked from commit 5bfa027d41)
2025-11-25 11:33:29 -05:00
Angelo Parziale 4634b467c2 docs(docs-infra): Fix anchor link DI
Fix anchor link for Dependency Injection Overview.

(cherry picked from commit 346caefa8d)
2025-11-25 11:05:45 -05:00
kirjs e3f5f34732 refactor(forms): Make reset take value
Now you can do form.reset({name: 'cat', age: 4});

(cherry picked from commit dec222d4d7)
2025-11-25 10:51:38 -05:00
Angular Robot 9aa3e92c82 build: lock file maintenance
See associated pull request for more information.
2025-11-25 10:34:12 -05:00
Miles Malerba 7d5c7cf99a feat(forms): add DI option for classes on Field directive
Adds a DI configuration option for signal forms that allows the
developer to specify CSS classes that should be automatically added
by the `Field` directive based on the field's status.

(cherry picked from commit c70e246c23)
2025-11-25 10:33:41 -05:00
SkyZeroZx 477df38d17 docs: improve core package API documentation with additional reference links
(cherry picked from commit 67d41e9bcc)
2025-11-25 10:19:39 -05:00
Cheng-Hsuan Tsai 69d6f8fe2c docs: replace aria grid overview example
(cherry picked from commit 56e059948f)
2025-11-25 10:17:00 -05:00
Leon Senft 8acf5d2756 fix(forms): allow dynamic type bindings on signal form controls
The type checker will no longer prohibit binding the Signal Forms `[field]`
directive to an input with a dynamic `[attr.type]` or `[type]` binding.

(cherry picked from commit 3a1eb07c46)
2025-11-25 09:16:01 -05:00
Oyama Michinoku c9f50b424b docs: fix typo by correcting W3 to W3C
(cherry picked from commit 2102bfe5aa)
2025-11-25 09:14:03 -05:00
Hussein Mahmoud Kandil d5b339c1a3 docs: fix example imports and missing event URL reference
The analytics tracking example contained unused and missing imports,
and it incorrectly referenced the page's URL.
This update fixes the imports and ensures the handler uses `event.url`,
allowing the example to work correctly.

(cherry picked from commit a294e3b94d)
2025-11-25 07:44:08 -05:00
Andrew Scott 0e458c7e12 refactor(core): Remove toggles used for zoneless by default migration
this migration is complete both internally and externally

(cherry picked from commit 51ebe9a4fc)
2025-11-24 16:57:52 -05:00
Kristiyan Kostadinov 70507b8c1c fix(core): debug data causing memory leak for root effects
We track all effects that are created for debugging purposes in the `resolverToEffects` map. This ends up leaking memory for effects registered on long-living resolvers (e.g. on the root injector), because they stay in the array, even if the effect itself has been destroyed.

These changes add a callback to clean up the references.

Fixes #65265.

(cherry picked from commit ca6ab6c914)
2025-11-24 15:26:12 -05:00
Leon Senft 4845a33018 refactor(forms): support custom control directives
Support binding `[field]` to directives that implement
`FormValueControl` or `FormCheckboxControl`.

The `[field]` binds to whichever directive (or component) matches first in the
event there are multiple implementations. We are considering whether to make
this an error state, which could be reported during type checking.

Closes #63910, Closes #64992

(cherry picked from commit f97a1d4856)
2025-11-24 13:48:20 -05:00
Ben Hong 534cc3dc37 docs: standardize aria code examples to not use component suffix
(cherry picked from commit d442c72f87)
2025-11-24 13:28:36 -05:00
Matthieu Riegler 6cb191bade docs: add callout on zone base testing helpers
With zoneless being the default, we need to make these requirements more explicit.

fixes #65539

(cherry picked from commit b34e48bdff)
2025-11-24 13:27:49 -05:00
Joey Perrott 0424a998c9 refactor(docs-infra): make docs-alert an inline token
Migrate docs-alert to be inline instead of block, this ensures that the content is placed within a <p> tag as expected. This is important
for ensuring that the iconography is placed correctly within the wrapper div generated for the alert. Additionally, we refactor the matcher
code to be more efficient, running with fewer loops.

(cherry picked from commit 046501fd33)
2025-11-24 13:26:03 -05:00
Matthieu Riegler 9b0900f0e9 ci: update pullapprove reviewers
Removing Minko from the pool of automatically picked reviewers

(cherry picked from commit 98ceb0a80d)
2025-11-24 13:25:30 -05:00
SkyZeroZx a62162d2ee docs: Update router docs to add references and components input fixed syntaxis
(cherry picked from commit 2ac826867b)
2025-11-24 13:18:31 -05:00
Alessio Pelliccione 9d6b86958a docs(docs-infra): fix missing syntax highlighting
closed angular#65565

(cherry picked from commit 7d20f2071c)
2025-11-24 13:13:25 -05:00
Shuaib Hasan Akib b513008fc8 refactor(common): remove redundant standalone: true as it is default now
-removing `standalone: true` from integration
- removed whitespace

(cherry picked from commit 93cff501e9)
2025-11-24 13:12:18 -05:00
Kristiyan Kostadinov 39c577bc36 fix(compiler-cli): do not type check native controls with ControlValueAccessor
Currently when we detect a `field` binding on a native element, we treat it as a built-in native control. This might not be the case if it's a pre-existing `ControlValueAccessor` relying on the CVA interop.

These changes try to detect any CVA-like directive on the element and disable the additional type checking if there are any.

Fixes #65468.

(cherry picked from commit 6b8720de91)
2025-11-24 13:08:46 -05:00
Kristiyan Kostadinov f0b34854cc refactor(compiler-cli): track public methods during analysis
Updates the directive analysis to track the public methods of the class.

(cherry picked from commit 5cfdd7897b)
2025-11-24 13:08:46 -05:00
Tomer953 f394215b14 fix(migrations): detect structural ngTemplateOutlet and ngComponentOutlet
the common-to-standalone migration only matched [ngTemplateOutlet] and
[ngComponentOutlet] bindings and missed their structural forms
(*ngTemplateOutlet and *ngComponentOutlet). This caused missing imports
when removing CommonModule. This change adds structural directive
patterns so the migration correctly identifies needed imports.

(cherry picked from commit a4f50bdd54)
2025-11-24 12:41:01 -05:00
Shuaib Hasan Akib 70bc3115c5 docs(docs-infra): keep 'Show code' button aligned right and prevent metadata wrapping
Ensures the example viewer header displays correctly by keeping the "Show code"
button aligned to the right and preventing metadata text from wrapping.
Improves layout consistency across documentation examples.

(cherry picked from commit b26fe73a91)
2025-11-24 12:23:40 -05:00
Matthieu Riegler f73cfd5a92 ci: adding myself as optional to the compiler scope
For whenever I feel confortable approving compiler PRs like diagnostics

(cherry picked from commit 9dd7cc13ca)
2025-11-24 12:18:30 -05:00
Alan Agius 6d4e68977f build: update release script to support changelog cherry-picking
This commit updates the release script to support cherry-picking changelog updates to the main branch when releasing from a patch branch. It also introduces a marker in the changelog to separate releases and ensures the GitHub release uses the formatted changelog from disk.

(cherry picked from commit c843a46912)
2025-11-24 12:17:23 -05:00
hawkgs 98520333bd refactor(compiler-cli): add a resource debugName transform (#64172)
Add a TS transform for `resource` (and `httpResource`) `debugName`. Test the transformations.

PR Close #64172
2025-11-24 11:30:13 -05:00
hawkgs 6de8926594 refactor(core): add debug name to resource (#64172)
Decorate `resource` (and `httpResource`) with `debugName`, along with all of its internal signals.

PR Close #64172
2025-11-24 11:30:13 -05:00
Matthieu Riegler 102cb872c7 docs: update devtools guide
- splits the injector inspector into its own guide
- update the screenshots
- add defer block section
- add hydration section

(cherry picked from commit b5ae62c02b)
2025-11-24 11:11:30 -05:00
NicoPolazzi 2739ae4b9d docs: correct signals tutorial inconsistencies in chapters 6-10
(cherry picked from commit 325ab18084)
2025-11-24 11:08:31 -05:00
Shuaib Hasan Akib 4303f5153c docs: html examples and replace <docs-code> with fenced code blocks
Replaced <docs-code language="html" with fenced html for improved readability and consistency across documentation.

(cherry picked from commit 0203dad09b)
2025-11-24 10:38:35 -05:00
Matthieu Riegler 1f20b54256 docs(docs-infra): simplify tab selection
Tab selection relied on the tabs being visible whe nthe example is loaded. That didn't work when `hideCode` was used.

fixes #65550

(cherry picked from commit 119c6ddaeb)
2025-11-24 10:24:42 -05:00
HyperLife1119 2ebe685298 docs: fix order of render phases in lifecycle documentation
(cherry picked from commit b6b6fae483)
2025-11-24 10:22:32 -05:00
Shuaib Hasan Akib cdfc782770 docs: fix internal links showing as external
Replace absolute URLs (https://angular.dev/...) with relative URLs
(/...) to prevent internal documentation links from being treated
as external links and opening in new tabs.

(cherry picked from commit 8f89507a0b)
2025-11-24 10:21:42 -05:00
Kristiyan Kostadinov 290513f5b6 test: remove unnecessary test calls
Removes calls to `TestBed.configureTestingModule` since they aren't necessary.

(cherry picked from commit 26e2092dd1)
2025-11-24 10:18:21 -05:00
Shuaib Hasan Akib d3c3b83f8b fix(docs-infra): update deprecated API link to use correct status value
Replaced `status=deprecated` with the correct numeric value `status=8`
to ensure the Deprecated APIs link resolves properly in the docs.

(cherry picked from commit 16a0b7dfdb)
2025-11-24 10:17:35 -05:00
Yahya-Almubarak 730803ad26 docs: fix typo in tutorial
(cherry picked from commit e501b7e445)
2025-11-24 10:15:05 -05:00
Alan Agius 2d658b3662 build: run e2e in sandbox
Updates the E2E test configuration to run within the Bazel sandbox.

(cherry picked from commit f7f9707508)
2025-11-24 10:03:03 -05:00
Angular Robot c7ae6f3fee build: update all github actions
See associated pull request for more information.
2025-11-24 09:34:02 -05:00
Alan Agius 4eb2d3ea2c docs: update ng serve builder to @angular/build:dev-server and detail proxy path matching behavior.
Closes #53652

(cherry picked from commit b28570b227)
2025-11-24 09:33:27 -05:00
Angular Robot de46b2429f build: update pnpm to v10.23.0
See associated pull request for more information.
2025-11-24 09:30:40 -05:00
Matthieu Riegler 92f0b6687d docs: fix v21 event header image
fixes #65572

(cherry picked from commit 48a05dd38c)
2025-11-24 09:08:22 -05:00
Hussein Mahmoud Kandil 696aaa11e9 docs: fix router event subscription in error handler example
The example incorrectly persisted the error message after a successful
navigation retry because the stream only emitted NavigationError events.
This update removes the filter and returns an empty string for non-error
events, allowing the signal to clear the message on normal navigation.

(cherry picked from commit 72b1f7fd43)
2025-11-22 09:10:57 -05:00
SkyZeroZx a70a191713 docs: Adds signal type checking documentation
(cherry picked from commit 38a354ffa2)
2025-11-21 16:31:16 -05:00
Matthieu Riegler 0ea1e07174 fix(core): apply bootstrap-options migration to platformBrowserDynamic
The migration wasn't applied to projects relying on `platformBrowserDynamic()` prior to this fix.

(cherry picked from commit b6fee3f107)
2025-11-21 16:28:23 -05:00
Shuaib Hasan Akib 5170fd4c05 docs: format JSON examples and replace <docs-code> with fenced code blocks
Replaced <docs-code language="json" for improved
readability and consistency across documentation.

(cherry picked from commit f884c181b3)
2025-11-21 16:23:55 -05:00
Shuaib Hasan Akib b8da1d4fdb docs: format JSON examples and replace <docs-code> with fenced code blocks
Replaced <docs-code language="json" header=".postcssrc.json"> with fenced
JSON code blocks using ```json {header: '.postcssrc.json'} for improved
readability and consistency across documentation.

(cherry picked from commit 68aa83e8cf)
2025-11-21 15:48:45 -05:00
Matthieu Riegler 16babdd74c refactor(devtools): don't query defer nodes
This prevents from throwing errors when selecting defer nodes

(cherry picked from commit 67d3c2529f)
2025-11-21 15:42:57 -05:00
cexbrayat df1d129d0b docs: consistent casing for onpush zoneless migration MCP tool name
The tool has been renamed in the CLI for consistency https://github.com/angular/angular-cli/pull/31866

(cherry picked from commit 88546ab127)
2025-11-21 13:26:02 -05:00
SkyZeroZx 93ef5d410e feat(docs-infra): add docs-image extension for enhanced image handling in markdown
Extends the Markdown parser to support `loading`, `decoding`, and `fetchpriority` attributes for images via curly brace syntax.

(cherry picked from commit 46269be842)
2025-11-21 13:25:02 -05:00
Shuaib Hasan Akib 0331b1f766 docs: format example code blocks for consistency and readability
(cherry picked from commit 6f1329f34a)
2025-11-21 13:24:26 -05:00
Joey Perrott d40770fd94 refactor(docs-infra): remove the multiple code example view modes
Rather than using multiple view modes for code examples, we can just treat the previous snippet mode as
as multifile mode that just only has one file in it.

(cherry picked from commit f61e61ac4f)
2025-11-21 13:22:03 -05:00
Joey Perrott a30fe81ae8 refactor(docs-infra): improve code efficiency for adding line numbers
Only run the code for adding line numbers if line numbers are required, otherwise skip the code block

(cherry picked from commit 88753d6a5a)
2025-11-21 13:20:49 -05:00
Joey Perrott 557cc41ff0 refactor(docs-infra): remove the unnecessary whitespace using shiki
Use a transformer within shiki to remove the unnecessary whitespace between code lines

(cherry picked from commit a873c4eb1a)
2025-11-21 13:20:49 -05:00
Joey Perrott 121997b8c2 refactor(docs-infra): drop support for providing a file diff in docs-code
Drop support for exposing a diff view in the docs-code element as it is unused and costly to even check for

(cherry picked from commit 8ec0a4ee5c)
2025-11-21 13:20:49 -05:00
Joey Perrott 7f7a2187a8 refactor(docs-infra): use shiki for highlighting
Use shiki to perform highlighting instead of a postprocessing action

(cherry picked from commit fee79e37d5)
2025-11-21 13:20:49 -05:00
Joey Perrott 70195636cc fix(docs-infra): link to the snippet location at the proper commit for examples
Within examples, we now link to the github URL using the commit that was made to create adev, rather than
always on main, which may change over time.

(cherry picked from commit a8f46e598a)
2025-11-21 13:19:55 -05:00
Shuaib Hasan Akib 133baadea1 docs: format example code blocks for consistency and readability and keep only file name in header
(cherry picked from commit 9565938534)
2025-11-21 13:17:20 -05:00
Shuaib Hasan Akib 0e13b4713c docs: clarify strictInputAccessModifiers applies to both input types
Update the strictInputAccessModifiers documentation to clarify that:
- The flag applies to both @Input() decorator and input() signal-based inputs
- The checking only applies to inputs, not outputs
- format interface with fenced block

Fixes docs part of #65243

(cherry picked from commit 34fa11ec9d)
2025-11-21 13:16:12 -05:00
SkyZeroZx 6b6af053f9 docs(docs-infra): update syntax highlighting for inline templates in decorators
Updates syntax highlighting rules to properly handle inline templates defined within decorators, improving readability and consistency in code examples

(cherry picked from commit 1672493d1a)
2025-11-21 13:14:57 -05:00
Shuaib Hasan Akib 444be37b41 docs: Indented the <docs-code> blocks inside numbered list items to ensure correct Markdown rendering and prevent the steps from breaking visually.
- Remove path from header

(cherry picked from commit aafc8e75a1)
2025-11-21 13:14:13 -05:00
Ben Hong 1dfce39775 docs: move aria tabs into content organization category
(cherry picked from commit 8f346ad070)
2025-11-21 12:25:39 -05:00
voi99 9d82c86811 docs(forms): update error class to error-list in signal forms example
(cherry picked from commit 5685e3879c)
2025-11-21 12:23:52 -05:00
Shuaib Hasan Akib 11df3d6ca8 docs: remove unnecessary standalone: true from examples
Standalone components are now the default, so explicitly specifying
`standalone: true` is no longer required. Updated relevant documentation
examples to avoid redundant configuration and keep the guides concise.

(cherry picked from commit f825547353)
2025-11-21 12:23:30 -05:00
Alan Agius 36c967e0ef build: automate GitHub release creation for vscode extension
Update the release script to automatically create a GitHub release and upload the VSIX asset.

Example release: https://github.com/angular/angular/releases/tag/vsix-21.0.0

(cherry picked from commit 74405c7e7a)
2025-11-21 12:22:22 -05:00
Angular Robot 77f059910e build: update bazel dependencies
See associated pull request for more information.
2025-11-21 12:21:20 -05:00
Syam Gadde bc34083d34 fix(compiler-cli): ignore non-existent files
Ignore files that fail fs.exists() rather than throw ENOENT.  Some applications deliberately create "broken" symbolic links that are not relevant to compilation (e.g. emacs lock files that link to owner "user@host").

(cherry picked from commit 1628125bcb)
2025-11-21 11:39:01 -05:00
Shuaib Hasan Akib 1cdcd5a947 docs: fix incorrect Signal Forms link
Updated outdated link guide/forms/signal-forms/ to the correct path guide/forms/signals/ to ensure proper navigation.

Fixes: #65461 #65462
(cherry picked from commit 68f5ceeb46)
2025-11-21 10:55:55 -05:00
Ben Hong 053bf98f57 docs: iterate on signal forms essentials guide
(cherry picked from commit b7d91a796b)
2025-11-21 10:48:04 -05:00
Shuaib Hasan Akib 2f44ede102 docs: add missing ARIA patterns and API reference
Adds the missing ARIA usage patterns and links to the relevant API reference
sections to improve accessibility guidance and ensure examples follow recommended
best practices.

(cherry picked from commit cea19803d8)
2025-11-21 10:18:39 -05:00
Alessio Pelliccione 1925721226 refactor(docs-infra): automate algolia index name based on package version
Previously, the Algolia index name was hardcoded in the configuration, requiring manual updates for every new major release branch.

This commit automates the index name selection by deriving the version directly @angular/core. It dynamically assigns:
- `angular_next_dev` for pre-releases (`-next`, `-rc`) and local snapshots (`0.0.0`).
- `angular_vXX` (e.g., `angular_v19`) for stable releases.

(cherry picked from commit 2ddf26e699)
2025-11-20 19:21:34 -05:00
SkyZeroZx b170aa925b docs: updates code block language tags in signal forms
(cherry picked from commit 889afe9aa2)
2025-11-20 19:20:33 -05:00
Raxabi fd44d7b794 docs: Fix missing single quote in the first navigateByUrl example.
(cherry picked from commit ee57b0f2fa)
2025-11-20 19:19:46 -05:00
marktechson c0a8f0c694 docs: fix update guide typo
The update from 20 to 21 featured the wrong number, this fixes that

(cherry picked from commit c4722820e7)
2025-11-20 19:19:19 -05:00
Alan Agius 70fb1d6cf2 ci: try to resolve vscode extension e2e flakes
Update e2e test runner to VS Code 1.102.0, streamline test activation, and manage temporary directories via `TEST_TMPDIR`.

(cherry picked from commit 1a094ddb2b)
2025-11-20 17:03:18 -05:00
Doug Parker da97099e67 docs: correct v21 LTS end date and v20 active end date
Updated to align the v20 active end date with the v21 release date and fix the v21 LTS to be 1-year after the active period ends.

(cherry picked from commit 2ecdb221d3)
2025-11-20 16:47:29 -05:00
Johannes Hoppe 65c39ea324 docs(core): remove outdated regex template restriction in best-practices.md
Regular expressions in templates are now supported as of Angular 21.

(cherry picked from commit 11da7a65c0)
2025-11-20 16:42:55 -05:00
Charles Lyding b9181f1172 docs: prioritize ng add for Tailwind CSS and clarify manual steps
This commit updates the Tailwind CSS integration guide (`adev/src/content/guide/tailwind.md`) to introduce `ng add tailwindcss` as the primary, automated method for integrating Tailwind CSS.

(cherry picked from commit 396c25ef5a)
2025-11-20 15:00:28 -05:00
Angular Robot 82c085d0b6 docs: update cross-repo adev docs
Updated Angular adev cross repo docs files.
2025-11-20 14:24:05 -05:00
Devin Chasanoff 72197597b9 docs: add v21 event game
(cherry picked from commit b8fa9cc7d5)
2025-11-20 13:27:49 -05:00
Ben Hong cd86de1447 docs: consolidate patterns and iterate on conclusion for angular aria overview
(cherry picked from commit be6f2f066f)
2025-11-20 12:38:22 -05:00
Matthieu Riegler 5467cdcaff docs: backport content from main 2025-11-20 12:37:13 -05:00
JoostK d7484f0519 refactor(core): let the profiler handle asymmetric events leniently
Although the prior commit has made more profiler events guaranteed symmetric
through the use of finally-blocks, there continue to be some situations
that could potentially result in asymmetric events, e.g. application
bootstrap doesn't guarantee symmetric events. This commit makes the profiler
lenient to these situations by unrolling the stack past the asymmetric event
data, eventually reaching the expected start event.

(cherry picked from commit 913cde8ab4)
2025-11-20 12:30:02 -05:00
JoostK a55482fca3 fix(core): notify profiler events in case of errors
Profiler events are expected to be symmetric, yet in the case of errors this symmetry may break
if events aren't always kept in sync with their corresponding start event. This commit moves
various end events to be run from a finally-block, allowing them to notify the profiler even
when an error has occurred.

Fixes #62947

(cherry picked from commit 3760045e3e)
2025-11-20 12:30:02 -05:00
kirjs cc3b4ae701 docs: remove unnecessary @ts-ignore from signal forms playground
The @ts-ignore comment is no longer needed as the module resolution
issue has been fixed in the playground editor configuration.

(cherry picked from commit bea7358225)
2025-11-20 12:26:25 -05:00
marktechson eadc8deaf8 docs: add 20 to 21 update guide
(cherry picked from commit 183d194025)
2025-11-20 11:46:49 -05:00
Wagner Maciel f349a9168b docs: fix standlone menu overlay
(cherry picked from commit 29185a864f)
2025-11-20 11:20:41 -05:00
David Kingma 630a3b29d8 refactor(core): add debugName option to rxjs-interop toSignal
toSignal predates the debugName option for signals to name the signals in the Angular dev-tools This adds the debugName option to toSignal.

(cherry picked from commit 0812ac3bec)
2025-11-20 10:49:54 -05:00
Charles Lyding 2a614aa25c docs: add note about Karma/Jasmine examples in testing services guide
This guide currently contains Karma/Jasmine specific code examples.
Adding a note to inform readers that Vitest equivalents are being worked on.

(cherry picked from commit 80202bffee)
2025-11-20 10:47:37 -05:00
Alessio Pelliccione 8d6d13afd2 fix(docs-infra): prevent icons from being translated in aria guide
This commit adds the `translate="no"` attribute to the icon elements to ensure they are preserved in their original form and not modified by translation tools.

Closes #65406

(cherry picked from commit 42c05650ff)
2025-11-20 10:47:15 -05:00
Ben Hong cf7579f506 docs: add signal forms custom controls guide
Co-authored-by: Leon Senft <leonsenft@users.noreply.github.com>

docs: add signal forms custom controls guide
(cherry picked from commit fc2e414262)
2025-11-20 10:35:01 -05:00
marktechson f31fbdd0b9 docs: adds a link to the signal forms example
(cherry picked from commit 890414245f)
2025-11-20 00:41:05 +00:00
Charles 88559649bb docs: separate Zone.js-specific testing utilities into new guide
This commit moves documentation for Zone.js-dependent testing utilities
(`waitForAsync`, `fakeAsync`, `tick`, `discardPeriodicTasks`, `flushMicrotasks`)
from `testing/utility-apis.md` to a new dedicated guide:
`testing/zone-js-testing-utilities.md`.

(cherry picked from commit e77fb1fb14)
2025-11-20 00:40:38 +00:00
tsc036 2bf0c52775 refactor(core): export profile event as enum and move profile_types.ts and framework to shared devtools folder
move framework enum and profile_types to a shared folder so it can be used by wiz

(cherry picked from commit 34e1fe235f)
2025-11-19 23:22:53 +00:00
Ben Hong dff1233cc1 docs: add signal forms validation guide 2025-11-19 15:18:16 -08:00
Angular Robot e0026c870a build: update cross-repo angular dependencies
See associated pull request for more information.
2025-11-19 15:08:39 -08:00
Joey Perrott 6ead2ce995 build: fix lockfile
Fix the missing lockfile entries
2025-11-19 15:08:06 -08:00
Ben Hong ac54791140 docs: add redirect for angular overview
(cherry picked from commit 4771dc9cf7)
2025-11-19 22:52:42 +00:00
SkyZeroZx cb15142190 docs: Adds documentation for generic type argument to SimpleChanges
(cherry picked from commit e9ba63a4c1)
2025-11-19 22:31:57 +00:00
Joey Perrott a877e8abaa build: update to latest ng-dev tooling for caretaker handoff update
Update to the latest tooling to upate how caretaker handoff is handled, using new standardized groupings

(cherry picked from commit 0bb09dc5ba)
2025-11-19 22:30:20 +00:00
Shuaib Hasan Akib 35dc3ecfda refactor(common): update examples to align with Angular best practices
Updated examples to use the standalone component approach and the latest

(cherry picked from commit c7affdfbc9)
2025-11-19 22:29:53 +00:00
Kristiyan Kostadinov cc1ec09931 perf(core): avoid repeat searches for field directive
The `getControlDirective` is called multiple times, both at init and during each update run. Under the hood it performs a linear search for the `Field` directive.

We can speed this up by finding its index once and reusing it since the array of directive matches is static.

(cherry picked from commit 5e6d8573f4)
2025-11-19 22:28:59 +00:00
Kristiyan Kostadinov 279824c953 refactor(compiler): remove interpolation-related symbols
We removed the ability to customize the interpolation some time ago. These changes remove the remaining code related to them.

(cherry picked from commit 81ce1ba1d9)
2025-11-19 22:28:23 +00:00
Kristiyan Kostadinov 00531864e0 refactor(compiler): remove container blocks config
Removes the ability to specify container blocks when creating an i18n parser. We were only passing in `switch` and it likely won't change.

(cherry picked from commit b6c141bf8b)
2025-11-19 22:28:23 +00:00
Miles Malerba de5fca94c5 fix(forms): run reset as untracked
Run the signal forms `reset()` as untracked so it does not trigger
`effect` to rerun when the model changes

Fixes https://github.com/angular/angular/issues/65322

(cherry picked from commit 7ddf4a6b07)
2025-11-19 22:27:55 +00:00
Alan Agius 47fc721202 refactor: improve release process instructions and vsce login handling
This commit introduces several improvements to the release process:

- Adds a clear warning and instructions to test the extension before merging the release PR
- Removes the explicit `vsce login` command.

(cherry picked from commit 22ad71d752)
2025-11-19 22:22:48 +00:00
Cheng-Hsuan Tsai d9017a4fcc docs: update aria overview page
(cherry picked from commit d2fe8674f1)
2025-11-19 22:11:23 +00:00
Alessio Pelliccione 404e90dd29 docs: add style binding example to style guide
Adds a parallel example for style bindings alongside the existing class binding example, demonstrating the preferred syntax of [style.property] and [style] over [ngStyle] directive.

(cherry picked from commit 7e5fca2608)
2025-11-19 22:09:50 +00:00
Alan Agius 2a38387466 docs: add release document
Adds the initial documentation for the VSCode Angular Language Service release.
2025-11-19 14:08:36 -08:00
Alan Agius f88e950f65 build: add vsce script
Adds a "vsce" script to package.json to facilitate easier VSCE packaging.
2025-11-19 14:08:36 -08:00
Joey Perrott 22f23ee7bc docs: add version 21 to update guide page
(cherry picked from commit 2013261243)
2025-11-19 22:08:10 +00:00
Georgi Serev df37a30924 docs(docs-infra): fix code editor file creation and renaming
Hide the field when the user unfocuses from it; Fill the input with the file name when renaming; Fix file path renaming

(cherry picked from commit 0a33a18fa4)
2025-11-19 22:07:34 +00:00
Ben Hong 1c1b50f180 docs: add signal forms field state management guide
(cherry picked from commit 2ead438634)
2025-11-19 22:07:06 +00:00
Ben Hong 563e505df0 docs: improve instruction for import in signal forms tutorial
(cherry picked from commit fb32a5bafa)
2025-11-19 22:06:16 +00:00
Ben Hong 9e16f0363f docs: add signal forms tutorial
(cherry picked from commit d352484773)
2025-11-19 22:06:15 +00:00
Angular Robot 480e8cfb8c docs: update cross-repo adev docs
Updated Angular adev cross repo docs files.
2025-11-19 14:05:01 -08:00
Devin Chasanoff 4e14a53ab6 docs: add release blog to v21 page
(cherry picked from commit c2317949a8)
2025-11-19 21:34:44 +00:00
Joey Perrott bcab911846 docs: link to v21 blog post in changelog
(cherry picked from commit 1b4d1f88dc)
2025-11-19 21:34:18 +00:00
Jessica Janiuk 685477632f build: bump core zone.js version
this bumps the core dep on zone.js to 0.16.0.

(cherry picked from commit 11ea1a01ff)
2025-11-19 21:22:17 +00:00
Joey Perrott 3d9c82c21d build: provide a specific version of zone.js for the vscode pre standalone test
Use zone.js 0.15.0 specifically instead of moving to a later verison of zone.js for the test

(cherry picked from commit c03883ec54)
2025-11-19 21:07:46 +00:00
Jessica Janiuk 28810e0914 build: bump adev version
Bump adev versions for v21 release

(cherry picked from commit d42d7523ec)
2025-11-19 20:09:29 +00:00
Joey Perrott fe5c9a1e6a release: bump version of in memory web api
(cherry picked from commit 9a663a28f9)
2025-11-19 20:05:54 +00:00
Jessica Janiuk 63a95c7b9e release: cut the v21.0.0 release 2025-11-19 10:07:09 -08:00
Joey Perrott 8b492ce06e docs: update the actively supported versions
Update the actively supported versions table

(cherry picked from commit a51ba9c7a9)
2025-11-19 16:47:51 +00:00
Wagner Maciel f06c1fb834 docs: fix menubar overlay bug
(cherry picked from commit 3e31a9967e)
2025-11-19 16:45:40 +00:00
kirjs ac34824608 fix(docs-infra): add moduleResolution to TypeScript compiler options for playground
This fixes signal forms, but idk if it breas other things

(cherry picked from commit 040af1aaa1)
2025-11-19 16:26:24 +00:00
Cheng-Hsuan Tsai e69855ad13 docs: aria grid replace overview example with a playful one
(cherry picked from commit 1289371474)
2025-11-19 16:18:59 +00:00
Joey Perrott 17b7d56ae9 build: force angular cli to run in non-TTY mode for adev and devapp
Force adev and devapp to run in non-TTY mode so it doesn't create a prompt that can't be interacted with. This will initially have no effect,
but the fix is expected to land in CLI to make this work as expected in the next few days.
2025-11-19 08:14:19 -08:00
Angular Robot 12193b1e36 build: update all github actions
See associated pull request for more information.
2025-11-19 08:13:48 -08:00
Ben Hong 27ef566b98 docs: update aria component api links
(cherry picked from commit d3ea7cbcc9)
2025-11-19 16:12:55 +00:00
Angular Robot 1017cf3b92 build: update bazel dependencies
See associated pull request for more information.
2025-11-19 08:10:35 -08:00
Aristeidis Bampakos 4598ca3766 fix(docs-infra): add install in pnpm
Add missing install option in pnpm command.

(cherry picked from commit 0e1ddce1cb)
2025-11-19 16:10:14 +00:00
Ben Hong 21c126e743 docs: remove redundant labels on aria since section is marked new
(cherry picked from commit 758cd113b3)
2025-11-19 16:08:30 +00:00
Ben Hong ccb0264edb docs: add signal forms playground template
(cherry picked from commit e0eb619c03)
2025-11-19 16:03:57 +00:00
Devin Chasanoff c2c0140532 docs: add v21 banner
(cherry picked from commit 3810422521)
2025-11-19 16:02:18 +00:00
Ben Hong 28c1a2dc72 docs: add signal forms comparison guide
(cherry picked from commit 7a910e66d4)
2025-11-19 01:01:42 +00:00
Matthieu Riegler 36784d70c0 docs: fix docs heading alignment
(cherry picked from commit c7424c8f07)
2025-11-19 01:00:29 +00:00
Ben Hong 012326e914 docs: update angular aria guides structure, subnav menu, and examples
(cherry picked from commit 47eb77ffb1)
2025-11-18 15:29:51 -08:00
Angular Robot 77fc03ffb6 build: update cross-repo angular dependencies
See associated pull request for more information.
2025-11-18 15:29:10 -08:00
Wagner Maciel 21e288963c docs: aria combobox examples
(cherry picked from commit 114c83ed8b)
2025-11-18 14:55:59 -08:00
Wagner Maciel d285ba27a6 docs: aria menubar examples
(cherry picked from commit 695f4df912)
2025-11-18 14:55:59 -08:00
Wagner Maciel dce20b9289 docs: aria menu examples
(cherry picked from commit 1963bd67cc)
2025-11-18 14:55:59 -08:00
Wagner Maciel 903cb23df9 docs: aria tabs examples
(cherry picked from commit 04859b41a2)
2025-11-18 14:55:59 -08:00
Wagner Maciel 363bcb311c docs: aria autocomplete examples
(cherry picked from commit b2080c8fb0)
2025-11-18 14:55:58 -08:00
Andrew Seguin 1355edde69 docs: hide temporary prerender tabs and multifile docs sections
(cherry picked from commit d4595791d6)
2025-11-18 14:54:52 -08:00
Amy Sorto e08a8e2678 docs: update overview page
(cherry picked from commit 111a7644ef)
2025-11-18 14:54:13 -08:00
Shuaib Hasan Akib 73e9700788 docs: format examples with replacing <docs-code> typescript examples with fenced ts code blocks
Update adev/src/content/reference/migrations/cleanup-unused-imports.md

Co-authored-by: Alan Agius <alan.agius4@gmail.com>

Update adev/src/content/reference/extended-diagnostics/NG8102.md

Co-authored-by: Alan Agius <alan.agius4@gmail.com>

Update adev/src/content/reference/extended-diagnostics/NG8103.md

Co-authored-by: Alan Agius <alan.agius4@gmail.com>

Update adev/src/content/reference/extended-diagnostics/NG8103.md

Co-authored-by: Alan Agius <alan.agius4@gmail.com>

Update adev/src/content/reference/extended-diagnostics/NG8103.md

Co-authored-by: Alan Agius <alan.agius4@gmail.com>

Update adev/src/content/reference/migrations/cleanup-unused-imports.md

Co-authored-by: Alan Agius <alan.agius4@gmail.com>

Update adev/src/content/reference/migrations/cleanup-unused-imports.md

Co-authored-by: Alan Agius <alan.agius4@gmail.com>
(cherry picked from commit 27fa993fb8)
2025-11-18 22:11:28 +00:00
Cheng-Hsuan Tsai 40875702b0 docs: add aria tree examples and disable text selection
(cherry picked from commit 24814ce43e)
2025-11-18 22:10:37 +00:00
Andrew Scott 00dcbf2eeb release: bump VSCode extension version to 21.0.0 2025-11-18 14:09:30 -08:00
Angular Robot e43b4dafbf build: update cross-repo angular dependencies
See associated pull request for more information.
2025-11-18 11:17:30 -08:00
Cheng-Hsuan Tsai 646d3a0df5 docs: add aria grid examples
(cherry picked from commit d0877a524a)
2025-11-18 19:14:58 +00:00
Cheng-Hsuan Tsai ff6e9c0b7b docs: add aria accordion examples
(cherry picked from commit c639f84347)
2025-11-18 19:14:30 +00:00
Cheng-Hsuan Tsai afc25d1f70 docs: add aria tree examples
(cherry picked from commit 41e9c7b4bf)
2025-11-18 19:13:55 +00:00
Nicolò Polazzi fdb8671493 docs: correct inconsistencies in signals tutorial
(cherry picked from commit 661a554b8d)
2025-11-18 19:11:29 +00:00
Angular Robot 56ba2c8344 build: lock file maintenance
See associated pull request for more information.
2025-11-18 08:17:14 -08:00
Shuaib Hasan Akib ab119a8bad docs: simplify docs-code header by removing paths and keeping only file name and info
(cherry picked from commit 374c36d810)
2025-11-18 16:15:46 +00:00
Shuaib Hasan Akib 6c3840b620 docs: replace legacy <docs-code> with fenced code blocks with highlight metadata
Replaced older <docs-code> components (e.g.
<docs-code language="ts" highlight="3">…</docs-code>)
with modern fenced code blocks using {highlight:[3]} metadata

(cherry picked from commit 0182939d5e)
2025-11-18 16:15:05 +00:00
Devin Chasanoff bc1eb6932f docs: add AI tutor instructions
(cherry picked from commit 631035a2e0)
2025-11-18 16:14:37 +00:00
Angular Robot 1b43bfbbab build: update cross-repo angular dependencies
See associated pull request for more information.
2025-11-17 16:35:53 -08:00
Angular Robot 9400afa5ba build: update cross-repo angular dependencies to v21.0.0-rc.3
See associated pull request for more information.
2025-11-17 15:20:16 -08:00
SkyZeroZx 97237483c7 docs: replace @HostListener with host event bindings in attribute directives
(cherry picked from commit c93d02151a)
2025-11-17 23:09:16 +00:00
ljasek cd74b94e9f docs: fix JetBrains AI Assistant MCP JSON configuration
(cherry picked from commit 6d35ab8c28)
2025-11-17 23:08:19 +00:00
hawkgs 91de09423c fix(devtools): refine when signal graph button is shown
Show the signal graph button only when a signal-graph-eligible node from the directive explorer is selected; Fix client app error when a `defer` node is selected (related)

(cherry picked from commit e7a6e31a70)
2025-11-17 22:45:05 +00:00
aparziale 5ffc906dbe docs(docs-infra): add advanced recommendations
Added recommendation in advanced section for redirectTo and canMatch will generate an error. These properties are incompatible together

fixes #65267

(cherry picked from commit c757fd6c29)
2025-11-17 22:40:13 +00:00
Alan Agius 414191e87e build: improve vscode-ng-language-service release process
This commit improves the release process for the vscode-ng-language-service by adding automated changelog generation and updating the package.json version.
2025-11-17 14:35:12 -08:00
Paul Leflon 123464a304 docs: fix markdown table in custom elements guide
(cherry picked from commit f13159f811)
2025-11-17 22:33:37 +00:00
Angelo Parziale cd7dee3fc3 refactor: convert docs-code blocks to inline TypeScript documentation
This PR converts the custom <docs-code> blocks to standard Markdown code blocks with TypeScript syntax highlighting.

(cherry picked from commit 7a2d5116f2)
2025-11-17 22:33:03 +00:00
Jessica Janiuk f279aabfb8 release: cut the v21.0.0-rc.3 release 2025-11-17 13:39:05 -08:00
Angular Robot e8f238a26c build: update cross-repo angular dependencies
See associated pull request for more information.
2025-11-17 11:47:21 -08:00
Cheng-Hsuan Tsai 5e66675bb0 docs(docs-infra): fix broken code tabs
When `<mat-tab-group>` is conditionally removed by `@if` it loses the
`<mat-tab>` projected content somehow.

(cherry picked from commit d104acb286)
2025-11-17 19:45:22 +00:00
Joey Perrott 6551b65172 docs: update examples to latest Angular
Updates the adev examples to use Angular 21.0.0-rc.2

(cherry picked from commit 7e70682f2b)
2025-11-17 19:18:01 +00:00
Joey Perrott b7e91839b6 Revert "ci: remove cache usage from pr.yml"
This reverts commit 3760feb5ec.

(cherry picked from commit 25546f6152)
2025-11-17 19:08:57 +00:00
Joey Perrott 655dacd0e4 ci: remove cache usage from ci.yml
Remove the @actions/cache usages from ci.yml

(cherry picked from commit cf07486532)
2025-11-17 19:08:57 +00:00
Angular Robot 652d719388 build: update cross-repo angular dependencies
See associated pull request for more information.
2025-11-17 10:58:30 -08:00
Angular Robot 1a7b854cfe docs: update cross-repo adev docs
Updated Angular adev cross repo docs files.
2025-11-17 10:57:39 -08:00
Wagner Maciel 7483c961b5 docs: aria listbox examples (#65273)
PR Close #65273
2025-11-17 18:39:01 +00:00
Wagner Maciel 0322f02fe5 docs: multiselect examples (#65273)
PR Close #65273
2025-11-17 18:39:00 +00:00
Wagner Maciel 92c81b862d docs: aria select skins (#65273)
docs: select examples

PR Close #65273
2025-11-17 18:39:00 +00:00
Wagner Maciel a2d6318906 docs: aria toolbar examples (#65273)
docs: aria toolbar retro example

docs: aria toolbar material example

docs: organize aria toolbar examples

docs: vertical examples

docs: final aria toolbar examples

docs: wip aria toolbar docs

PR Close #65273
2025-11-17 18:39:00 +00:00
Ben Hong 68cbcaec93 docs: add aria menubar component guide
(cherry picked from commit 9b87689558)
2025-11-17 18:38:28 +00:00
Jessica Janiuk 210f5ea5ec Revert "docs: replace legacy <docs-code> with fenced code blocks with highlight metadata"
This reverts commit c5c1689348.

(cherry picked from commit b2171c6c14)
2025-11-17 18:37:00 +00:00
Jessica Janiuk 127cadd3fc Revert "refactor(core): let the profiler handle asymmetric events leniently"
This reverts commit da9911f2b4.

(cherry picked from commit 88dfd96ec9)
2025-11-17 18:10:41 +00:00
Jessica Janiuk e430d69603 Revert "fix(core): notify profiler events in case of errors"
This reverts commit af1ba52587.

(cherry picked from commit adc2a57be0)
2025-11-17 18:10:41 +00:00
Matthew Beck ecea909bcc fix(compiler): don't choke on unbalanced parens in declaration block
Following https://github.com/angular/angular/pull/64509 we started
choking on unbalanced closing parentheses in declaration blocks,
specifically in quoted background-image urls. This was reported in
https://github.com/angular/angular/issues/65137.

This occured because we previously (and now again) traverse the entire
declaration block when selecting for :host-context() selectors to shim.
This is an oddity of how we parse styles today, and is likely something
we'd want to remove if we parsed selectors properly.

This change adds a new flag to _splitOnTopLevelCommas which allows it to
continue past unbalanced closing parentheses in the declaration block,
returning _convertColonHostContext to its previous behavior while
keeping support for the extra nesting in :host-context().

(cherry picked from commit 9e7ddcaa10)
2025-11-17 17:46:04 +00:00
Matthieu Riegler 035e07e3be refactor(core): promote the custom track profiler to stable.
We didn't get much report on the feature itself so we feel confident about promoting it to stable. In parallel we'll also land #62959 but one is not blocking the other.

fixes #64996

(cherry picked from commit c15836c8c7)
2025-11-17 17:42:35 +00:00
Matthieu Riegler 91d8d55a80 fix(forms): Set error message of a schema error.
Use the error message of the issue as the error message of the error itself.

fixes #65247

(cherry picked from commit b41a94bc85)
2025-11-17 17:41:57 +00:00
Miles Malerba 6aa4b7ea63 refactor(forms): avoid console warnings when setting NaN
It can be useful for a developer to set `NaN` as the value for a number
input, as a way to say "clear the input". However, directly setting this
value to the `.valueAsNumber` causes a console warning. This PR fixes
the console warning by just doing `.value = ''` when we would otherwise
to `.valueAsNumber = NaN`

(cherry picked from commit f47637426f)
2025-11-17 17:41:32 +00:00
Leon Senft e682f00e29 refactor(forms): reduce boilerplate needed to define custom controls
An early piece of feedback received regarding custom controls hosted on
native inputs was that they required a lot of boilerplate to bind
`FieldState` properties. Each property required an input to accept the
property, and a host binding to forward it to the native control.

(cherry picked from commit c727df5d38)
2025-11-17 17:41:02 +00:00
JoostK 780e37241f refactor(core): let the profiler handle asymmetric events leniently
Although the prior commit has made more profiler events guaranteed symmetric
through the use of finally-blocks, there continue to be some situations
that could potentially result in asymmetric events, e.g. application
bootstrap doesn't guarantee symmetric events. This commit makes the profiler
lenient to these situations by unrolling the stack past the asymmetric event
data, eventually reaching the expected start event.

(cherry picked from commit da9911f2b4)
2025-11-17 17:40:10 +00:00
JoostK 7ada2519f1 fix(core): notify profiler events in case of errors
Profiler events are expected to be symmetric, yet in the case of errors this symmetry may break
if events aren't always kept in sync with their corresponding start event. This commit moves
various end events to be run from a finally-block, allowing them to notify the profiler even
when an error has occurred.

Fixes #62947

(cherry picked from commit af1ba52587)
2025-11-17 17:40:10 +00:00
Joey Perrott cc621ea634 ci: remove cache usage from pr.yml
Remove the @actions/cache usages from pr.yml

(cherry picked from commit 3760feb5ec)
2025-11-17 17:29:52 +00:00
Cheng-Hsuan Tsai b5cd4522d9 docs(docs-infra): aria attribute typo
(cherry picked from commit 4dc226231c)
2025-11-17 17:29:29 +00:00
Cheng-Hsuan Tsai ac4a95e364 docs: add aria grid basic examples: pill list, calendar, and table
(cherry picked from commit 35d8654a02)
2025-11-17 17:29:06 +00:00
Shuaib Hasan Akib f340398141 docs: replace <docs-code> shell examples with fenced shell code blocks
Updated shell command examples to use fenced code blocks (```shell) instead of <docs-code> components, improving formatting consistency and aligning with current documentation standards.

(cherry picked from commit dff9d12bc3)
2025-11-17 17:28:43 +00:00
Cheng-Hsuan Tsai 16abc8a0d5 docs(docs-infra): set max-height to code example
(cherry picked from commit 138e65356b)
2025-11-17 17:28:19 +00:00
SkyZeroZx a7dddcca51 docs: Adds links to relevant guides for APIs in core package
(cherry picked from commit 0432e76171)
2025-11-17 16:47:40 +00:00
SkyZeroZx 697f3616b1 docs: add documentation for HostAttributeToken
(cherry picked from commit d70310896c)
2025-11-17 16:47:03 +00:00
SkyZeroZx 00ffe91c89 refactor(common): removes unused NgModuleFactory config in NgComponentOutlet
Removes the `ngComponentOutletNgModuleFactory`  in `_needToReCreateNgModuleInstance`

(cherry picked from commit 24243e34d9)
2025-11-17 16:46:12 +00:00
Alessio Pelliccione 363a0ddb8b fix(devtools): ensure external docs link opens correctly from extension popup
Adds target="_blank" and rel="noopener noreferrer" to prevent tab-nabbing and follow modern security best practices.

(cherry picked from commit 1aed9408a4)
2025-11-17 16:45:37 +00:00
Shuaib Hasan Akib 8e03261a58 docs: replace legacy <docs-code> with fenced code blocks with highlight metadata
Replaced older <docs-code> components (e.g.
<docs-code language="ts" highlight="3">…</docs-code>)
with modern fenced code blocks using {highlight:[3]} metadata

(cherry picked from commit c5c1689348)
2025-11-17 16:43:41 +00:00
Alessio Pelliccione 5308d83cbd docs(docs-infra): update ARIA binding guidance and remove outdated attr. prefix requirement
(cherry picked from commit bc03c45b60)
2025-11-17 16:43:03 +00:00
Shuaib Hasan Akib 1aaeb98411 docs: replace <docs-code> bash examples with fenced bash code blocks
Updated bash command examples to use fenced code blocks (```bash) instead of <docs-code> components, improving formatting consistency and aligning with current documentation standards.

(cherry picked from commit 7ea60052f0)
2025-11-17 16:42:27 +00:00
hawkgs 30125eeb27 fix(devtools): show profiler exec details only if there are directives
Show the execution details of a captured frame entry only if there are recorded directives.

(cherry picked from commit 68d823a241)
2025-11-17 16:39:39 +00:00
hawkgs cf0552ffa0 fix(devtools): don't round decimal vals previews in the state serializer
The actual numerical data can only be checked in the prop edit mode. This fixes that and makes the real value visible all the time.

(cherry picked from commit d6be289603)
2025-11-17 16:39:13 +00:00
Alessio Pelliccione 67c06a4c12 fix(devtools): forward Angular detection to background
Ensure the content script forwards Angular detection results to the service worker so the popup/icon reflects the page state.

(cherry picked from commit 7d41716703)
2025-11-17 16:38:23 +00:00
hawkgs 7497ad4302 refactor(devtools): increase font weight in the demo app
Increase the global font weight to `500`.

(cherry picked from commit 6fdb12357f)
2025-11-17 16:37:58 +00:00
Leon Senft d89e522a1f fix(forms): debounce updates from interop controls
* Apply any debounce rules to updates from interop controls (if configured).
* Add tests to ensure debouncing works for all control types (native, custom,
  and interop).

(cherry picked from commit b1037ec2f0)
2025-11-17 16:37:29 +00:00
Shuaib Hasan Akib 2bfd841611 docs: replace <docs-code> shell examples with fenced shell code blocks
Updated shell command examples to use fenced code blocks (```shell) instead of components, improving formatting consistency and aligning with current documentation standards.

(cherry picked from commit 576f9ba889)
2025-11-17 16:35:20 +00:00
Shuaib Hasan Akib 70736309f5 docs: improve accessibility with descriptive link and main landmark
- Replaced <a><button></button></a> with a proper <a> containing text and
  aria-label to ensure links have discernible text.

- Added main tag in home page to provide
  a consistent main landmark, improving accessibility for screen readers
  and satisfying WCAG and Lighthouse requirements.

Fixes #65181.

(cherry picked from commit ee5947db38)
2025-11-17 16:32:05 +00:00
Shuaib Hasan Akib c03b1fa8a0 fix(docs-infra): add bash language support for shell prompt rendering
Code blocks with `bash` language identifier were not rendering the `$`
prefix, while `shell` blocks did.

This ensures consistent command-line prompt rendering across both
`bash` and `shell` code blocks in the documentation.

(cherry picked from commit f462684211)
2025-11-17 16:31:31 +00:00
Shuaib Hasan Akib 5f8f007cca docs(docs-infra): simplify file headers in <docs-code> blocks
Removed redundant "src/app/" prefix from file headers (e.g.
"src/app/open-close.component.ts" → "open-close.component.ts")
to keep examples concise and avoid unnecessary path noise.

Aligns with prior cleanup patterns (similar to angular#65016).

(cherry picked from commit 073dcd7ffd)
2025-11-17 16:30:35 +00:00
SkyZeroZx 02061d4b81 docs: add documentation for DOCUMENT injection token usage in SSR
(cherry picked from commit 846d50ab23)
2025-11-17 16:28:05 +00:00
Angelo Parziale b770d39493 docs(docs-infra): add npm link documentation for library development
Add comprehensive guide for using npm link with Angular libraries, including required angular.json.

(cherry picked from commit a458a83133)
2025-11-17 16:26:02 +00:00
Angular Robot d591a64122 build: update bazel dependencies
See associated pull request for more information.
2025-11-17 08:24:23 -08:00
Aristeidis Bampakos 97c18819fa docs: use the new format for the X account
(cherry picked from commit 73295b1087)
2025-11-17 16:22:24 +00:00
Angular Robot 9adc71afef docs: update cross-repo adev docs
Updated Angular adev cross repo docs files.
2025-11-17 08:21:28 -08:00
Charles Lyding 59543d6b19 docs: add bun package manager and standardize order in testing guides
This commit updates the testing documentation to include `bun` as a package manager option in all relevant code examples.

Additionally, it standardizes the presentation of package manager commands by:
- Consistently using a multi-tab format (`<docs-code-multifile>`).
- Enforcing a consistent order: `npm`, `yarn`, `pnpm`, `bun`.

These changes improve the user experience by providing clear instructions for multiple package managers and ensuring consistency across the testing guides.

(cherry picked from commit 599b72ec5a)
2025-11-17 16:11:26 +00:00
Charles Lyding b43ed852dd docs: update testing guides for Vitest and reorder navigation
This commit updates the unit testing, code coverage, and debugging guides to align with the Vitest test runner, which is now the default for new Angular CLI projects.

Key changes include:
- **Unit Testing Overview**: Revised to focus on Vitest, including details on DOM emulation (jsdom/happy-dom), browser testing setup, and custom Vitest configuration via `runnerConfig`. A prominent note links to the Karma-to-Vitest migration guide.
- **Code Coverage**: Updated to reflect Vitest-specific prerequisites (`@vitest/coverage-v8`), command-line flags, and `angular.json` configuration for coverage reporting and threshold enforcement.
- **Debugging**: Completely rewritten to provide instructions for debugging Vitest tests in both Node.js and browser environments using the `--debug` flag.
- **Navigation Reordering**: The 'Testing' section in `sub-navigation-data.ts` has been reordered to present a more logical educational flow, starting with core concepts and progressing to advanced topics and migration.

(cherry picked from commit f5a7719373)
2025-11-17 16:11:26 +00:00
Ben Hong f62e2b599f docs: add draft aria component guides (pt 2)
(cherry picked from commit c61a195391)
2025-11-17 16:09:14 +00:00
portneon 7928ff1637 docs(router): update navigation event example to use event.code
(cherry picked from commit 93d548fba4)
2025-11-17 16:08:33 +00:00
Cheng-Hsuan Tsai 7020ef6c60 docs(docs-infra): make show code button more discoverable when collapsed
(cherry picked from commit 48cff8c128)
2025-11-17 16:07:06 +00:00
hawkgs 97a6f9fd4f docs(docs-infra): fix misaligned tutorials card
Fix the "Deferrable views" illustration which fixes the aligned within the `docs-card`.

(cherry picked from commit 6bfe107404)
2025-11-17 16:06:37 +00:00
Kristiyan Kostadinov 7ec9f357f4 fix(docs-infra): prevent example resets from affecting CDK
The example viewer has some `::ng-deep` styles that are used to reset global styles that leak into the live examples. It works by applying a style like `.docs-example-viewer-preview * {all: revert;}`.

The problem with this is that depending on when the first example is rendered, the styles will be lower or higher in the cascade, thus making the reset unreliable. Furthermore, it can affect structural styles from the CDK which intentionally have low specificity.

These changes move the resets into the global stylesheet to make them more predictable.

(cherry picked from commit 1ba50caefc)
2025-11-17 16:05:15 +00:00
Angular Robot 63ca0de1ec build: update dependency bazel to v7.7.1
See associated pull request for more information.
2025-11-17 08:01:00 -08:00
Shuaib Hasan Akib d365024444 docs(docs-infra): simplify file headers in <docs-code> blocks
Removed redundant "src/app/" prefix from file headers (e.g.,
"src/app/open-close.component.ts" → "open-close.component.ts")
to make code examples cleaner and more focused.

(cherry picked from commit b3adb6001c)
2025-11-17 16:00:25 +00:00
Charles Lyding 31ae88f411 docs: standardize package manager commands in guides
This commit updates the elements and tailwind guides to use the standardized `docs-code-multifile` format for package manager commands. This change introduces `yarn`, `pnpm`, and `bun` alternatives to the existing `npm` commands, providing a consistent experience for users across different package managers.

(cherry picked from commit 6208016026)
2025-11-17 15:59:53 +00:00
Angular Robot 0f5c0dae51 docs: update cross-repo adev docs
Updated Angular adev cross repo docs files.
2025-11-17 07:58:36 -08:00
Angular Robot 74b95dec3b build: update cross-repo angular dependencies
See associated pull request for more information.
2025-11-14 15:35:56 -08:00
SkyZeroZx a315afbfd3 docs: add formArray clear() example clarifies array manipulation
(cherry picked from commit c1057c69f0)
2025-11-14 23:30:52 +00:00
Miles Malerba e1a7c35370 refactor(forms): improve typing on min & max (#65212)
If we're calling `min` on a path that's guaranteed to be `number` we
don't want to make the users validator function handle the `null` or
`string` cases.

This uncovered an issue in the `SchemaTreePath` type which needed to be
fixed by preventing the model type from being distributed over.

PR Close #65212
2025-11-14 21:56:58 +00:00
Miles Malerba ff4633dab8 refactor(forms): allow passing number|string|null paths to min & max (#65212)
Relaxes the constraints on which paths can be used with the `min` &
`max` validation rules, since people may want to validate a
potentially-null number, or a numeric value represented as a string

PR Close #65212
2025-11-14 21:56:58 +00:00
Wagner Maciel 05cf14ba44 docs: aria toolbar examples
(cherry picked from commit a99e724c60)
2025-11-14 21:56:16 +00:00
Angular Robot ad0c059bb2 build: update cross-repo angular dependencies
See associated pull request for more information.
2025-11-14 13:55:52 -08:00
Cheng-Hsuan Tsai 3228cce727 docs(docs-infra): enable tabs layout
(cherry picked from commit de234def0e)
2025-11-14 20:24:05 +00:00
Ben Hong 8a5b284ef5 docs: add draft of aria component guides
(cherry picked from commit 8b59653788)
2025-11-14 19:26:50 +00:00
Miles Malerba 966bfae337 build(forms): expose signal forms compat package
Hooks up @angular/forms/signals/compat to be released and have its docs
published

(cherry picked from commit fc1ef79ad4)
2025-11-14 17:23:39 +00:00
Angular Robot 911999e75b docs: update cross-repo adev docs
Updated Angular adev cross repo docs files.
2025-11-14 08:53:42 -08:00
cexbrayat f550f4ab4a docs: ExperimentalIsolatedShadowDom mentions
(cherry picked from commit c137f1fe91)
2025-11-14 16:41:16 +00:00
cexbrayat 1a8dbd79e6 docs: FormArrayDirective mentions
(cherry picked from commit b0dd813664)
2025-11-14 16:40:44 +00:00
Kristiyan Kostadinov 4dda271985 refactor(compiler-cli): split up large file
The `type_check_block.ts` file was getting quite large and difficult to navigate. These changes split up the different pieces of functionality into separate files.

(cherry picked from commit 81bd455de8)
2025-11-14 16:40:14 +00:00
Leon Senft 8e988124ab test(forms): [field] inputs on components should just pass through
Test that a component with a bound `[field]` input is not treated as a
control, and that `fieldBinding` does not include the corresponding
`Field` instance.

(cherry picked from commit acb78eeb7a)
2025-11-14 16:37:45 +00:00
Angular Robot 513c5f5d1c build: update pnpm to v10.22.0
See associated pull request for more information.
2025-11-14 08:35:37 -08:00
Angular Robot 84bf0d26bf build: update cross-repo angular dependencies
See associated pull request for more information.
2025-11-14 08:33:42 -08:00
SkyZeroZx 8481939f5b docs: Uses the self-closing tag syntax
(cherry picked from commit 9ec964334e)
2025-11-14 16:32:40 +00:00
KAUSHIK REDDY AWALA 167eb584ed docs(docs-infra): update di factory provider function to use correct parameters
This PR fixes a parameter mismatch in the `apiClientFactory` function documentation example. The factory was previously passing only http and `userService` to the ``ApiClient`` constructor, but the constructor actually requires http, `baseUrl`, and `rateLimitMs` as separate parameters.

Key Changes:

Extracts baseUrl and rateLimitMs from UserService using getter methods
Updates the ApiClient instantiation to pass all three required constructor parameters
Adds a comment explaining the assumption about UserService providing these values

(cherry picked from commit 6f716e400e)
2025-11-14 16:32:12 +00:00
Alan Agius 4fb29588cf fix(docs-infra): update firebase caching regex for generated files
The regex for caching generated files in firebase.json has been updated to
include lowercase letters and underscores in the 8-character hash. This
ensures that files with names like `chunk-CrXHmw_W.js` are correctly
cached.

(cherry picked from commit e840cd547d)
2025-11-14 08:29:06 -08:00
Ben Hong c2a52fd278 docs: add aria toolbar component guide 2025-11-13 16:02:14 -08:00
Cheng-Hsuan Tsai afeba79ac8 docs(docs-infra): hide file tabs when code example is hidden
(cherry picked from commit 6d8c3fc888)
2025-11-13 23:58:14 +00:00
Ben Hong 750da17f48 docs: add signal forms models guide 2025-11-13 15:41:36 -08:00
Angular Robot d7101de374 build: update cross-repo angular dependencies
See associated pull request for more information.
2025-11-13 15:23:10 -08:00
Angular Robot 99945bf9a5 docs: update cross-repo adev docs
Updated Angular adev cross repo docs files.
2025-11-13 15:21:55 -08:00
Joey Perrott 4b0f20830b ci: use hardcoded global approvers group
Use a single hardcoded, within the pullapprove config file, group for global approvers instead of leveraging a github team as a group
2025-11-13 15:13:25 -08:00
Alessio Pelliccione 482e1376e9 docs(docs-infra): improve theme picker accessibility and add animations
(cherry picked from commit 25320ae1eb)
2025-11-13 22:05:12 +00:00
Matthieu Riegler 16d51f6fbe refactor(core): flip ngDevMode condition for formatter
In cases the `ngDevMode` flag hasn't been set, still enable the formatter. What matters is if `ngDevMode` is `false ` we tree shake that away.

(cherry picked from commit 1b895fece6)
2025-11-13 18:01:13 +00:00
SkyZeroZx 9950165145 docs: adds guide references to router APIs
Adds `@see` tags with links to relevant guides in the router documentation.

(cherry picked from commit 718eb7bb3a)
2025-11-13 18:00:24 +00:00
Leon Senft 37463525be refactor(forms): use AbortSignal to cancel debounced updates
Add an `AbortSignal` parameter to `Debouncer`. Implementations may
choose to accept this parameter to be informed when a debounced
operation is aborted. This may be useful for canceling pending timers or
avoiding unnecessary work.

(cherry picked from commit 98ce9a7b17)
2025-11-13 17:59:22 +00:00
Angular Robot 2406172d50 docs: update cross-repo adev docs
Updated Angular adev cross repo docs files.
2025-11-13 09:45:50 -08:00
Matthieu Riegler 4f6f9b8e8d docs(docs-infra): Add support for metadata on fenced code blocks
This will help us replace `docs-code` with inline code usages and prevent future indentation issues

(cherry picked from commit f737a9dd5c)
2025-11-13 17:36:17 +00:00
Ben Hong 119be3488e docs: add signal forms overview guide 2025-11-13 09:35:53 -08:00
Shuaib Hasan Akib c12f0159f9 docs: replace <docs-code> block with standard fenced code block for typescript example
Replaced the <docs-code> wrapper with a Markdown fenced code block to improve
copy/paste usability, syntax highlighting consistency, and alignment with current
documentation formatting standards.

Inspired by #65043

(cherry picked from commit 3cfd4361a5)
2025-11-13 17:34:15 +00:00
Kristiyan Kostadinov 67fbd5ff1e fix(core): SSR error in signal forms
Resolves an SSR error, because we weren't checking if `MutationObserver` is available.

(cherry picked from commit 3f80ae74ba)
2025-11-13 17:12:45 +00:00
Matthieu Riegler 0c27954a4d refactor(core): remove resource flag.
This was used to migrate G3 and is no longer necessary.

(cherry picked from commit d1ab73dd87)
2025-11-13 17:12:22 +00:00
Shuaib Hasan Akib c7df828c48 docs: replace <docs-code> block with standard fenced code block for typescript example
Replaced the <docs-code> wrapper with a Markdown fenced code block to improve
copy/paste usability, syntax highlighting consistency, and alignment with current
documentation formatting standards.

Inspired by angular#65043

(cherry picked from commit caaa5ec8e6)
2025-11-13 17:11:26 +00:00
Charles Lyding 50938b786e docs: create Vitest migration guide
This commit introduces a new guide for migrating existing Angular projects from Karma/Jasmine to Vitest.

The guide covers:
- Manual steps for installing dependencies and updating `angular.json`.
- Handling custom `karma.conf.js` configurations.
- Removing Karma-related files and packages.
- Configuring browser mode for Vitest.
- Details on the `refactor-jasmine-vitest` schematic for automated test refactoring.

The guide also clarifies that while Vitest is the default for new projects, migration for existing projects is experimental. It emphasizes reviewing changes and provides guidance on adapting custom Karma configurations to Vitest.

Renames `experimental-unit-test.md` to `migrating-to-vitest.md` and updates `sub-navigation-data.ts` accordingly.

(cherry picked from commit 258c295b92)
2025-11-13 17:10:59 +00:00
Angular Robot 2606b6e938 build: update cross-repo angular dependencies
See associated pull request for more information.
2025-11-13 09:09:10 -08:00
hawkgs c133f48902 docs(docs-infra): improve playground layout
Improve the layout and optimize the empty space; Introduce some minor improvements to the code editor

(cherry picked from commit 7ab1b3a32a)
2025-11-13 17:07:58 +00:00
SkyZeroZx 31ca56aa20 docs: Fixed mermaid diagram node label contrast in dark mode
(cherry picked from commit b6a91d4c39)
2025-11-12 23:01:40 +00:00
Kristiyan Kostadinov be371292f2 refactor(compiler-cli): rework type checking for signal forms
Reworks the way we approach type checking of signal forms to be closer to the behavior at runtime. There are a couple of scenarios that we handle:

1. For native controls, we now produce simplified type checking code that looks as follows:

```
var t1 = null! as number | string; // Type depends on the input `type`.
t1 = someField().value();
```

2. For custom controls we generate bindings to the individual inputs, rather than checking conformance against `FormValueControl`/`FormCheckboxControl`. This is closer to the behavior at runtime and it allows us to handle generic directives properly.

(cherry picked from commit f7e58577a4)
2025-11-12 21:13:51 +00:00
Kristiyan Kostadinov afda85f24c refactor(core): remove unused type
Removes the `ExtractFromControlValue` type since it won't be necessary anymore.

(cherry picked from commit 14152f69b9)
2025-11-12 21:13:51 +00:00
SkyZeroZx 4d8b97627c docs: update tutorials with self-closing tags, standalone router directives, and fix syntax highlighting
(cherry picked from commit 4544135b1e)
2025-11-12 21:13:27 +00:00
Angular Robot eb9034d4a8 build: update cross-repo angular dependencies
See associated pull request for more information.
2025-11-12 11:56:11 -08:00
SkyZeroZx dc11db1f37 docs: correct example for RouteReuseStrategy getRouteKey
Update the example to properly demonstrate the getRouteKey method usage fixes #65021

(cherry picked from commit a48029b810)
2025-11-12 19:49:08 +00:00
Angular Robot 16f2c5529a docs: update cross-repo adev docs
Updated Angular adev cross repo docs files.
2025-11-12 11:48:42 -08:00
SkyZeroZx 129e16dc86 docs: correct code block language in error handling and signals interop
(cherry picked from commit 05ef2a5ca9)
2025-11-12 19:35:14 +00:00
Angular Robot 1021b7a394 build: update cross-repo angular dependencies
See associated pull request for more information.
2025-11-12 11:32:20 -08:00
Angular Robot 18cc2606e3 build: update bazel dependencies
See associated pull request for more information.
2025-11-12 09:41:42 -08:00
Angular Robot 8636f8aa83 build: update pnpm to v10.21.0
See associated pull request for more information.
2025-11-12 09:38:59 -08:00
Ben Hong 4f936cafda docs: iterate on essentials signal forms guide 2025-11-12 09:37:15 -08:00
Ben Hong d02374a45c docs: iterate on signal forms essential guide 2025-11-12 09:37:15 -08:00
Alan Agius a55a96a5fb build: allow any version of @angular/* packages for peer dependencies
This change configures pnpm to allow any version of  `@angular/*` packages to satisfy peer dependencies. This is necessary because `@angular/*` packages are managed within this monorepo, and this rule prevents issues with peer dependency resolution when different versions might be present during development or testing.

(cherry picked from commit 46099910c0)
2025-11-12 09:36:01 -08:00
Andrew Kushnir 909588e57f release: cut the v21.0.0-rc.2 release 2025-11-12 08:39:31 -08:00
Danny Koppenhagen c05cf4145b refactor(core): render additional WAI-ARIA 1.3 property bindings as attributes
Support additional ARIA properties from Accessible Rich Internet Applications (WAI-ARIA) version 1.3.

| attribute | property |
|-----------|----------|
| `aria-activedescendant`           | `ariaActiveDescendantElement` |
| `aria-colindextext`           | `ariaColIndexText` |
| `aria-controls`           | `ariaControlsElements ` |
| `aria-describeyby`           | `ariaDescribedByElements ` |
| `aria-description`           | `ariaDescription` |
| `aria-details`           | `ariaDetailsElements ` |
| `aria-errormessage`           | `ariaErrorMessageElements ` |
| `aria-flowto`           | `ariaFlowToElements ` |
| `aria-labelledby`           | `ariaLabelledByElements ` |
| `aria-owns`           | `ariaOwnsElements ` |
| `aria-rowindextext`           | `ariaRowIndexText ` |

closes #64847

(cherry picked from commit c3e82fb2d5)
2025-11-11 14:09:02 -08:00
Matthew Beck 814b2713f5 fix(compiler): support complex selectors in :nth-child()
:nth-child() (and its siblings) support complex expressions, e.g.
`:nth-child(2n of :is(.foo, .bar))`. Previously we'd choke because of
the `:is()`. Now, we reuse the `_parenSuffix` subexpression to match
nested parentheses the same way we do for :host() and :host-context().
Note that we only support 3 levels of nesting, so a selector like
`:nth-child(n of :is(:has(:not(.foo))))` will still break.

I'll say yet again that we really should add a proper parser so we stop
getting bug reports like this :)

Fixes #64913

(cherry picked from commit 24cfd5a0ed)
2025-11-11 14:03:37 -08:00
Alan Agius 7811d95b89 refactor(core): improve resource loading with async/await
Refactor  to use async/await for clearer asynchronous operations and enhanced error handling.
Simplify resource caching and streamline the resolution of component templates and styles.
Update  in the router to align with the new async resource resolution.

(cherry picked from commit 4ed8781301)
2025-11-11 12:50:19 -08:00
Andrew Scott e5b0a9739c Revert "feat(service-worker): notify clients about version failures (#62718)"
This reverts commit 6d011687ec.

issue #63500 reproduces at head on the main branch in the dev app.
Reverting this change along resolves it.

fixes https://github.com/angular/angular/issues/63500

(cherry picked from commit 4af408afcb)
2025-11-11 12:48:49 -08:00
Leon Senft a278ee358c feat(forms): add debounce() rule for signal forms
The `debounce()` rule allows developers to control when changes to a
form control are synchronized to the form model.

This feature necessitated some changes to `FieldState`:

  * `controlValue` is a new signal property that represents the current
    value of a form field as it appears in its corresponding control.

  * `value` conceptually remains unchanged; however, its value may lag
    behind that of `controlValue` if a `debounce()` rule is applied.

The `debounce()` rule essentially manages when changes to `controlValue` are
synchronized to `value`. The intent is that an expensive or slow
validation rule can react to the debounced `value`, rather than a more
frequently changing `controlValue`.

Directly updating `value` immediately updates `controlValue`, and cancels any
pending debounced updates.

When multiple `debounce()` rules are applied to the same field, the last
currently active rule is used to debounce an update. These rules are
applied to child fields as well, unless they override them with their
own rule.

(cherry picked from commit d337cfb68f)
2025-11-11 12:00:13 -08:00
Leon Senft 33ed7d116b refactor(forms): do not infer accumulated metadata type from initial value
This removes the need to specify type arguments for
`reducedMetadataKey()` when the value returned from the `getIntial`
callback is a subtype of the accumulated type.

(cherry picked from commit 8866934334)
2025-11-11 12:00:12 -08:00
Angular Robot fc3a28e647 build: update cross-repo angular dependencies
See associated pull request for more information.
2025-11-11 11:51:32 -08:00
Angular Robot baf33d01c1 build: update cross-repo angular dependencies
See associated pull request for more information.
2025-11-11 10:21:35 -08:00
Doug Parker c9f977833e fix(core): skip Angular formatting when formatting signals recursively
The flag `skipFormatting` got renamed to `ngSkipFormatting` during review of https://github.com/angular/angular/pull/64000, but a couple usages got missed, causing some unfortunate UI recursion.

(cherry picked from commit 490435bf76)
2025-11-11 10:14:33 -08:00
Kristiyan Kostadinov 20319fea85 refactor(compiler): remove unused code
The `fullInheritane` flag from the metadata and the `CopyDefinitionFeature` that it controls appear to no longer be used since `fullInheritance` is always false. The feature appears to have been there to support ngcc which was removed some time ago.

(cherry picked from commit 8277906455)
2025-11-11 10:04:32 -08:00
Angular Robot 91dbb4b4c1 build: lock file maintenance
See associated pull request for more information.
2025-11-11 08:48:21 -08:00
SkyZeroZx 8765b66f5a docs: add reference to Built-in Pipes in multiple pipe files
(cherry picked from commit d999667b57)
2025-11-11 08:47:12 -08:00
Matthieu Riegler 6213cbf1a8 refactor(core): rename ExperimentalIsolatedShadowDom to IsolatedShadowDom
This API is still experimental

(cherry picked from commit 21ca49cf62)
2025-11-11 08:46:10 -08:00
Matthieu Riegler 5e86299ec4 docs(docs-infra): Add support for experimental enum entries
(cherry picked from commit 16e61f5dd0)
2025-11-11 08:46:09 -08:00
RobinReinecke 557213e211 docs: correct mermaid code block formatting
(cherry picked from commit 07703875b5)
2025-11-11 08:33:32 -08:00
SkyZeroZx c72efd67de docs: improve discoverability in service worker documentation
(cherry picked from commit dde18c2303)
2025-11-11 08:32:19 -08:00
cexbrayat eea81c2733 docs: remove error mentions in signal forms docs
`error` no longer exists and is called `validate`

(cherry picked from commit 800b01f5a1)
2025-11-11 08:30:13 -08:00
Devin Chasanoff 2019940ddc docs: add links to SDUI example and livestream
(cherry picked from commit 5af33724a4)
2025-11-10 14:16:23 -08:00
arturovt ab98e71c41 fix(common): remove placeholder image listeners once view is removed
Prior to this commit, attempting to resolve a `ChangeDetectorRef` after views or app have been destroyed would result in an error. In this commit, we clean up listeners once the view is destroyed, before the placeholder loads or fails to load.

(cherry picked from commit feb86e3fde)
2025-11-10 12:05:24 -08:00
Shuaib Hasan Akib e5a19cb736 refactor(router): add ngDevMode guards to InjectionToken names and cleanup imports
Wraps InjectionToken names with `typeof ngDevMode !== 'undefined' && ngDevMode`
checks to enable tree-shaking of descriptive token names in production builds.
This ensures debug-only strings are removed from production bundles, reducing size.

Also removes unused imports found during refactor.

(cherry picked from commit b0b834d7f1)
2025-11-10 12:04:35 -08:00
arturovt 8ab084754b refactor(core): mark VERSION as @__PURE__ for better tree-shaking
Annotate the `new Version(...)` call with `/* @__PURE__ */` to signal to optimizers that the constructor is side-effect free.

Without this hint, bundlers such as Terser or ESBuild may conservatively retain the `VERSION` instantiation even when unused. With the annotation, the constant can be tree-shaken away in production builds if not referenced, reducing bundle size.

(cherry picked from commit d3f67f6ca8)
2025-11-10 12:04:09 -08:00
Alan Agius 5f1436779c docs: use markdown code fences in service worker docs
Replaces the <docs-code> component with standard markdown code fences in the service worker documentation. This improves the readability and maintainability of the documentation.

(cherry picked from commit d42f9ce3a9)
2025-11-10 12:03:36 -08:00
Angular Robot 63418fb938 docs: update cross-repo adev docs
Updated Angular adev cross repo docs files.
2025-11-10 10:35:02 -08:00
SkyZeroZx 650af71026 refactor(http): migrate XSRF classes to use inject() function
Remove constructor injection in favor of inject() calls

(cherry picked from commit 55be477979)
2025-11-10 09:49:14 -08:00
arturovt 9db114f4ff refactor(router): replace Optional with inject() flags
Replace `@Optional() link: RouterLink` constructor parameter with
`link = inject(RouterLink, {optional: true})` to enable tree-shaking
of the `Optional` decorator and its factory scaffolding.

Bundle size reduction: `Optional` is a runtime value created by
`makeParamDecorator()`. Even in production builds, ESBuild and other
bundlers must keep their factory code because it is referenced via
`Optional`. With `inject()`, this class is no longer referenced,
allowing it and the `makeParamDecorator` scaffolding to be tree-shaken
when unused elsewhere.

Note: This updates the constructor signature but should not be
considered a breaking change. Angular's official guidance is that
directives, components, and pipes should be instantiated by the
framework, not by user code. Directly calling `new RouterLinkActive(...)`
is an unsupported pattern that goes against Angular's design principles.

(cherry picked from commit 7724a9460d)
2025-11-10 09:48:36 -08:00
Angular Robot afa2ac2801 build: update cross-repo angular dependencies
See associated pull request for more information.
2025-11-10 08:24:22 -08:00
Shuaib Hasan Akib 5092a89e96 docs: add shell language to CLI installation examples
Added `language="shell"` to installation command examples to display
the shell prompt `$` icon consistently across npm, pnpm, yarn, and bun
code blocks.

(cherry picked from commit 27d54654e3)
2025-11-10 08:01:34 -08:00
Shuaib Hasan Akib af0ed124c4 docs(docs-infra): simplify file headers in <docs-code> blocks
Removed redundant "src/app/" prefix from file headers (e.g.,
"src/app/open-close.component.ts" → "open-close.component.ts")
to make code examples cleaner and more focused.

(cherry picked from commit e0a4bdd72b)
2025-11-10 08:00:38 -08:00
Shuaib Hasan Akib 55360994af docs(docs-infra): removed unused import and use self-closing syntax for component
(cherry picked from commit 8c6619a531)
2025-11-10 08:00:11 -08:00
SkyZeroZx 511200265b docs: improve discoverability of forms
(cherry picked from commit e3fc57e8fc)
2025-11-10 07:57:48 -08:00
jnizet 0e13ae5dfc fix(docs-infra): avoid double slash in sitemap urls
Previously, the URLs in the  generated sitemap contained double slashes between the host and the path. It's not the case anymore.

fix #65022

(cherry picked from commit afe5fc0399)
2025-11-10 07:53:44 -08:00
SkyZeroZx 50a9ca0bb1 docs: correct import path and self-closing tag in ng-content example
(cherry picked from commit 6a2f4a88de)
2025-11-10 07:52:51 -08:00
Matthew Beck b69763c728 test(compiler): add test for :host:has(> .foo)
I took a quick look at my recent changes to see if I had inadvertently
fixed this bug, but I couldn't seem to reproduce it even before my
changes. Seems like it's working, though.

Closes #58436

(cherry picked from commit 4b871b139b)
2025-11-10 07:51:21 -08:00
arturovt a8b123c18d refactor(core): tree-shake REF_EXTRACTOR_REGEXP (and dependencies)
`new RegExp()` with computed strings can't be analyzed statically. The bundler can't prove the template string evaluation has no side effects; as thus this expression is considered a side-effect.

(cherry picked from commit 7f95f02d05)
2025-11-10 07:48:42 -08:00
Leon Senft 2667d8c23d refactor(forms): remove a TODO and simplify update on <select> mutations
Remove an unnecessary TODO comment. The native `<select>` tracks its
`value` by keeping track of the selected `<option>`. Thus if the value
was set *before* the corresponding option is created, the `<select>`
will ignore it, but the framework doesn't know that and will cache the
bound value anyways. Therefore, checking if the value changed since it
was last bound when the mutation that creates the selected `<option>`
occurs would in fact prevent a needed update, leaving the `<select>` and
field values out of sync.

Furthermore, we know the control type is a native `<select>` element, so
we can update its value directly instead of going through
`updateNativeControl()` which would perform a redundant input type
check.

(cherry picked from commit 44cd18c183)
2025-11-10 07:48:01 -08:00
hawkgs 6c025fa709 refactor(devtools): update inspect icon
Use a custom version of Material `pin_end` icon that doesn't have a dot.

(cherry picked from commit 402f396b76)
2025-11-10 07:47:18 -08:00
Ben Hong 1876c7c48c docs: add draft for aria autocomplete component guide 2025-11-10 07:46:48 -08:00
Danny Koppenhagen 590244a8f9 docs(core): add a11y considerations related to @defer()
closes #53466

(cherry picked from commit d2b854b37e)
2025-11-07 15:27:15 -08:00
Andrew Scott 647e640603 refactor(core): Extract NavigateEvent cancel steps based on recent spec update
This updates the cancel/abort steps of fake navigation to match the
current spec.

Relevant commit seems to be
* https://github.com/whatwg/html/commit/b0b40cca16f5d04b7fdca5a1bdca32cc6f824689

(cherry picked from commit 8bccd8671c)
2025-11-07 12:54:18 -08:00
Andrew Scott 916ff6a340 refactor(core): Update commit steps of PlatformNavigation fake to match spec updates
Brings commit steps in line with recent spec updates

* https://github.com/whatwg/html/commit/a3809244c003103243e769855aa4c5792b8937e3
* https://github.com/whatwg/html/commit/bd347bdfebc558f4009109c101bf7fb495400031

(cherry picked from commit 7a5ac69144)
2025-11-07 12:54:17 -08:00
Angular Robot 6db214899a docs: update cross-repo adev docs
Updated Angular adev cross repo docs files.
2025-11-07 12:52:12 -08:00
Leon Senft 781a3299f9 perf(forms): only update interop controls when bound field changes
https://github.com/angular/angular/pull/64590 implemented change
detection for field bindings, but only for those bound to native or
custom form controls. This change extends that optimization to apply to
field bindings on interoperable controls built using Reactive Forms as well.

(cherry picked from commit 850f0d6b3d)
2025-11-07 11:58:20 -08:00
Kristiyan Kostadinov c81620f2c1 refactor(compiler-cli): update set of required inputs
Updates the required inputs that can be ignored for form controls.

(cherry picked from commit 877678345a)
2025-11-07 11:57:53 -08:00
Kristiyan Kostadinov cc25f96f02 test(forms): fix type checking errors in signal form tests
Fixes some type checking errors in the signal forms tests that accumulated while there wasn't any type checking.

(cherry picked from commit 10915f2f5f)
2025-11-07 11:57:53 -08:00
Kristiyan Kostadinov 71ab11ccf0 fix(compiler-cli): make field detection logic more robust
Currently the logic for detecting `Field` directives only works if it's imported from `@angular/forms/signals` which doesn't cover our own tests.

These changes make the check more robust.

(cherry picked from commit 0b6b78ca74)
2025-11-07 11:57:53 -08:00
Kristiyan Kostadinov 5b55200edf fix(compiler-cli): allow value to be set on radio fields
Updates the logic that checks for unsupported bindigns to allow `value` to be set on `radio` controls.

(cherry picked from commit a61e01d51f)
2025-11-07 11:57:53 -08:00
Kristiyan Kostadinov bd322ca410 fix(compiler-cli): do not flag custom control required inputs as missing when field is present
Adds some logic that won't report the `value` or `checked` inputs as missing when the `Field` directive is present since it will bind to the inputs implicitly.

(cherry picked from commit 165634264e)
2025-11-07 11:57:53 -08:00
Kristiyan Kostadinov 01290ab275 fix(compiler-cli): use any when checking field interface conformance
Switches to checking against `FormValueControl<any>` instead of `FormValueControl<unknown>` when checking whether custom controls conform to the interface.

Fixes #64946.

(cherry picked from commit 4d0778529f)
2025-11-07 11:57:53 -08:00
Andrew Scott 89095946cf fix(language-service): address potential memory leak during project creation
This addresses a potential memory leak in plugin-factory.ts.
The require call inside the create function reloads the entire language
service module for every new project, which is inefficient and could be a cause of the memory leak during branch
switching. This ensures the module is loaded only once and the same
instance is shared across all projects.

(cherry picked from commit 4405725943)
2025-11-07 11:57:25 -08:00
Alan Agius aada582e96 build: update rules_angular to latest
Update `rules_angular` to latest.
2025-11-07 11:43:47 -08:00
Alan Agius 1e53f4e957 refactor: exclude tsconfig.json from VSIX package contents (#64991)
The  file is no longer included in the VSCode extension package.
This change updates the golden file and the  file to reflect this exclusion.

PR Close #64991
2025-11-07 11:36:31 -08:00
Alan Agius 8967d9bc40 test: add golden file test for VSCode extension package contents (#64991)
This commit introduces a golden file test to verify the contents of the VSCode extension package.
The test ensures that the list of files included in the extension package remains consistent.

A new Bazel rule  is added to generate the list of files, and  is used to compare it against the golden file. A helper script  is also added to facilitate the generation of the golden file.

PR Close #64991
2025-11-07 11:36:31 -08:00
Matthew Beck f54cc4f28a fix(compiler): support commas in :host() argument
This change adds support for commas in :host() arguments (e.g.
`:host(:not(.foo, .bar))` as well as in nested parens when the argument
is applied without parens (e.g. `:host:not(:has(.foo, .bar))`).
Previously these selectors would receive an extra `[nghost]` attr, e.g.
`[nghost]:not(.foo, [nghost].bar)`.

I didn't file a bug for this one, but it's also blocking on an internal
LSC. Like the other CSS changes, I'll run a TGP to confirm this isn't
breaking.

(cherry picked from commit 680c3c7bff)
2025-11-07 10:43:37 -08:00
Shuaib Hasan Akib 0552e728a8 docs(docs-infra): use self-closing syntax for component examples
Replaced multiple component tags such as `<example></example>` with
self-closing syntax (`<example />`) across documentation examples.
This improves readability and aligns with the current Angular
style conventions.

(cherry picked from commit a2cd36777a)
2025-11-07 10:24:41 -08:00
Charles Lyding 31846ded2d docs: remove invalid service dependency guide section
The current section `Services with dependencies` within the testing services
guide is non-functional and has been removed. The example service is using
`inject` but the test code is using constructor-based injection. The further
sections discuss the use of TestBed to adjust providers which better handles
these cases.

(cherry picked from commit e3143036ba)
2025-11-07 10:23:50 -08:00
SkyZeroZx 46c1a80b8f docs(docs-infra): refactor update to use host property and refactor isWindows
(cherry picked from commit dff803514e)
2025-11-07 10:13:26 -08:00
Alon Mishne dec8d74ecf docs: Update MCP docs to include all current stable and experimental tools
(cherry picked from commit b481fee049)
2025-11-07 10:12:33 -08:00
Charles Lyding 27b355b220 docs: Update testing guides for Vitest and Karma
This commit updates the testing documentation to reflect the introduction of Vitest as the default test runner, while ensuring Karma testing instructions are still available.

Key changes include:
- Adding a new guide for "Testing with Karma" (`guide/testing/karma.md`).
- Updating the "Code Coverage" guide (`guide/testing/code-coverage.md`) to use `angular.json` for coverage enforcement and referencing Vitest documentation.
- Modifying the "Testing Overview" guide (`guide/testing/overview.md`) to introduce Vitest as the default, update `ng test` output examples, and link to the new Karma guide.
- Updating navigation data to include the new Karma testing guide.

(cherry picked from commit 2a2397acc4)
2025-11-07 10:10:29 -08:00
Andrew Scott 3f7111a9c3 fix(language-server): fix directory renaming on Windows
Hopefully addresses issues on Windows where fs.watch on a directory
locks that directory.

fixes https://github.com/angular/vscode-ng-language-service/issues/1398

(cherry picked from commit c91d8203a2)
2025-11-07 10:10:00 -08:00
Miles Malerba a3cb1dfd1a refactor(forms): nicer type errors
By intersecting with `object` instead of `unknown` in the primitive and
`FormControl` cases, we get TypeScript to show nicer type errors that
mention `FieldTree<...>` insetad of `() => FieldState<...>`

(cherry picked from commit 0efb3f6d1f)
2025-11-07 15:45:08 +00:00
SkyZeroZx b15325f409 refactor(devtools): replace HostListener with host metadata for keydown handling
Uses host metadata instead of the HostListener decorator for keydown events

(cherry picked from commit c74367c5de)
2025-11-07 15:44:46 +00:00
khanhkhanhlele 59798a13dd docs: Fix typos in some files
(cherry picked from commit a625f6bb20)
2025-11-07 15:44:08 +00:00
Angular Robot 8e73f54f38 build: update cross-repo angular dependencies
See associated pull request for more information.
2025-11-06 15:28:28 -08:00
tsc036 e69ada4ceb refactor(core): move profile_types.ts to primtives
move profile_types.ts so the types can be used in Wiz code

(cherry picked from commit cf47ce2db9)
2025-11-06 22:22:38 +00:00
Miles Malerba 6d6fda8610 refactor(forms): allow FieldTree of recursive type
Adjusts our typings to work better with recursive types and avoid
infinite recursion in the type system.

(cherry picked from commit faccf03ee0)
2025-11-06 21:43:46 +00:00
Miles Malerba 9ea1c2216d refactor(forms): expose pathKeys as part of the API
Currently we maintain the pathKeys internally, but do not expose them
through the `FieldContext`, this PR updates the `FieldContext` to expose
this property.

(cherry picked from commit 2fd8dc9195)
2025-11-06 21:43:15 +00:00
Miles Malerba 8b4195fe7e refactor(forms): support dynamic object logic
extends `applyEach` to work on objects as well, conditionally applying
logic to each property of the object.

(cherry picked from commit c9058087ae)
2025-11-06 21:42:51 +00:00
Angular Robot 86a9feb9b5 build: update cross-repo angular dependencies to v21.0.0-rc.1
See associated pull request for more information.
2025-11-06 13:22:03 -08:00
Jessica Janiuk dcfd7fe399 Revert "build: restrain visibility to compiler-cli subpackages (#64732)"
This reverts commit acaa1e6104.
2025-11-06 13:09:27 -08:00
Jessica Janiuk 7c0daeac89 Revert "refactor(compiler-cli): remove deep imports from compiler-cli (#64732)"
This reverts commit af16b48ac7.
2025-11-06 13:09:27 -08:00
Matthieu Riegler acaa1e6104 build: restrain visibility to compiler-cli subpackages (#64732)
This should solve future deep imports issues.

PR Close #64732
2025-11-06 20:01:27 +00:00
Matthieu Riegler af16b48ac7 refactor(compiler-cli): remove deep imports from compiler-cli (#64732)
Accessed symbols are grouped into dedicated `private` entries

PR Close #64732
2025-11-06 20:01:27 +00:00
SkyZeroZx 593f902f24 refactor(platform-browser): remove unused Platform ID dependency from DomRendererFactory2
Eliminates the unnecessary injection and usage of Platform ID in the renderer factory logic, along with related test scaffolding cleanup

(cherry picked from commit 5343001835)
2025-11-06 20:00:50 +00:00
Angular Robot de2ff121d5 build: update cross-repo angular dependencies
See associated pull request for more information.
2025-11-06 11:56:14 -08:00
arturovt e90f9e418c refactor(forms): tree-shake ngControlStatusHost and ngGroupStatusHost
This commit removes `ngGroupStatusHost` variable because it's a side-effect, ending up preserving `ngControlStatusHost` and `ngGroupStatusHost`.

(cherry picked from commit 9f76fb61df)
2025-11-06 18:57:48 +00:00
Matthew Berry aad6ced0ef fix(compiler): support one additional level of nesting in :host()
Previously we supported one level of nested parentheses inside of a
`:host()` selector, e.g. `:host(:not(p))`. This caused a breakage in g3
when I migrated a selector from `:host:not(:has(p))` to
`:host(:not(:has(p)))`. This change adds support for just one more level
of nesting.

It'd be nice to move everything to a real CSS parser (or even update it
to count parentheses like I did with :host-context()), but I wasn't able
to get that to work in ~20 minutes and I'm focusing on other things at
the moment.

This change punts the problem until somebody tries to use just one more
level of nesting in a selector.

Fixes #64830

(cherry picked from commit 444143758e)
2025-11-06 18:53:47 +00:00
kirjs 3bbcae6ce8 refactor(forms): add compatForm
This allows using reactive form controls in signal forms

(cherry picked from commit 60447945bc)
2025-11-06 18:51:31 +00:00
Alan Agius 3bed9f0f16 build: format md files
This commit configures prettier to format markdown files.
2025-11-06 10:07:13 -08:00
Miles Malerba 60ce31fb62 test(forms): re-enable some disabled tests
Adjusts test behavior to reflect current implementation and enables them

(cherry picked from commit fa02d96508)
2025-11-06 17:41:31 +00:00
Jessica Janiuk a3c2fe819a Revert "refactor(common): Removes unused imports to clean up dependencies"
This reverts commit 6d3e0f1a51.
2025-11-06 09:05:05 -08:00
SkyZeroZx 6d3e0f1a51 refactor(common): Removes unused imports to clean up dependencies
Eliminates unnecessary imports to reduce clutter and improve maintainability

(cherry picked from commit ca3ef38143)
2025-11-06 16:35:32 +00:00
tsc036 b30bcc514d refactor(core): export types from primitives
export Version type and a type for linkedSignal previous value so they can be used for the Wiz implementations

(cherry picked from commit 104f7d57c1)
2025-11-06 16:34:58 +00:00
SkyZeroZx d8c656bd58 docs: correct formatting in dependency injection guides
(cherry picked from commit 61066071cf)
2025-11-06 16:34:31 +00:00
Joey Perrott 26995e2082 fix(docs-infra): properly expose the prerendered routes for sitemap generation
Properly expose the prerendered routes for sitemap generation rather than only copying the browser directory
2025-11-06 07:52:22 -08:00
Joey Perrott 5fb0b80f10 feat(docs-infra): generate the sitemap for angular.dev
We automatically generate the sitemap for the angular.dev deployment and include it in the assets pushed
to firebase.

Co-authored-by: Matthieu Riegler <kyro38@gmail.com>
2025-11-06 07:52:22 -08:00
Miles Malerba f3e2252f4b refactor(forms): add better support for Object.keys and Symbol.iterator
Improves support for using `Object.keys` (and related methods) and
`Symbol.iterator` to work with a `FieldTree` of unknown shape.

(cherry picked from commit e87f423d90)
2025-11-06 15:51:31 +00:00
Miles Malerba d1f4c8c18c refactor(forms): improved select support
When we set the `value` on a `<select>` element we're really just
setting the selected `<option>`. It treats the selected option as the
source of truth, rather than the actual value. This means that if
options are added or removed or their value changes, the `<select>` may
wind up with a different `value` than what's in our model.

This PR resolves this issue by adding a `MutationObserver` to the select
that is used to resync its value to the model whenever the options may
have changed.

(cherry picked from commit 194b41199b)
2025-11-06 15:49:09 +00:00
Angular Robot 87ffa3ca28 docs: update cross-repo adev docs
Updated Angular adev cross repo docs files.
2025-11-06 07:47:27 -08:00
Angular Robot f0ffd9bebd build: update cross-repo angular dependencies
See associated pull request for more information.
2025-11-05 15:26:25 -08:00
Joey Perrott 827a267511 build: update diff release package script
Update the diff relase package script to properly recursively apply the chmod and support a flag for writing the
diff to a file instead of only logging it to the console.

(cherry picked from commit de1f22cf2c)
2025-11-05 23:24:53 +00:00
Angular Robot 086ce4b40f build: update all github actions
See associated pull request for more information.
2025-11-05 15:17:38 -08:00
Angular Robot 0a75a0aee2 build: update bazel dependencies
See associated pull request for more information.
2025-11-05 15:17:18 -08:00
Miles Malerba 4bdd317596 docs: improve docs generation for namespaces (#64747)
Improves docs epxerience for interfaces / type aliases that are merged
with a namespace.

PR Close #64747
2025-11-05 22:42:59 +00:00
Miles Malerba c3b4bea951 refactor(forms): improve discoverability of ValidationError flavors (#64747)
Improves discoverability by putting the WithField, WithoutField, etc as
subtypes of the main ValidationError type

PR Close #64747
2025-11-05 22:42:59 +00:00
Erik Wegner bf19fd499f docs: Add the missing function call to use the signal's actual value
(cherry picked from commit e18aac88d4)
2025-11-05 11:47:20 -08:00
Andrew Scott 24f9d760a6 release: cut the v21.0.0-rc.1 release 2025-11-05 19:27:38 +00:00
Matthieu Riegler 01c5ba50d2 docs(docs-infra): fix heading layout on mobile
Long code blocks overflow the headings on narrow screen (like mobiles), this messes up the global layout of the page. With the ellipsis with fix that.

fixes #64845

(cherry picked from commit 7f44345db3)
2025-11-05 09:49:53 -08:00
Andrew Scott d3d2a3416f build: 20.3.3 release notes
update release notes for 20.3.3 of vscode extension
2025-11-05 17:36:29 +00:00
Andrew Scott 3a63bfda94 build: 20.3.2 release for vscode extension
changelog and version bump for 20.3.2
2025-11-05 17:36:29 +00:00
Kristiyan Kostadinov bdecb0345a test(compiler-cli): set up TCB tests for signal forms
Adds TCB-specific tests for the generated code in signal forms since they tend to be a bit easier to read and follow.

(cherry picked from commit 748caf9a74)
2025-11-05 09:35:53 -08:00
Kristiyan Kostadinov 0e081a6ef9 refactor(compiler-cli): check that custom control conforms to control interfaces
Generates additional type checking code to ensure that custom control conform to either `FormValueControl` or `FormCheckboxControl`.

(cherry picked from commit 3c7751020e)
2025-11-05 09:35:53 -08:00
Kristiyan Kostadinov 93283e076f refactor(compiler-cli): flag unsupported static bindings on field directives
Expands the diagnostic for unuspported bindings on fields to also capture static attributes.

(cherry picked from commit 04ed91071b)
2025-11-05 09:35:52 -08:00
Kristiyan Kostadinov d1a9258ed2 refactor(compiler-cli): split up form field ops
Splits up the custom form field and native form field into two separate `TcbOp`s with a shared base class.

(cherry picked from commit a5b596b83d)
2025-11-05 09:35:51 -08:00
Kristiyan Kostadinov c371251e4c fix(compiler-cli): report invalid bindings on form controls
Adds validation that users don't bind to unsupported properties on nodes with the `Field` directive.

(cherry picked from commit f20103a1d7)
2025-11-05 09:35:51 -08:00
Kristiyan Kostadinov 471da8a311 fix(compiler-cli): infer type of custom field controls
Adds the logic to infer the type of a custom field control that's on the same element as the `Field` directive.

(cherry picked from commit 948e2f4f01)
2025-11-05 09:35:51 -08:00
Kristiyan Kostadinov 6df098f76c refactor(core): add utility type for extracting the value of a custom control
Adds the `ɵExtractFormControlValue` type that we can use during template type checking to extract the type of a custom control.

(cherry picked from commit 4b68bddd62)
2025-11-05 09:35:50 -08:00
Kristiyan Kostadinov 96cb0cffda fix(compiler-cli): infer types of signal forms set on native inputs
Sets up the logic for inferring the type of the signal form that is set on a native `input`, `textarea` or `select`.

(cherry picked from commit 6b51fc3e9d)
2025-11-05 09:35:50 -08:00
Kristiyan Kostadinov a021006276 refactor(compiler-cli): allow the forms module to be loaded in tests
Updates the testing utilities to allow for `@angular/forms` to be loaded.

(cherry picked from commit c5ac77cb32)
2025-11-05 09:35:50 -08:00
SkyZeroZx 47578e0967 refactor(common): remove redundant providedIn: 'root' from injection tokens
Removes unnecessary `providedIn: 'root'` declarations from injection tokens

(cherry picked from commit 7c49c5338f)
2025-11-05 09:08:44 -08:00
SkyZeroZx 6de14b14e0 refactor(http): simplifies destruction tracking using destroyed property
Replaces the manual destroyed state with destroyed property

(cherry picked from commit 44435ea97b)
2025-11-05 09:05:34 -08:00
Jessica Janiuk a453d603c0 fix(core): skip leave animations on view swaps
We accounted for skipping leave animations during moves, but not swaps.
This accounts for the swap cases and updates how we deal with swaps and
moves. Now we always queue animations and then essentially dequeue them
if we attach them back in the same render pass.

fixes: #64818
fixes: #64730
(cherry picked from commit 373d263834)
2025-11-05 09:04:21 -08:00
Alan Agius 78c12b32e8 build: update typescript dependency for vscode-ng-language-service
Updates the typescript dependency to 5.9.3 in vscode-ng-language-service/package.json
and updates pnpm-lock.yaml accordingly.

(cherry picked from commit 3ef2edc076)
2025-11-05 09:02:41 -08:00
Leon Senft 507b3466ee perf(forms): implement change detection for field control bindings
For each field state property, check if it has changed since the last
time it was checked before writing it the corresponding form control
property.

The `pattern` and `required` properties of the field state now return a
default value rather than `undefined` if not defined by metadata.

(cherry picked from commit 41be02da2f)
2025-11-04 16:11:33 -08:00
Angular Robot bb267d1f04 build: update cross-repo angular dependencies
See associated pull request for more information.
2025-11-05 00:07:49 +00:00
Lukas Matta e1f933fed0 fix(migrations): Prevent removal of templates referenced with preceding whitespace characters
In https://github.com/angular/angular/pull/64745, a fix was introduced for templates referenced with a trailing semicolon. However, templates are still incorrectly removed when there are whitespace characters before the template name.

This commit updates the control flow migration logic to ensure templates referenced with preceding whitespace are not removed.

Fixes #64854

(cherry picked from commit 5b210e97af)
2025-11-04 15:26:08 -08:00
SkyZeroZx 9c59ea869a docs(docs-infra): add missing meta tags for author, keywords, and Twitter
(cherry picked from commit b5e37ffb77)
2025-11-04 14:58:34 -08:00
Angular Robot 9596020956 docs: update cross-repo adev docs
Updated Angular adev cross repo docs files.
2025-11-04 19:16:54 +00:00
Angular Robot 0b1339ef34 build: lock file maintenance
See associated pull request for more information.
2025-11-04 18:56:49 +00:00
Andrew Scott 65d6c9317a build: release VSCode extension 20.3.1
bump version and readme for vscode extension release
2025-11-04 18:54:06 +00:00
Jan Martin bb839bec33 ci: update handle for jkrems/hybrist
The username was changed earlier today and the old username is no
longer in use.
2025-11-04 17:48:38 +00:00
Gerome Grignon 3ccda42182 docs(router): uniformize lazy loading syntax
(cherry picked from commit 8f49af90d0)
2025-11-04 09:39:21 -08:00
SkyZeroZx 36f4c9b299 refactor(core): Removes unused flag for onDestroy
Eliminates an unnecessary configuration flag

(cherry picked from commit 2ad1b5979f)
2025-11-03 20:21:07 -08:00
SkyZeroZx 3140b87fd6 docs: simplify tutorial signals with self-closing component tags
(cherry picked from commit b61847f877)
2025-11-03 16:34:46 -08:00
SkyZeroZx 250e4c4a82 docs: Update highlight inputs & code block formatting in component guides
(cherry picked from commit 82a579c7e6)
2025-11-03 16:32:48 -08:00
SkyZeroZx 33f833984d refactor(platform-browser): remove redundant providedIn: 'root' from injection tokens
Removes unnecessary `providedIn: 'root'` declarations from injection tokens

(cherry picked from commit 97169b4689)
2025-11-03 16:31:58 -08:00
SkyZeroZx 1b5e2c84b5 refactor(platform-server): remove redundant providedIn: 'root' from injection tokens
Removes unnecessary `providedIn: 'root'` declarations from injection tokens

(cherry picked from commit 5e4437baf8)
2025-11-03 16:31:58 -08:00
SkyZeroZx f32a364045 refactor(router): remove redundant providedIn: 'root' from injection tokens
Removes unnecessary `providedIn: 'root'` declarations from injection tokens

(cherry picked from commit 67da4eb04c)
2025-11-03 16:31:58 -08:00
SkyZeroZx d3ed745653 refactor(forms): remove redundant providedIn: 'root' from injection tokens
Removes unnecessary `providedIn: 'root'` declarations from injection tokens

(cherry picked from commit 78e6716f40)
2025-11-03 16:31:58 -08:00
SkyZeroZx 20fa3841ba refactor(core): remove redundant providedIn: 'root' from injection tokens
Removes unnecessary `providedIn: 'root'` declarations from injection tokens

(cherry picked from commit 64efbc53aa)
2025-11-03 16:31:58 -08:00
Shuaib Hasan Akib 34f53aad06 docs: remove standalone: true since it's now the default
Removes redundant `standalone: true` declarations from code examples.
Standalone components are now the default in Angular, so the flag is
no longer necessary in documentation snippets.

(cherry picked from commit c4c7fb88ac)
2025-11-03 16:27:04 -08:00
Angular Robot a702c87833 build: update cross-repo angular dependencies
See associated pull request for more information.
2025-11-04 00:00:22 +00:00
marktechson fcd5f9f0ef docs: add v21 landing page
Adds a new landing page for developer events, starting with the v21 page. It also includes an ICS file link for calendar invites. Also updated the tests for the docs-pill to support two new attributes so developers can add the event to their calendars.

(cherry picked from commit 7a422c209a)
2025-11-03 15:59:31 -08:00
Matthieu Riegler 6b3fdf3e9f docs: remove feature from changelog.
#64584 reverted that change
2025-11-03 23:29:55 +00:00
SkyZeroZx d66384db49 docs(docs-infra): Improve font loading performance with preconnect
Adds preconnect links for Google Fonts domains to establish early
connections, reducing latency and improving font loading speed

(cherry picked from commit ffa19ddd3f)
2025-11-03 14:31:09 -08:00
Angular Robot 97c31ae1a8 build: update dependency bazel to v7.7.0
See associated pull request for more information.
2025-11-03 22:27:46 +00:00
SkyZeroZx 92f7052bc3 docs(docs-infra): Updates page title strategy to sync meta tags
Ensures that page title changes are reflected in relevant meta tags for improved SEO and sharing support

(cherry picked from commit 429672d6ab)
2025-11-03 13:30:21 -08:00
Kristiyan Kostadinov 4c6e29f72f fix(compiler-cli): make required inputs diagnostic less noisy
Currently when a required input is missing, we produce a diagnostic on the entire start tag. This can be really noisy if there are already some attributes on the element.

This change switch to only highlighting the tag name instead.

(cherry picked from commit f233f7420a)
2025-11-03 13:27:54 -08:00
Matthieu Riegler dc99f4c55a docs(docs-infra): ensure all redirections are absolute
fixes #64824

(cherry picked from commit 434ddbcfc9)
2025-11-03 13:01:54 -08:00
Angular Robot 32a166bdb7 build: update bazel dependencies
See associated pull request for more information.
2025-11-03 20:18:33 +00:00
Matthieu Riegler 5d75d0ec30 refactor(core): Replace usages of the Function type for animations
`Function` is usually not recommended as its not specific enough.

(cherry picked from commit 79b7ac722a)
2025-11-03 12:05:09 -08:00
Angular Robot 303bff6740 build: update cross-repo angular dependencies
See associated pull request for more information.
2025-11-03 19:52:27 +00:00
Angular Robot ac97c72495 build: update pnpm to v10.20.0
See associated pull request for more information.
2025-11-03 19:49:47 +00:00
SkyZeroZx a44083a2b9 docs(devtools): Removes comment about enum deprecation
Removes comment about enum deprecation

(cherry picked from commit a0fe177682)
2025-10-30 12:40:23 -07:00
SkyZeroZx c4742322dc refactor(devtools): Removes redundant input undefined in angularVersion
Simplifies the initialization of the version input by removing
an unnecessary undefined

(cherry picked from commit bd27e96273)
2025-10-30 12:40:22 -07:00
Kristiyan Kostadinov a4fe078969 refactor(common): remove unused import (#64699)
Cleans up unused code to improve readability and maintainability.

PR Close #64699
2025-10-30 19:27:34 +00:00
Ben Hong fee4baf5e5 docs: update dependency injection guides (part 1) (#63652)
PR Close #63652
2025-10-30 19:22:42 +00:00
Alan Agius 26f4944586 ci: refactor cross-repo documentation update scripts (#64792)
Consolidate separate scripts for updating Aria, CDK, and CLI documentation into a single, unified  script. This change streamlines the documentation update process and improves maintainability. The workflow file has been updated to use the new consolidated script.

PR Close #64792
2025-10-30 19:19:21 +00:00
Matthieu Riegler d23bb3cf6d docs(docs-infra): allow cors for json files (#64783)
fixes #64710

PR Close #64783
2025-10-30 17:50:07 +00:00
SkyZeroZx eb78d3552c docs: Standardize route parameter input signal & code block tags in routing docs (#64788)
PR Close #64788
2025-10-30 17:48:00 +00:00
Angular Robot c721de112c build: update cross-repo angular dependencies (#64781)
See associated pull request for more information.

PR Close #64781
2025-10-30 17:47:12 +00:00
aparziale ca0e77b25f fix(docs-infra): Cannot find module message (#64701)
Fixed the import error message in the editor section. The build would complete successfully, but an error message would be incorrectly reported.

PR Close #64701
2025-10-30 17:42:27 +00:00
Ben Hong 58f921d34c docs: add essential signal forms guide (#64665)
PR Close #64665
2025-10-30 17:24:58 +00:00
Joey Perrott 7a4813104c ci: make the github action fail when a firebase command fails (#64801)
When a firebase command line execution fails, the github action should be shown as failing instead of continuing to attempt to run and resulting in
an exit code of 0 and success

PR Close #64801
2025-10-30 17:24:27 +00:00
Angular Robot 90452f53df docs: update Angular Aria apis (#64804)
Updated Angular Aria api files.

PR Close #64804
2025-10-30 17:17:32 +00:00
Andrew Scott 60cc3cbde4 refactor(core): Move patch toggles inside functions to allow tree shaking
In general, global level const will cause DCE bailouts.

(cherry picked from commit fb569ef614)
2025-10-29 13:57:56 -07:00
Matthieu Riegler 366392b692 refactor(compiler): desambiguate and export RegularExpressionLiteralExpr
This allows all symbols used by `ExpressionVisitor` to be accessible.

(cherry picked from commit cfba831966)
2025-10-29 13:45:20 -07:00
Cheng-Hsuan Tsai 81b18fcbb7 ci: add workflow to copy and generate aria api pages
- add a script to copy Aria API json files from `angular/aria-builds`.
- build Aria API docs from json files.

(cherry picked from commit 3784fbcc12)
2025-10-29 13:38:40 -07:00
Matthieu Riegler 20b4b2c43c refactor(core): expose isWritableSignal to the publicApi
This is alongside the already exisiting isSignal()

fixes #64763

(cherry picked from commit 76adbbcd0a)
2025-10-29 13:31:53 -07:00
Miles Malerba 981fabc9b6 feat(docs-infra): add support for namespaces
Adds support for generating docs for namespaces (and merged declarations
of namespace + type)

(cherry picked from commit 662f0e5c00)
2025-10-29 13:22:26 -07:00
paszesoft 2a06e2b138 docs: Rename TodoListItem to UserProfile and fix usage of isValidUserId
(cherry picked from commit 6cc6d93e70)
2025-10-29 18:49:47 +01:00
paszesoft c9f8671960 Update button disabled property logic in template logical bug fix
isValidUserId = true is logically wrong to use to disable the Save button.
So is logically wrong to use isValidUserId = false to enable the Save button.
Also the default state of this button should be most likely disabled, if we are bothering to check, so the initial value of the signal should most likely be set to true.
To resolve these 2 issues, I propose to use:
- isInValidUserId instead of isValidUserId and:
- isInValidUserId = signal(true); // isValidUserId = signal(false);
After these 2 changes the snippet should make logical sense.

(cherry picked from commit b5dae85b27)
2025-10-29 18:49:47 +01:00
SkyZeroZx 207a26c125 docs(docs-infra): Prevent empty extends clause in interface documentation
Interfaces with no extends clause were incorrectly rendered with a trailing extends keyword followed by nothing, resulting in invalid TypeScript syntax

(cherry picked from commit f3d056a065)
2025-10-29 18:48:35 +01:00
Shuaib Hasan Akib ed500e42e6 fix(docs-infra): extract header attribute as title in multifile code snippets
The DocViewer component's getCodeSnippetsFromMultifileWrapper method was not
extracting the header attribute from nested <docs-code> elements, causing the
ExampleViewer to fall back to displaying file paths instead of custom headers
in tab labels.

This change adds title extraction from the header attribute when processing
multifile code snippets, ensuring that custom headers are properly displayed
in the code viewer tabs.

Fixes #64760

(cherry picked from commit 5d8b76b4fa)
2025-10-29 18:48:05 +01:00
Angular Robot 81fcfe5cbc docs: update Angular CLI help
Updated Angular CLI help contents.
2025-10-29 18:47:13 +01:00
Kristiyan Kostadinov 07b6fcac59 release: cut the v21.0.0-rc.0 release 2025-10-29 18:43:43 +01:00
Kristiyan Kostadinov db72aeff78 release: cut the v21.0.0-next.10 release 2025-10-29 18:40:08 +01:00
Lukas Matta 95344c19f3 fix(migrations): Do not remove a template if it is referenced even with a trailing semilocon
This commit fixes a behavior where under certain conditions, the migration script ignored
a template reference with a trailing semicolon and incorrectly removed the definition
of a referenced template.

Fixes #64741

(cherry picked from commit 64cb08529d)
2025-10-29 10:51:01 +01:00
Alan Agius feac577414 build: update typescript to 5.9.3
The beta version was unused in the pnpmfile.

(cherry picked from commit 13c386936b)
2025-10-29 10:46:50 +01:00
Angular Robot 209f0f964f build: update github/codeql-action action to v4.31.0
See associated pull request for more information.
2025-10-29 10:44:25 +01:00
Angular Robot ba5ca63330 build: update dependency node to v22.21.1
See associated pull request for more information.
2025-10-29 10:43:26 +01:00
Miles Malerba 9cecae81de docs(forms): make FIELD experimental
Adds `@experimental` tag to `FIELD`

(cherry picked from commit a7180b65db)
2025-10-29 10:40:53 +01:00
Miles Malerba e0a9cfc973 refactor(forms): rename the logic property on FieldPathNode
`logic` was a confusing name, as it is a logic builder instance, not a
logic instance.

(cherry picked from commit 3d70d68676)
2025-10-29 10:40:10 +01:00
Miles Malerba 60c8e2779c refactor(forms): preserve logic order when apply is used on root path
In some cases the logic order was not preserved properly when using `apply`. In particular this occurs when some logic is registered on a child of the root, followed by an apply to the root, followed by further logic registered on a child. In this case the final registered logic wound up running before the applied logic.

This happened because `FieldPathNode` for a child path was caching its `LogicNodeBuilder` at creation time. This meant that if the parent's `LogicNodeBuilder` changed (e.g., due to an `apply` call), the child would still be using the old one.

This commit fixes the issue by dynamically resolving the `LogicNodeBuilder` for a child path whenever it is accessed.

(cherry picked from commit fa13a167f1)
2025-10-29 10:40:09 +01:00
Alan Agius 6e004caa5b refactor(docs-infra): switch to unit test builder for unit tests
- Deletes the old Karma configuration and test entry point.
- Updates `angular.json` to use the `@angular/build` builders.
- Adjusts test files to align with the new setup.
2025-10-28 20:53:12 +01:00
Miles Malerba 07e56596a5 refactor(forms): track arrays in a parent array by index
This commit changes arrays in a parent array to be tracked the same way
as primitive values like strings and numbers. This is necessary because
the tracking key symbol used to maintain identity for objects in an
array does not survive the array spread operation:

```
return {...oldValue} // tracking symbol preserved ✅
return [...oldValue] // tracking symbol lost ❌
```

(cherry picked from commit f80b51a738)
2025-10-28 20:52:54 +01:00
Alan Agius ebdfd71f50 refactor(migrations): exclude all @angular/* packages from schematics bundle
This change updates the rollup configuration for the core schematics to exclude all `@angular/*` packages from the bundle. This is possible following https://github.com/angular/angular/pull/64703

This significantly reduces the size of the `@angular/core` schematics bundle, resulting in a size reduction to 5.8mb.

(cherry picked from commit b4e798ed87)
2025-10-28 20:51:53 +01:00
kirjs d74fb923cc refactor(forms): Allow returning plain values from validators
This makes the API nicer to use

(cherry picked from commit c57bbaa87d)
2025-10-28 20:50:48 +01:00
kirjs 07b9be1d2c refactor(forms): Allow returning plain values from validators
This makes the API nicer to use

(cherry picked from commit 8562e29be4)
2025-10-28 20:50:48 +01:00
kirjs 71a6266dd3 refactor(forms): Allow returning plain values from validators
This makes the API nicer to use

(cherry picked from commit 28847c9a19)
2025-10-28 20:50:48 +01:00
kirjs 2c2ea2c0da refactor(forms): Allow returning plain values from validators
This makes the API nicer to use

(cherry picked from commit b5c29d0d0a)
2025-10-28 20:50:48 +01:00
Angular Robot 098f6751ef build: update cross-repo angular dependencies
See associated pull request for more information.
2025-10-28 20:49:10 +01:00
Angular Robot b41a0704ec build: update cross-repo angular dependencies
See associated pull request for more information.
2025-10-28 10:26:32 -07:00
Matthieu Riegler d1d5c724e3 docs(docs-infra): allow cors for json files
fixes #64710

(cherry picked from commit f2de963bf3)
2025-10-28 16:55:57 +01:00
Matthieu Riegler 4f21ea72cb refactor(compiler-cli): Remove deep imports of compiler-cli in angular/core
migration schematics will pull from `compiler-cli/private/migrations`
core tests will pull from `compiler-cli/private/testing`

(cherry picked from commit 8e50cdb930)
2025-10-28 15:58:59 +01:00
Shuaib Hasan Akib c0a50bf18f fix(docs-infra): update guide navigation to remain active with query params
The navigation list component was using `routerLinkActive` with
`{ exact: true }`, which required an exact URL match including query
parameters. When visiting `/update-guide?v=19.0-20.0&l=1`, the link
`/update-guide` didn't match, so the active class wasn't applied.

Updated `routerLinkActiveOptions` to ignore query parameters while
maintaining exact path matching so the navigation item stays highlighted
when interacting with the update guide form.

(cherry picked from commit 33a872d90a)
2025-10-28 15:58:29 +01:00
Andrew Scott d303cde96d refactor(core): Remove zone toggles for test and standalone
The migration is complete internally. All that remains is bootstrapModule

(cherry picked from commit a253739ac8)
2025-10-28 15:58:02 +01:00
arielbackenroth 3fbaaa0176 refactor(http): add hooks for propagating traces across XHR callbacks.
Enables propagating a trace across XHR callbacks by providing a hook for
wrapping the callback with a function bound to the send trace context.

(cherry picked from commit 07b8e953f4)
2025-10-28 15:09:00 +01:00
tjshiu 3617167d3c docs: align adev best practices with llm-eval
(cherry picked from commit 763db3a70b)
2025-10-28 15:08:17 +01:00
Angular Robot 81b876582c build: lock file maintenance
See associated pull request for more information.
2025-10-28 10:27:50 +01:00
Shuaib Hasan Akib 845c1cd63e docs: remove shell language from terminal output block
Changed terminal output code block in installation.md from shell
language to plain text to prevent rendering of shell prompt ($).
The block displays read-only log output that users should not
execute as commands.

(cherry picked from commit e9b29c359d)
2025-10-28 10:26:53 +01:00
Angular Robot c87d1e0d84 docs: update Angular CLI help
Updated Angular CLI help contents.
2025-10-28 10:26:25 +01:00
Matthieu Riegler 7b77336603 docs: callout for provide function order
(cherry picked from commit be731deb7c)
2025-10-28 10:25:00 +01:00
Shuaib Hasan Akib ba719f4d15 refactor(router): remove redundant default value from routerOutletData input
Since `input()` defaults to `undefined`, the explicit initializer was unnecessary.
This improves clarity and reduces boilerplate.

(cherry picked from commit 8291760f9b)
2025-10-28 10:24:27 +01:00
Matt Lewis 54ad2304e3 fix(core): Clear lView from IcuIteratorState when stack is empty to prevent memory leak
If a component template contains an icu expression it is being retained until the next change detection cycle for that template. This results in a net retention of only ever a single copy of the given lView but that creates an opportunity for compounding leaks.

Change the icu i18n_icu_container_visitor to free the IcuIteratorState retained lView when the stack is empty so that garbage collection can occur when the view is discarded.

(cherry picked from commit 59e648913c)
2025-10-27 19:42:22 +01:00
SkyZeroZx 05bfda484e refactor(devtools): Improves clipboard error feedback with snackbar and logging
Enhances user experience by displaying a snackbar notification when clipboard copy fails, and logs detailed error information via the message bus

(cherry picked from commit bfcaf17005)
2025-10-27 19:41:57 +01:00
Matthieu Riegler ce5ca247e5 refactor(migrations): use the applicationProviders for the zoneless migration
PR #64354 introduced the `applicationProviders` for `bootstrapModule`, this allows a simpler migration output.

(cherry picked from commit eec6669733)
2025-10-27 19:41:32 +01:00
Angular Robot 8511759706 build: update rules_angular digest to 1f1aa3e
See associated pull request for more information.
2025-10-27 17:14:19 +01:00
Angular Robot 87eb11f961 build: update cross-repo angular dependencies
See associated pull request for more information.
2025-10-27 17:14:00 +01:00
Alan Agius 843f30afc9 build: reduce package size of @angular/core
The schematics bundle size is reduced by externalizing @angular/compiler. This reduces the package size from 11mb to 9.1mb.

(cherry picked from commit 9d00c6892f)
2025-10-27 17:12:51 +01:00
csorrentino bd780366e8 refactor(forms): add onError callback to validateHttp for HTTP errors
Adds onError callback inside validateHttp validator in signal forms

PR-Close: #63949
(cherry picked from commit a5678f6f2b)
2025-10-27 17:12:28 +01:00
Matthew Beck 04dd75ba94 fix(compiler): support arbitrary nesting in :host-context()
Previously we supported one level of nested pseudo-element selectors
inside :host-context(), e.g. :host-context(:is(.foo, .bar)). This was
based on a regex-based approach. We could support deeper levels of
nesting by updating the regex, but using a regex approach prohibits us
from supporting arbitrary nesting.

Rather than just adding one more level to the existing expression, I've
added a new generator function which splits selectors on commas in a
parenthesis-aware way. This allows us to support arbitrary nesting.

It's likely we'll want to reuse this in other places where we're not as
careful today. We'll probably do this on a request-based basis, though.

Fixes #59176

(cherry picked from commit b478e91068)
2025-10-27 13:40:50 +01:00
Alan Agius fdedc24794 build: remove unused rollup-plugin-sourcemaps dependency
This dependency is not used as we use `rollup-plugin-sourcemaps2` instead.

(cherry picked from commit 7a187a3bfd)
2025-10-27 13:40:02 +01:00
Alan Agius 350a16a28f build: add @babel/core to list of rollup_runtime_deps
This will be needed following https://github.com/devversion/rules_angular/pull/72

(cherry picked from commit fffd34bb6e)
2025-10-27 13:39:36 +01:00
Alan Agius a1b4e381e6 build: refactor location of best-practices.md
This commit moves the best-practices.md file from adev/src/context to packages/core/resources. The BUILD.bazel files and other configuration files have been updated to reflect this change.

(cherry picked from commit 25e8bcbdf6)
2025-10-27 09:31:39 +01:00
Shuaib Hasan Akib e62da0d1c7 fix(docs-infra): preserve shell class for multifile code blocks
The ExampleViewer component was extracting only innerHTML from code
blocks in multifile examples, which lost the shell class applied by
the formatCode function. This caused the $ prompt to not appear for
shell commands in multifile blocks even when language="shell" was set.

Modified the Snippet interface to track shell language state and
updated getCodeSnippetsFromMultifileWrapper and getStandaloneCodeSnippet
methods to preserve the shell class. Updated example-viewer template
to conditionally apply the shell class to the code wrapper element.

Fixes inconsistency between standalone and multifile shell code blocks.

(cherry picked from commit 27e183330e)
2025-10-27 09:29:42 +01:00
idembele70 00a996dd12 docs: fix accessibility of @empty block message
(cherry picked from commit 202fceed73)
2025-10-27 09:29:15 +01:00
Angular Robot 38606bb99a build: update cross-repo angular dependencies
See associated pull request for more information.
2025-10-27 09:28:44 +01:00
Miles Malerba 22c012c985 refactor(forms): fix some typos
Fix some typos in signal forms code

(cherry picked from commit 01e1ad2b37)
2025-10-27 09:27:05 +01:00
Alan Agius 9b77b43241 refactor(docs-infra): streamline adev build configuration
This commit introduces a number of changes to streamline the build configuration for adev, the documentation application.

(cherry picked from commit 53287bce9b)
2025-10-27 09:26:25 +01:00
SkyZeroZx 3bc260c630 docs: Adds guide links to HTTP API docs for better discoverability
(cherry picked from commit c5e6b8bdc8)
2025-10-27 09:26:01 +01:00
aparziale 91eb1e1fe2 refactor: inject an instance of typescript-vfs.worker
Modified tsVfsWorker worker initialization logic

(cherry picked from commit e155a1e9d7)
2025-10-27 09:25:00 +01:00
AleksanderBodurri cbeedb03d4 refactor(devtools): use getRouterInstance to replace manual parsing logic
Previously we would look in the DI tree for a token named 'Router' and resolve its value.

Now we use the already existing getRouterInstance, which depends on ng global debug APIs to get the router instance of an application.

(cherry picked from commit c963569c0e)
2025-10-27 09:23:20 +01:00
Andrew Scott 7a2d029f51 refactor(router): Add provider for integrating with Navigation API and Location shim
This adds a (private) provider for integrating with the browser Navigation API.
This provider ensures that interactions with the `Location` service
use the underlying platform navigation rather than the history and
location APIs.

(cherry picked from commit dd09da8ba2)
2025-10-27 09:22:00 +01:00
Kristiyan Kostadinov 9e8b4eb686 fix(docs-infra): fix broken adev tests
Fixes some adev tests that are broken on main.

(cherry picked from commit b5f8d0b5b1)
2025-10-24 21:28:32 +02:00
Alan Agius e9f55a8817 Revert "build: refactor location of best-practices.md"
This reverts commit 07a51872d5.

(cherry picked from commit 620e2c4926)
2025-10-24 19:02:42 +02:00
Angular Robot 5099ed4f18 build: update cross-repo angular dependencies
See associated pull request for more information.
2025-10-24 18:48:39 +02:00
Matthieu Riegler d8388b210a docs(docs-infra): Support linking to individual playground templates
(cherry picked from commit 6e7b3c2aa6)
2025-10-24 18:47:14 +02:00
SkyZeroZx 2abf2fb501 feat(common): Blocks IPv6 localhost from preconnect checks
Prevents unnecessary preconnect warnings by adding IPv6 loopback ('[::1]') to the blocklist.

(cherry picked from commit a3639e2258)
2025-10-24 18:46:48 +02:00
SkyZeroZx fd65ebca0f refactor(common): Add missing OnDestroy interface in PreconnectLinkChecker
The OnDestroy interface was implemented but not declared; this adds the missing interface declaration

(cherry picked from commit 207baad322)
2025-10-24 18:46:48 +02:00
Andrew Scott de5b0661e9 fix(zone.js): Support jasmine v6
This fixes the jasmine patch to ensure we are patching the private APIs
off of the right location, which changed in v6.

see https://github.com/jasmine/jasmine/commit/168ff0a751b6280b170ce097410d77a4c7c1f449

(cherry picked from commit 48abe007d9)
2025-10-24 18:46:09 +02:00
Alan Agius fb13537949 build: refactor location of best-practices.md
This commit moves the best-practices.md file from adev/src/context to packages/core/resources. The BUILD.bazel files and other configuration files have been updated to reflect this change.

(cherry picked from commit 07a51872d5)
2025-10-24 18:45:36 +02:00
Angular Robot d430d99965 docs: update Angular CLI help
Updated Angular CLI help contents.
2025-10-24 15:29:27 +02:00
Angular Robot a8f1784970 build: update cross-repo angular dependencies
See associated pull request for more information.
2025-10-24 15:26:00 +02:00
jase88 4f5a4a4297 docs: update workspace configuration link in security documentation
(cherry picked from commit cdfd073448)
2025-10-24 15:25:15 +02:00
SkyZeroZx 17a71e9c59 docs: Fix syntax highlighting & formatting in HTTP guide
(cherry picked from commit b1a0bad342)
2025-10-24 15:24:02 +02:00
Matthieu Riegler c89062b130 docs(docs-infra): enable strict templates
(cherry picked from commit 57af0d7e1b)
2025-10-24 15:23:32 +02:00
Angular Robot c02aa80c5e docs: update Angular CDK apis (#64642)
Updated Angular CDK api files.

PR Close #64642
2025-10-24 09:38:54 +02:00
Angular Robot ebdef35a6b build: update cypress-io/github-action action to v6.10.3 (#64636)
See associated pull request for more information.

PR Close #64636
2025-10-24 09:36:34 +02:00
Angular Robot c590401e74 build: update cross-repo angular dependencies (#64630)
See associated pull request for more information.

PR Close #64630
2025-10-24 09:33:45 +02:00
Alan Agius 9c518fcfc5 build: enable auto merge strategy for pull requests (#64624)
This commit enables the 'auto' merge strategy for pull requests.
This strategy automatically determines the best merge method based on the
pull request's commits.

The auto merge strategy can:
- Delegate to the autosquash merge strategy if the PR has fixup/squash
  commits against multiple normal commits.
- Squash commits if the PR has only one normal commit and some
  fixup/squash commits.
- Rebase commits if the PR has no fixup/squash commits.

This improves the developer experience by automating the merge process. A
key benefit is that PRs that can be cleanly rebased will now appear as
'merged' in GitHub's UI, providing a clearer history than the previous
'unmerged' status that could occur with squashing.

Additionally, `dev-infra` and `bazel` are removed from the exempted scopes
for target labels as they are no longer necessary.

PR Close #64624
2025-10-24 09:32:13 +02:00
Matthieu Riegler a1ac9a6415 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 aa389a691b fix(core): ensure @for iteration over field is reactive (#64113)
When working with a proxy object such as signal forms' `Field`,
accessing the `lenght` or `Symbol.iterator` may trgger a reactive read.
This change ensures that `@for` properly captrues this before clearing
the active consumer.

PR Close #64113
2025-10-24 09:29:29 +02:00
Miles Malerba 0af83e6855 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
Angular Robot d7e85a4da5 docs: update Angular CLI help (#64620)
Updated Angular CLI help contents.

PR Close #64620
2025-10-23 18:24:28 +02:00
Angular Robot 4ce1ffc65c build: update cross-repo angular dependencies (#64623)
See associated pull request for more information.

PR Close #64623
2025-10-23 18:23:56 +02:00
Miles Malerba 02f7263133 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 a6a5fd7b7d 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 f3c547b750 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 d963e7c035 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
Angular Robot 0385c8163a build: update cross-repo angular dependencies (#64617)
See associated pull request for more information.

PR Close #64617
2025-10-23 16:00:22 +02:00
Angular Robot c443c07225 build: update cross-repo angular dependencies (#64610)
See associated pull request for more information.

PR Close #64610
2025-10-23 12:39:58 +02:00
Angular Robot b23c876d2a build: update pnpm to v10.19.0 (#64608)
See associated pull request for more information.

PR Close #64608
2025-10-23 12:38:35 +02:00
Angular Robot 29fd414a05 build: update dependency aspect_rules_js to v2.7.0 (#64607)
See associated pull request for more information.

PR Close #64607
2025-10-23 12:37:55 +02:00
SkyZeroZx 87afeb833b docs: Add router config options (#64529)
PR Close #64529
2025-10-23 12:34:58 +02:00
Andrew Scott b7cefeb864 fix(router): handle parenthesized outlets without a name in DefaultUrlSerializer (#64507)
Previously, the `DefaultUrlSerializer` would incorrectly parse URLs with a parenthesized outlet that did not have a name, such as `/(left)`. This would result in an `undefined` outlet name in the serialized URL.

This commit fixes the issue by ensuring that parenthesized outlets without a name are treated as primary outlets.

fixes #58516. Based on the description, either the URL was constructed
manually or by custom serializer.

PR Close #64507
2025-10-23 12:33:59 +02:00
Andrew Scott 292b9e3da5 refactor(zone.js): Improve missing proxy zone error for jest imported (#64497)
test functions

This improves the fakeAsync error message when importing it, describe,
etc from jest

We will not be further expanding the ZoneJS patches to support
additional use-cases.

fixes #47603

PR Close #64497
2025-10-22 23:26:25 +00:00
Angular Robot de2ee6ebd5 docs: update Angular CDK apis (#64599)
Updated Angular CDK api files.

PR Close #64599
2025-10-22 21:57:17 +00:00
Angular Robot d183153545 build: update cross-repo angular dependencies (#64602)
See associated pull request for more information.

PR Close #64602
2025-10-22 21:46:06 +00:00
Jessica Janiuk 2b51a838b2 release: cut the v21.0.0-next.9 release 2025-10-22 14:24:57 -07:00
2173 changed files with 143461 additions and 75152 deletions
+1 -1
View File
@@ -143,7 +143,7 @@ build:trusted-build --remote_upload_local_results=true
# Ensure that tags like "no-remote-exec" get propagated to actions created by rules,
# even if the rule implementation does not explicitly pass them to the execution requirements.
# https://bazel.build/reference/command-line-reference#flag--experimental_allow_tags_propagation
common --experimental_allow_tags_propagation
common --incompatible_allow_tags_propagation
# Disable network access in the sandbox by default. To enable network access
# for a particular target, use:
+1 -1
View File
@@ -1 +1 @@
7.6.2
8.4.2
+14 -14
View File
@@ -1,4 +1,4 @@
import {cp, mkdtemp, readFile, rm, writeFile} from 'node:fs/promises';
import {mkdtemp, readFile, rm, writeFile} from 'node:fs/promises';
import {Deployment} from './deployments.mjs';
import {join} from 'node:path';
@@ -9,7 +9,7 @@ import {getCredentialFilePath} from './credential.mjs';
export async function deployToFirebase(
deployment: Deployment,
configPath: string,
distDirPath: string,
stagingDir: string,
) {
if (deployment.destination == undefined) {
console.log(`No deployment necessary for docs created from: ${deployment.branch}`);
@@ -18,37 +18,33 @@ export async function deployToFirebase(
console.log('Preparing for deployment to firebase...');
const tmpDeployDir = await mkdtemp(join(tmpdir(), 'deploy-directory'));
const deployConfigPath = join(tmpDeployDir, 'firebase.json');
const deployConfigPath = join(stagingDir, 'firebase.json');
const config = JSON.parse(await readFile(configPath, {encoding: 'utf-8'})) as {
hosting: {public: string};
};
config['hosting']['public'] = './dist';
config['hosting']['public'] = './browser';
await writeFile(deployConfigPath, JSON.stringify(config, null, 2));
await cp(distDirPath, join(tmpDeployDir, 'dist'), {recursive: true});
spawnSync(`chmod 777 -R ${tmpDeployDir}`, {encoding: 'utf-8', shell: true});
firebase(
`target:clear --config ${deployConfigPath} --project angular-dev-site hosting angular-docs`,
tmpDeployDir,
stagingDir,
);
firebase(
`target:apply --config ${deployConfigPath} --project angular-dev-site hosting angular-docs ${deployment.destination}`,
tmpDeployDir,
stagingDir,
);
firebase(
`deploy --config ${deployConfigPath} --project angular-dev-site --only hosting --non-interactive`,
tmpDeployDir,
stagingDir,
);
firebase(
`target:clear --config ${deployConfigPath} --project angular-dev-site hosting angular-docs`,
tmpDeployDir,
stagingDir,
);
await rm(tmpDeployDir, {recursive: true});
await rm(stagingDir, {recursive: true});
}
export async function setupRedirect(deployment: Deployment) {
@@ -103,7 +99,7 @@ export async function setupRedirect(deployment: Deployment) {
}
function firebase(cmd: string, cwd?: string) {
spawnSync('npx', `-y firebase-tools@13.15.1 ${cmd}`.split(' '), {
const {status} = spawnSync('npx', `-y firebase-tools@13.15.1 ${cmd}`.split(' '), {
cwd,
encoding: 'utf-8',
shell: true,
@@ -113,4 +109,8 @@ function firebase(cmd: string, cwd?: string) {
GOOGLE_APPLICATION_CREDENTIALS: getCredentialFilePath(),
},
});
if (status !== 0) {
console.error('Firebase command failed, see log above for details.');
process.exit(status);
}
}
@@ -9,6 +9,7 @@ export interface Deployment {
to: string;
};
destination?: string;
servingUrl: string;
}
export type Deployments = Map<string, Deployment>;
@@ -31,6 +32,7 @@ export async function getDeployments(): Promise<Deployments> {
docSites.set(branch.name, {
branch: branch.name,
destination: `v${branch.version.major}-angular-dev`,
servingUrl: `https://v${branch.version.major}.angular.dev/`,
});
});
@@ -40,12 +42,14 @@ export async function getDeployments(): Promise<Deployments> {
from: `v${releaseTrains.latest.version.major}-angular-dev`,
to: 'https://angular.dev',
},
servingUrl: 'https://angular.dev/',
destination: 'angular-dev-site',
});
if (releaseTrains.releaseCandidate) {
docSites.set(releaseTrains.next.branchName, {
branch: releaseTrains.next.branchName,
servingUrl: 'https://next.angular.dev/',
});
docSites.set(releaseTrains.releaseCandidate.branchName, {
@@ -55,11 +59,13 @@ export async function getDeployments(): Promise<Deployments> {
from: `v${releaseTrains.releaseCandidate.version.major}-angular-dev`,
to: 'https://next.angular.dev',
},
servingUrl: 'https://next.angular.dev/',
});
} else {
docSites.set(releaseTrains.next.branchName, {
branch: releaseTrains.next.branchName,
destination: 'next-angular-dev',
servingUrl: 'https://next.angular.dev/',
});
}
+14 -10
View File
@@ -2,19 +2,18 @@ import {getInput, setFailed} from '@actions/core';
import {context} from '@actions/github';
import {deployToFirebase, setupRedirect} from './deploy.mjs';
import {getDeployments} from './deployments.mjs';
import {AuthenticatedGitClient, GithubConfig, setConfig} from '@angular/ng-dev';
import {generateSitemap} from './sitemap.mjs';
import {assertValidGithubConfig, AuthenticatedGitClient, getConfig} from '@angular/ng-dev';
import {githubReleaseTrainReadToken} from './credential.mjs';
import {spawnSync} from 'child_process';
import {cp, mkdtemp} from 'fs/promises';
import {tmpdir} from 'os';
import {join} from 'path';
const refMatcher = /refs\/heads\/(.*)/;
async function deployDocs() {
setConfig({
github: {
mainBranchName: 'main',
name: 'angular',
owner: 'angular',
} as GithubConfig,
});
getConfig([assertValidGithubConfig]);
AuthenticatedGitClient.configure(githubReleaseTrainReadToken);
@@ -28,7 +27,11 @@ async function deployDocs() {
const currentBranch = matchedRef[1];
const configPath = getInput('configPath');
const distDir = getInput('distDir');
const stagingDir = await mkdtemp(join(tmpdir(), 'deploy-directory'));
// Copy all files from the distDir into stagingDir and modify the permissions for editing
await cp(getInput('distDir'), stagingDir, {recursive: true});
spawnSync(`chmod 777 -R ${stagingDir}`, {encoding: 'utf-8', shell: true});
const deployment = (await getDeployments()).get(currentBranch);
if (deployment === undefined) {
@@ -57,7 +60,8 @@ async function deployDocs() {
console.log(` To: ${deployment.redirect.to}`);
}
await deployToFirebase(deployment, configPath, distDir);
await generateSitemap(deployment, stagingDir);
await deployToFirebase(deployment, configPath, stagingDir);
await setupRedirect(deployment);
}
@@ -0,0 +1,33 @@
import {Deployment} from './deployments.mjs';
import {join} from 'path';
import {readFileSync, writeFileSync} from 'fs';
export async function generateSitemap(deployment: Deployment, distDir: string) {
const servingUrlWithoutEndingSlash = deployment.servingUrl.endsWith('/')
? deployment.servingUrl.slice(0, -1)
: deployment.servingUrl;
/** Timestamp string used to of the last file update. */
const lastModifiedTimestamp = new Date().toISOString();
/** An object containing all of the routes available within the application. */
const routes = JSON.parse(readFileSync(join(distDir, 'prerendered-routes.json'), 'utf-8'));
/** The generated sitemap string. */
const sitemap = `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
${Object.keys(routes.routes)
.map((route) => {
const routeWithoutLeadingSlash = route.startsWith('/') ? route.slice(1) : route;
return `
<url>
<loc>${servingUrlWithoutEndingSlash}/${routeWithoutLeadingSlash}</loc>
<lastmod>${lastModifiedTimestamp}</lastmod>
<changefreq>daily</changefreq>
<priority>1.0</priority>
</url>
`;
})
.join('')}
</urlset>`;
writeFileSync(join(distDir, 'browser', 'sitemap.xml'), sitemap, 'utf-8');
console.log(`Generated sitemap with ${Object.keys(routes.routes).length} entries.`);
}
File diff suppressed because one or more lines are too long
@@ -2,6 +2,7 @@
"compilerOptions": {
"module": "NodeNext",
"target": "ES2021",
"types": ["node"],
"lib": ["es2021"],
"experimentalDecorators": true,
"strict": true,
@@ -11,6 +12,5 @@
"noImplicitReturns": true,
"declaration": true,
"sourceMap": true
}
}
+2 -2
View File
@@ -5,9 +5,9 @@ runs:
using: 'composite'
steps:
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/bazel/setup@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Setup Saucelabs Variables
uses: angular/dev-infra/github-actions/saucelabs@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/saucelabs@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Starting Saucelabs tunnel service
shell: bash
run: ./tools/saucelabs/sauce-service.sh run &
+5 -5
View File
@@ -21,16 +21,16 @@ jobs:
(github.event.action == 'synchronize' && contains(github.event.pull_request.labels.*.name, 'adev: preview'))
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/bazel/setup@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/bazel/configure-remote@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Install node modules
run: pnpm install --frozen-lockfile
- name: Build adev
run: pnpm bazel build //adev:build.production
- uses: angular/dev-infra/github-actions/previews/pack-and-upload-artifact@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
run: pnpm bazel build //adev:build.production --config=snapshot-build
- uses: angular/dev-infra/github-actions/previews/pack-and-upload-artifact@90bba8b673b749ce67760b4d993b9b421adac30f
with:
workflow-artifact-name: 'adev-preview'
pull-number: '${{github.event.pull_request.number}}'
+2 -2
View File
@@ -29,7 +29,7 @@ jobs:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' }}
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
with:
token: '${{secrets.GITHUB_TOKEN}}'
@@ -40,7 +40,7 @@ jobs:
npx -y firebase-tools@latest target:clear --config adev/firebase.json --project ${{env.PREVIEW_PROJECT}} hosting angular-docs
npx -y firebase-tools@latest target:apply --config adev/firebase.json --project ${{env.PREVIEW_PROJECT}} hosting angular-docs ${{env.PREVIEW_SITE}}
- uses: angular/dev-infra/github-actions/previews/upload-artifacts-to-firebase@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
- uses: angular/dev-infra/github-actions/previews/upload-artifacts-to-firebase@90bba8b673b749ce67760b4d993b9b421adac30f
with:
github-token: '${{secrets.GITHUB_TOKEN}}'
workflow-artifact-name: 'adev-preview'
@@ -12,10 +12,11 @@ permissions:
jobs:
assistant_to_the_branch_manager:
runs-on: ubuntu-latest
if: github.event.repository.fork == false
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
persist-credentials: false
- uses: angular/dev-infra/github-actions/branch-manager@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
- uses: angular/dev-infra/github-actions/branch-manager@90bba8b673b749ce67760b4d993b9b421adac30f
with:
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
+2 -2
View File
@@ -28,7 +28,7 @@ jobs:
- uses: alessbell/pull-request-comment-branch@aad01d65d6982b8eacabed5e9a684cd8ceb98da6 # v1.1
id: comment-branch
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
# Specify repository as the PR branch might be from a fork.
repository: ${{steps.comment-branch.outputs.head_owner}}/${{steps.comment-branch.outputs.head_repo}}
@@ -38,7 +38,7 @@ jobs:
- run: pnpm install --frozen-lockfile
- uses: angular/dev-infra/github-actions/bazel/configure-remote@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
- uses: angular/dev-infra/github-actions/bazel/configure-remote@90bba8b673b749ce67760b4d993b9b421adac30f
with:
bazelrc: ./.bazelrc.user
+29 -38
View File
@@ -21,7 +21,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Install node modules
run: pnpm install --frozen-lockfile
- name: Check code lint
@@ -39,20 +39,15 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@90bba8b673b749ce67760b4d993b9b421adac30f
with:
disable-package-manager-cache: true
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/bazel/setup@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/bazel/configure-remote@90bba8b673b749ce67760b4d993b9b421adac30f
with:
google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }}
- name: Cache downloaded Cypress binary
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: '~/.cache/Cypress'
key: cypress-cache-${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}
- name: Install node modules
run: pnpm install --frozen-lockfile
- name: Run unit tests
@@ -60,7 +55,7 @@ jobs:
- name: Test build
run: pnpm devtools:build:chrome
- name: Cypress run
uses: cypress-io/github-action@b8ba51a856ba5f4c15cf39007636d4ab04f23e3c # v6.10.2
uses: cypress-io/github-action@7ef72e250a9e564efb4ed4c2433971ada4cc38b4 # v6.10.4
with:
command: pnpm devtools:test:e2e
start: pnpm bazel run //devtools/src:devserver
@@ -72,11 +67,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/bazel/setup@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Setup Bazel Remote Caching
uses: angular/dev-infra/github-actions/bazel/configure-remote@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/bazel/configure-remote@90bba8b673b749ce67760b4d993b9b421adac30f
with:
google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }}
- name: Install node modules
@@ -88,11 +83,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/bazel/setup@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Setup Bazel Remote Caching
uses: angular/dev-infra/github-actions/bazel/configure-remote@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/bazel/configure-remote@90bba8b673b749ce67760b4d993b9b421adac30f
with:
google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }}
- name: Install node modules
@@ -105,11 +100,11 @@ jobs:
labels: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/bazel/setup@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/bazel/configure-remote@90bba8b673b749ce67760b4d993b9b421adac30f
with:
google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }}
- name: Install node modules
@@ -124,20 +119,15 @@ jobs:
labels: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/bazel/setup@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/bazel/configure-remote@90bba8b673b749ce67760b4d993b9b421adac30f
with:
google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }}
- name: Install node modules
run: pnpm install --frozen-lockfile
- name: Cache downloaded vscode binary
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: '~/.cache/vscode-test'
key: vscode-cache-${{ runner.os }}-${{ hashFiles('vscode-ng-language-service/integration/e2e/index.ts') }} # The version is specified in this file.
- name: Run tests
run: pnpm bazel test //vscode-ng-language-service/...
@@ -146,11 +136,11 @@ jobs:
labels: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/bazel/setup@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/bazel/configure-remote@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Install node modules
run: pnpm install --frozen-lockfile
- run: echo "https://${{secrets.SNAPSHOT_BUILDS_GITHUB_TOKEN}}:@github.com" > ${HOME}/.git_credentials
@@ -162,11 +152,11 @@ jobs:
labels: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/bazel/setup@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/bazel/configure-remote@90bba8b673b749ce67760b4d993b9b421adac30f
with:
google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }}
- name: Install node modules
@@ -216,22 +206,23 @@ jobs:
runs-on: ubuntu-latest-8core
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/bazel/setup@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/bazel/configure-remote@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Install node modules
run: pnpm install --frozen-lockfile
- name: Build adev
run: pnpm bazel build //adev:build.production --config=release
# `snapshot-build` config is used to stamp the exact version with sha in the footer.
run: pnpm bazel build //adev:build.production --config=snapshot-build
- name: Deploy to firebase
uses: ./.github/actions/deploy-docs-site
with:
serviceKey: ${{ secrets.ANGULAR_DEV_SITE_DEPLOY }}
githubReleaseTrainReadToken: ${{ secrets.DOCS_DEPLOY_GITHUB_RELEASE_TRAIN_TOKEN }}
configPath: 'adev/firebase.json'
distDir: 'dist/bin/adev/dist/browser'
distDir: 'dist/bin/adev/dist'
- name: Update Algolia synonym record
run: pnpm tsx adev/scripts/synonyms/update-synonyms.mts
env:
@@ -0,0 +1,59 @@
name: Update ADEV Cross Repo Docs
on:
workflow_dispatch:
inputs: {}
push:
branches:
- 'main'
- '[0-9]+.[0-9]+.x'
# Declare default permissions as read only.
permissions:
contents: read
jobs:
update_adev_cross_repo_docs:
name: Update Cross Repo ADEV Docs
if: github.repository == 'angular/angular'
runs-on: ubuntu-latest
# Prevents multiple concurrent runs of this workflow for the same branch
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
steps:
- name: Checkout the repository
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
# Setting `persist-credentials: false` prevents the github-action account from being the
# account that is attempted to be used for authentication, instead the remote is set to
# an authenticated URL.
persist-credentials: false
- name: Generate Docs
run: node adev/scripts/update-cross-repo-docs/index.mjs
env:
ANGULAR_READONLY_GITHUB_TOKEN: ${{ secrets.READONLY_GITHUB_TOKEN }}
- name: Create a PR (if necessary)
uses: peter-evans/create-pull-request@84ae59a2cdc2258d6fa0732dd66352dddae2a412 # v7.0.9
with:
token: ${{ secrets.ANGULAR_ROBOT_ACCESS_TOKEN }}
push-to-fork: 'angular-robot/angular'
delete-branch: true
maintainer-can-modify: false
branch: docs-cross-repo-update-${{github.ref_name}}
committer: Angular Robot <angular-robot@google.com>
author: Angular Robot <angular-robot@google.com>
title: 'docs: update cross-repo adev docs [${{github.ref_name}}]'
body: |
Updated Angular adev cross repo docs files.
labels: |
action: merge
area: docs
target: automation
commit-message: |
docs: update cross-repo adev docs
Updated Angular adev cross repo docs files.
+4 -4
View File
@@ -12,14 +12,14 @@ jobs:
labels:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: angular/dev-infra/github-actions/pull-request-labeling@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
- uses: angular/dev-infra/github-actions/pull-request-labeling@90bba8b673b749ce67760b4d993b9b421adac30f
with:
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
post_approval_changes:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: angular/dev-infra/github-actions/post-approval-changes@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
- uses: angular/dev-infra/github-actions/post-approval-changes@90bba8b673b749ce67760b4d993b9b421adac30f
with:
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
+2 -2
View File
@@ -13,8 +13,8 @@ jobs:
statuses: write
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: angular/dev-infra/github-actions/google-internal-tests@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
- uses: angular/dev-infra/github-actions/google-internal-tests@90bba8b673b749ce67760b4d993b9b421adac30f
with:
run-tests-guide-url: http://go/angular-g3sync-start
github-token: ${{ secrets.GITHUB_TOKEN }}
+4 -4
View File
@@ -13,15 +13,15 @@ jobs:
JOBS: 2
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Install node modules
run: pnpm install --frozen-lockfile
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/bazel/setup@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Setup Bazel Remote Caching
uses: angular/dev-infra/github-actions/bazel/configure-remote@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/bazel/configure-remote@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Setup Saucelabs Variables
uses: angular/dev-infra/github-actions/saucelabs@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/saucelabs@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Set up Sauce Tunnel Daemon
run: pnpm bazel run //tools/saucelabs-daemon/background-service -- $JOBS &
env:
+1 -1
View File
@@ -9,6 +9,6 @@ jobs:
status:
runs-on: ubuntu-latest
steps:
- uses: angular/dev-infra/github-actions/unified-status-check@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
- uses: angular/dev-infra/github-actions/unified-status-check@90bba8b673b749ce67760b4d993b9b421adac30f
with:
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
+3 -3
View File
@@ -21,7 +21,7 @@ jobs:
workflows: ${{ steps.workflows.outputs.workflows }}
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Install node modules
run: pnpm install --frozen-lockfile
- id: workflows
@@ -36,9 +36,9 @@ jobs:
workflow: ${{ fromJSON(needs.list.outputs.workflows) }}
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/bazel/setup@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Install node modules
run: pnpm install --frozen-lockfile
# We utilize the google-github-actions/auth action to allow us to get an active credential using workflow
+21 -31
View File
@@ -19,7 +19,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Install node modules
run: pnpm install --frozen-lockfile
- name: Check code lint
@@ -37,7 +37,7 @@ jobs:
- name: Check code format
run: pnpm ng-dev format changed --check ${{ github.event.pull_request.base.sha }}
- name: Check Package Licenses
uses: angular/dev-infra/github-actions/linting/licenses@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/linting/licenses@90bba8b673b749ce67760b4d993b9b421adac30f
with:
allow-dependencies-licenses: 'pkg:npm/google-protobuf@'
@@ -45,18 +45,13 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@90bba8b673b749ce67760b4d993b9b421adac30f
with:
disable-package-manager-cache: true
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/bazel/setup@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
- name: Cache downloaded Cypress binary
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: '~/.cache/Cypress'
key: cypress-cache-${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}
uses: angular/dev-infra/github-actions/bazel/configure-remote@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Install node modules
run: pnpm install --frozen-lockfile
- name: Run unit tests
@@ -64,7 +59,7 @@ jobs:
- name: Test build
run: pnpm devtools:build:chrome
- name: Cypress run
uses: cypress-io/github-action@b8ba51a856ba5f4c15cf39007636d4ab04f23e3c # v6.10.2
uses: cypress-io/github-action@7ef72e250a9e564efb4ed4c2433971ada4cc38b4 # v6.10.4
with:
command: pnpm devtools:test:e2e
start: pnpm bazel run //devtools/src:devserver
@@ -76,11 +71,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/bazel/setup@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Setup Bazel Remote Caching
uses: angular/dev-infra/github-actions/bazel/configure-remote@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/bazel/configure-remote@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Install node modules
run: pnpm install --frozen-lockfile
- name: Run CI tests for framework
@@ -100,11 +95,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/bazel/setup@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Setup Bazel Remote Caching
uses: angular/dev-infra/github-actions/bazel/configure-remote@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/bazel/configure-remote@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Install node modules
run: pnpm install --frozen-lockfile
- name: Run integration CI tests for framework
@@ -115,11 +110,11 @@ jobs:
labels: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/bazel/setup@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/bazel/configure-remote@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Install node modules
run: pnpm install --frozen-lockfile
- name: Run tests
@@ -132,18 +127,13 @@ jobs:
labels: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/bazel/setup@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/bazel/configure-remote@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Install node modules
run: pnpm install --frozen-lockfile
- name: Cache downloaded vscode binary
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: '~/.cache/vscode-test'
key: vscode-cache-${{ runner.os }}-${{ hashFiles('vscode-ng-language-service/integration/e2e/index.ts') }} # The version is specified in this file.
- name: Run tests
run: pnpm bazel test //vscode-ng-language-service/...
@@ -152,11 +142,11 @@ jobs:
labels: ubuntu-latest
steps:
- name: Initialize environment
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Setup Bazel
uses: angular/dev-infra/github-actions/bazel/setup@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/bazel/setup@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Setup Bazel RBE
uses: angular/dev-infra/github-actions/bazel/configure-remote@5c8f5f7c0a4e805a8ee33706ee2df99854396bbd
uses: angular/dev-infra/github-actions/bazel/configure-remote@90bba8b673b749ce67760b4d993b9b421adac30f
- name: Install node modules
run: pnpm install --frozen-lockfile
- run: |
+2 -2
View File
@@ -25,7 +25,7 @@ jobs:
steps:
- name: 'Checkout code'
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
persist-credentials: false
@@ -47,6 +47,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard.
- name: 'Upload to code-scanning'
uses: github/codeql-action/upload-sarif@16140ae1a102900babc80a33c44059580f687047 # v4.30.9
uses: github/codeql-action/upload-sarif@fdbfb4d2750291e159f0156def62b853c2798ca2 # v4.31.5
with:
sarif_file: results.sarif
@@ -1,89 +0,0 @@
name: Update ADEV Angular CDK APIs and CLI Help
on:
workflow_dispatch:
inputs: {}
push:
branches:
- 'main'
- '[0-9]+.[0-9]+.x'
# Declare default permissions as read only.
permissions:
contents: read
jobs:
update_adev_docs:
name: Update Angular CDK APIs and CLI Help (if necessary)
if: github.repository == 'angular/angular'
runs-on: ubuntu-latest
# Prevents multiple concurrent runs of this workflow for the same branch
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
steps:
- name: Checkout the repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
# Setting `persist-credentials: false` prevents the github-action account from being the
# account that is attempted to be used for authentication, instead the remote is set to
# an authenticated URL.
persist-credentials: false
# Angular CDK
- name: Generate CDK apis
run: node adev/scripts/update-cdk-apis/index.mjs
env:
ANGULAR_CDK_BUILDS_READONLY_GITHUB_TOKEN: ${{ secrets.ANGULAR_CDK_BUILDS_READONLY_GITHUB_TOKEN }}
- name: Create a PR CDK apis (if necessary)
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
with:
token: ${{ secrets.ANGULAR_ROBOT_ACCESS_TOKEN }}
push-to-fork: 'angular-robot/angular'
delete-branch: true
maintainer-can-modify: false
branch: docs-update-cdk-apis-${{github.ref_name}}
committer: Angular Robot <angular-robot@google.com>
author: Angular Robot <angular-robot@google.com>
title: 'docs: update Angular CDK apis [${{github.ref_name}}]'
body: |
Updated Angular CDK api files.
labels: |
action: merge
area: docs
target: automation
commit-message: |
docs: update Angular CDK apis
Updated Angular CDK api files.
# Angular CLI
- name: Reset to current GitHub ref
run: |
git reset --hard ${{ github.ref }}
- name: Generate CLI help
run: node adev/scripts/update-cli-help/index.mjs
env:
ANGULAR_CLI_BUILDS_READONLY_GITHUB_TOKEN: ${{ secrets.ANGULAR_CLI_BUILDS_READONLY_GITHUB_TOKEN }}
- name: Create a PR CLI help (if necessary)
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
with:
token: ${{ secrets.ANGULAR_ROBOT_ACCESS_TOKEN }}
push-to-fork: 'angular-robot/angular'
delete-branch: true
maintainer-can-modify: false
branch: docs-update-cli-help-${{github.ref_name}}
committer: Angular Robot <angular-robot@google.com>
author: Angular Robot <angular-robot@google.com>
title: 'docs: update Angular CLI help [${{github.ref_name}}]'
body: |
Updated Angular CLI help contents.
labels: |
action: merge
area: docs
target: automation
commit-message: |
docs: update Angular CLI help
Updated Angular CLI help contents.
@@ -1,7 +1,9 @@
import {CaretakerConfig} from '@angular/ng-dev';
/** The configuration for `ng-dev caretaker` commands. */
export const caretaker: CaretakerConfig = {
/**
* The configuration for `ng-dev caretaker` commands.
*
* @type { import("@angular/ng-dev").CaretakerConfig }
*/
export const caretaker = {
g3SyncConfigPath: './.ng-dev/google-sync-config.json',
githubQueries: [
{
@@ -17,5 +19,5 @@ export const caretaker: CaretakerConfig = {
query: `is:open no:milestone -draft:true`,
},
],
caretakerGroup: 'angular-caretaker',
hasEmeaCaretaker: true,
};
@@ -1,9 +1,9 @@
import {CommitMessageConfig} from '@angular/ng-dev';
/**
* The configuration for `ng-dev commit-message` commands.
*
* @type { import("@angular/ng-dev").CommitMessageConfig }
*/
export const commitMessage: CommitMessageConfig = {
export const commitMessage = {
maxLineLength: Infinity,
minBodyLength: 20,
minBodyLengthTypeExcludes: ['docs'],
+1 -8
View File
@@ -5,11 +5,4 @@ import {github} from './github.mjs';
import {pullRequest} from './pull-request.mjs';
import {release} from './release.mjs';
export {
commitMessage,
format,
github,
pullRequest,
caretaker,
release,
};
export {commitMessage, format, github, pullRequest, caretaker, release};
+9
View File
@@ -0,0 +1,9 @@
/**
* Configuration for the `ng-dev format` command.
*
* @type { import("@angular/ng-dev").FormatConfig }
*/
export const format = {
'prettier': true,
'buildifier': true,
};
-34
View File
@@ -1,34 +0,0 @@
import {FormatConfig} from '@angular/ng-dev';
/**
* Configuration for the `ng-dev format` command.
*/
export const format: FormatConfig = {
'prettier': {
'matchers': [
'**/*.{yaml,yml}',
'**/*.{js,ts,mjs,mts,cjs,cts,tsx}',
'devtools/**/*.{js,ts,mjs,mts,cjs,cts,html,scss}',
'integration/**/size.json',
// Do not format d.ts files as they are generated
'!**/*.d.ts',
// Both third_party and .yarn are directories containing copied code which should
// not be modified.
'!third_party/**',
// Do not format the locale files which are checked-in for Google3, but generated using
// the `generate-locales-tool` from `packages/common/locales`.
'!packages/core/src/i18n/locale_en.ts',
'!packages/common/locales/closure-locale.ts',
'!packages/common/src/i18n/currencies.ts',
// Test cases contain non valid code.
'!packages/compiler-cli/test/compliance/test_cases/**/*.{js,ts,mjs,mts,cjs,cts}',
// Ignore generated javascript file(s)
'!.github/actions/deploy-docs-site/main.js',
// Ignore testing data files for language service
'!vscode-ng-language-service/syntaxes/test/data/*.ts',
],
},
'buildifier': true,
};
+4 -4
View File
@@ -1,12 +1,12 @@
import {GithubConfig} from '@angular/ng-dev';
/**
* Github configuration for the `ng-dev` command. This repository is used as
* remote for the merge script and other utilities like `ng-dev pr rebase`.
*
* @type { import("@angular/ng-dev").GithubConfig }
*/
export const github: GithubConfig = {
export const github = {
owner: 'angular',
name: 'angular',
mainBranchName: 'main',
useNgDevAuthService: true,
mergeMode: 'caretaker-only',
};
@@ -1,11 +1,14 @@
import {PullRequestConfig} from '@angular/ng-dev';
/**
* Configuration for the merge tool in `ng-dev`. This sets up the labels which
* are respected by the merge script (e.g. the target labels).
*
* @type { import("@angular/ng-dev").PullRequestConfig }
*/
export const pullRequest: PullRequestConfig = {
githubApiMerge: false,
export const pullRequest = {
githubApiMerge: {
default: 'auto',
labels: [{pattern: 'merge: squash commits', method: 'squash'}],
},
requiredBaseCommits: {
// PRs that target either `main` or the patch branch, need to be rebased
// on top of the latest commit message validation fix.
@@ -13,10 +16,8 @@ export const pullRequest: PullRequestConfig = {
'main': '5aeb9a4124922d8ac08eb73b8f322905a32b0b3a',
'10.0.x': '27b95ba64a5d99757f4042073fd1860e20e3ed24',
},
// `dev-infra` and `docs-infra` are not affecting the public NPM packages. Similarly,
// the `bazel` package is not considered part of the public API so that features
// can land in patch branches.
targetLabelExemptScopes: ['dev-infra', 'docs-infra', 'bazel'],
// `docs-infra` are not affecting the public NPM packages.
targetLabelExemptScopes: ['docs-infra'],
// enables specific validations during the pull request merge process
validators: {
assertEnforceTested: true,
+6 -4
View File
@@ -1,7 +1,9 @@
import {ReleaseConfig} from '@angular/ng-dev';
/** Configuration for the `ng-dev release` command. */
export const release: ReleaseConfig = {
/**
* Configuration for the `ng-dev release` command.
*
* @type { import("@angular/ng-dev").ReleaseConfig }
*/
export const release = {
publishRegistry: 'https://wombat-dressing-room.appspot.com',
representativeNpmPackage: '@angular/core',
npmPackages: [
+1 -1
View File
@@ -1 +1 @@
22.21.0
22.21.1
+1 -1
View File
@@ -25,7 +25,7 @@ function readPackage(pkg, context) {
pkg.dependencies = {
...pkg.dependencies,
'@angular/compiler': 'workspace:*',
'typescript': '5.9.0-beta',
'typescript': '5.9.3',
};
}
+34 -2
View File
@@ -1,3 +1,35 @@
.prettierrc
pnpm-lock.yaml
pnpm-lock.yaml
# Do not format d.ts files as they are generated
**/*.d.ts
# Both third_party and .yarn are directories containing copied code which should
# not be modified.
third_party/**/*.js
third_party/**/*.css
third_party/**/*.md
third_party/**/*.json
# Do not format the locale files which are checked-in for Google3, but generated using
# the `generate-locales-tool` from `packages/common/locales`.
packages/core/src/i18n/locale_en.ts
packages/common/locales/closure-locale.ts
packages/common/src/i18n/currencies.ts
# Test cases contain non valid code.
packages/compiler-cli/test/compliance/test_cases/**/*.js
packages/compiler-cli/test/compliance/test_cases/**/*.ts
# Ignore generated javascript file(s)
.github/actions/deploy-docs-site/main.js
# Ignore testing data files for language service
vscode-ng-language-service/syntaxes/test/data/*.ts
# Ignore goldens MD files
goldens/**/*.api.md
# adev generated files
adev/src/content/aria/**/*.json
adev/src/content/cli/**/*.json
adev/src/content/cdk/**/*.json
+16 -1
View File
@@ -7,5 +7,20 @@
"semi": true,
"quoteProps": "preserve",
"bracketSpacing": false,
"trailingComma": "all"
"trailingComma": "all",
"overrides": [
{
"files": ["./.prettierrc"],
"options": {
"parser": "json"
}
},
{
"files": ["*.html"],
"excludeFiles": ["**/test/**"],
"options": {
"parser": "angular"
}
}
]
}
+8 -69
View File
@@ -15,9 +15,6 @@
# - We trust that people do the right thing and won't approve changes they don't feel confident reviewing
# - We enforce that only approved PRs are merged ensuring that unreviewed code isn't accidentally merged
# - We distribute approval rights as much as possible to help us scale better
# - Groups have one or two global approvers groups as fallbacks:
# - @angular/fw-global-approvers: for approving minor changes, large-scale refactorings, and emergency situations.
# - @angular/fw-global-approvers-for-docs-only-changes: for approving minor documentation-only changes that don't require engineering review
# - A small number of file groups have very limited number of reviewers because incorrect changes to the files they guard would have serious consequences (e.g. security, public api)
#
# Configuration nuances:
@@ -37,23 +34,6 @@
# See reviewer list under `required-minimum-review` group. Team member names and
# usernames are managed there.
####################################################################################
# Approval Groups
####################################################################################
# =========================================================
# @angular/framework-global-approvers
# =========================================================
# Used for approving minor changes, large-scale refactorings, and in emergency situations.
#
# alxhub
# jelbourn
# josephperrott
#
# =========================================================
# @angular/framework-global-approvers-for-docs-only-changes
# =========================================================
# Used for approving minor documentation-only changes that don't require engineering review.
version: 3
#availability:
@@ -97,14 +77,6 @@ overrides:
- if: len(groups.active.exclude("required-minimum-review").exclude("global-*")) == 0 and len(groups.approved.include("global-*")) == 0
status: failure
explanation: 'At least one group must match this PR. Please update an existing review group, or create a new group.'
# If any global dev-infra approval is given the status should be passing.
- if: len(groups.approved.include("global-dev-infra-approvers")) == 1
status: success
explanation: 'Passing as globally approved by dev-infra'
# If any global docs approval is given the status should be passing.
- if: len(groups.approved.include("global-docs-approvers")) == 1
status: success
explanation: 'Passing as globally approved by docs'
# If any global approval is given the status should be passing.
- if: len(groups.approved.include("global-approvers")) == 1
status: success
@@ -138,6 +110,7 @@ groups:
- ~amishne
- ~leonsenft
- ~mattrbeck
- ~JeanMeche
# =========================================================
# Framework: General (most code in our packages)
@@ -290,7 +263,7 @@ groups:
- devversion
- josephperrott
- ~pkozlowski-opensource
- mgechev
- ~mgechev
- MarkTechson
- mmalerba
- ~hawkgs
@@ -314,7 +287,7 @@ groups:
- ~devversion
- dgp1130
- hawkgs
- jkrems
- hybrist
- ~josephperrott
- JeanMeche
- milomg
@@ -406,7 +379,7 @@ groups:
- crisbeto
- devversion
- JeanMeche
- ~jkrems
- ~hybrist
- ~iteriani
- ~tbondwilkinson
- ~rahatarmanahmed
@@ -536,44 +509,10 @@ groups:
global-approvers:
type: optional
reviewers:
teams:
- framework-global-approvers
reviews:
request: 0
required: 1
reviewed_for: required
# =========================================================
# Global Approvers For Docs
#
# All reviews performed for global docs approvals require
# using the `Reviewed-for:` specifier to set the approval
# specificity as documented at:
# https://docs.pullapprove.com/reviewed-for/
# =========================================================
global-docs-approvers:
type: optional
reviewers:
teams:
- framework-global-approvers-for-docs-only-changes
reviews:
request: 0
required: 1
reviewed_for: required
# =========================================================
# Global Approvers For Dev-Infra changes
#
# All reviews performed for global dev-infra approvals
# require using the `Reviewed-for:` specifier to set the
# approval specificity as documented at:
# https://docs.pullapprove.com/reviewed-for/
# =========================================================
global-dev-infra-approvers:
type: optional
reviewers:
teams:
- dev-infra-framework
users:
- alxhub
- jelbourn
- josephperrott
reviews:
request: 0
required: 1
+5388 -3584
View File
File diff suppressed because it is too large Load Diff
+5519 -5035
View File
File diff suppressed because it is too large Load Diff
+13 -13
View File
@@ -14,20 +14,20 @@ appearance, race, religion, or sexual identity and orientation.
Examples of behavior that contributes to creating a positive environment
include:
* Use welcoming and inclusive language
* Respect each other
* Provide and gracefully accept constructive criticism
* Show empathy towards other community members
- Use welcoming and inclusive language
- Respect each other
- Provide and gracefully accept constructive criticism
- Show empathy towards other community members
Examples of unacceptable behavior by participants include:
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
- Trolling, insulting/derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or electronic
address, without explicit permission
* The use of sexualized language or imagery
* Unwelcome sexual attention or advances
* Other conduct which could reasonably be considered inappropriate in a
- The use of sexualized language or imagery
- Unwelcome sexual attention or advances
- Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
@@ -69,9 +69,9 @@ members of the project's leadership.
If you are banned you may contest the decision. To do so email conduct@angular.io with the subject line "Repeal Ban for {{your name here}}" and body with the responses to the following:
* Why do you believe you did not violate the Code of Conduct?
* Were other factors involved in this situation the leadership team may have been unaware of?
* Why do you wish to be a part of the Angular community?
- Why do you believe you did not violate the Code of Conduct?
- Were other factors involved in this situation the leadership team may have been unaware of?
- Why do you wish to be a part of the Angular community?
## Attribution
+97 -90
View File
@@ -3,22 +3,20 @@
We would love for you to contribute to Angular and help make it even better than it is today!
As a contributor, here are the guidelines we would like you to follow:
- [Code of Conduct](#coc)
- [Question or Problem?](#question)
- [Issues and Bugs](#issue)
- [Feature Requests](#feature)
- [Submission Guidelines](#submit)
- [Coding Rules](#rules)
- [Commit Message Guidelines](#commit)
- [Signing the CLA](#cla)
- [Code of Conduct](#coc)
- [Question or Problem?](#question)
- [Issues and Bugs](#issue)
- [Feature Requests](#feature)
- [Submission Guidelines](#submit)
- [Coding Rules](#rules)
- [Commit Message Guidelines](#commit)
- [Signing the CLA](#cla)
## <a name="coc"></a> Code of Conduct
Help us keep Angular open and inclusive.
Please read and follow our [Code of Conduct][coc].
## <a name="question"></a> Got a Question or Problem?
Do not open issues for general support questions as we want to keep GitHub issues for bug reports and feature requests.
@@ -34,28 +32,25 @@ To save your and our time, we will systematically close all issues that are requ
If you would like to chat about the question in real-time, you can reach out via [the Angular community Discord server][discord].
## <a name="issue"></a> Found a Bug?
If you find a bug in the source code, you can help us by [submitting an issue](#submit-issue) to our [GitHub Repository][github].
Even better, you can [submit a Pull Request](#submit-pr) with a fix.
## <a name="feature"></a> Missing a Feature?
You can *request* a new feature by [submitting an issue](#submit-issue) to our GitHub Repository.
If you would like to *implement* a new feature, please consider the size of the change in order to determine the right steps to proceed:
* For a **Major Feature**, first open an issue and outline your proposal so that it can be discussed.
You can _request_ a new feature by [submitting an issue](#submit-issue) to our GitHub Repository.
If you would like to _implement_ a new feature, please consider the size of the change in order to determine the right steps to proceed:
- For a **Major Feature**, first open an issue and outline your proposal so that it can be discussed.
This process allows us to better coordinate our efforts, prevent duplication of work, and help you to craft the change so that it is successfully accepted into the project.
**Note**: Adding a new topic to the documentation, or significantly re-writing a topic, counts as a major feature.
* **Small Features** can be crafted and directly [submitted as a Pull Request](#submit-pr).
- **Small Features** can be crafted and directly [submitted as a Pull Request](#submit-pr).
## <a name="submit"></a> Submission Guidelines
### <a name="submit-issue"></a> Submitting an Issue
Before you submit an issue, please search the issue tracker. An issue for your problem might already exist and the discussion might inform you of workarounds readily available.
@@ -74,50 +69,67 @@ Unfortunately, we are not able to investigate / fix bugs without a minimal repro
You can file new issues by selecting from our [new issue templates](https://github.com/angular/angular/issues/new/choose) and filling out the issue template.
### <a name="pr-quality"></a> Contribution Quality
We strongly value open source contribution and pull requests from community contributors. Please note that every pull request is reviewed and merged by an actual person on the team, which does take time and effort. That is time and effort that does take away from other valuable work. With that in mind we have an minimum set of expectations that are required of any community contribution pull request that is opened.
1. Search [GitHub](https://github.com/angular/angular/pulls) for an open or closed PR that relates to your submission.
- You don't want to duplicate existing efforts.
2. Be sure that an issue or pull request clearly describes the problem you're fixing, or documents the design for the feature you'd like to add. Issues require a _minimal_ reproduction.
3. Discussing the design in an issue upfront helps to ensure that we're ready to accept your work. Pull requests are not the right place to do design work.
- When in doubt, open an issue first before doing any sort of speculative implementation work
4. Ideally the PR should be tied to an issue, but this is not required
5. The change should improve code quality (i.e. addressing a TODO) or should impact / improve a feature
6. Micro optimizations will only be accepted if they are validated by an actual benchmark
7. Do not open pull requests that are addressing feature requests that are not labeled as "help wanted" as they usually need additional design work before we could accept pull requests
8. The change should be well tested
If your pull request does not meet these minimum expectations, we may close your PR. Also, if your PR introduces a breaking change, it's possible the level of churn this breaking change causes may block our ability to move forward with it. We may close your PR in that situation, as well. Otherwise, we're excited to see your contributions and enthusiasm for Angular!
### <a name="submit-pr"></a> Submitting a Pull Request (PR)
Before you submit your Pull Request (PR) consider the following guidelines:
1. Search [GitHub](https://github.com/angular/angular/pulls) for an open or closed PR that relates to your submission.
You don't want to duplicate existing efforts.
2. Be sure that an issue describes the problem you're fixing, or documents the design for the feature you'd like to add.
Discussing the design upfront helps to ensure that we're ready to accept your work.
3. Please sign our [Contributor License Agreement (CLA)](#cla) before sending PRs.
1. Please sign our [Contributor License Agreement (CLA)](#cla) before sending PRs.
We cannot accept code without a signed CLA.
Make sure you author all contributed Git commits with email address associated with your CLA signature.
4. [Fork](https://docs.github.com/en/github/getting-started-with-github/fork-a-repo) the [angular/angular](https://github.com/angular/angular/fork) repo.
2. [Fork](https://docs.github.com/en/github/getting-started-with-github/fork-a-repo) the [angular/angular](https://github.com/angular/angular/fork) repo.
5. In your forked repository, make your changes in a new git branch:
3. In your forked repository, make your changes in a new git branch:
```shell
git checkout -b my-fix-branch main
```
```shell
git checkout -b my-fix-branch main
```
6. Create your patch, **including appropriate test cases**.
4. Create your patch, **including appropriate test cases**.
7. Follow our [Coding Rules](#rules).
5. Follow our [Coding Rules](#rules).
8. Run the full Angular test suite, as described in the [developer documentation][dev-doc], and ensure that all tests pass.
6. Run the full Angular test suite, as described in the [developer documentation][dev-doc], and ensure that all tests pass.
9. Commit your changes using a descriptive commit message that follows our [commit message conventions][commit-message-guidelines].
7. Commit your changes using a descriptive commit message that follows our [commit message conventions][commit-message-guidelines].
Adherence to these conventions is necessary because release notes are automatically generated from these messages.
```shell
git commit --all
```
Note: the optional commit `--all` command line option will automatically "add" and "rm" edited files.
```shell
git commit --all
```
10. Push your branch to GitHub:
Note: the optional commit `--all` command line option will automatically "add" and "rm" edited files.
```shell
git push origin my-fix-branch
```
8. Push your branch to GitHub:
11. In GitHub, send a pull request to `angular:main`.
```shell
git push origin my-fix-branch
```
9. In GitHub, send a pull request to `angular:main`.
### Reviewing a Pull Request
@@ -133,16 +145,15 @@ If we ask for changes via code reviews then:
3. Create a fixup commit and push to your GitHub repository (this will update your Pull Request):
```shell
git commit --all --fixup HEAD
git push
```
```shell
git commit --all --fixup HEAD
git push
```
For more info on working with fixup commits see [here](./contributing-docs/using-fixup-commits.md).
For more info on working with fixup commits see [here](./contributing-docs/using-fixup-commits.md).
That's it! Thank you for your contribution!
##### Updating the commit message
A reviewer might often suggest changes to a commit message (for example, to add more context for a change or adhere to our [commit message guidelines][commit-message-guidelines]).
@@ -150,69 +161,68 @@ In order to update the commit message of the last commit on your branch:
1. Check out your branch:
```shell
git checkout my-fix-branch
```
```shell
git checkout my-fix-branch
```
2. Amend the last commit and modify the commit message:
```shell
git commit --amend
```
```shell
git commit --amend
```
3. Push to your GitHub repository:
```shell
git push --force-with-lease
```
```shell
git push --force-with-lease
```
> NOTE:<br />
> If you need to update the commit message of an earlier commit, you can use `git rebase` in interactive mode.
> See the [git docs](https://git-scm.com/docs/git-rebase#_interactive_mode) for more details.
#### After your pull request is merged
After your pull request is merged, you can safely delete your branch and pull the changes from the main (upstream) repository:
* Delete the remote branch on GitHub either through the GitHub web UI or your local shell as follows:
- Delete the remote branch on GitHub either through the GitHub web UI or your local shell as follows:
```shell
git push origin --delete my-fix-branch
```
```shell
git push origin --delete my-fix-branch
```
* Check out the main branch:
- Check out the main branch:
```shell
git checkout main -f
```
```shell
git checkout main -f
```
* Delete the local branch:
- Delete the local branch:
```shell
git branch -D my-fix-branch
```
```shell
git branch -D my-fix-branch
```
* Update your local `main` with the latest upstream version:
```shell
git pull --ff upstream main
```
- Update your local `main` with the latest upstream version:
```shell
git pull --ff upstream main
```
## <a name="rules"></a> Coding Rules
To ensure consistency throughout the source code, keep these rules in mind as you are working:
* All features or bug fixes **must be tested** by one or more specs (unit-tests).
* All public API methods **must be documented**.
* We follow [Google's TypeScript Style Guide][ts-style-guide], but wrap all code at **100 characters**.
An automated formatter is available, see [building-and-testing-angular.md](./contributing-docs/building-and-testing-angular.md#formatting-your-source-code).
- All features or bug fixes **must be tested** by one or more specs (unit-tests).
- All public API methods **must be documented**.
- We follow [Google's TypeScript Style Guide][ts-style-guide], but wrap all code at **100 characters**.
An automated formatter is available, see [building-and-testing-angular.md](./contributing-docs/building-and-testing-angular.md#formatting-your-source-code).
## <a name="commit"></a> Commit Message Guidelines
We have very precise rules over how our Git commit messages must be formatted:
```
<type>(<scope>): <short summary>
```
@@ -224,21 +234,18 @@ See [Commit Message Guidelines][commit-message-guidelines] for details.
Please sign our Contributor License Agreement (CLA) before sending pull requests. For any code
changes to be accepted, the CLA must be signed. It's a quick process, we promise!
* For individuals, we have a [simple click-through form][individual-cla].
* For corporations, we'll need you to
- For individuals, we have a [simple click-through form][individual-cla].
- For corporations, we'll need you to
[print, sign and one of scan+email, fax or mail the form][corporate-cla].
If you have more than one GitHub accounts, or multiple email addresses associated with a single GitHub account, you must sign the CLA using the primary email address of the GitHub account used to author Git commits and send pull requests.
The following documents can help you sort out issues with GitHub accounts and multiple email addresses:
* https://help.github.com/articles/setting-your-commit-email-address-in-git/
* https://stackoverflow.com/questions/37245303/what-does-usera-committed-with-userb-13-days-ago-on-github-mean
* https://help.github.com/articles/about-commit-email-addresses/
* https://help.github.com/articles/blocking-command-line-pushes-that-expose-your-personal-email-address/
- https://help.github.com/articles/setting-your-commit-email-address-in-git/
- https://stackoverflow.com/questions/37245303/what-does-usera-committed-with-userb-13-days-ago-on-github-mean
- https://help.github.com/articles/about-commit-email-addresses/
- https://help.github.com/articles/blocking-command-line-pushes-that-expose-your-personal-email-address/
[coc]: https://github.com/angular/code-of-conduct/blob/main/CODE_OF_CONDUCT.md
[corporate-cla]: https://cla.developers.google.com/about/google-corporate
+11 -11
View File
@@ -5,27 +5,27 @@ module(
)
bazel_dep(name = "rules_pkg", version = "1.1.0")
bazel_dep(name = "rules_nodejs", version = "6.6.0")
bazel_dep(name = "aspect_rules_ts", version = "3.7.0")
bazel_dep(name = "aspect_rules_js", version = "2.6.2")
bazel_dep(name = "aspect_rules_esbuild", version = "0.23.0")
bazel_dep(name = "rules_nodejs", version = "6.6.2")
bazel_dep(name = "aspect_rules_ts", version = "3.7.1")
bazel_dep(name = "aspect_rules_js", version = "2.8.3")
bazel_dep(name = "aspect_rules_esbuild", version = "0.24.0")
bazel_dep(name = "aspect_rules_jasmine", version = "2.0.0")
bazel_dep(name = "aspect_rules_rollup", version = "2.0.1")
bazel_dep(name = "bazel_skylib", version = "1.8.2")
bazel_dep(name = "aspect_bazel_lib", version = "2.21.2")
bazel_dep(name = "tar.bzl", version = "0.6.0")
bazel_dep(name = "yq.bzl", version = "0.3.1")
bazel_dep(name = "aspect_bazel_lib", version = "2.22.0")
bazel_dep(name = "tar.bzl", version = "0.7.0")
bazel_dep(name = "yq.bzl", version = "0.3.2")
bazel_dep(name = "rules_angular")
git_override(
module_name = "rules_angular",
commit = "c3721b6ece2050a59a97562e3b95527a3092b03b",
commit = "7133b97252508f8528e5c5818a9a73cacc2e2a0e",
remote = "https://github.com/devversion/rules_angular.git",
)
bazel_dep(name = "devinfra")
git_override(
module_name = "devinfra",
commit = "5c8f5f7c0a4e805a8ee33706ee2df99854396bbd",
commit = "90bba8b673b749ce67760b4d993b9b421adac30f",
remote = "https://github.com/angular/dev-infra.git",
)
@@ -39,7 +39,7 @@ git_override(
bazel_dep(name = "rules_browsers")
git_override(
module_name = "rules_browsers",
commit = "6a699bf3e896690e2923cf3ade29fbd4e492e366",
commit = "8ef3e996d5fc040a35770f860987d8b9cad8ef3d",
remote = "https://github.com/devversion/rules_browsers.git",
)
@@ -47,7 +47,7 @@ yq = use_extension("@yq.bzl//yq:extensions.bzl", "yq")
use_repo(yq, "yq_toolchains")
node = use_extension("@rules_nodejs//nodejs:extensions.bzl", "node")
node.toolchain(node_version = "20.19.0")
node.toolchain(node_version = "22.21.1")
use_repo(node, "nodejs_toolchains")
use_repo(node, "nodejs_darwin_amd64")
use_repo(node, "nodejs_darwin_arm64")
+570 -747
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -146,11 +146,11 @@ Join the conversation and help the community.
[angularelements]: https://angular.dev/guide/elements
[ssr]: https://angular.dev/guide/ssr
[schematics]: https://angular.dev/tools/cli/schematics
[lazyloading]: https://angular.dev/guide/ngmodules/lazy-loading
[lazyloading]: https://angular.dev/guide/routing/define-routes#lazily-loaded-components
[node.js]: https://nodejs.org/
[npm]: https://www.npmjs.com/get-npm
[codeofconduct]: CODE_OF_CONDUCT.md
[X (formerly Twitter)]: https://www.twitter.com/angular
[X (formerly Twitter)]: https://www.x.com/angular
[bluesky]: https://bsky.app/profile/angular.dev
[discord]: https://discord.gg/angular
[stackoverflow]: https://stackoverflow.com/questions/tagged/angular
+55 -59
View File
@@ -14,8 +14,8 @@ exports_files([
])
APPLICATION_FILES = [
"//adev/src/context:llms_full",
"//adev/src/assets/images",
"//adev/src/assets/images/v21-event:v21-event-images",
"//adev/src/assets/others",
"//adev/src/assets/previews",
"//adev/src/assets:tutorials",
@@ -31,38 +31,35 @@ APPLICATION_FILES = [
)
APPLICATION_DEPS = [
"//adev:node_modules/@angular-devkit/build-angular",
"//adev:node_modules/@codemirror/autocomplete",
"//adev:node_modules/@codemirror/commands",
"//adev:node_modules/@codemirror/lang-angular",
"//adev:node_modules/@codemirror/lang-css",
"//adev:node_modules/@codemirror/lang-html",
"//adev:node_modules/@codemirror/lang-javascript",
"//adev:node_modules/@codemirror/lang-sass",
"//adev:node_modules/@codemirror/language",
"//adev:node_modules/@codemirror/lint",
"//adev:node_modules/@codemirror/search",
"//adev:node_modules/@codemirror/state",
"//adev:node_modules/@codemirror/view",
"//adev:node_modules/@lezer/common",
"//adev:node_modules/@lezer/highlight",
"//adev:node_modules/@lezer/javascript",
"//adev:node_modules/@stackblitz/sdk",
"//adev:node_modules/@typescript/vfs",
"//adev:node_modules/@webcontainer/api",
"//adev:node_modules/@xterm/addon-fit",
"//adev:node_modules/@xterm/xterm",
"//adev:node_modules/algoliasearch",
"//adev:node_modules/angular-split",
"//adev:node_modules/fflate",
"//adev:node_modules/marked",
"//adev:node_modules/ngx-progressbar",
"//adev:node_modules/open-in-idx",
"//adev:node_modules/tailwindcss",
"//adev:node_modules/typescript",
"//adev:node_modules/xhr2",
"//adev:node_modules/@types/node",
"//adev:node_modules/@types/dom-navigation",
":node_modules/@codemirror/autocomplete",
":node_modules/@codemirror/commands",
":node_modules/@codemirror/lang-angular",
":node_modules/@codemirror/lang-css",
":node_modules/@codemirror/lang-html",
":node_modules/@codemirror/lang-javascript",
":node_modules/@codemirror/lang-sass",
":node_modules/@codemirror/language",
":node_modules/@codemirror/lint",
":node_modules/@codemirror/search",
":node_modules/@codemirror/state",
":node_modules/@codemirror/view",
":node_modules/@lezer/common",
":node_modules/@lezer/highlight",
":node_modules/@lezer/javascript",
":node_modules/@stackblitz/sdk",
":node_modules/@typescript/vfs",
":node_modules/@webcontainer/api",
":node_modules/@xterm/addon-fit",
":node_modules/@xterm/xterm",
":node_modules/algoliasearch",
":node_modules/angular-split",
":node_modules/fflate",
":node_modules/marked",
":node_modules/ngx-progressbar",
":node_modules/open-in-idx",
":node_modules/tailwindcss",
":node_modules/typescript",
":node_modules/@types/dom-navigation",
# The imports below are packages that our code does not directly import, but our upstream deps import from
# these locations directly. By design, rather than hoisting these packages into the "root" node_modules the
@@ -70,32 +67,30 @@ APPLICATION_DEPS = [
# a "hoisted" location within the `.aspect_rules_js/` directories in the node_modules directory. This prevents
# the bundler from being able to find it as expected. We instead specifically provide it as a dep within bazel
# as a mechanism of "hoisting" the package for our usage by this target.
"//adev:node_modules/@algolia/client-common",
"//adev:node_modules/@algolia/requester-browser-xhr",
"//adev:node_modules/@algolia/requester-node-http",
"//adev:node_modules/@lezer/css",
"//adev:node_modules/@lezer/html",
"//adev:node_modules/@lezer/lr",
"//adev:node_modules/@lezer/sass",
"//adev:node_modules/@marijn/find-cluster-break",
"//adev:node_modules/crelt",
"//adev:node_modules/style-mod",
"//adev:node_modules/w3c-keyname",
":node_modules/@algolia/client-common",
":node_modules/@algolia/requester-browser-xhr",
":node_modules/@algolia/requester-node-http",
":node_modules/@lezer/css",
":node_modules/@lezer/html",
":node_modules/@lezer/lr",
":node_modules/@lezer/sass",
":node_modules/@marijn/find-cluster-break",
":node_modules/crelt",
":node_modules/style-mod",
":node_modules/w3c-keyname",
]
TEST_FILES = APPLICATION_FILES + [
"karma.conf.js",
"test-main.ts",
] + glob(["src/**/*.spec.ts"])
TEST_FILES = APPLICATION_FILES + glob(["src/app/**/*.spec.ts"])
TEST_DEPS = [
dep
for dep in APPLICATION_DEPS
if dep != "//adev:node_modules/@types/node"
] + [
TEST_DEPS = APPLICATION_DEPS + [
":node_modules/@types/jasmine",
":node_modules/karma",
":node_modules/karma-chrome-launcher",
":node_modules/karma-jasmine",
":node_modules/karma-coverage",
":node_modules/karma-jasmine-html-reporter",
":node_modules/jasmine-core",
"@rules_browsers//browsers/chromium",
"@rules_browsers//browsers/firefox",
"//adev/tools:windows-chromium-path",
]
ng_config(name = "ng_config")
@@ -109,9 +104,10 @@ ng_application(
],
env = {
"NG_BUILD_PARTIAL_SSR": "1",
"NG_FORCE_TTY": "0",
},
ng_config = ":ng_config",
node_modules = "//adev:node_modules",
node_modules = ":node_modules",
project_name = "angular-dev",
serve_args = [
"--port",
@@ -135,9 +131,10 @@ ng_application(
],
env = {
"NG_BUILD_OPTIMIZE_CHUNKS": "1",
"NG_FORCE_TTY": "0",
},
ng_config = ":ng_config",
node_modules = "//adev:node_modules",
node_modules = ":node_modules",
project_name = "angular-dev",
serve_args = [
"--port",
@@ -161,10 +158,9 @@ ng_test(
"CHROMEDRIVER_BIN": "../" + "$(CHROMEDRIVER)",
},
ng_config = ":ng_config",
node_modules = "//adev:node_modules",
node_modules = ":node_modules",
project_name = "angular-dev",
toolchains = [
"@rules_browsers//browsers/chromium:toolchain_alias",
"@rules_browsers//browsers/firefox:toolchain_alias",
],
)
+3 -4
View File
@@ -17,7 +17,7 @@ git clone https://github.com/angular/angular.git
cd angular
# Install dependencies
pnpm
pnpm install
# Build and run local dev server
# NOTE: Initial build will take some time
@@ -52,8 +52,7 @@ pnpm bazel clean
pnpm bazel clean --expunge
```
## High level architecture
## High level architecture
The angular.dev website is a modern Angular application that utilizes Static Site Generation (SSG) to deliver pre-rendered, high-performance content to users.
@@ -61,4 +60,4 @@ The architecture is designed for efficiency and maintainability:
Content Sources: The documentation is sourced from two main places within the monorepo. The guides and tutorials are written in Markdown files, while the API reference pages are automatically generated by extracting documentation directly from the TypeScript source code of the Angular framework packages.
Build Process: During the build process, the Markdown files are converted into HTML. Simultaneously, the API documentation is extracted from the code comments. This content is then integrated into the Angular application.
Build Process: During the build process, the Markdown files are converted into HTML. Simultaneously, the API documentation is extracted from the code comments. This content is then integrated into the Angular application.
+11 -21
View File
@@ -19,7 +19,7 @@
"build": {
"builder": "@angular/build:application",
"options": {
"externalDependencies": ["path"],
"externalDependencies": ["path", "xhr2"],
"outputMode": "static",
"outputPath": "dist",
"index": "src/index.html",
@@ -31,9 +31,9 @@
"assets": [
"src/favicon.ico",
"src/robots.txt",
"src/llms.txt",
"src/assets",
"src/context",
"src/llms.txt"
"src/assets/images/v21-event"
],
"styles": ["@angular/docs/styles/global-styles.scss", "./src/local-styles.scss"],
"scripts": [],
@@ -57,7 +57,7 @@
"defaultConfiguration": "production"
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"builder": "@angular/build:dev-server",
"configurations": {
"production": {
"buildTarget": "angular-dev:build:production"
@@ -75,24 +75,14 @@
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"buildTarget": "angular-dev:build"
}
},
"test": {
"builder": "@angular/build:karma",
"options": {
"tsConfig": "tsconfig.spec.json",
"include": ["src/app"],
"karmaConfig": "karma.conf.js",
"main": "test-main.ts",
"inlineStyleLanguage": "scss",
"assets": ["src/favicon.ico", "src/assets"],
"styles": ["@angular/docs/styles/global-styles.scss"],
"scripts": [],
"webWorkerTsConfig": "tsconfig.worker.json"
"builder": "@angular/build:unit-test",
"options": {
"runner": "karma",
"browsers": ["ChromeHeadlessNoSandbox"],
"include": [
"src/app/**/*.spec.ts"
]
}
}
}
+14 -2
View File
@@ -19,7 +19,20 @@
]
},
{
"source": "/**/*-[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z].*",
"source": "assets/others/versions.json",
"headers": [
{
"key": "Cross-Origin-Resource-Policy",
"value": "cross-origin"
},
{
"key": "Access-Control-Allow-Origin",
"value": "*"
}
]
},
{
"source": "/**/*-[0-9A-Za-z_][0-9A-Za-z_][0-9A-Za-z_][0-9A-Za-z_][0-9A-Za-z_][0-9A-Za-z_][0-9A-Za-z_][0-9A-Za-z_].*",
"headers": [
{
"key": "Cache-Control",
@@ -56,7 +69,6 @@
"key": "Cross-Origin-Opener-Policy",
"value": "same-origin"
},
{
"key": "Cross-Origin-Embedder-Policy",
"value": "require-corp"
-85
View File
@@ -1,85 +0,0 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
// Karma configuration file, see link for more information
// https://karma-runner.github.io/1.0/config/configuration-file.html
const {getAdjustedChromeBinPathForWindows} = require('./tools/windows-chromium-path');
process.env.CHROME_BIN = getAdjustedChromeBinPathForWindows();
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage'),
{'reporter:jasmine-seed': ['type', JasmineSeedReporter]},
],
proxies: {
'/dummy/image': 'src/assets/images/logos/angular/angular.png',
},
client: {
clearContext: false, // leave Jasmine Spec Runner output visible in browser
jasmine: {
// you can add configuration options for Jasmine here
// the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
// for example, you can disable the random execution with `random: false`
// or set a specific seed with `seed: 4321`
random: true,
seed: '',
},
},
jasmineHtmlReporter: {
suppressAll: true, // removes the duplicated traces
},
coverageReporter: {
dir: require('path').join(__dirname, './coverage/site'),
subdir: '.',
reporters: [{type: 'html'}, {type: 'text-summary'}],
},
reporters: ['progress', 'kjhtml', 'jasmine-seed'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
customLaunchers: {
ChromeHeadlessNoSandbox: {
base: 'ChromeHeadless',
// See /integration/README.md#browser-tests for more info on these args
flags: [
'--no-sandbox',
'--headless',
'--disable-gpu',
'--disable-dev-shm-usage',
'--hide-scrollbars',
'--mute-audio',
],
},
},
browsers: ['ChromeHeadlessNoSandbox'],
browserNoActivityTimeout: 60000,
singleRun: false,
restartOnFileChange: true,
});
};
// Helpers
function JasmineSeedReporter(baseReporterDecorator) {
baseReporterDecorator(this);
this.onBrowserComplete = (browser, result) => {
const seed = result.order && result.order.random && result.order.seed;
if (seed) this.write(`${browser}: Randomized with seed ${seed}.\n`);
};
this.onRunComplete = () => undefined;
}
+27 -28
View File
@@ -1,48 +1,57 @@
{
"dependencies": {
"@algolia/client-search": "5.40.1",
"@angular-devkit/build-angular": "21.0.0-next.8",
"@algolia/client-common": "5.41.0",
"@algolia/client-search": "5.41.0",
"@algolia/requester-browser-xhr": "5.41.0",
"@algolia/requester-node-http": "5.41.0",
"@angular/animations": "workspace:*",
"@angular/build": "21.0.0-next.8",
"@angular/cdk": "21.0.0-next.10",
"@angular/cli": "21.0.0-next.8",
"@angular/aria": "21.0.3",
"@angular/build": "21.0.3",
"@angular/cdk": "21.0.3",
"@angular/cli": "21.0.3",
"@angular/common": "workspace:*",
"@angular/compiler-cli": "workspace:*",
"@angular/compiler": "workspace:*",
"@angular/compiler-cli": "workspace:*",
"@angular/core": "workspace:*",
"@angular/docs": "workspace:*",
"@angular/forms": "workspace:*",
"@angular/material": "21.0.0-next.10",
"@angular/material": "21.0.3",
"@angular/platform-browser": "workspace:*",
"@angular/platform-server": "workspace:*",
"@angular/router": "workspace:*",
"@angular/ssr": "21.0.0-next.8",
"@codemirror/autocomplete": "6.19.0",
"@codemirror/commands": "6.9.0",
"@angular/ssr": "21.0.3",
"@codemirror/autocomplete": "6.19.1",
"@codemirror/commands": "6.10.0",
"@codemirror/lang-angular": "0.1.4",
"@codemirror/lang-css": "6.3.1",
"@codemirror/lang-html": "6.4.11",
"@codemirror/lang-javascript": "6.2.4",
"@codemirror/lang-sass": "6.0.2",
"@codemirror/language": "6.11.3",
"@codemirror/lint": "6.9.0",
"@codemirror/lint": "6.9.1",
"@codemirror/search": "6.5.11",
"@codemirror/state": "6.5.2",
"@codemirror/view": "6.38.6",
"@lezer/common": "1.3.0",
"@lezer/css": "1.3.0",
"@lezer/highlight": "1.2.2",
"@lezer/html": "1.3.12",
"@lezer/javascript": "1.5.4",
"@lezer/lr": "1.4.2",
"@lezer/sass": "1.1.0",
"@marijn/find-cluster-break": "1.0.2",
"@stackblitz/sdk": "1.11.0",
"@types/dom-navigation": "1.0.6",
"@types/jasmine": "5.1.12",
"@types/jsdom": "27.0.0",
"@types/node": "24.9.1",
"@typescript/vfs": "1.6.1",
"@typescript/vfs": "1.6.2",
"@webcontainer/api": "1.6.1",
"@xterm/addon-fit": "0.10.0",
"@xterm/xterm": "5.5.0",
"algoliasearch": "5.40.1",
"algoliasearch": "5.41.0",
"angular-split": "20.0.0",
"crelt": "1.0.6",
"diff": "8.0.2",
"emoji-regex": "10.6.0",
"fflate": "0.8.2",
@@ -50,37 +59,27 @@
"jsdom": "27.0.1",
"karma-chrome-launcher": "3.2.0",
"karma-coverage": "2.2.1",
"karma-jasmine-html-reporter": "2.1.0",
"karma-jasmine": "5.1.0",
"karma-jasmine-html-reporter": "2.1.0",
"marked": "16.4.1",
"mermaid": "11.12.0",
"ngx-progressbar": "14.0.0",
"open-in-idx": "0.1.1",
"playwright-core": "1.56.1",
"preact-render-to-string": "6.6.2",
"preact": "10.27.2",
"preact-render-to-string": "6.6.3",
"prettier": "3.6.2",
"rxjs": "7.8.2",
"shiki": "3.13.0",
"shiki": "3.14.0",
"style-mod": "4.1.3",
"tinyglobby": "0.2.15",
"tslib": "2.8.1",
"typescript": "5.9.3",
"xhr2": "0.2.1",
"zone.js": "0.15.1",
"@algolia/client-common": "5.40.1",
"@algolia/requester-browser-xhr": "5.40.1",
"@algolia/requester-node-http": "5.40.1",
"@lezer/css": "1.3.0",
"@lezer/html": "1.3.12",
"@lezer/lr": "1.4.2",
"@lezer/sass": "1.1.0",
"@marijn/find-cluster-break": "1.0.2",
"crelt": "1.0.6",
"style-mod": "4.1.3",
"w3c-keyname": "2.2.8"
},
"devDependencies": {
"autoprefixer": "10.4.21",
"karma": "~6.4.4",
"postcss": "8.5.6",
"tailwindcss": "3.4.18"
}
-3
View File
@@ -1,3 +0,0 @@
# Generating data for `angular.dev/api` CDK packages
This script updates the Angular CDK api JSON files stored in `adev/src/content/cdk`. This files are used to generate the [angular.dev api](https://angular.dev/api) pages for the CDK packages.
-35
View File
@@ -1,35 +0,0 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import {dirname, resolve as resolvePath} from 'node:path';
import {fileURLToPath} from 'node:url';
import {copyJsonAssets} from '../shared/copy-json-assets.mjs';
import {GithubClient} from '../shared/github-client.mjs';
const scriptDir = dirname(fileURLToPath(import.meta.url));
const CDK_BUILDS_REPO = 'angular/cdk-builds';
const CDK_APIS_CONTENT_PATH = resolvePath(scriptDir, '../../src/content/cdk');
async function main() {
await copyJsonAssets({
repo: CDK_BUILDS_REPO,
assetsPath: '_adev_assets',
destPath: CDK_APIS_CONTENT_PATH,
githubApi: new GithubClient(
CDK_BUILDS_REPO,
process.env.ANGULAR_CDK_BUILDS_READONLY_GITHUB_TOKEN,
'ADEV_Angular_CDK_Sources_Update',
),
});
}
main().catch((err) => {
console.error(err);
process.exit(1);
});
-3
View File
@@ -1,3 +0,0 @@
# Generating data for `angular.dev/cli`
This script updates the Angular CLI help JSON files stored in `adev/src/content/cli/help`. This files are used to generate the [angular.dev CLI](https://angular.dev/cli) pages.
-35
View File
@@ -1,35 +0,0 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import {dirname, resolve as resolvePath} from 'node:path';
import {fileURLToPath} from 'node:url';
import {copyJsonAssets} from '../shared/copy-json-assets.mjs';
import {GithubClient} from '../shared/github-client.mjs';
const scriptDir = dirname(fileURLToPath(import.meta.url));
const CLI_BUILDS_REPO = 'angular/cli-builds';
const CLI_HELP_CONTENT_PATH = resolvePath(scriptDir, '../../src/content/cli/help');
async function main() {
await copyJsonAssets({
repo: CLI_BUILDS_REPO,
assetsPath: 'help',
destPath: CLI_HELP_CONTENT_PATH,
githubApi: new GithubClient(
CLI_BUILDS_REPO,
process.env.ANGULAR_CLI_BUILDS_READONLY_GITHUB_TOKEN,
'ADEV_Angular_CLI_Sources_Update',
),
});
}
main().catch((err) => {
console.error(err);
process.exit(1);
});
@@ -0,0 +1,15 @@
# Update cross-repository documentation assets
This script updates documentation assets from other repositories for `angular.dev`.
## Aria Packages
Updates the Angular Aria API JSON files in `adev/src/content/aria`, used for the [angular.dev API](https://angular.dev/api) pages.
## CDK Packages
Updates the Angular CDK API JSON files in `adev/src/content/cdk`, used for the [angular.dev API](https://angular.dev/api) pages.
## CLI Help Pages
Updates the Angular CLI help JSON files in `adev/src/content/cli`, used for the [angular.dev CLI](https://angular.dev/cli) pages.
@@ -0,0 +1,41 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
//tslint:disable:no-console
import {execSync} from 'node:child_process';
import {join} from 'node:path';
import {updateAssets} from './update-assets.mjs';
async function main() {
await updateAssets({
repo: 'angular/aria-builds',
assetsPath: '_adev_assets',
destPath: join(import.meta.dirname, '../../src/content/aria'),
});
await updateAssets({
repo: 'angular/cdk-builds',
assetsPath: '_adev_assets',
destPath: join(import.meta.dirname, '../../src/content/cdk'),
});
await updateAssets({
repo: 'angular/cli-builds',
assetsPath: 'help',
destPath: join(import.meta.dirname, '../../src/content/cli'),
});
console.log('\n-----------------------------------------------');
console.log('Change list');
console.log('-----------------------------------------------\n');
execSync(`git status --porcelain`, {stdio: 'inherit'});
}
main().catch((err) => {
console.error(err);
process.exit(1);
});
@@ -10,11 +10,25 @@
import assert from 'node:assert';
import {execSync} from 'node:child_process';
import {existsSync, constants as fsConstants} from 'node:fs';
import {copyFile, mkdtemp, readdir, readFile, realpath, unlink, writeFile} from 'node:fs/promises';
import {
copyFile,
mkdtemp,
readdir,
readFile,
realpath,
rm,
unlink,
writeFile,
} from 'node:fs/promises';
import {tmpdir} from 'node:os';
import {join} from 'node:path';
import {GithubClient} from './github-client.mjs';
export async function updateAssets({repo, assetsPath, destPath}) {
console.log('\n-----------------------------------------------');
console.log(`Processing: ${repo}`);
console.log('-----------------------------------------------\n');
export async function copyJsonAssets({repo, githubApi, assetsPath, destPath}) {
const buildInfoPath = join(destPath, '_build-info.json');
if (!existsSync(buildInfoPath)) {
throw new Error(`${buildInfoPath} does not exist.`);
@@ -27,6 +41,13 @@ export async function copyJsonAssets({repo, githubApi, assetsPath, destPath}) {
await readFile(buildInfoPath, 'utf-8'),
);
assert(process.env.ANGULAR_READONLY_GITHUB_TOKEN);
const githubApi = new GithubClient(
repo,
process.env.ANGULAR_READONLY_GITHUB_TOKEN,
'ADEV_Cross_Repo_Docs_Update',
);
let downstreamBranch = currentBranch;
let latestSha = await githubApi.getShaForBranch(currentBranch);
if (
@@ -53,38 +74,43 @@ export async function copyJsonAssets({repo, githubApi, assetsPath, destPath}) {
changedFiles.map((f) => '* ' + f).join('\n'),
);
const temporaryDir = await realpath(await mkdtemp(join(tmpdir(), 'copy-json-assets-')));
const execOptions = {cwd: temporaryDir, stdio: 'inherit'};
execSync('git init', execOptions);
execSync(`git remote add origin https://github.com/${repo}.git`, execOptions);
// fetch a commit
execSync(`git fetch origin ${latestSha}`, execOptions);
// reset this repository's main branch to the commit of interest
execSync('git reset --hard FETCH_HEAD', execOptions);
// get sha when files where changed
shaWhenFilesChanged = execSync(`git rev-list -1 ${latestSha} "${assetsPath}/"`, {
encoding: 'utf8',
cwd: temporaryDir,
stdio: ['ignore', 'pipe', 'ignore'],
}).trim();
const temporaryDir = await realpath(await mkdtemp(join(tmpdir(), 'update-assets-')));
// Delete existing asset files.
const apiFilesUnlink = (await readdir(destPath))
.filter((f) => f.endsWith('.json'))
.map((f) => unlink(join(destPath, f)));
try {
const execOptions = {cwd: temporaryDir, stdio: 'inherit'};
execSync('git init', execOptions);
execSync(`git remote add origin https://github.com/${repo}.git`, execOptions);
// fetch a commit
execSync(`git fetch origin ${latestSha}`, execOptions);
// reset this repository's main branch to the commit of interest
execSync('git reset --hard FETCH_HEAD', execOptions);
// get sha when files where changed
shaWhenFilesChanged = execSync(`git rev-list -1 ${latestSha} "${assetsPath}/"`, {
encoding: 'utf8',
cwd: temporaryDir,
stdio: ['ignore', 'pipe', 'ignore'],
}).trim();
await Promise.allSettled(apiFilesUnlink);
// Delete existing asset files.
const apiFilesUnlink = (await readdir(destPath))
.filter((f) => f.endsWith('.json'))
.map((f) => unlink(join(destPath, f)));
// Copy new asset files
const tempAssetsDir = join(temporaryDir, assetsPath);
const assetFilesCopy = (await readdir(tempAssetsDir)).map((f) => {
const src = join(tempAssetsDir, f);
const dest = join(destPath, f);
await Promise.allSettled(apiFilesUnlink);
return copyFile(src, dest, fsConstants.COPYFILE_FICLONE);
});
// Copy new asset files
const tempAssetsDir = join(temporaryDir, assetsPath);
const assetFilesCopy = (await readdir(tempAssetsDir)).map((f) => {
const src = join(tempAssetsDir, f);
const dest = join(destPath, f);
await Promise.allSettled(assetFilesCopy);
return copyFile(src, dest, fsConstants.COPYFILE_FICLONE);
});
await Promise.allSettled(assetFilesCopy);
} finally {
await rm(temporaryDir, {force: true, recursive: true});
}
console.log(`Successfully updated asset files in '${destPath}'.\n`);
} else {
@@ -103,10 +129,4 @@ export async function copyJsonAssets({repo, githubApi, assetsPath, destPath}) {
2,
),
);
// The below command will show uncommitted changes.
// This is expected because the framework repo and component/cli might have different minors
// (e.g. during exceptional minor releases), leading to changes that need to be committed.
console.log('\nChanges: ');
execSync(`git status --porcelain`, {stdio: 'inherit'});
}
+1
View File
@@ -20,6 +20,7 @@ ts_project(
"//adev/shared-docs/components/search-dialog",
"//adev/shared-docs/components/select",
"//adev/shared-docs/components/slide-toggle",
"//adev/shared-docs/components/tab-group",
"//adev/shared-docs/components/table-of-contents",
"//adev/shared-docs/components/text-field",
"//adev/shared-docs/components/top-level-banner",
@@ -1,52 +1,52 @@
<!-- Algolia logo -->
<svg
id="Layer_1"
class="docs-algolia-logo"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 2196.2 500"
id="Layer_1"
class="docs-algolia-logo"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 2196.2 500"
>
<defs>
<style>
.cls-1,
.cls-2 {
fill: #003dff;
}
.cls-2 {
fill-rule: evenodd;
}
</style>
</defs>
<path
class="cls-2"
d="M1070.38,275.3V5.91c0-3.63-3.24-6.39-6.82-5.83l-50.46,7.94c-2.87,.45-4.99,2.93-4.99,5.84l.17,273.22c0,12.92,0,92.7,95.97,95.49,3.33,.1,6.09-2.58,6.09-5.91v-40.78c0-2.96-2.19-5.51-5.12-5.84-34.85-4.01-34.85-47.57-34.85-54.72Z"
/>
<rect class="cls-1" x="1845.88" y="104.73" width="62.58" height="277.9" rx="5.9" ry="5.9" />
<path
class="cls-2"
d="M1851.78,71.38h50.77c3.26,0,5.9-2.64,5.9-5.9V5.9c0-3.62-3.24-6.39-6.82-5.83l-50.77,7.95c-2.87,.45-4.99,2.92-4.99,5.83v51.62c0,3.26,2.64,5.9,5.9,5.9Z"
/>
<path
class="cls-2"
d="M1764.03,275.3V5.91c0-3.63-3.24-6.39-6.82-5.83l-50.46,7.94c-2.87,.45-4.99,2.93-4.99,5.84l.17,273.22c0,12.92,0,92.7,95.97,95.49,3.33,.1,6.09-2.58,6.09-5.91v-40.78c0-2.96-2.19-5.51-5.12-5.84-34.85-4.01-34.85-47.57-34.85-54.72Z"
/>
<path
class="cls-2"
d="M1631.95,142.72c-11.14-12.25-24.83-21.65-40.78-28.31-15.92-6.53-33.26-9.85-52.07-9.85-18.78,0-36.15,3.17-51.92,9.85-15.59,6.66-29.29,16.05-40.76,28.31-11.47,12.23-20.38,26.87-26.76,44.03-6.38,17.17-9.24,37.37-9.24,58.36,0,20.99,3.19,36.87,9.55,54.21,6.38,17.32,15.14,32.11,26.45,44.36,11.29,12.23,24.83,21.62,40.6,28.46,15.77,6.83,40.12,10.33,52.4,10.48,12.25,0,36.78-3.82,52.7-10.48,15.92-6.68,29.46-16.23,40.78-28.46,11.29-12.25,20.05-27.04,26.25-44.36,6.22-17.34,9.24-33.22,9.24-54.21,0-20.99-3.34-41.19-10.03-58.36-6.38-17.17-15.14-31.8-26.43-44.03Zm-44.43,163.75c-11.47,15.75-27.56,23.7-48.09,23.7-20.55,0-36.63-7.8-48.1-23.7-11.47-15.75-17.21-34.01-17.21-61.2,0-26.89,5.59-49.14,17.06-64.87,11.45-15.75,27.54-23.52,48.07-23.52,20.55,0,36.63,7.78,48.09,23.52,11.47,15.57,17.36,37.98,17.36,64.87,0,27.19-5.72,45.3-17.19,61.2Z"
/>
<path
class="cls-2"
d="M894.42,104.73h-49.33c-48.36,0-90.91,25.48-115.75,64.1-14.52,22.58-22.99,49.63-22.99,78.73,0,44.89,20.13,84.92,51.59,111.1,2.93,2.6,6.05,4.98,9.31,7.14,12.86,8.49,28.11,13.47,44.52,13.47,1.23,0,2.46-.03,3.68-.09,.36-.02,.71-.05,1.07-.07,.87-.05,1.75-.11,2.62-.2,.34-.03,.68-.08,1.02-.12,.91-.1,1.82-.21,2.73-.34,.21-.03,.42-.07,.63-.1,32.89-5.07,61.56-30.82,70.9-62.81v57.83c0,3.26,2.64,5.9,5.9,5.9h50.42c3.26,0,5.9-2.64,5.9-5.9V110.63c0-3.26-2.64-5.9-5.9-5.9h-56.32Zm0,206.92c-12.2,10.16-27.97,13.98-44.84,15.12-.16,.01-.33,.03-.49,.04-1.12,.07-2.24,.1-3.36,.1-42.24,0-77.12-35.89-77.12-79.37,0-10.25,1.96-20.01,5.42-28.98,11.22-29.12,38.77-49.74,71.06-49.74h49.33v142.83Z"
/>
<path
class="cls-2"
d="M2133.97,104.73h-49.33c-48.36,0-90.91,25.48-115.75,64.1-14.52,22.58-22.99,49.63-22.99,78.73,0,44.89,20.13,84.92,51.59,111.1,2.93,2.6,6.05,4.98,9.31,7.14,12.86,8.49,28.11,13.47,44.52,13.47,1.23,0,2.46-.03,3.68-.09,.36-.02,.71-.05,1.07-.07,.87-.05,1.75-.11,2.62-.2,.34-.03,.68-.08,1.02-.12,.91-.1,1.82-.21,2.73-.34,.21-.03,.42-.07,.63-.1,32.89-5.07,61.56-30.82,70.9-62.81v57.83c0,3.26,2.64,5.9,5.9,5.9h50.42c3.26,0,5.9-2.64,5.9-5.9V110.63c0-3.26-2.64-5.9-5.9-5.9h-56.32Zm0,206.92c-12.2,10.16-27.97,13.98-44.84,15.12-.16,.01-.33,.03-.49,.04-1.12,.07-2.24,.1-3.36,.1-42.24,0-77.12-35.89-77.12-79.37,0-10.25,1.96-20.01,5.42-28.98,11.22-29.12,38.77-49.74,71.06-49.74h49.33v142.83Z"
/>
<path
class="cls-2"
d="M1314.05,104.73h-49.33c-48.36,0-90.91,25.48-115.75,64.1-11.79,18.34-19.6,39.64-22.11,62.59-.58,5.3-.88,10.68-.88,16.14s.31,11.15,.93,16.59c4.28,38.09,23.14,71.61,50.66,94.52,2.93,2.6,6.05,4.98,9.31,7.14,12.86,8.49,28.11,13.47,44.52,13.47h0c17.99,0,34.61-5.93,48.16-15.97,16.29-11.58,28.88-28.54,34.48-47.75v50.26h-.11v11.08c0,21.84-5.71,38.27-17.34,49.36-11.61,11.08-31.04,16.63-58.25,16.63-11.12,0-28.79-.59-46.6-2.41-2.83-.29-5.46,1.5-6.27,4.22l-12.78,43.11c-1.02,3.46,1.27,7.02,4.83,7.53,21.52,3.08,42.52,4.68,54.65,4.68,48.91,0,85.16-10.75,108.89-32.21,21.48-19.41,33.15-48.89,35.2-88.52V110.63c0-3.26-2.64-5.9-5.9-5.9h-56.32Zm0,64.1s.65,139.13,0,143.36c-12.08,9.77-27.11,13.59-43.49,14.7-.16,.01-.33,.03-.49,.04-1.12,.07-2.24,.1-3.36,.1-1.32,0-2.63-.03-3.94-.1-40.41-2.11-74.52-37.26-74.52-79.38,0-10.25,1.96-20.01,5.42-28.98,11.22-29.12,38.77-49.74,71.06-49.74h49.33Z"
/>
<path
class="cls-1"
d="M249.83,0C113.3,0,2,110.09,.03,246.16c-2,138.19,110.12,252.7,248.33,253.5,42.68,.25,83.79-10.19,120.3-30.03,3.56-1.93,4.11-6.83,1.08-9.51l-23.38-20.72c-4.75-4.21-11.51-5.4-17.36-2.92-25.48,10.84-53.17,16.38-81.71,16.03-111.68-1.37-201.91-94.29-200.13-205.96,1.76-110.26,92-199.41,202.67-199.41h202.69V407.41l-115-102.18c-3.72-3.31-9.42-2.66-12.42,1.31-18.46,24.44-48.53,39.64-81.93,37.34-46.33-3.2-83.87-40.5-87.34-86.81-4.15-55.24,39.63-101.52,94-101.52,49.18,0,89.68,37.85,93.91,85.95,.38,4.28,2.31,8.27,5.52,11.12l29.95,26.55c3.4,3.01,8.79,1.17,9.63-3.3,2.16-11.55,2.92-23.58,2.07-35.92-4.82-70.34-61.8-126.93-132.17-131.26-80.68-4.97-148.13,58.14-150.27,137.25-2.09,77.1,61.08,143.56,138.19,145.26,32.19,.71,62.03-9.41,86.14-26.95l150.26,133.2c6.44,5.71,16.61,1.14,16.61-7.47V9.48C499.66,4.25,495.42,0,490.18,0H249.83Z"
/>
<defs>
<style>
.cls-1,
.cls-2 {
fill: #003dff;
}
.cls-2 {
fill-rule: evenodd;
}
</style>
</defs>
<path
class="cls-2"
d="M1070.38,275.3V5.91c0-3.63-3.24-6.39-6.82-5.83l-50.46,7.94c-2.87,.45-4.99,2.93-4.99,5.84l.17,273.22c0,12.92,0,92.7,95.97,95.49,3.33,.1,6.09-2.58,6.09-5.91v-40.78c0-2.96-2.19-5.51-5.12-5.84-34.85-4.01-34.85-47.57-34.85-54.72Z"
/>
<rect class="cls-1" x="1845.88" y="104.73" width="62.58" height="277.9" rx="5.9" ry="5.9" />
<path
class="cls-2"
d="M1851.78,71.38h50.77c3.26,0,5.9-2.64,5.9-5.9V5.9c0-3.62-3.24-6.39-6.82-5.83l-50.77,7.95c-2.87,.45-4.99,2.92-4.99,5.83v51.62c0,3.26,2.64,5.9,5.9,5.9Z"
/>
<path
class="cls-2"
d="M1764.03,275.3V5.91c0-3.63-3.24-6.39-6.82-5.83l-50.46,7.94c-2.87,.45-4.99,2.93-4.99,5.84l.17,273.22c0,12.92,0,92.7,95.97,95.49,3.33,.1,6.09-2.58,6.09-5.91v-40.78c0-2.96-2.19-5.51-5.12-5.84-34.85-4.01-34.85-47.57-34.85-54.72Z"
/>
<path
class="cls-2"
d="M1631.95,142.72c-11.14-12.25-24.83-21.65-40.78-28.31-15.92-6.53-33.26-9.85-52.07-9.85-18.78,0-36.15,3.17-51.92,9.85-15.59,6.66-29.29,16.05-40.76,28.31-11.47,12.23-20.38,26.87-26.76,44.03-6.38,17.17-9.24,37.37-9.24,58.36,0,20.99,3.19,36.87,9.55,54.21,6.38,17.32,15.14,32.11,26.45,44.36,11.29,12.23,24.83,21.62,40.6,28.46,15.77,6.83,40.12,10.33,52.4,10.48,12.25,0,36.78-3.82,52.7-10.48,15.92-6.68,29.46-16.23,40.78-28.46,11.29-12.25,20.05-27.04,26.25-44.36,6.22-17.34,9.24-33.22,9.24-54.21,0-20.99-3.34-41.19-10.03-58.36-6.38-17.17-15.14-31.8-26.43-44.03Zm-44.43,163.75c-11.47,15.75-27.56,23.7-48.09,23.7-20.55,0-36.63-7.8-48.1-23.7-11.47-15.75-17.21-34.01-17.21-61.2,0-26.89,5.59-49.14,17.06-64.87,11.45-15.75,27.54-23.52,48.07-23.52,20.55,0,36.63,7.78,48.09,23.52,11.47,15.57,17.36,37.98,17.36,64.87,0,27.19-5.72,45.3-17.19,61.2Z"
/>
<path
class="cls-2"
d="M894.42,104.73h-49.33c-48.36,0-90.91,25.48-115.75,64.1-14.52,22.58-22.99,49.63-22.99,78.73,0,44.89,20.13,84.92,51.59,111.1,2.93,2.6,6.05,4.98,9.31,7.14,12.86,8.49,28.11,13.47,44.52,13.47,1.23,0,2.46-.03,3.68-.09,.36-.02,.71-.05,1.07-.07,.87-.05,1.75-.11,2.62-.2,.34-.03,.68-.08,1.02-.12,.91-.1,1.82-.21,2.73-.34,.21-.03,.42-.07,.63-.1,32.89-5.07,61.56-30.82,70.9-62.81v57.83c0,3.26,2.64,5.9,5.9,5.9h50.42c3.26,0,5.9-2.64,5.9-5.9V110.63c0-3.26-2.64-5.9-5.9-5.9h-56.32Zm0,206.92c-12.2,10.16-27.97,13.98-44.84,15.12-.16,.01-.33,.03-.49,.04-1.12,.07-2.24,.1-3.36,.1-42.24,0-77.12-35.89-77.12-79.37,0-10.25,1.96-20.01,5.42-28.98,11.22-29.12,38.77-49.74,71.06-49.74h49.33v142.83Z"
/>
<path
class="cls-2"
d="M2133.97,104.73h-49.33c-48.36,0-90.91,25.48-115.75,64.1-14.52,22.58-22.99,49.63-22.99,78.73,0,44.89,20.13,84.92,51.59,111.1,2.93,2.6,6.05,4.98,9.31,7.14,12.86,8.49,28.11,13.47,44.52,13.47,1.23,0,2.46-.03,3.68-.09,.36-.02,.71-.05,1.07-.07,.87-.05,1.75-.11,2.62-.2,.34-.03,.68-.08,1.02-.12,.91-.1,1.82-.21,2.73-.34,.21-.03,.42-.07,.63-.1,32.89-5.07,61.56-30.82,70.9-62.81v57.83c0,3.26,2.64,5.9,5.9,5.9h50.42c3.26,0,5.9-2.64,5.9-5.9V110.63c0-3.26-2.64-5.9-5.9-5.9h-56.32Zm0,206.92c-12.2,10.16-27.97,13.98-44.84,15.12-.16,.01-.33,.03-.49,.04-1.12,.07-2.24,.1-3.36,.1-42.24,0-77.12-35.89-77.12-79.37,0-10.25,1.96-20.01,5.42-28.98,11.22-29.12,38.77-49.74,71.06-49.74h49.33v142.83Z"
/>
<path
class="cls-2"
d="M1314.05,104.73h-49.33c-48.36,0-90.91,25.48-115.75,64.1-11.79,18.34-19.6,39.64-22.11,62.59-.58,5.3-.88,10.68-.88,16.14s.31,11.15,.93,16.59c4.28,38.09,23.14,71.61,50.66,94.52,2.93,2.6,6.05,4.98,9.31,7.14,12.86,8.49,28.11,13.47,44.52,13.47h0c17.99,0,34.61-5.93,48.16-15.97,16.29-11.58,28.88-28.54,34.48-47.75v50.26h-.11v11.08c0,21.84-5.71,38.27-17.34,49.36-11.61,11.08-31.04,16.63-58.25,16.63-11.12,0-28.79-.59-46.6-2.41-2.83-.29-5.46,1.5-6.27,4.22l-12.78,43.11c-1.02,3.46,1.27,7.02,4.83,7.53,21.52,3.08,42.52,4.68,54.65,4.68,48.91,0,85.16-10.75,108.89-32.21,21.48-19.41,33.15-48.89,35.2-88.52V110.63c0-3.26-2.64-5.9-5.9-5.9h-56.32Zm0,64.1s.65,139.13,0,143.36c-12.08,9.77-27.11,13.59-43.49,14.7-.16,.01-.33,.03-.49,.04-1.12,.07-2.24,.1-3.36,.1-1.32,0-2.63-.03-3.94-.1-40.41-2.11-74.52-37.26-74.52-79.38,0-10.25,1.96-20.01,5.42-28.98,11.22-29.12,38.77-49.74,71.06-49.74h49.33Z"
/>
<path
class="cls-1"
d="M249.83,0C113.3,0,2,110.09,.03,246.16c-2,138.19,110.12,252.7,248.33,253.5,42.68,.25,83.79-10.19,120.3-30.03,3.56-1.93,4.11-6.83,1.08-9.51l-23.38-20.72c-4.75-4.21-11.51-5.4-17.36-2.92-25.48,10.84-53.17,16.38-81.71,16.03-111.68-1.37-201.91-94.29-200.13-205.96,1.76-110.26,92-199.41,202.67-199.41h202.69V407.41l-115-102.18c-3.72-3.31-9.42-2.66-12.42,1.31-18.46,24.44-48.53,39.64-81.93,37.34-46.33-3.2-83.87-40.5-87.34-86.81-4.15-55.24,39.63-101.52,94-101.52,49.18,0,89.68,37.85,93.91,85.95,.38,4.28,2.31,8.27,5.52,11.12l29.95,26.55c3.4,3.01,8.79,1.17,9.63-3.3,2.16-11.55,2.92-23.58,2.07-35.92-4.82-70.34-61.8-126.93-132.17-131.26-80.68-4.97-148.13,58.14-150.27,137.25-2.09,77.1,61.08,143.56,138.19,145.26,32.19,.71,62.03-9.41,86.14-26.95l150.26,133.2c6.44,5.71,16.61,1.14,16.61-7.47V9.48C499.66,4.25,495.42,0,490.18,0H249.83Z"
/>
</svg>

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

@@ -1,22 +1,28 @@
@if (!hasAccepted()) {
<div class="docs-cookies-popup docs-invert-mode">
<p>This site uses cookies from Google to deliver its services and to analyze traffic.</p>
<div class="docs-cookies-popup docs-invert-mode">
<p>This site uses cookies from Google to deliver its services and to analyze traffic.</p>
<div>
<a href="https://policies.google.com/technologies/cookies" target="_blank" rel="noopener">
<button type="button" class="docs-primary-btn" [attr.text]="'Learn more'" aria-label="Learn More">
<div>
<a
href="https://policies.google.com/technologies/cookies"
target="_blank"
rel="noopener"
class="docs-primary-btn"
aria-label="Learn more about how Google uses cookies"
text="Learn more"
>
Learn more
</a>
<button
type="button"
(click)="accept()"
class="docs-primary-btn"
text="Ok, Got it"
aria-label="Ok, Got it"
>
Ok, Got it
</button>
</a>
<button
type="button"
(click)="accept()"
class="docs-primary-btn"
[attr.text]="'Ok, Got it'"
aria-label="Ok, Got it"
>
Ok, Got it
</button>
</div>
</div>
</div>
}
@@ -0,0 +1,19 @@
load("//adev/shared-docs:defaults.bzl", "ng_project")
ng_project(
name = "copy-link-anchor",
srcs = [
"copy-link-anchor.component.ts",
],
visibility = [
"//adev/shared-docs/components:__pkg__",
"//adev/shared-docs/components/viewers:__pkg__",
],
deps = [
"//adev:node_modules/@angular/cdk",
"//adev:node_modules/@angular/common",
"//adev:node_modules/@angular/core",
"//adev:node_modules/@angular/material",
"//adev/shared-docs/components/icon",
],
)
@@ -0,0 +1,66 @@
/*!
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import {ChangeDetectionStrategy, Component, inject, input, signal} from '@angular/core';
import {Clipboard} from '@angular/cdk/clipboard';
import {MatTooltip} from '@angular/material/tooltip';
import {IconComponent} from '../icon/icon.component';
export const CONFIRMATION_DISPLAY_TIME_MS = 1000;
@Component({
selector: 'docs-copy-link-button',
template: `<docs-icon>{{ showCopySuccess() ? 'check' : 'link' }}</docs-icon>`,
styles: `
:host {
cursor: pointer;
padding: 0;
margin-left: 8px;
display: inline-flex;
align-items: center;
opacity: 0;
transition: opacity 0.3s ease;
color: var(--quaternary-contrast);
vertical-align: middle;
}
:host(.docs-copy-link-success) {
color: var(--bright-blue);
}
`,
hostDirectives: [
{
directive: MatTooltip,
inputs: ['matTooltip'],
},
],
host: {
'[ariaLabel]': '"Copy link to " + label()',
'(click)': 'copyLink()',
'matTooltipPosition': 'above',
'[class.docs-copy-link-success]': 'showCopySuccess()',
},
imports: [IconComponent],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class CopyLinkButton {
readonly href = input.required<string>();
readonly label = input.required<string>();
protected readonly showCopySuccess = signal(false);
private readonly clipboard = inject(Clipboard);
copyLink(): void {
const link = `${window.location.origin}${this.href()}`;
this.clipboard.copy(link);
this.showCopySuccess.set(true);
setTimeout(() => {
this.showCopySuccess.set(false);
}, CONFIRMATION_DISPLAY_TIME_MS);
}
}
@@ -56,24 +56,6 @@ describe('CopySourceCodeButton', () => {
expect(copySpy.calls.argsFor(0)[0].trim()).toBe(expectedCodeToBeCopied);
});
it('should not copy lines marked as deleted when code snippet contains diff', async () => {
const codeInHtmlFormat = `
<code>
<div class="line remove"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> *<span class="hljs-attr">ngFor</span>=<span class="hljs-string">"let product of products"</span>&gt;</span></div>
<div class="line add"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> *<span class="hljs-attr">ngFor</span>=<span class="hljs-string">"let product of products()"</span>&gt;</span></div>
</code>
`;
const expectedCodeToBeCopied = `<div *ngFor="let product of products()">`;
component.code.set(codeInHtmlFormat);
await fixture.whenStable();
const button = fixture.debugElement.query(By.directive(CopySourceCodeButton)).nativeElement;
button.click();
expect(copySpy.calls.argsFor(0)[0].trim()).toBe(expectedCodeToBeCopied);
});
it(`should set ${SUCCESSFULLY_COPY_CLASS_NAME} for ${CONFIRMATION_DISPLAY_TIME_MS} ms when copy was executed properly`, () => {
const clock = jasmine.clock().install();
component.code.set('example');
@@ -12,6 +12,7 @@ ng_project(
],
visibility = [
"//adev/shared-docs/components:__pkg__",
"//adev/shared-docs/components/copy-link-anchor:__pkg__",
"//adev/shared-docs/components/copy-source-code-button:__pkg__",
"//adev/shared-docs/components/navigation-list:__pkg__",
"//adev/shared-docs/components/table-of-contents:__pkg__",
@@ -11,13 +11,14 @@
}
@for (item of items; track $index) {
<li class="docs-faceted-list-item">
@let itemLabel = item.label!;
@if (item.path) {
@if (item.isExternal) {
<a
[href]="item.path"
target="_blank"
[matTooltip]="item.label"
[matTooltipDisabled]="item.label.length < 27"
[matTooltipDisabled]="itemLabel.length < 27"
matTooltipPosition="after"
[attr.aria-label]="item.label"
[matTooltipClass]="'API-tooltip'"
@@ -38,10 +39,10 @@
<a
[routerLink]="'/' + item.path"
routerLinkActive="docs-faceted-list-item-active"
[routerLinkActiveOptions]="{ exact: true }"
[routerLinkActiveOptions]="{ paths: 'exact', queryParams: 'ignored', matrixParams: 'ignored', fragment: 'ignored' }"
(click)="emitClickOnLink()"
[matTooltip]="item.label"
[matTooltipDisabled]="item.label.length < 27"
[matTooltipDisabled]="itemLabel.length < 27"
matTooltipPosition="after"
[attr.aria-label]="item.label"
[matTooltipClass]="'API-tooltip'"
@@ -62,7 +63,7 @@
<div
class="docs-secondary-nav-header"
[matTooltip]="item.label"
[matTooltipDisabled]="item.label.length < 27"
[matTooltipDisabled]="itemLabel.length < 27"
matTooltipPosition="after"
[attr.aria-label]="item.label"
[matTooltipClass]="'API-tooltip'"
@@ -90,7 +91,7 @@
[class.docs-nav-item-has-icon]="
item.children && item.level === expandableLevel() && !item.isExpanded"
[matTooltip]="item.label"
[matTooltipDisabled]="item.label.length < 27"
[matTooltipDisabled]="itemLabel.length < 27"
matTooltipPosition="after"
[attr.aria-label]="item.label"
[matTooltipClass]="'API-tooltip'"
@@ -105,7 +106,9 @@
</button>
}
}
@if (displayItemsToLevel() > item.level && item.children?.length > 0) {
@if (
item.level && displayItemsToLevel() > item.level && item.children && item.children.length > 0
) {
<ng-container
*ngTemplateOutlet="navigationList; context: {$implicit: item.children, level: item.level}"
/>
@@ -16,7 +16,7 @@
<p class="title">Recent</p>
<ul class="history-results recent">
@for (item of items.recent; track item.id; let idx = $index) {
<li docsSearchItem [item]="item" (mouseenter)="onMouseEnter($event, idx)">
<li docsSearchItem (mouseenter)="onMouseEnter($event, idx)">
<a
[routerLink]="'/' + item.url | relativeLink: 'pathname'"
[fragment]="item.url | relativeLink: 'hash'"
@@ -55,11 +55,7 @@
<p class="title">Favorite</p>
<ul class="history-results favorite">
@for (item of items.favorite; track item.id; let idx = $index) {
<li
docsSearchItem
[item]="item"
(mouseenter)="onMouseEnter($event, items.recent.length + idx)"
>
<li docsSearchItem (mouseenter)="onMouseEnter($event, items.recent.length + idx)">
<a
[routerLink]="'/' + item.url | relativeLink: 'pathname'"
[fragment]="item.url | relativeLink: 'hash'"
@@ -0,0 +1,46 @@
load("//adev/shared-docs:defaults.bzl", "ng_project", "sass_binary", "ts_project", "zoneless_web_test_suite")
package(default_visibility = ["//visibility:private"])
ng_project(
name = "tab-group",
srcs = [
"tab-group.component.ts",
],
assets = [
":tab-group.component.css",
"tab-group.component.html",
],
visibility = [
"//adev/shared-docs/components:__pkg__",
"//adev/shared-docs/components/viewers:__pkg__",
],
deps = [
"//adev:node_modules/@angular/cdk",
"//adev:node_modules/@angular/common",
"//adev:node_modules/@angular/core",
"//adev:node_modules/@angular/platform-browser",
],
)
sass_binary(
name = "style",
src = "tab-group.component.scss",
)
ts_project(
name = "test_lib",
testonly = True,
srcs = glob(
["*.spec.ts"],
),
deps = [
":tab-group",
"//adev:node_modules/@angular/core",
],
)
zoneless_web_test_suite(
name = "test",
deps = [":test_lib"],
)
@@ -0,0 +1,26 @@
<div role="tablist" class="docs-tab-list">
@for (tab of computedTabs(); track tab.tabId) {
<button
[id]="tab.tabId"
role="tab"
class="docs-tab"
[class.docs-tab-active]="tab.tabId === selectedTab()"
[aria-selected]="tab.tabId === selectedTab()"
[aria-controls]="tab.tabPanelId"
(click)="selectedTab.set(tab.tabId)"
>
{{tab.label}}
</button>
}
</div>
@for (tab of computedTabs(); track tab.tabId) {
<div
[id]="tab.tabPanelId"
role="tabpanel"
class="docs-tab-panel"
[attr.aria-labelledby]="tab.tabId"
[hidden]="tab.tabId !== selectedTab()"
#tabpanel
></div>
}
@@ -0,0 +1,57 @@
.docs-tab-list {
font-size: .875rem;
font-weight: 500;
border-block-end: 1px solid var(--senary-contrast);
}
.docs-tab {
padding: 1rem;
position: relative;
background-color: var(--quaternary-contrast);
background-clip: text;
-webkit-background-clip: text;
color: transparent;
transition: background-color 0.3s ease;
&::before {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 1px;
background: var(--primary-contrast);
opacity: 0;
transform: scaleX(0.7);
transition: transform 0.3s ease, opacity 0.3s ease;
}
&:hover {
background-color: var(--primary-contrast);
&::before {
opacity: 0.3;
}
}
&.docs-tab-active {
// font gradient
background-image: var(--pink-to-purple-vertical-gradient);
&::before {
opacity: 1;
transform: scaleX(1);
background: var(--pink-to-purple-vertical-gradient);
}
&:hover {
&::before {
opacity: 1;
transform: scaleX(1.1);
}
}
}
}
.docs-tab-panel {
padding-top: 1rem;
}
@@ -0,0 +1,36 @@
/*!
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {TabGroup} from './tab-group.component';
import {provideZonelessChangeDetection} from '@angular/core';
describe('TabGroup', () => {
let fixture: ComponentFixture<TabGroup>;
beforeEach(() => {
fixture = TestBed.createComponent(TabGroup);
fixture.detectChanges();
});
it('should update tabs and tabpanels', () => {
const testPanel = document.createElement('div');
testPanel.textContent = 'panel 1';
fixture.componentRef.setInput('tabs', [{label: 'tab 1', panel: testPanel}]);
fixture.detectChanges();
const tabs = fixture.nativeElement.querySelectorAll('.docs-tab');
const tabpanels = fixture.nativeElement.querySelectorAll('.docs-tab-panel');
expect(tabs.length).toBe(1);
expect(tabpanels.length).toBe(1);
expect(tabs[0].textContent.trim()).toBe('tab 1');
expect(tabpanels[0].textContent.trim()).toBe('panel 1');
});
});
@@ -0,0 +1,69 @@
/*!
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import {
Component,
input,
inject,
computed,
linkedSignal,
viewChildren,
afterRenderEffect,
Renderer2,
ElementRef,
} from '@angular/core';
import {_IdGenerator} from '@angular/cdk/a11y';
/**
* A simple tabs implementation with proper aria roles.
*
* TODO: Consider migrate to Angular Aria Tabs pattern to enable keyboard navigation.
*/
@Component({
selector: 'docs-tab-group',
templateUrl: './tab-group.component.html',
styleUrls: ['./tab-group.component.scss'],
host: {
class: 'docs-tab-group',
},
})
export class TabGroup {
private readonly _renderer = inject(Renderer2);
private readonly _idGenerator = inject(_IdGenerator);
private readonly _tabpanels = viewChildren<ElementRef<HTMLDivElement>>('tabpanel');
readonly tabs = input<{label: string; panel: HTMLElement}[]>();
readonly computedTabs = computed(
() =>
this.tabs()?.map((tab) => ({
tabId: this._idGenerator.getId('docs-tab-'),
tabPanelId: this._idGenerator.getId('docs-tab-panel-'),
label: tab.label,
panel: tab.panel,
})) ?? [],
);
readonly selectedTab = linkedSignal(() => this.computedTabs()[0]?.tabId);
constructor() {
afterRenderEffect(() => {
const tabs = this.computedTabs();
const tabpanels = this._tabpanels();
if (tabpanels.length !== tabs.length) return;
for (let i = 0; i < tabs.length; i++) {
tabpanels[i].nativeElement.innerHTML = '';
this._renderer.appendChild(tabpanels[i].nativeElement, tabs[i].panel);
// Reset class name and attributes.
tabs[i].panel.removeAttribute('class');
tabs[i].panel.removeAttribute('label');
}
});
}
}
@@ -6,13 +6,20 @@
<ul class="docs-faceted-list">
<!-- TODO: Hide li elements with class docs-toc-item-h3 for laptop, table and phone screen resolutions -->
@for (item of tableOfContentItems(); track item.id) {
<li class="docs-faceted-list-item" [class.docs-toc-item-h2]="item.level === TableOfContentsLevel.H2"
[class.docs-toc-item-h3]="item.level === TableOfContentsLevel.H3">
<!-- Not using routerLink + fragment because of: https://github.com/angular/angular/issues/30139 -->
<a [href]="location.path() + '#' + item.id" [class.docs-faceted-list-item-active]="item.id === activeItemId()">
{{ item.title }}
</a>
</li>
<li
class="docs-faceted-list-item"
[class.docs-toc-item-h2]="item.level === TableOfContentsLevel.H2"
[class.docs-toc-item-h3]="item.level === TableOfContentsLevel.H3"
>
<!-- Not using routerLink + fragment because of: https://github.com/angular/angular/issues/30139 -->
<a
[href]="location.path() + '#' + item.id"
[class.docs-faceted-list-item-active]="item.id === activeItemId()"
[title]="item.title"
>
{{ item.title }}
</a>
</li>
}
</ul>
</nav>
@@ -20,4 +27,4 @@
<docs-icon role="presentation">arrow_upward_alt</docs-icon>
Back to the top
</button>
</aside>
</aside>
@@ -61,6 +61,9 @@
display: block; // to prevent overflow from the li parent
padding: 0.5rem 0.5rem 0.5rem 1rem;
font-weight: 500;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
&.docs-toc-item-h3 a {
@@ -96,4 +99,4 @@ button {
@include mq.for-large-desktop-down {
display: none;
}
}
}
@@ -25,8 +25,10 @@ ng_project(
"//adev:node_modules/@angular/router",
"//adev:node_modules/rxjs",
"//adev/shared-docs/components/breadcrumb",
"//adev/shared-docs/components/copy-link-anchor",
"//adev/shared-docs/components/copy-source-code-button",
"//adev/shared-docs/components/icon",
"//adev/shared-docs/components/tab-group",
"//adev/shared-docs/components/table-of-contents",
"//adev/shared-docs/interfaces",
"//adev/shared-docs/providers",
@@ -62,6 +64,7 @@ ts_project(
"//adev:node_modules/@angular/platform-browser",
"//adev:node_modules/@angular/router",
"//adev/shared-docs/components/breadcrumb",
"//adev/shared-docs/components/copy-link-anchor",
"//adev/shared-docs/components/copy-source-code-button",
"//adev/shared-docs/components/icon",
"//adev/shared-docs/components/table-of-contents",
@@ -1,5 +1,4 @@
@use '../../../styles/links' as links;
@use '../../../styles/anchor' as anchor;
@use '../../../styles/media-queries' as mq;
:host {
@@ -21,8 +20,7 @@
max-width: var(--page-width);
}
//applying styles when TOC position got translated to the top right
// applying styles when TOC position got translated to the top right
@include mq.for-large-desktop-up {
// take the available space except a reserved area for TOC
margin-left: -16rem;
@@ -32,8 +30,13 @@
// restrict the content to be fluid until it reaches that width
// $screen-xl is the breakpoint where Main content stop being fluid and made fixed
>*:not(docs-table-of-contents) {
max-width: calc(mq.$screen-xl - var(--secondary-nav-width) - var(--primary-nav-width) - var(--layout-padding)*2)
> *:not(docs-table-of-contents) {
max-width: calc(
mq.$screen-xl - var(--secondary-nav-width) - var(--primary-nav-width) - var(
--layout-padding
) *
2
);
}
pre {
@@ -50,8 +53,19 @@
margin-block-start: 0.75rem;
display: inline-block;
color: inherit;
max-width: 100%;
@include anchor.docs-anchor();
code {
// This can be useful on mobile if the heading contains a long code block
overflow: hidden;
text-overflow: ellipsis;
vertical-align: middle;
}
}
// Show copy link button when hovering the heading
&:hover docs-copy-link-button {
opacity: 1;
}
}
@@ -90,7 +104,6 @@
}
a:not(.docs-github-links):not(.docs-card):not(.docs-pill):not(.docs-example-github-link) {
&[href^='http:'],
&[href^='https:'] {
@include links.external-link-with-icon();
@@ -98,7 +111,6 @@
}
&-scroll-margin-large {
h2,
h3 {
scroll-margin: 5em;
@@ -109,7 +121,7 @@
.docs-header {
margin-block-end: 1rem;
&>p:first-child {
& > p:first-child {
color: var(--quaternary-contrast);
font-weight: 500;
margin: 0;
@@ -140,4 +152,4 @@
}
}
}
}
}
@@ -11,14 +11,16 @@ import {By} from '@angular/platform-browser';
import {provideRouter} from '@angular/router';
import {ExampleViewerContentLoader} from '../../../interfaces';
import {EXAMPLE_VIEWER_CONTENT_LOADER} from '../../../providers';
import {CodeExampleViewMode, ExampleViewer} from '../example-viewer/example-viewer.component';
import {ExampleViewer} from '../example-viewer/example-viewer.component';
import {DocViewer} from './docs-viewer.component';
import {IconComponent} from '../../icon/icon.component';
import {Breadcrumb} from '../../breadcrumb/breadcrumb.component';
import {NavigationState} from '../../../services';
import {CopySourceCodeButton} from '../../copy-source-code-button/copy-source-code-button.component';
import {CopyLinkButton} from '../../copy-link-anchor/copy-link-anchor.component';
import {TableOfContents} from '../../table-of-contents/table-of-contents.component';
import {provideZonelessChangeDetection} from '@angular/core';
import {Clipboard} from '@angular/cdk/clipboard';
describe('DocViewer', () => {
let fixture: ComponentFixture<DocViewer>;
@@ -70,6 +72,12 @@ describe('DocViewer', () => {
<h3>Heading h3</h3>
`;
const exampleContentWithDocsAnchor = `
<h2 id="test-section">
<a href="#test-section" class="docs-anchor" tabindex="-1" aria-label="Link to Test Section">Test Section</a>
</h2>
`;
beforeEach(() => {
exampleContentSpy = jasmine.createSpyObj('ExampleViewerContentLoader', ['getCodeExampleData']);
navigationStateSpy = jasmine.createSpyObj(NavigationState, ['activeNavigationItem']);
@@ -87,27 +95,24 @@ describe('DocViewer', () => {
});
fixture = TestBed.createComponent(DocViewer);
fixture.detectChanges();
});
it('should load doc into innerHTML', () => {
it('should load doc into innerHTML', async () => {
const fixture = TestBed.createComponent(DocViewer);
fixture.componentRef.setInput('docContent', 'hello world');
fixture.detectChanges();
await fixture.whenStable();
expect(fixture.nativeElement.innerHTML).toBe('hello world');
});
it('should instantiate example viewer in snippet view mode', async () => {
it('should instantiate example viewer with only a single file', async () => {
const fixture = TestBed.createComponent(DocViewer);
fixture.componentRef.setInput('docContent', exampleDocContentWithExampleViewerPlaceholders);
fixture.detectChanges();
await fixture.whenStable();
const exampleViewer = fixture.debugElement.query(By.directive(ExampleViewer));
expect(exampleViewer).not.toBeNull();
expect(exampleViewer.componentInstance.view()).toBe(CodeExampleViewMode.SNIPPET);
const copySourceCodeButton = fixture.debugElement.query(By.directive(CopySourceCodeButton));
expect(copySourceCodeButton).not.toBeNull();
@@ -126,13 +131,11 @@ describe('DocViewer', () => {
'docContent',
exampleDocContentWithExpandedExampleViewerPlaceholders,
);
fixture.detectChanges();
await fixture.whenStable();
const exampleViewer = fixture.debugElement.query(By.directive(ExampleViewer));
expect(exampleViewer).not.toBeNull();
expect(exampleViewer.componentInstance.view()).toBe(CodeExampleViewMode.MULTI_FILE);
expect(exampleViewer.componentInstance.tabs().length).toBe(2);
});
@@ -141,7 +144,6 @@ describe('DocViewer', () => {
const renderComponentSpy = spyOn(fixture.componentInstance, 'renderComponent' as any);
fixture.componentRef.setInput('docContent', exampleContentWithIcons);
fixture.detectChanges();
await fixture.whenStable();
expect(renderComponentSpy).toHaveBeenCalledTimes(2);
@@ -167,7 +169,6 @@ describe('DocViewer', () => {
const renderComponentSpy = spyOn(fixture.componentInstance, 'renderComponent' as any);
fixture.componentRef.setInput('docContent', exampleContentWithBreadcrumbPlaceholder);
fixture.detectChanges();
await fixture.whenStable();
expect(renderComponentSpy).toHaveBeenCalledTimes(1);
@@ -178,7 +179,6 @@ describe('DocViewer', () => {
const fixture = TestBed.createComponent(DocViewer);
fixture.componentRef.setInput('docContent', exampleContentWithCodeSnippet);
fixture.detectChanges();
await fixture.whenStable();
const copySourceCodeButton = fixture.debugElement.query(By.directive(CopySourceCodeButton));
@@ -192,7 +192,6 @@ describe('DocViewer', () => {
fixture.componentRef.setInput('docContent', exampleContentWithHeadings);
fixture.componentRef.setInput('hasToc', true);
fixture.detectChanges();
await fixture.whenStable();
expect(renderComponentSpy).toHaveBeenCalled();
@@ -205,9 +204,42 @@ describe('DocViewer', () => {
fixture.componentRef.setInput('docContent', exampleContentWithHeadings);
fixture.componentRef.setInput('hasToc', false);
fixture.detectChanges();
await fixture.whenStable();
expect(renderComponentSpy).not.toHaveBeenCalled();
});
it('should setup copy link functionality for docs-anchor elements', async () => {
const fixture = TestBed.createComponent(DocViewer);
fixture.componentRef.setInput('docContent', exampleContentWithDocsAnchor);
await fixture.whenStable();
const copyLinkButton = fixture.debugElement.query(By.directive(CopyLinkButton));
expect(copyLinkButton).toBeTruthy();
const anchor = fixture.nativeElement.querySelector('a.docs-anchor');
expect(anchor).toBeTruthy();
const copyButton = fixture.nativeElement.querySelector('docs-copy-link-button');
expect(copyButton).toBeTruthy();
});
it('should copy link to clipboard when copy button is clicked', async () => {
const clipboard = TestBed.inject(Clipboard);
const clipboardSpy = spyOn(clipboard, 'copy').and.returnValue(true);
const fixture = TestBed.createComponent(DocViewer);
fixture.componentRef.setInput('docContent', exampleContentWithDocsAnchor);
await fixture.whenStable();
const copyButton = fixture.nativeElement.querySelector('docs-copy-link-button');
copyButton.click();
expect(clipboardSpy).toHaveBeenCalled();
// Because the copyButton click bubbles up to an anchor tag, causing a navigation, it is
// necessary to undo this location change by going back in the history.
window.history.back();
});
});
@@ -14,40 +14,43 @@ import {
ComponentRef,
createComponent,
DestroyRef,
effect,
ElementRef,
EnvironmentInjector,
inject,
Injector,
input,
output,
PendingTasks,
PLATFORM_ID,
Type,
ViewContainerRef,
ViewEncapsulation,
PendingTasks,
output,
input,
effect,
} from '@angular/core';
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';
import {TOC_SKIP_CONTENT_MARKER, NavigationState} from '../../../services';
import {TableOfContents} from '../../table-of-contents/table-of-contents.component';
import {IconComponent} from '../../icon/icon.component';
import {handleHrefClickEventWithRouter} from '../../../utils';
import {Snippet} from '../../../interfaces';
import {Router} from '@angular/router';
import {fromEvent} from 'rxjs';
import {Snippet} from '../../../interfaces';
import {NavigationState, TOC_SKIP_CONTENT_MARKER} from '../../../services';
import {handleHrefClickEventWithRouter} from '../../../utils';
import {IconComponent} from '../../icon/icon.component';
import {TableOfContents} from '../../table-of-contents/table-of-contents.component';
import {DomSanitizer} from '@angular/platform-browser';
import {Breadcrumb} from '../../breadcrumb/breadcrumb.component';
import {CopySourceCodeButton} from '../../copy-source-code-button/copy-source-code-button.component';
import {CopyLinkButton} from '../../copy-link-anchor/copy-link-anchor.component';
import {ExampleViewer} from '../example-viewer/example-viewer.component';
import {DomSanitizer} from '@angular/platform-browser';
import {TabGroup} from '../../tab-group/tab-group.component';
const TOC_HOST_ELEMENT_NAME = 'docs-table-of-contents';
export const ASSETS_EXAMPLES_PATH = 'assets/content/examples';
export const DOCS_VIEWER_SELECTOR = 'docs-viewer, main[docsViewer]';
export const DOCS_CODE_SELECTOR = '.docs-code';
export const DOCS_CODE_MUTLIFILE_SELECTOR = '.docs-code-multifile';
// TODO: Update the branch/sha
export const GITHUB_CONTENT_URL = 'https://github.com/angular/angular/blob/main/';
export const DOCS_CODE_TAB_GROUP_SELECTOR = '.docs-tab-group';
export const DOCS_CODE_TAB_SELECTOR = '.docs-tab';
const GITHUB_CONTENT_URL = 'https://github.com/angular/angular/blob/{{BUILD_SCM_ABBREV_HASH}}';
@Component({
selector: DOCS_VIEWER_SELECTOR,
@@ -118,6 +121,11 @@ export class DocViewer {
// In case when content contains static code snippets, then create buttons
// responsible for copy source code.
this.loadCopySourceCodeButtons();
// Setup copy link functionality for section anchor links
this.loadCopyLinkAnchors(contentContainer);
// In case when content contains tabs, create tabs component and move
// content in a tab into tab panel.
this.constructTabs(contentContainer);
}
// Display Breadcrumb component if the `<docs-breadcrumb>` element exists
@@ -165,11 +173,18 @@ export class DocViewer {
return;
}
const firstHeading = element.querySelector<HTMLHeadingElement>('h2,h3[id]');
let firstHeading = element.querySelector<HTMLElement>('h2,h3[id]');
if (!firstHeading) {
return;
}
// If the first header is in a card container element, place TOC element
// before the container.
const parentEl = firstHeading.parentElement;
if (parentEl && parentEl.classList.contains('docs-card-container-header')) {
firstHeading = parentEl.parentElement;
}
// Since the content of the main area is dynamically created and there is
// no host element for a ToC component, we create it manually.
let tocHostElement: HTMLElement | null = element.querySelector(TOC_HOST_ELEMENT_NAME);
@@ -190,6 +205,7 @@ export class DocViewer {
const preview = Boolean(placeholder.getAttribute('preview'));
const hideCode = Boolean(placeholder.getAttribute('hideCode'));
const title = placeholder.getAttribute('header') ?? undefined;
const style = placeholder.getAttribute('style') ?? undefined;
const firstCodeSnippetTitle =
snippets.length > 0 ? (snippets[0].title ?? snippets[0].name) : undefined;
const exampleRef = this.viewContainer.createComponent(ExampleViewer);
@@ -202,6 +218,7 @@ export class DocViewer {
preview,
hideCode,
id: this.countOfExamples,
style,
});
exampleRef.setInput('githubUrl', `${GITHUB_CONTENT_URL}/${snippets[0].name}`);
@@ -221,6 +238,8 @@ export class DocViewer {
name: tab.getAttribute('path') ?? tab.getAttribute('header') ?? '',
sanitizedContent: this.sanitizer.bypassSecurityTrustHtml(tab.innerHTML),
visibleLinesRange: tab.getAttribute('visibleLines') ?? undefined,
shell: tab.classList.contains('shell'),
title: tab.getAttribute('header') ?? undefined,
}));
}
@@ -243,6 +262,7 @@ export class DocViewer {
? this.sanitizer.bypassSecurityTrustHtml(content.outerHTML)
: '',
visibleLinesRange: visibleLines,
shell: element.classList.contains('shell'),
};
}
@@ -250,7 +270,11 @@ export class DocViewer {
// the code
private loadCopySourceCodeButtons(): void {
const staticCodeSnippets = <Element[]>(
Array.from(this.elementRef.nativeElement.querySelectorAll('.docs-code:not([mermaid])'))
Array.from(
this.elementRef.nativeElement.querySelectorAll(
'.docs-code:not([mermaid],[hideCopy],.docs-no-copy)',
),
)
);
for (let codeSnippet of staticCodeSnippets) {
@@ -259,6 +283,22 @@ export class DocViewer {
}
}
private loadCopyLinkAnchors(element: HTMLElement): void {
const docsAnchors = Array.from(element.querySelectorAll<HTMLAnchorElement>('a.docs-anchor'));
for (const anchor of docsAnchors) {
const href = anchor.getAttribute('href')!;
const label = anchor.textContent!;
const copyLinkButtonRef = this.viewContainer.createComponent(CopyLinkButton);
copyLinkButtonRef.setInput('href', href);
copyLinkButtonRef.setInput('label', label);
copyLinkButtonRef.setInput('matTooltip', `Copy link to ${label}`);
anchor.appendChild(copyLinkButtonRef.location.nativeElement);
}
}
private loadBreadcrumb(element: HTMLElement): void {
const breadcrumbPlaceholder = element.querySelector('docs-breadcrumb') as HTMLElement;
const activeNavigationItem = this.navigationState.activeNavigationItem();
@@ -282,7 +322,7 @@ export class DocViewer {
*/
private renderComponent<T>(
type: Type<T>,
hostElement: HTMLElement,
hostElement: Element,
inputs?: {[key: string]: unknown},
): ComponentRef<T> {
const componentRef = createComponent(type, {
@@ -360,4 +400,18 @@ export class DocViewer {
(anchor as HTMLAnchorElement).href = this.location.path() + url.hash;
}
}
/** Replace .docs-tab-group and .docs-tab with tabs component. */
private constructTabs(element: HTMLElement) {
for (const tabGroup of Array.from(element.querySelectorAll(DOCS_CODE_TAB_GROUP_SELECTOR))) {
const tabs = Array.from(tabGroup.querySelectorAll(DOCS_CODE_TAB_SELECTOR)).map((t) => ({
label: t.getAttribute('label') ?? '',
panel: t,
}));
const tabGroupRef = this.viewContainer.createComponent(TabGroup);
tabGroupRef.setInput('tabs', tabs);
tabGroup.parentElement!.replaceChild(tabGroupRef.location.nativeElement, tabGroup);
}
}
}
@@ -1,11 +1,12 @@
<div class="docs-example-viewer" role="group">
<header class="docs-example-viewer-actions">
@if (view() === CodeExampleViewMode.SNIPPET) {
<span>{{ exampleMetadata()?.title }}</span>
}
@if (view() === CodeExampleViewMode.MULTI_FILE) {
<mat-tab-group #codeTabs animationDuration="0ms" mat-stretch-tabs="false">
@if (showCode()) {
<mat-tab-group
#codeTabs
animationDuration="0ms"
mat-stretch-tabs="false"
(selectedTabChange)="onTabIndexChange($event.index)"
>
@for (tab of tabs(); track tab) {
<mat-tab [label]="tab.name" />
}
@@ -17,13 +18,18 @@
type="button"
role="switch"
class="docs-example-code-toggle"
[class.docs-example-code-toggle__show]="!showCode()"
[attr.aria-checked]="showCode()"
[attr.aria-label]="showCode() ? 'Hide code' : 'Show code'"
(click)="showCode.set(!showCode())"
[matTooltip]="showCode() ? 'Hide code' : 'Show code'"
matTooltipPosition="above"
>
<docs-icon>{{showCode() ? 'code_off' : 'code'}}</docs-icon>
@if (!showCode()) {
<span class="docs-example-show-code"><docs-icon>code</docs-icon> Show Code</span>
} @else {
<docs-icon>code_off</docs-icon>
}
</button>
<button
type="button"
@@ -93,14 +99,10 @@
</header>
@if (showCode()) {
<div
class="docs-example-viewer-code-wrapper"
[class.docs-example-viewer-snippet]="view() === CodeExampleViewMode.SNIPPET"
[class.docs-example-viewer-multi-file]="view() === CodeExampleViewMode.MULTI_FILE"
>
<div class="docs-example-viewer-code-wrapper" [class.shell]="snippetCode()?.shell">
<button docs-copy-source-code></button>
@if (snippetCode()?.sanitizedContent; as content) {
<div [innerHTML]="content"></div>
<div class="docs-example-code-block" [innerHTML]="content"></div>
}
</div>
}
@@ -28,9 +28,12 @@
align-items: center;
gap: 0.5rem;
border-bottom: 1px solid var(--senary-contrast);
transition: background 0.3s ease, border-color 0.3s ease;
transition:
background 0.3s ease,
border-color 0.3s ease;
padding-inline-end: 0.65rem;
font-family: var(--inter-tight-font);
height: 3rem;
mat-tab-group {
max-width: calc(100% - 140px);
@@ -56,6 +59,9 @@
.docs-example-viewer-icons {
display: flex;
gap: 0.75rem;
width: 100%;
justify-content: flex-end;
padding-inline-start: 1rem;
a,
button {
@@ -78,6 +84,18 @@
color: var(--tertiary-contrast);
}
}
.docs-example-code-toggle {
display: flex;
align-items: center;
width: auto;
.docs-example-show-code {
display: flex;
gap: 0.5rem;
align-items: center;
}
}
}
}
@@ -94,38 +112,10 @@
button[docs-copy-source-code] {
top: 0.31rem;
}
}
// stylelint-disable-next-line
::ng-deep {
.docs-example-viewer-preview {
// stylelint-disable-next-line
all: initial;
display: block;
padding: 1rem;
border-block-start: 1px solid var(--senary-contrast);
*,
code::before,
code,
pre,
a,
i,
p,
h1,
h2,
h3,
h4,
h5,
h6,
ol,
ul,
li,
hr,
input,
select,
table {
all: revert;
}
.docs-example-code-block {
overflow: auto;
// Roughly 20 lines of code.
max-height: 35rem;
}
}
@@ -233,8 +233,7 @@ describe('ExampleViewer', () => {
expect(component.expanded()).toBeFalse();
});
// TODO(josephperrott): enable once the docs-viewer/example-viewer circle is sorted out.
xit('should call clipboard service when clicked on copy source code', async () => {
it('should call clipboard service when clicked on copy source code', async () => {
const expectedCodeSnippetContent = 'typescript code';
componentRef.setInput(
'metadata',
@@ -252,6 +251,7 @@ describe('ExampleViewer', () => {
const spy = spyOn(clipboardService, 'copy');
await component.renderExample();
await fixture.whenStable();
const button = fixture.debugElement.query(By.directive(CopySourceCodeButton)).nativeElement;
button.click();
@@ -270,7 +270,8 @@ describe('ExampleViewer', () => {
By.css('button.docs-example-copy-link'),
).nativeElement;
button.click();
expect(spy.calls.argsFor(0)[0].trim()).toBe(`${window.location.href}#example-1`);
const expectedUrl = location.origin + location.pathname + location.search + '#example-1';
expect(spy.calls.argsFor(0)[0].trim()).toBe(expectedUrl);
});
it('should hide code content when `hideCode` is true', async () => {
@@ -346,6 +347,7 @@ const getMetadata = (value: Partial<ExampleMetadata> = {}): ExampleMetadata => {
preview: false,
hideCode: false,
...value,
style: undefined,
};
};
@@ -12,30 +12,22 @@ import {
ChangeDetectorRef,
Component,
computed,
DestroyRef,
ElementRef,
inject,
Injector,
input,
signal,
Type,
viewChild,
} from '@angular/core';
import {DOCUMENT, NgComponentOutlet, NgTemplateOutlet} from '@angular/common';
import {MatTabGroup, MatTabsModule} from '@angular/material/tabs';
import {MatTabsModule} from '@angular/material/tabs';
import {Clipboard} from '@angular/cdk/clipboard';
import {CopySourceCodeButton} from '../../copy-source-code-button/copy-source-code-button.component';
import {IconComponent} from '../../icon/icon.component';
import {ExampleMetadata, Snippet} from '../../../interfaces/index';
import {EXAMPLE_VIEWER_CONTENT_LOADER} from '../../../providers/index';
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';
import {MatTooltipModule} from '@angular/material/tooltip';
export enum CodeExampleViewMode {
SNIPPET = 'snippet',
MULTI_FILE = 'multi',
}
export const CODE_LINE_NUMBER_CLASS_NAME = 'shiki-ln-number';
export const CODE_LINE_CLASS_NAME = 'line';
export const GAP_CODE_LINE_CLASS_NAME = 'gap';
@@ -59,11 +51,8 @@ export class ExampleViewer {
readonly exampleMetadata = input<ExampleMetadata | null>(null, {alias: 'metadata'});
readonly githubUrl = input<string | null>(null);
readonly stackblitzUrl = input<string | null>(null);
readonly matTabGroup = viewChild<MatTabGroup>('codeTabs');
private readonly changeDetector = inject(ChangeDetectorRef);
private readonly clipboard = inject(Clipboard);
private readonly destroyRef = inject(DestroyRef);
private readonly document = inject(DOCUMENT);
private readonly injector = inject(Injector);
private readonly elementRef = inject(ElementRef<HTMLElement>);
@@ -77,7 +66,6 @@ export class ExampleViewer {
return new Set(fileExtensions).size !== fileExtensions.length;
});
CodeExampleViewMode = CodeExampleViewMode;
exampleComponent?: Type<unknown>;
readonly expandable = signal<boolean>(false);
@@ -91,11 +79,6 @@ export class ExampleViewer {
code: file.sanitizedContent,
})),
);
readonly view = computed(() =>
this.exampleMetadata()?.files.length === 1
? CodeExampleViewMode.SNIPPET
: CodeExampleViewMode.MULTI_FILE,
);
async renderExample(): Promise<void> {
// Lazy load live example component
@@ -120,10 +103,6 @@ export class ExampleViewer {
`example-${this.exampleMetadata()?.id.toString()!}`,
);
this.matTabGroup()?.realignInkBar();
this.listenToMatTabIndexChange();
const lines = this.getHiddenCodeLines();
const lineNumbers = this.getHiddenCodeLineNumbers();
@@ -150,16 +129,9 @@ export class ExampleViewer {
this.clipboard.copy(fullUrl);
}
private listenToMatTabIndexChange(): void {
const matTabGroup = this.matTabGroup();
matTabGroup?.realignInkBar();
matTabGroup?.selectedIndexChange
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((index) => {
this.snippetCode.set(this.exampleMetadata()?.files[index]);
this.changeDetector.detectChanges();
this.setCodeLinesVisibility();
});
protected onTabIndexChange(index: number): void {
this.snippetCode.set(this.exampleMetadata()?.files[index]);
this.setCodeLinesVisibility();
}
private getFileExtension(name: string): string {
@@ -216,7 +188,7 @@ export class ExampleViewer {
const appendGapBefore = [];
for (const [index, line] of lines.entries()) {
if (!linesToDisplay.includes(index)) {
if (!linesToDisplay.includes(index + 1)) {
line.classList.add(HIDDEN_CLASS_NAME);
} else if (!linesToDisplay.includes(index - 1)) {
appendGapBefore.push(line);
@@ -25,6 +25,8 @@ export interface Snippet {
sanitizedContent: SafeHtml;
/** Text in following format `start-end`. Start and end are numbers, based on them provided range of lines will be displayed in collapsed mode */
visibleLinesRange?: string;
shell?: boolean;
}
export interface ExampleMetadata {
@@ -40,4 +42,6 @@ export interface ExampleMetadata {
preview: boolean;
/** Whether to hide code example by default. */
hideCode: boolean;
/** Visual style for the code example */
style?: 'prefer' | 'avoid';
}
+1 -1
View File
@@ -151,7 +151,7 @@ export type PlaygroundRouteData = {
starterTemplate?: PlaygroundTemplate;
};
export type PlaygroundTemplate = Required<Pick<NavigationItem, 'path' | 'label'>>;
export type PlaygroundTemplate = Required<Pick<NavigationItem, 'path' | 'label'>> & {id: string};
// Note: only the fields being used are defined in this type
export interface PackageJson {
+8 -8
View File
@@ -2,14 +2,14 @@
"name": "@angular/docs",
"version": "0.0.0-PLACEHOLDER",
"peerDependencies": {
"@angular/cdk": "^21.0.0-next",
"@angular/common": "^21.0.0-next",
"@angular/core": "^21.0.0-next",
"@angular/forms": "^21.0.0-next",
"@angular/material": "^21.0.0-next",
"@angular/platform-browser": "^21.0.0-next",
"@angular/router": "^21.0.0-next",
"@angular/ssr": "^21.0.0-next",
"@angular/cdk": "^21.0.0",
"@angular/common": "^21.0.0",
"@angular/core": "^21.0.0",
"@angular/forms": "^21.0.0",
"@angular/material": "^21.0.0",
"@angular/platform-browser": "^21.0.0",
"@angular/router": "^21.0.0",
"@angular/ssr": "^21.0.0",
"algoliasearch": "^5.0.0",
"rxjs": "^7.8.1"
},
@@ -11,6 +11,7 @@ import type {DocEntry, EntryCollection, FunctionEntry, JsDocTagEntry} from '@ang
export interface ManifestEntry {
name: string;
aliases?: string[];
type: string;
category: string | undefined;
deprecated: {version: string | undefined} | undefined;
@@ -81,6 +82,7 @@ export function generateManifest(apiCollections: EntryCollection[]): Manifest {
.filter((entry) => !isHiddenEntry(entry))
.map((entry: DocEntry) => ({
name: entry.name,
...(entry.aliases && {aliases: entry.aliases}),
type: entry.entryType,
deprecated: getTagSinceVersion(entry, 'deprecated', true),
developerPreview: getTagSinceVersion(entry, 'developerPreview'),
@@ -35,6 +35,8 @@ export enum MemberType {
Getter = 'getter',
Setter = 'setter',
EnumItem = 'enum_item',
Interface = 'interface',
TypeAlias = 'type_alias',
}
export enum DecoratorType {
@@ -96,6 +98,7 @@ export interface ConstantEntry extends DocEntry {
/** Documentation entity for a type alias. */
export interface TypeAliasEntry extends ConstantEntry {
generics: GenericEntry[];
members: MemberEntry[]; // For merged namespaces
}
/** Documentation entity for a TypeScript class. */
@@ -191,6 +194,12 @@ export interface PropertyEntry extends MemberEntry {
/** Sub-entry for a class method. */
export type MethodEntry = MemberEntry & FunctionEntry;
/** Sub-entry for an interface (included via namespace). */
export type InterfaceMemberEntry = MemberEntry & InterfaceEntry;
/** Sub-entry for a type alias (included via namespace). */
export type TypeAliasMemberEntry = MemberEntry & TypeAliasEntry;
/** Sub-entry for a single function parameter. */
export interface ParameterEntry {
name: string;
@@ -84,10 +84,13 @@ export function isEnumEntry(entry: DocEntry): entry is EnumEntry {
}
/** Gets whether the given entry represents an interface. */
export function isInterfaceEntry(
entry: MemberEntryRenderable,
): entry is InterfaceEntryRenderable & MemberEntryRenderable;
export function isInterfaceEntry(entry: DocEntryRenderable): entry is InterfaceEntryRenderable;
export function isInterfaceEntry(entry: DocEntry): entry is InterfaceEntry;
export function isInterfaceEntry(entry: DocEntry): entry is InterfaceEntry {
return entry.entryType === EntryType.Interface;
export function isInterfaceEntry(entry: DocEntry | MemberEntryRenderable): entry is InterfaceEntry {
return (entry as DocEntry).entryType === EntryType.Interface;
}
/** Gets whether the given member entry is a method entry. */
@@ -171,8 +174,9 @@ function getTag<T extends HasJsDocTags | FunctionEntry>(entry: T, tag: string, e
export function getTagSinceVersion<T extends HasJsDocTags>(
entry: T,
tagName: string,
every = false,
): {version: string | undefined} | undefined {
const tag = getTag(entry, tagName);
const tag = getTag(entry, tagName, every);
if (!tag) {
return undefined;
}
@@ -56,7 +56,11 @@ export type ConstantEntryRenderable = ConstantEntry &
};
/** Documentation entity for a type alias augmented transformed content for rendering. */
export type TypeAliasEntryRenderable = TypeAliasEntry & DocEntryRenderable & HasRenderableToc;
export type TypeAliasEntryRenderable = TypeAliasEntry &
DocEntryRenderable &
HasRenderableToc & {
members: MemberEntryRenderable[];
};
/** Documentation entity for a TypeScript class augmented transformed content for rendering. */
export type ClassEntryRenderable = ClassEntry &
@@ -104,6 +108,12 @@ export interface MemberEntryRenderable extends MemberEntry {
jsdocTags: JsDocTagRenderable[];
deprecationMessage: string | null;
htmlUsageNotes: string;
displayName?: string;
stable: {version: string | undefined} | undefined;
deprecated: {version: string | undefined} | undefined;
developerPreview: {version: string | undefined} | undefined;
experimental: {version: string | undefined} | undefined;
}
/** Sub-entry for a class method augmented transformed content for rendering. */
@@ -21,8 +21,15 @@ export function setCurrentSymbol(symbol: string): void {
currentSymbol = symbol;
}
export function getSymbols() {
return symbols;
/** Convert Record<string, string> to ApiEntries format */
export function getSymbolsAsApiEntries(): Record<string, {moduleName: string}> {
const result: Record<string, {moduleName: string}> = {};
for (const symbol in symbols) {
result[symbol] = {moduleName: symbols[symbol]};
}
return result;
}
export function getCurrentSymbol(): string | undefined {
@@ -34,7 +41,7 @@ export function setSymbols(newSymbols: Record<string, string>): void {
}
export function getSymbolUrl(symbol: string): string | undefined {
return sharedGetSymbolUrl(symbol, symbols);
return sharedGetSymbolUrl(symbol, getSymbolsAsApiEntries());
}
export function unknownSymbolMessage(link: string, symbol: string): string {
@@ -7,14 +7,17 @@
*/
import {Fragment, h} from 'preact';
import {MemberType} from '../entities.mjs';
import {
isClassMethodEntry,
isGetterEntry,
isInterfaceEntry,
isPropertyEntry,
isSetterEntry,
} from '../entities/categorization.mjs';
import {MemberEntryRenderable, MethodEntryRenderable} from '../entities/renderables.mjs';
import {
PARAM_KEYWORD_CLASS_NAME,
REFERENCE_MEMBER_CARD,
REFERENCE_MEMBER_CARD_BODY,
REFERENCE_MEMBER_CARD_HEADER,
@@ -23,6 +26,7 @@ import {
import {getFunctionMetadataRenderable} from '../transforms/function-transforms.mjs';
import {ClassMethodInfo} from './class-method-info';
import {CodeSymbol} from './code-symbols';
import {CodeTableOfContents} from './code-table-of-contents';
import {DeprecatedLabel} from './deprecated-label';
import {RawHtml} from './raw-html';
@@ -33,7 +37,7 @@ export function ClassMember(props: {member: MemberEntryRenderable}) {
const signature = method.signatures.length ? method.signatures : [method.implementation];
return signature.map((sig) => {
const renderableMember = getFunctionMetadataRenderable(sig, method.moduleName, method.repo);
return <ClassMethodInfo entry={renderableMember} options={{showUsageNotes: true}} />;
return <ClassMethodInfo entry={renderableMember} />;
});
};
@@ -44,6 +48,7 @@ export function ClassMember(props: {member: MemberEntryRenderable}) {
) : member.htmlDescription || member.deprecationMessage ? (
<div className={REFERENCE_MEMBER_CARD_ITEM}>
<DeprecatedLabel entry={member} />
{member.experimental && <span className="docs-member-tag">@experimental</span>}
<RawHtml value={member.htmlDescription} />
</div>
) : (
@@ -53,11 +58,12 @@ export function ClassMember(props: {member: MemberEntryRenderable}) {
);
const memberName = member.name;
const displayName = member.displayName;
const returnType = getMemberType(member);
return (
<div id={memberName} className={REFERENCE_MEMBER_CARD}>
<header className={REFERENCE_MEMBER_CARD_HEADER}>
<h3>{memberName}</h3>
<h3>{displayName ?? memberName}</h3>
{isClassMethodEntry(member) && member.signatures.length > 1 ? (
<span>{member.signatures.length} overloads</span>
) : returnType ? (
@@ -67,6 +73,11 @@ export function ClassMember(props: {member: MemberEntryRenderable}) {
)}
</header>
{body}
{isInterfaceEntry(member) ? (
<CodeTableOfContents entry={member} hideCopyButton={true} embedded={true} />
) : (
<></>
)}
</div>
);
}
@@ -76,6 +87,10 @@ function getMemberType(entry: MemberEntryRenderable): string | null {
return entry.implementation.returnType;
} else if (isPropertyEntry(entry) || isGetterEntry(entry) || isSetterEntry(entry)) {
return entry.type;
} else if (entry.memberType === MemberType.TypeAlias) {
return 'type';
} else if (entry.memberType === MemberType.Interface) {
return 'interface';
}
return null;
}
@@ -7,7 +7,10 @@
*/
import {Fragment, h} from 'preact';
import {FunctionSignatureMetadataRenderable, ParameterEntryRenderable} from '../entities/renderables.mjs';
import {
FunctionSignatureMetadataRenderable,
ParameterEntryRenderable,
} from '../entities/renderables.mjs';
import {PARAM_KEYWORD_CLASS_NAME, REFERENCE_MEMBER_CARD_ITEM} from '../styling/css-classes.mjs';
import {DeprecatedLabel} from './deprecated-label';
import {Parameter} from './parameter';
@@ -17,12 +20,7 @@ import {CodeSymbol} from './code-symbols';
/**
* Component to render the method-specific parts of a class's API reference.
*/
export function ClassMethodInfo(props: {
entry: FunctionSignatureMetadataRenderable;
options?: {
showUsageNotes?: boolean;
};
}) {
export function ClassMethodInfo(props: {entry: FunctionSignatureMetadataRenderable}) {
const entry = props.entry;
return (
@@ -45,9 +43,9 @@ export function ClassMethodInfo(props: {
<span className={PARAM_KEYWORD_CLASS_NAME}>@returns</span>
<CodeSymbol code={entry.returnType} />
</div>
{entry.htmlUsageNotes && props.options?.showUsageNotes ? (
{entry.htmlUsageNotes ? (
<div className={'docs-usage-notes'}>
<span className={PARAM_KEYWORD_CLASS_NAME}>Usage notes</span>
<span className={'docs-usage-notes-heading'}>Usage notes</span>
<RawHtml value={entry.htmlUsageNotes} />
</div>
) : (
@@ -41,11 +41,9 @@ export function ClassReference(
<div className={SECTION_CONTAINER + ' docs-reference-api-section'}>
<SectionHeading name="Pipe usage" />
<RawHtml
value={codeToHtml(
getHighlighterInstance(),
(entry as PipeEntry).usage,
'angular-html',
)}
value={codeToHtml(getHighlighterInstance(), (entry as PipeEntry).usage, {
language: 'angular-html',
})}
/>
</div>
</>
@@ -8,10 +8,14 @@
import {h} from 'preact';
import {renderToString} from 'preact-render-to-string';
import {CodeLineGroup} from './code-line-group';
import {HasRenderableToc} from '../entities/traits.mjs';
import {CodeLineGroup} from './code-line-group';
export function CodeTableOfContents(props: {entry: HasRenderableToc}) {
export function CodeTableOfContents(props: {
entry: HasRenderableToc;
hideCopyButton?: boolean;
embedded?: boolean;
}) {
let html: string;
// Prefer the formatted code if available
if (props.entry.formattedCode) {
@@ -26,5 +30,14 @@ export function CodeTableOfContents(props: {entry: HasRenderableToc}) {
${props.entry.afterCodeGroups}`;
}
return <div class="docs-code" dangerouslySetInnerHTML={{__html: html}}></div>;
return (
<div
className={
(props.hideCopyButton ? 'docs-no-copy' : '') +
(props.embedded ? ' embedded' : '') +
' docs-code'
}
dangerouslySetInnerHTML={{__html: html}}
></div>
);
}
@@ -16,9 +16,12 @@ export function DocsPillRow(props: {links: LinkEntryRenderable[]}) {
return (
<nav class="docs-pill-row">
{props.links.map((link) => (
<a class="docs-pill" href={link.url} title={link.title}>
{link.label}
</a>
<a
class="docs-pill"
href={link.url}
title={link.title}
dangerouslySetInnerHTML={{__html: link.label}}
></a>
))}
</nav>
);
@@ -9,12 +9,11 @@
import {h} from 'preact';
import {RawHtml} from './raw-html';
import {codeToHtml} from '../../../shared/shiki.mjs';
import {get} from 'http';
import {getHighlighterInstance} from '../shiki/shiki.mjs';
/** Component to render a header of the CLI page. */
export function HighlightTypeScript(props: {code: string}) {
const result = codeToHtml(getHighlighterInstance(), props.code, 'typescript');
const result = codeToHtml(getHighlighterInstance(), props.code, {language: 'typescript'});
const withScrollTrack = result.replace(/^(<pre class="shiki)/, '$1 docs-mini-scroll-track');
return <RawHtml value={withScrollTrack} className="docs-code" />;
@@ -17,7 +17,7 @@ export function SectionHeading(props: {name: string}) {
return (
<h2 id={id} class={SECTION_HEADING}>
<a href={'#' + id} aria-label={label} tabIndex={-1}>
<a class="docs-anchor" href={'#' + id} aria-label={label} tabIndex={-1}>
{props.name}
</a>
</h2>
@@ -6,14 +6,15 @@
* found in the LICENSE file at https://angular.dev/license
*/
import {h} from 'preact';
import {Fragment, h} from 'preact';
import {TypeAliasEntryRenderable} from '../entities/renderables.mjs';
import {HeaderApi} from './header-api';
import {SectionDescription} from './section-description';
import {SectionUsageNotes} from './section-usage-notes';
import {SectionApi} from './section-api';
import {API_REFERENCE_CONTAINER} from '../styling/css-classes.mjs';
import {API_REFERENCE_CONTAINER, REFERENCE_MEMBERS} from '../styling/css-classes.mjs';
import {DeprecationWarning} from './deprecation-warning';
import {ClassMemberList} from './class-member-list';
/** Component to render a type alias API reference document. */
export function TypeAliasReference(entry: TypeAliasEntryRenderable) {
@@ -22,6 +23,13 @@ export function TypeAliasReference(entry: TypeAliasEntryRenderable) {
<HeaderApi entry={entry} />
<DeprecationWarning entry={entry} />
<SectionApi entry={entry} />
{entry.members && entry.members.length > 0 ? (
<div class={REFERENCE_MEMBERS}>
<ClassMemberList members={entry.members} />
</div>
) : (
<></>
)}
<SectionDescription entry={entry} />
<SectionUsageNotes entry={entry} />
</div>
@@ -178,7 +178,7 @@
"Emulated",
"None",
"ShadowDom",
"IsolatedShadowDom"
"ExperimentalIsolatedShadowDom"
],
"description": "The view encapsulation strategy to use in the new application."
}
@@ -369,7 +369,7 @@
"Emulated",
"None",
"ShadowDom",
"IsolatedShadowDom"
"ExperimentalIsolatedShadowDom"
],
"description": "The view encapsulation strategy to use in the new component."
}
@@ -6,7 +6,31 @@
* found in the LICENSE file at https://angular.dev/license
*/
import {makeGenericsText} from '../../transforms/code-transforms.mjs';
import {formatExtendsClause, makeGenericsText} from '../../transforms/code-transforms.mjs';
describe('formatExtendsClause', () => {
it('should return an empty string when extendsValue is undefined', () => {
expect(formatExtendsClause(undefined)).toBe('');
});
it('should return an empty string when extendsValue is an empty array', () => {
expect(formatExtendsClause([])).toBe('');
});
it('should format a single string extends value', () => {
expect(formatExtendsClause('BaseClass')).toBe(' extends BaseClass');
});
it('should format a single item array', () => {
expect(formatExtendsClause(['BaseInterface'])).toBe(' extends BaseInterface');
});
it('should format multiple items in an array', () => {
expect(formatExtendsClause(['IAwesome1', 'IAwesome2', 'IAwesome3'])).toBe(
' extends IAwesome1, IAwesome2, IAwesome3',
);
});
});
describe('makeGenericsText', () => {
it('should return an empty string if no generics are provided', () => {
@@ -9,7 +9,11 @@
import {initHighlighter} from '../../../../shared/shiki.mjs';
import {setHighlighterInstance} from '../../shiki/shiki.mjs';
import {setCurrentSymbol, setSymbols} from '../../symbol-context.mjs';
import {addHtmlAdditionalLinks, addHtmlDescription} from '../../transforms/jsdoc-transforms.mjs';
import {
addHtmlAdditionalLinks,
addHtmlDescription,
setEntryFlags,
} from '../../transforms/jsdoc-transforms.mjs';
// @ts-ignore This compiles fine, but Webstorm doesn't like the ESM import in a CJS context.
describe('jsdoc transforms', () => {
@@ -139,6 +143,47 @@ describe('jsdoc transforms', () => {
});
});
it('should convert backticks to code tags in markdown links', () => {
const entry = addHtmlAdditionalLinks({
jsdocTags: [
{
name: 'see',
comment:
'[Host view using `ViewContainerRef.createComponent`](guide/components/programmatic-rendering#host-view-using-viewcontainerrefcreatecomponent)',
},
{
name: 'see',
comment:
'[Popup attached to `document.body` with `createComponent` + `hostElement`](guide/components/programmatic-rendering#popup-attached-to-documentbody-with-createcomponent--hostelement)',
},
{
name: 'see',
comment: '[Method with `backticks` in title](https://example.com "Title with `code`")',
},
],
moduleName: 'test',
});
expect(entry.additionalLinks[0]).toEqual({
label: 'Host view using <code>ViewContainerRef.createComponent</code>',
url: 'guide/components/programmatic-rendering#host-view-using-viewcontainerrefcreatecomponent',
title: undefined,
});
expect(entry.additionalLinks[1]).toEqual({
label:
'Popup attached to <code>document.body</code> with <code>createComponent</code> + <code>hostElement</code>',
url: 'guide/components/programmatic-rendering#popup-attached-to-documentbody-with-createcomponent--hostelement',
title: undefined,
});
expect(entry.additionalLinks[2]).toEqual({
label: 'Method with <code>backticks</code> in title',
url: 'https://example.com',
title: 'Title with `code`',
});
});
it('should throw on invalid relatie @link', () => {
const entryFn = () =>
addHtmlAdditionalLinks({
@@ -189,4 +234,62 @@ function setupRouter() {
expect(entry.htmlDescription).toContain('/api/angular/router/Router');
});
it('should only mark as deprecated if all overloads are deprecated', () => {
const entry = setEntryFlags({
name: 'Injectable',
jsdocTags: [
{'name': 'see', 'comment': '[Introduction to Services and DI](guide/di)'},
{
'name': 'see',
'comment': '[Creating and using services](guide/di/creating-and-using-services)',
},
],
signatures: [
{
'parameters': [],
'jsdocTags': [{'name': 'see', 'comment': '[Introduction to Services and DI](guide/di)'}],
},
{
'parameters': [],
'jsdocTags': [
{
'name': 'deprecated',
'comment':
"The `providedIn: NgModule` or `providedIn:'any'` options are deprecated. Please use the other signatures.",
},
],
},
],
} as any);
expect(entry.deprecated).toEqual(undefined);
const deprecatedEntry = setEntryFlags({
name: 'Injectable',
jsdocTags: [
{'name': 'see', 'comment': '[Introduction to Services and DI](guide/di)'},
{
'name': 'see',
'comment': '[Creating and using services](guide/di/creating-and-using-services)',
},
],
signatures: [
{
'parameters': [],
'jsdocTags': [
{'name': 'see', 'comment': '[Introduction to Services and DI](guide/di)'},
{'name': 'deprecated', 'comment': '19.0 something something'},
],
},
{
'parameters': [],
'jsdocTags': [{'name': 'deprecated', 'comment': '19.0 something something'}],
},
],
} as any);
// It's deprecated by
expect(deprecatedEntry.deprecated).toEqual({version: '19.0'});
});
});

Some files were not shown because too many files have changed in this diff Show More