fix(docs-infra): give duplicated headings their own anchor ids

Eight guides have headings that generate the same anchor id twice or more.
Because an id resolves to the first element that claims it, the table of
contents lists two entries pointing at the same place, the second section
cannot be reached from the ToC at all, and the copy link button on the
later heading hands out a URL for the earlier one.

On `guide/forms/reactive-forms` the two "Display the component" steps sit
5176px apart and both ToC entries scroll to the first.

Give the later heading on each page an explicit id with the `{#custom-id}`
syntax the pipeline already supports. Only later duplicates are changed, so
every anchor that resolves today keeps pointing at the same heading.
This commit is contained in:
Kam
2026-08-22 16:46:05 +03:00
committed by Leon Senft
parent 355a9d83e3
commit 698a14d735
8 changed files with 30 additions and 34 deletions
@@ -105,7 +105,7 @@ export class SearchResults {
As the `query` signal changes, the `query$` Observable emits the latest query and triggers a new HTTP request.
### Injection context
### Injection context {#injection-context-to-observable}
`toObservable` by default needs to run in an [injection context](guide/di/dependency-injection-context), such as during construction of a component or service. If an injection context is not available, you can manually specify the `Injector` to use instead.
@@ -201,7 +201,7 @@ export interface DataGroup {
Each `DataGroup` is defined by the following data group properties.
#### `name`
#### `name` {#datagroups-name}
Similar to `assetGroups`, every data group has a `name` which uniquely identifies it.
@@ -318,7 +318,7 @@ If you are not able to implement CORS — for example, if you don't control the
</docs-callout>
#### `cacheQueryOptions`
#### `cacheQueryOptions` {#datagroups-cachequeryoptions}
See [assetGroups](#assetgroups) for details.
+15 -15
View File
@@ -36,13 +36,13 @@ Adding the class `animated-class` to an element would trigger the animation on t
The animations package allowed you to define various states using the [`state()`](api/animations/state) function within a component. Examples might be an `open` or `closed` state containing the styles for each respective state within the definition. For example:
#### With Animations Package
#### With Animations Package {#animating-state-and-styles-with-animations-package}
<docs-code header="open-close.ts" path="adev/src/content/examples/animations/src/app/open-close.ts" region="state1"/>
This same behavior can be accomplished natively by using CSS classes, either with a keyframe animation or transition styling.
#### With Native CSS
#### With Native CSS {#animating-state-and-styles-with-native-css}
<docs-code header="animations.css" path="adev/src/content/examples/animations/src/app/animations.css" region="animation-states"/>
@@ -66,7 +66,7 @@ Similarly, you can use `transition-duration`, `transition-delay`, and `transitio
The animations package required specifying triggers using the `trigger()` function and nesting all of your states within it. With native CSS, this is unnecessary. Animations can be triggered by toggling CSS styles or classes. Once a class is present on an element, the animation will occur. Removing the class will revert the element back to whatever CSS is defined for that element. This results in significantly less code to do the same animation. Here's an example:
#### With Animations Package
#### With Animations Package {#triggering-an-animation-with-animations-package}
<docs-code-multifile>
<docs-code header="open-close.ts" path="adev/src/content/examples/animations/src/app/animations-package/open-close.ts" />
@@ -74,7 +74,7 @@ The animations package required specifying triggers using the `trigger()` functi
<docs-code header="open-close.css" path="adev/src/content/examples/animations/src/app/animations-package/open-close.css"/>
</docs-code-multifile>
#### With Native CSS
#### With Native CSS {#triggering-an-animation-with-native-css}
<docs-code-multifile preview path="adev/src/content/examples/animations/src/app/native-css/open-close.ts">
<docs-code header="open-close.ts" path="adev/src/content/examples/animations/src/app/native-css/open-close.ts" />
@@ -94,7 +94,7 @@ These state matching patterns are not needed at all when animating with CSS dire
The animations package offers the ability to animate things that have been historically difficult to animate, like animating a set height to `height: auto`. You can now do this with pure CSS as well.
#### With Animations Package
#### With Animations Package {#automatic-property-calculation-with-animations-package}
<docs-code-multifile>
<docs-code header="auto-height.ts" path="adev/src/content/examples/animations/src/app/animations-package/auto-height.ts" />
@@ -104,7 +104,7 @@ The animations package offers the ability to animate things that have been histo
You can use CSS Grid to animate to auto height.
#### With Native CSS
#### With Native CSS {#automatic-property-calculation-with-native-css}
<docs-code-multifile preview path="adev/src/content/examples/animations/src/app/native-css/auto-height.ts">
<docs-code header="auto-height.ts" path="adev/src/content/examples/animations/src/app/native-css/auto-height.ts" />
@@ -118,7 +118,7 @@ If you don't have to worry about supporting all browsers, you can also check out
The animations package offered the previously mentioned pattern matching for entering and leaving but also included the shorthand aliases of `:enter` and `:leave`.
#### With Animations Package
#### With Animations Package {#enter-and-leave-with-animations-package}
<docs-code-multifile>
<docs-code header="insert-remove.ts" path="adev/src/content/examples/animations/src/app/animations-package/insert-remove.ts" />
@@ -126,7 +126,7 @@ The animations package offered the previously mentioned pattern matching for ent
<docs-code header="insert-remove.css" path="adev/src/content/examples/animations/src/app/animations-package/insert-remove.css" />
</docs-code-multifile>
#### With Native CSS
#### With Native CSS {#enter-with-native-css}
<docs-code-multifile preview path="adev/src/content/examples/animations/src/app/native-css/insert.ts">
<docs-code header="insert.ts" path="adev/src/content/examples/animations/src/app/native-css/insert.ts" />
@@ -134,7 +134,7 @@ The animations package offered the previously mentioned pattern matching for ent
<docs-code header="insert.css" path="adev/src/content/examples/animations/src/app/native-css/insert.css" />
</docs-code-multifile>
#### With Native CSS
#### With Native CSS {#leave-with-native-css}
<docs-code-multifile preview path="adev/src/content/examples/animations/src/app/native-css/remove.ts">
<docs-code header="remove.ts" path="adev/src/content/examples/animations/src/app/native-css/remove.ts" />
@@ -148,7 +148,7 @@ For more information on `animate.enter` and `animate.leave`, see the [Enter and
Along with the aforementioned `:enter` and `:leave`, there's also `:increment` and `:decrement`. You can animate these also by adding and removing classes. Unlike the animation package built-in aliases, there is no automatic application of classes when the values go up or down. You can apply the appropriate classes programmatically. Here's an example:
#### With Animations Package
#### With Animations Package {#increment-and-decrement-with-animations-package}
<docs-code-multifile>
<docs-code header="increment-decrement.ts" path="adev/src/content/examples/animations/src/app/animations-package/increment-decrement.ts" />
@@ -156,7 +156,7 @@ Along with the aforementioned `:enter` and `:leave`, there's also `:increment` a
<docs-code header="increment-decrement.css" path="adev/src/content/examples/animations/src/app/animations-package/increment-decrement.css" />
</docs-code-multifile>
#### With Native CSS
#### With Native CSS {#increment-and-decrement-with-native-css}
<docs-code-multifile preview path="adev/src/content/examples/animations/src/app/native-css/increment-decrement.ts">
<docs-code header="increment-decrement.ts" path="adev/src/content/examples/animations/src/app/native-css/increment-decrement.ts" />
@@ -221,7 +221,7 @@ To toggle classes for child nodes within a template, you can use class and style
The `stagger()` function allowed you to delay the animation of each item in a list of items by a specified time to create a cascade effect. You can replicate this behavior in native CSS by utilizing `animation-delay` or `transition-delay`. Here is an example of what that CSS might look like.
#### With Animations Package
#### With Animations Package {#stagger-with-animations-package}
<docs-code-multifile>
<docs-code header="stagger.ts" path="adev/src/content/examples/animations/src/app/animations-package/stagger.ts" />
@@ -229,7 +229,7 @@ The `stagger()` function allowed you to delay the animation of each item in a li
<docs-code header="stagger.css" path="adev/src/content/examples/animations/src/app/animations-package/stagger.css" />
</docs-code-multifile>
#### With Native CSS
#### With Native CSS {#stagger-with-native-css}
<docs-code-multifile preview path="adev/src/content/examples/animations/src/app/native-css/stagger.ts">
<docs-code header="stagger.ts" path="adev/src/content/examples/animations/src/app/native-css/stagger.ts" />
@@ -255,7 +255,7 @@ In this example, the `rotate` and `fade-in` animations fire at the same time.
Items reordering in a list works out of the box using the previously described techniques. No additional special work is required. Items in a `@for` loop will be removed and re-added properly, which will fire off animations using `@starting-styles` for entry animations. Alternatively, you can use `animate.enter` for this same behavior. Use `animate.leave` to animate elements as they are removed, as seen in the example above.
#### With Animations Package
#### With Animations Package {#reordering-list-with-animations-package}
<docs-code-multifile>
<docs-code header="reorder.ts" path="adev/src/content/examples/animations/src/app/animations-package/reorder.ts" />
@@ -263,7 +263,7 @@ Items reordering in a list works out of the box using the previously described t
<docs-code header="reorder.css" path="adev/src/content/examples/animations/src/app/animations-package/reorder.css" />
</docs-code-multifile>
#### With Native CSS
#### With Native CSS {#reordering-list-with-native-css}
<docs-code-multifile preview path="adev/src/content/examples/animations/src/app/native-css/reorder.ts">
<docs-code header="reorder.ts" path="adev/src/content/examples/animations/src/app/native-css/reorder.ts" />
+3 -3
View File
@@ -288,7 +288,7 @@ Binding to an input is the same in both signal-based and decorator-based inputs:
The `@Input` decorator accepts a config object that lets you change the way that input works.
#### Required inputs
#### Required inputs {#required-inputs-decorator}
You can specify the `required` option to enforce that a given input must always have a value.
@@ -301,7 +301,7 @@ export class CustomSlider {
If you try to use a component without specifying all of its required inputs, Angular reports an error at build-time.
#### Input transforms
#### Input transforms {#input-transforms-decorator}
You can specify a `transform` function to change the value of an input when it's set by Angular. This transform function works identically to transform functions for signal-based inputs described above.
@@ -319,7 +319,7 @@ function trimString(value: string | undefined) {
}
```
#### Input aliases
#### Input aliases {#input-aliases-decorator}
You can specify the `alias` option to change the name of an input in templates.
@@ -164,7 +164,7 @@ Use a `button` element to add a button to the bottom of the form to trigger the
The button in the preceding snippet also has a `disabled` binding attached to it to disable the button when `profileForm` is invalid. You aren't performing any validation yet, so the button is always enabled. Basic form validation is covered in the [Validating form input](#validating-form-input) section.
</docs-step>
<docs-step title="Display the component">
<docs-step title="Display the component {#display-the-component-form-group}">
To display the `ProfileEditor` component that contains the form, add it to a component template.
<docs-code header="app.component.html (profile editor)" path="adev/src/content/examples/reactive-forms/src/app/app.component.1.html" region="app-profile-editor"/>
@@ -385,9 +385,7 @@ NOTE: In zoneless applications, mutating a reactive forms model (for example cal
import {ChangeDetectorRef, Component, inject} from '@angular/core';
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';
@Component({
/* ... */
})
@Component({/* ... */})
export class ProfileEditor {
private readonly cdr = inject(ChangeDetectorRef);
@@ -615,9 +613,7 @@ When updating form controls programmatically, you have precise control over how
By default `emitEvent: true`, any change to a control emits events through the `valueChanges` and `statusChanges` observables. Setting `emitEvent: false` suppresses these emissions, which is useful when setting values programmatically without triggering reactive behavior like auto-save, avoiding circular updates between controls, or performing bulk updates where events should emit only once at the end.
```ts
@Component({
/* ... */
})
@Component({/* ... */})
export class BlogPostEditor {
postForm = new FormGroup({
title: new FormControl(''),
+1 -1
View File
@@ -124,7 +124,7 @@ Include [interpolations](guide/templates/binding#render-dynamic-text-with-text-i
$localize`string_to_translate ${variable_name}`;
```
### Name the interpolation placeholder
### Name the interpolation placeholder {#name-the-interpolation-placeholder-in-code}
```ts
$localize`string_to_translate ${variable_name}:placeholder_name:`;
@@ -255,7 +255,7 @@ Every node in the tree, including the root form object, provides the same signal
| `readonly()` | Returns `true` if the node is readonly |
| `errors()` | Returns an array of validation errors with `kind` and `message` properties |
### Complete example
### Complete example {#complete-example-validation}
<docs-code-multifile preview path="adev/src/content/examples/signal-forms/src/login-validation/app/app.ts">
<docs-code header="app.ts" path="adev/src/content/examples/signal-forms/src/login-validation/app/app.ts"/>
@@ -64,7 +64,7 @@ In some cases this can lead to compilation errors when classes with Angular deco
other classes with Angular decorators. If you enable this option, the migration will generate an
additional constructor signature to keep it backwards compatible, at the expense of more code.
#### Before
#### Before {#backwards-compatible-constructors-before}
```typescript
import {Component} from '@angular/core';
@@ -76,7 +76,7 @@ export class MyComp {
}
```
#### After
#### After {#backwards-compatible-constructors-after}
```ts
import { Component } from '@angular/core';
@@ -105,7 +105,7 @@ at the expense of potentially hiding type errors.
**NOTE:** non-null assertions won't be added to parameters that are already typed to be nullable,
because the code that depends on them likely already accounts for their nullability.
#### Before
#### Before {#non-nullable-optional-before}
```typescript
import {Component, Inject, Optional} from '@angular/core';
@@ -120,7 +120,7 @@ export class MyComp {
}
```
#### After
#### After {#non-nullable-optional-after}
```typescript
import {Component, inject} from '@angular/core';