Skip to content

Commit 8bdd98e

Browse files
MeAkibJeanMeche
authored andcommitted
fix(docs-infra): prevent duplicate description rendering for block API entries
Block entries (@if, @defer, @for,@let, @switch) were falling back to the generic DocsReference template, causing the description to appear twice - once in the header section and once in the main content area. This commit adds a dedicated rendering path for block entries: - Creates BlockEntryRenderable type and associated transforms - Adds BlockReference template that uses RawHtml directly - Modifies HeaderApi to accept hideDescription prop - Updates processing and rendering pipelines to handle blocks The fix ensures block documentation displays only one description section while preserving the existing behavior for all other API entry types. Update adev/shared-docs/pipeline/api-gen/rendering/transforms/block-transforms.mts Co-authored-by: Matthieu Riegler <kyro38@gmail.com>
1 parent 933ca9e commit 8bdd98e

8 files changed

Lines changed: 94 additions & 6 deletions

File tree

adev/shared-docs/pipeline/api-gen/rendering/entities.mts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,9 @@ export type FunctionEntry = FunctionDefinitionEntry &
161161
implementation: FunctionSignatureMetadata;
162162
};
163163

164+
/** Documentation entity for a block. */
165+
export interface BlockEntry extends DocEntry {}
166+
164167
/** Interface describing a function with overload signatures. */
165168
export interface FunctionDefinitionEntry {
166169
name: string;

adev/shared-docs/pipeline/api-gen/rendering/entities/categorization.mts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
*/
88

99
import {
10+
BlockEntry,
1011
ClassEntry,
1112
ConstantEntry,
1213
DecoratorEntry,
@@ -27,6 +28,7 @@ import {
2728
import {CliCommand} from '../cli-entities.mjs';
2829

2930
import {
31+
BlockEntryRenderable,
3032
ClassEntryRenderable,
3133
ConstantEntryRenderable,
3234
DecoratorEntryRenderable,
@@ -107,6 +109,13 @@ export function isFunctionEntry(entry: DocEntry): entry is FunctionEntry {
107109
return entry.entryType === EntryType.Function;
108110
}
109111

112+
/** Gets whether the given entry represents a block */
113+
export function isBlockEntry(entry: DocEntryRenderable): entry is BlockEntryRenderable;
114+
export function isBlockEntry(entry: DocEntry): entry is BlockEntry;
115+
export function isBlockEntry(entry: DocEntry): entry is BlockEntry {
116+
return entry.entryType === EntryType.Block;
117+
}
118+
110119
export function isInitializerApiFunctionEntry(
111120
entry: DocEntryRenderable,
112121
): entry is InitializerApiFunctionRenderable;

adev/shared-docs/pipeline/api-gen/rendering/entities/renderables.mts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
ParameterEntry,
2222
PipeEntry,
2323
TypeAliasEntry,
24+
EntryType,
2425
} from '../entities.mjs';
2526

2627
import {CliCommand, CliOption} from '../cli-entities.mjs';
@@ -106,6 +107,9 @@ export type FunctionSignatureMetadataRenderable = FunctionSignatureMetadata &
106107
params: ParameterEntryRenderable[];
107108
};
108109

110+
/** Documentation entity for a block augmented with transformed content for rendering. */
111+
export type BlockEntryRenderable = DocEntry & DocEntryRenderable;
112+
109113
/** Sub-entry for a single class or enum member augmented with transformed content for rendering. */
110114
export interface MemberEntryRenderable extends MemberEntry {
111115
htmlDescription: string;

adev/shared-docs/pipeline/api-gen/rendering/processing.mts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
isInitializerApiFunctionEntry,
2020
isInterfaceEntry,
2121
isTypeAliasEntry,
22+
isBlockEntry,
2223
} from './entities/categorization.mjs';
2324
import {CliCommandRenderable, DocEntryRenderable} from './entities/renderables.mjs';
2425
import {getClassRenderable} from './transforms/class-transforms.mjs';
@@ -39,6 +40,7 @@ import {
3940
import {addModuleName} from './transforms/module-name.mjs';
4041
import {addRepo} from './transforms/repo.mjs';
4142
import {getTypeAliasRenderable} from './transforms/type-alias-transforms.mjs';
43+
import {getBlockRenderable} from './transforms/block-transforms.mjs';
4244

4345
export async function getRenderable(
4446
entry: DocEntry | CliCommand,
@@ -73,6 +75,9 @@ export async function getRenderable(
7375
if (isInitializerApiFunctionEntry(entry)) {
7476
return getInitializerApiFunctionRenderable(entry, moduleName, repo);
7577
}
78+
if (isBlockEntry(entry)) {
79+
return getBlockRenderable(entry, moduleName, repo);
80+
}
7681

7782
// Fallback to an uncategorized renderable.
7883
return setEntryFlags(

adev/shared-docs/pipeline/api-gen/rendering/rendering.mts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
isInitializerApiFunctionEntry,
1919
isInterfaceEntry,
2020
isTypeAliasEntry,
21+
isBlockEntry,
2122
} from './entities/categorization.mjs';
2223
import {CliCommandRenderable, DocEntryRenderable} from './entities/renderables.mjs';
2324
import {ClassReference} from './templates/class-reference';
@@ -30,6 +31,7 @@ import {InitializerApiFunction} from './templates/initializer-api-function';
3031
import {TypeAliasReference} from './templates/type-alias-reference';
3132
import {DecoratorReference} from './templates/decorator-reference';
3233
import {setCurrentSymbol} from './symbol-context.mjs';
34+
import {BlockReference} from './templates/block-reference';
3335

3436
/** Given a doc entry, get the transformed version of the entry for rendering. */
3537
export function renderEntry(renderable: DocEntryRenderable | CliCommandRenderable): string {
@@ -59,6 +61,9 @@ export function renderEntry(renderable: DocEntryRenderable | CliCommandRenderabl
5961
if (isInitializerApiFunctionEntry(renderable)) {
6062
return render(InitializerApiFunction(renderable));
6163
}
64+
if (isBlockEntry(renderable)) {
65+
return render(BlockReference(renderable));
66+
}
6267

6368
// Fall back rendering nothing while in development.
6469
return render(DocsReference(renderable));
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*!
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.dev/license
7+
*/
8+
9+
import {h} from 'preact';
10+
import {BlockEntryRenderable} from '../entities/renderables.mjs';
11+
import {HeaderApi} from './header-api';
12+
import {RawHtml} from './raw-html';
13+
import {API_REFERENCE_CONTAINER} from '../styling/css-classes.mjs';
14+
15+
/** Component to render a block API reference document. */
16+
export function BlockReference(entry: BlockEntryRenderable) {
17+
return (
18+
<div className={API_REFERENCE_CONTAINER}>
19+
<HeaderApi entry={entry} hideDescription={true} />
20+
<RawHtml value={entry.htmlDescription} />
21+
</div>
22+
);
23+
}

adev/shared-docs/pipeline/api-gen/rendering/templates/header-api.tsx

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {DocsPillRow} from './docs-pill-row';
2121
export function HeaderApi(props: {
2222
entry: DocEntryRenderable | PipeEntryRenderable;
2323
showFullDescription?: boolean;
24+
hideDescription?: boolean;
2425
}) {
2526
const entry = props.entry;
2627

@@ -60,12 +61,14 @@ export function HeaderApi(props: {
6061
)}
6162
</div>
6263

63-
<section
64-
className={'docs-reference-description'}
65-
dangerouslySetInnerHTML={{
66-
__html: props.showFullDescription ? entry.htmlDescription : entry.shortHtmlDescription,
67-
}}
68-
></section>
64+
{!props.hideDescription && (
65+
<section
66+
className={'docs-reference-description'}
67+
dangerouslySetInnerHTML={{
68+
__html: props.showFullDescription ? entry.htmlDescription : entry.shortHtmlDescription,
69+
}}
70+
></section>
71+
)}
6972

7073
<DocsPillRow links={entry.additionalLinks} />
7174
</header>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*!
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.dev/license
7+
*/
8+
9+
import {DocEntry} from '../entities.mjs';
10+
import {BlockEntryRenderable} from '../entities/renderables.mjs';
11+
import {
12+
addHtmlAdditionalLinks,
13+
addHtmlDescription,
14+
addHtmlJsDocTagComments,
15+
addHtmlUsageNotes,
16+
setEntryFlags,
17+
} from './jsdoc-transforms.mjs';
18+
import {addModuleName} from './module-name.mjs';
19+
import {addRepo} from './repo.mjs';
20+
21+
/** Given an unprocessed block entry, get the fully renderable block entry. */
22+
export function getBlockRenderable(
23+
blockEntry: DocEntry,
24+
moduleName: string,
25+
repo: string,
26+
): BlockEntryRenderable {
27+
return setEntryFlags(
28+
addHtmlAdditionalLinks(
29+
addHtmlDescription(
30+
addHtmlUsageNotes(
31+
addHtmlJsDocTagComments(addRepo(addModuleName(blockEntry, moduleName), repo)),
32+
),
33+
),
34+
),
35+
);
36+
}

0 commit comments

Comments
 (0)