Skip to content

Commit 61e207e

Browse files
amysortodevchas
authored andcommitted
docs: update what is angular page
1 parent 85fe323 commit 61e207e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+3025
-206
lines changed

.aspect/rules/external_repository_action_cache/npm_translate_lock_MzA5NzUwNzMx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
adev/shared-docs/pipeline/api-gen/package.json=939673974
77
integration/package.json=-239561259
88
modules/package.json=450100502
9-
package.json=-1187216265
9+
package.json=1423170514
1010
packages/animations/package.json=-678724831
1111
packages/common/package.json=1729763064
1212
packages/compiler-cli/linker/babel/test/package.json=939673974
@@ -21,7 +21,7 @@ packages/platform-browser/package.json=-1163479450
2121
packages/router/package.json=860819913
2222
packages/upgrade/package.json=16347051
2323
packages/zone.js/package.json=-1005735564
24-
pnpm-lock.yaml=-1560711032
24+
pnpm-lock.yaml=-140868321
2525
pnpm-workspace.yaml=1973735808
2626
tools/bazel/rules_angular_store/package.json=-239561259
27-
yarn.lock=-448136563
27+
yarn.lock=79232593

adev/shared-docs/components/viewers/BUILD.bazel

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,21 @@ ng_project(
2727
"//:node_modules/@angular/cdk",
2828
"//:node_modules/@angular/material",
2929
"//:node_modules/rxjs",
30+
"//adev/shared-docs/components/breadcrumb",
3031
"//adev/shared-docs/components/breadcrumb:breadcrumb_rjs",
32+
"//adev/shared-docs/components/copy-source-code-button",
3133
"//adev/shared-docs/components/copy-source-code-button:copy-source-code-button_rjs",
34+
"//adev/shared-docs/components/table-of-contents",
3235
"//adev/shared-docs/components/table-of-contents:table-of-contents_rjs",
36+
"//adev/shared-docs/interfaces",
3337
"//adev/shared-docs/interfaces:interfaces_rjs",
38+
"//adev/shared-docs/providers",
3439
"//adev/shared-docs/providers:providers_rjs",
40+
"//packages/common",
41+
"//packages/core",
42+
"//packages/router",
43+
"@npm//@angular/cdk",
44+
"@npm//@angular/material",
3545
],
3646
)
3747

adev/shared-docs/components/viewers/docs-viewer/docs-viewer.component.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,11 +165,18 @@ export class DocViewer {
165165
return;
166166
}
167167

168-
const firstHeading = element.querySelector<HTMLHeadingElement>('h2,h3[id]');
168+
let firstHeading = element.querySelector<HTMLElement>('h2,h3[id]');
169169
if (!firstHeading) {
170170
return;
171171
}
172172

173+
// If the first header is in a card container element, place TOC element
174+
// before the container.
175+
const parentEl = firstHeading.parentElement;
176+
if (parentEl && parentEl.classList.contains('docs-card-container-header')) {
177+
firstHeading = parentEl.parentElement;
178+
}
179+
173180
// Since the content of the main area is dynamically created and there is
174181
// no host element for a ToC component, we create it manually.
175182
let tocHostElement: HTMLElement | null = element.querySelector(TOC_HOST_ELEMENT_NAME);

adev/shared-docs/pipeline/guides/extensions/docs-card/docs-card-container.mts

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

99
import {Tokens, Token, RendererThis, TokenizerThis} from 'marked';
10+
import {loadWorkspaceRelativeFile} from '../../utils.mjs';
11+
import {formatHeading} from '../../tranformations/heading.mjs';
1012

1113
interface DocsCardContainerToken extends Tokens.Generic {
1214
type: 'docs-card-container';
1315
cards: string;
16+
headerTitle?: string;
17+
headerImgSrc?: string;
18+
headerImgDarkSrc?: string;
1419
tokens: Token[];
1520
}
1621

17-
const cardContainerRule = /^<docs-card-container>(.*?)<\/docs-card-container>/s;
22+
// Capture group 1: all attributes on the opening tag
23+
// Capture group 2: all content between the open and close tags
24+
const cardContainerRule =
25+
/^[^<]*<docs-card-container\s([^>]*)>((?:.(?!\/docs-card-container))*)<\/docs-card-container>/s;
26+
const headerTitleRule = /headerTitle="([^"]*)"/;
27+
const headerImgSrcRule = /headerImgSrc="([^"]*)"/;
28+
const headerImgDarkSrcRule = /headerImgDarkSrc="([^"]*)"/;
1829

1930
export const docsCardContainerExtension = {
2031
name: 'docs-card-container',
@@ -26,11 +37,20 @@ export const docsCardContainerExtension = {
2637
const match = cardContainerRule.exec(src);
2738

2839
if (match) {
29-
const body = match[1];
40+
const attr = match[1].trim();
41+
const headerTitle = headerTitleRule.exec(attr);
42+
const headerImgSrc = headerImgSrcRule.exec(attr);
43+
const headerImgDarkSrc = headerImgDarkSrcRule.exec(attr);
44+
45+
const body = match[2].trim();
46+
3047
const token: DocsCardContainerToken = {
3148
type: 'docs-card-container',
3249
raw: match[0],
3350
cards: body ?? '',
51+
headerTitle: headerTitle ? headerTitle[1] : undefined,
52+
headerImgSrc: headerImgSrc ? headerImgSrc[1] : undefined,
53+
headerImgDarkSrc: headerImgDarkSrc ? headerImgDarkSrc[1] : undefined,
3454
tokens: [],
3555
};
3656
this.lexer.blockTokens(token.cards, token.tokens);
@@ -39,10 +59,44 @@ export const docsCardContainerExtension = {
3959
return undefined;
4060
},
4161
renderer(this: RendererThis, token: DocsCardContainerToken) {
42-
return `
62+
return token.headerTitle
63+
? getContainerWithHeader(this, token)
64+
: getStandardContainer(this, token);
65+
},
66+
};
67+
68+
function getStandardContainer(renderer: RendererThis, token: DocsCardContainerToken) {
69+
return `
4370
<div class="docs-card-grid">
44-
${this.parser.parse(token.tokens)}
71+
${renderer.parser.parse(token.tokens)}
4572
</div>
4673
`;
47-
},
48-
};
74+
}
75+
76+
function getContainerWithHeader(renderer: RendererThis, token: DocsCardContainerToken) {
77+
// We can assume that all illustrations are svg files
78+
// We need to read svg content, instead of renering svg with `img`,
79+
// cause we would like to use CSS variables to support dark and light mode.
80+
let illustration = '';
81+
if (token.headerImgSrc) {
82+
illustration = loadWorkspaceRelativeFile(token.headerImgSrc!);
83+
}
84+
85+
let illustrationDark = '';
86+
if (token.headerImgDarkSrc) {
87+
illustrationDark = loadWorkspaceRelativeFile(token.headerImgDarkSrc!);
88+
}
89+
90+
return `
91+
<div class="docs-card-container-wrapper">
92+
<div class="docs-card-container-header">
93+
${formatHeading({text: token.headerTitle!, depth: 2})}
94+
<span class="img-light">${illustration}</span>
95+
<span class="img-dark">${illustrationDark}</span>
96+
</div>
97+
<div class="docs-card-container-content docs-card-grid">
98+
${renderer.parser.parse(token.tokens)}
99+
</div>
100+
</div>
101+
`;
102+
}

adev/shared-docs/pipeline/guides/extensions/docs-card/docs-card.mts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ interface DocsCardToken extends Tokens.Generic {
1717
link?: string;
1818
href?: string;
1919
imgSrc?: string;
20+
iconImgSrc?: string; // Need image since icons are custom
2021
tokens: Token[];
2122
}
2223

@@ -28,6 +29,7 @@ const titleRule = /title="([^"]*)"/;
2829
const linkRule = /link="([^"]*)"/;
2930
const hrefRule = /href="([^"]*)"/;
3031
const imgSrcRule = /imgSrc="([^"]*)"/;
32+
const iconImgSrcRule = /iconImgSrc="([^"]*)"/;
3133

3234
export const docsCardExtension = {
3335
name: 'docs-card',
@@ -44,6 +46,7 @@ export const docsCardExtension = {
4446
const link = linkRule.exec(attr);
4547
const href = hrefRule.exec(attr);
4648
const imgSrc = imgSrcRule.exec(attr);
49+
const iconImgSrc = iconImgSrcRule.exec(attr);
4750

4851
const body = match[2].trim();
4952

@@ -55,6 +58,7 @@ export const docsCardExtension = {
5558
href: href ? href[1] : undefined,
5659
link: link ? link[1] : undefined,
5760
imgSrc: imgSrc ? imgSrc[1] : undefined,
61+
iconImgSrc: iconImgSrc ? iconImgSrc[1] : undefined,
5862
tokens: [],
5963
};
6064
this.lexer.blockTokens(token.body, token.tokens);
@@ -68,7 +72,23 @@ export const docsCardExtension = {
6872
};
6973

7074
function getStandardCard(renderer: RendererThis, token: DocsCardToken) {
71-
if (token.href) {
75+
if (token.iconImgSrc && token.href) {
76+
// We can assume that all icons are svg files since they are custom.
77+
// We need to read svg content, instead of renering svg with `img`,
78+
// cause we would like to use CSS variables to support dark and light mode.
79+
const icon = loadWorkspaceRelativeFile(token.iconImgSrc);
80+
81+
return `
82+
<a href="${token.href}" ${anchorTarget(token.href)} class="docs-card">
83+
<div>
84+
${icon}
85+
<h3>${token.title}</h3>
86+
${renderer.parser.parse(token.tokens)}
87+
</div>
88+
<span>${token.link ? token.link : 'Learn more'}</span>
89+
</a>
90+
`;
91+
} else if (token.href) {
7292
return `
7393
<a href="${token.href}" ${anchorTarget(token.href)} class="docs-card">
7494
<div>
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
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 {Tokens, Token, RendererThis, TokenizerThis} from 'marked';
10+
import { loadWorkspaceRelativeFile } from '../../utils.mjs';
11+
12+
interface DocsNavCardToken extends Tokens.Generic {
13+
type: 'docs-nav-card';
14+
title: string;
15+
items: string;
16+
tokens: Token[];
17+
iconImgSrc?: string; // Need image since icons are custom
18+
}
19+
20+
// Capture group 1: all attributes on the opening tag
21+
// Capture group 2: all content between the open and close tags
22+
const navCardRule = /^[^<]*<docs-nav-card\s([^>]*)>((?:.(?!\/docs-nav-card))*)<\/docs-nav-card>/s;
23+
const titleRule = /title="([^"]*)"/;
24+
const hrefRule = /href="([^"]*)"/;
25+
const iconImgSrcRule = /iconImgSrc="([^"]*)"/;
26+
27+
export const docsNavCardExtension = {
28+
name: 'docs-nav-card',
29+
level: 'block' as const,
30+
start(src: string) {
31+
return src.match(/^\s*<docs-nav-card\s*/m)?.index;
32+
},
33+
tokenizer(this: TokenizerThis, src: string): DocsNavCardToken | undefined {
34+
const match = navCardRule.exec(src);
35+
36+
if (match) {
37+
const attr = match[1].trim();
38+
const title = titleRule.exec(attr);
39+
const iconImgSrc = iconImgSrcRule.exec(attr);
40+
41+
const items = match[2].trim();
42+
43+
const token: DocsNavCardToken = {
44+
type: 'docs-nav-card',
45+
raw: match[0],
46+
title: title ? title[1] : '',
47+
items: items ?? '',
48+
iconImgSrc: iconImgSrc ? iconImgSrc[1] : undefined,
49+
tokens: [],
50+
};
51+
this.lexer.blockTokens(token.items, token.tokens);
52+
return token;
53+
}
54+
return undefined;
55+
},
56+
renderer(this: RendererThis, token: DocsNavCardToken) {
57+
// We need to read svg content, instead of renering svg with `img`,
58+
// cause we would like to use CSS variables to support dark and light mode.
59+
const illustration = loadWorkspaceRelativeFile(
60+
'adev/src/assets/images/editor-light-horizontal.svg',
61+
);
62+
63+
// We can assume that all icons are svg files since they are custom.
64+
// We need to read svg content, instead of renering svg with `img`,
65+
// cause we would like to use CSS variables to support dark and light mode.
66+
let icon = '';
67+
if (token.iconImgSrc) {
68+
icon = loadWorkspaceRelativeFile(token.iconImgSrc);
69+
}
70+
71+
return `
72+
<div class="docs-nav-card">
73+
<div class="docs-nav-card-title">
74+
${icon}
75+
<h6>${token.title}</h6>
76+
</div>
77+
<div class="docs-nav-card-content">
78+
<div class="docs-nav-card-links">
79+
${this.parser.parse(token.tokens)}
80+
</div>
81+
<div class="docs-nav-card-svg">
82+
${illustration}
83+
</div>
84+
</div>
85+
</div>
86+
`;
87+
},
88+
};
89+
90+
interface DocsNavLinkToken extends Tokens.Generic {
91+
type: 'docs-nav-link';
92+
title: string;
93+
body: string;
94+
href: string;
95+
iconImgSrc?: string; // Need image since icons are custom
96+
bodyTokens: Token[];
97+
}
98+
99+
// Capture group 1: all attributes on the opening tag
100+
// Capture group 2: all content between the open and close tags
101+
const navLinkRule = /^[^<]*<docs-nav-link\s([^>]*)>((?:.(?!\/docs-nav-link))*)<\/docs-nav-link>/s;
102+
103+
export const docsNavLinkExtension = {
104+
name: 'docs-nav-link',
105+
level: 'block' as const,
106+
start(src: string) {
107+
src.match(/^\s*<docs-nav-link/m)?.index;
108+
},
109+
tokenizer(this: TokenizerThis, src: string): DocsNavLinkToken | undefined {
110+
const match = navLinkRule.exec(src);
111+
112+
if (match) {
113+
const attr = match[1].trim();
114+
const title = titleRule.exec(attr);
115+
const iconImgSrc = iconImgSrcRule.exec(attr);
116+
const href = hrefRule.exec(attr);
117+
118+
const body = match[2].trim();
119+
120+
const token: DocsNavLinkToken = {
121+
type: 'docs-nav-link',
122+
raw: match[0],
123+
title: title ? title[1] : '',
124+
href: href ? href[1] : '',
125+
body: body ?? '',
126+
iconImgSrc: iconImgSrc ? iconImgSrc[1] : undefined,
127+
bodyTokens: [],
128+
};
129+
this.lexer.blockTokens(token.body, token.bodyTokens);
130+
return token;
131+
}
132+
return undefined;
133+
},
134+
renderer(this: RendererThis, token: DocsNavLinkToken) {
135+
// We can assume that all icons are svg files since they are custom.
136+
// We need to read svg content, instead of renering svg with `img`,
137+
// cause we would like to use CSS variables to support dark and light mode.
138+
let icon = '';
139+
if (token.iconImgSrc) {
140+
icon = loadWorkspaceRelativeFile(token.iconImgSrc);
141+
}
142+
143+
return `
144+
<a href="${token.href}" class="docs-card docs-nav-link">
145+
<div class="docs-card-text-content">
146+
<div class="docs-nav-link-title">
147+
${icon}
148+
<h3>${token.title}</h3>
149+
</div>
150+
${this.parser.parse(token.bodyTokens)}
151+
</div>
152+
</a>
153+
`;
154+
},
155+
};

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy