Skip to content

docs: update what is angular page #62276

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
adev/shared-docs/pipeline/api-gen/package.json=939673974
integration/package.json=-239561259
modules/package.json=450100502
package.json=-1187216265
package.json=1423170514
packages/animations/package.json=-678724831
packages/common/package.json=1729763064
packages/compiler-cli/linker/babel/test/package.json=939673974
Expand All @@ -21,7 +21,7 @@ packages/platform-browser/package.json=-1163479450
packages/router/package.json=860819913
packages/upgrade/package.json=16347051
packages/zone.js/package.json=-1005735564
pnpm-lock.yaml=-1560711032
pnpm-lock.yaml=-140868321
pnpm-workspace.yaml=1973735808
tools/bazel/rules_angular_store/package.json=-239561259
yarn.lock=-448136563
yarn.lock=79232593
10 changes: 10 additions & 0 deletions adev/shared-docs/components/viewers/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,21 @@ ng_project(
"//:node_modules/@angular/cdk",
"//:node_modules/@angular/material",
"//:node_modules/rxjs",
"//adev/shared-docs/components/breadcrumb",
"//adev/shared-docs/components/breadcrumb:breadcrumb_rjs",
"//adev/shared-docs/components/copy-source-code-button",
"//adev/shared-docs/components/copy-source-code-button:copy-source-code-button_rjs",
"//adev/shared-docs/components/table-of-contents",
"//adev/shared-docs/components/table-of-contents:table-of-contents_rjs",
"//adev/shared-docs/interfaces",
"//adev/shared-docs/interfaces:interfaces_rjs",
"//adev/shared-docs/providers",
"//adev/shared-docs/providers:providers_rjs",
"//packages/common",
"//packages/core",
"//packages/router",
"@npm//@angular/cdk",
"@npm//@angular/material",
],
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,11 +165,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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,25 @@
*/

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

interface DocsCardContainerToken extends Tokens.Generic {
type: 'docs-card-container';
cards: string;
headerTitle?: string;
headerImgSrc?: string;
headerImgDarkSrc?: string;
tokens: Token[];
}

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

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

if (match) {
const body = match[1];
const attr = match[1] ? match[1].trim() : '';
const headerTitle = headerTitleRule.exec(attr);
const headerImgSrc = headerImgSrcRule.exec(attr);
const headerImgDarkSrc = headerImgDarkSrcRule.exec(attr);

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

const token: DocsCardContainerToken = {
type: 'docs-card-container',
raw: match[0],
cards: body ?? '',
headerTitle: headerTitle ? headerTitle[1] : undefined,
headerImgSrc: headerImgSrc ? headerImgSrc[1] : undefined,
headerImgDarkSrc: headerImgDarkSrc ? headerImgDarkSrc[1] : undefined,
tokens: [],
};
this.lexer.blockTokens(token.cards, token.tokens);
Expand All @@ -39,10 +59,44 @@ export const docsCardContainerExtension = {
return undefined;
},
renderer(this: RendererThis, token: DocsCardContainerToken) {
return `
return token.headerTitle
? getContainerWithHeader(this, token)
: getStandardContainer(this, token);
},
};

function getStandardContainer(renderer: RendererThis, token: DocsCardContainerToken) {
return `
<div class="docs-card-grid">
${this.parser.parse(token.tokens)}
${renderer.parser.parse(token.tokens)}
</div>
`;
},
};
}

function getContainerWithHeader(renderer: RendererThis, token: DocsCardContainerToken) {
// We can assume that all illustrations are svg files
// We need to read svg content, instead of renering svg with `img`,
// cause we would like to use CSS variables to support dark and light mode.
let illustration = '';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: these two would be cleaner as const ternaries

if (token.headerImgSrc) {
illustration = loadWorkspaceRelativeFile(token.headerImgSrc!);
}

let illustrationDark = '';
if (token.headerImgDarkSrc) {
illustrationDark = loadWorkspaceRelativeFile(token.headerImgDarkSrc!);
}

return `
<div class="docs-card-container-wrapper">
<div class="docs-card-container-header">
${formatHeading({text: token.headerTitle!, depth: 2})}
<span class="img-light">${illustration}</span>
<span class="img-dark">${illustrationDark}</span>
</div>
<div class="docs-card-container-content docs-card-grid">
${renderer.parser.parse(token.tokens)}
</div>
</div>
`;
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,19 @@ interface DocsCardToken extends Tokens.Generic {
link?: string;
href?: string;
imgSrc?: string;
iconImgSrc?: string; // Need image since icons are custom
tokens: Token[];
}

// Capture group 1: all attributes on the opening tag
// Capture group 2: all content between the open and close tags
const cardRule = /^[^<]*<docs-card\s([^>]*)>((?:.(?!\/docs-card))*)<\/docs-card>/s;
const cardRule = /^[^<]*<docs-card(?:\s([^>]*))?>((?:.(?!\/docs-card))*)<\/docs-card>/s;

const titleRule = /title="([^"]*)"/;
const linkRule = /link="([^"]*)"/;
const hrefRule = /href="([^"]*)"/;
const imgSrcRule = /imgSrc="([^"]*)"/;
const iconImgSrcRule = /iconImgSrc="([^"]*)"/;

export const docsCardExtension = {
name: 'docs-card',
Expand All @@ -39,11 +41,12 @@ export const docsCardExtension = {
const match = cardRule.exec(src);

if (match) {
const attr = match[1].trim();
const attr = match[1] ? match[1].trim() : '';
const title = titleRule.exec(attr);
const link = linkRule.exec(attr);
const href = hrefRule.exec(attr);
const imgSrc = imgSrcRule.exec(attr);
const iconImgSrc = iconImgSrcRule.exec(attr);

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

Expand All @@ -55,6 +58,7 @@ export const docsCardExtension = {
href: href ? href[1] : undefined,
link: link ? link[1] : undefined,
imgSrc: imgSrc ? imgSrc[1] : undefined,
iconImgSrc: iconImgSrc ? iconImgSrc[1] : undefined,
tokens: [],
};
this.lexer.blockTokens(token.body, token.tokens);
Expand All @@ -68,7 +72,23 @@ export const docsCardExtension = {
};

function getStandardCard(renderer: RendererThis, token: DocsCardToken) {
if (token.href) {
if (token.iconImgSrc && token.href) {
// We can assume that all icons are svg files since they are custom.
// We need to read svg content, instead of renering svg with `img`,
// cause we would like to use CSS variables to support dark and light mode.
const icon = loadWorkspaceRelativeFile(token.iconImgSrc);

return `
<a href="${token.href}" ${anchorTarget(token.href)} class="docs-card">
<div>
${icon}
<h3>${token.title}</h3>
${renderer.parser.parse(token.tokens)}
</div>
<span>${token.link ? token.link : 'Learn more'}</span>
</a>
`;
} else if (token.href) {
return `
<a href="${token.href}" ${anchorTarget(token.href)} class="docs-card">
<div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
/*!
* @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 {Tokens, Token, RendererThis, TokenizerThis} from 'marked';
import {loadWorkspaceRelativeFile} from '../../utils.mjs';

interface DocsNavCardToken extends Tokens.Generic {
type: 'docs-nav-card';
title: string;
items: string;
tokens: Token[];
iconImgSrc?: string; // Need image since icons are custom
}

// Capture group 1: all attributes on the opening tag
// Capture group 2: all content between the open and close tags
const navCardRule = /^[^<]*<docs-nav-card\s([^>]*)>((?:.(?!\/docs-nav-card))*)<\/docs-nav-card>/s;
const titleRule = /title="([^"]*)"/;
const hrefRule = /href="([^"]*)"/;
const iconImgSrcRule = /iconImgSrc="([^"]*)"/;

export const docsNavCardExtension = {
name: 'docs-nav-card',
level: 'block' as const,
start(src: string) {
return src.match(/^\s*<docs-nav-card\s*/m)?.index;
},
tokenizer(this: TokenizerThis, src: string): DocsNavCardToken | undefined {
const match = navCardRule.exec(src);

if (match) {
const attr = match[1].trim();
const title = titleRule.exec(attr);
const iconImgSrc = iconImgSrcRule.exec(attr);

const items = match[2].trim();

const token: DocsNavCardToken = {
type: 'docs-nav-card',
raw: match[0],
title: title ? title[1] : '',
items: items ?? '',
iconImgSrc: iconImgSrc ? iconImgSrc[1] : undefined,
tokens: [],
};
this.lexer.blockTokens(token.items, token.tokens);
return token;
}
return undefined;
},
renderer(this: RendererThis, token: DocsNavCardToken) {
// We need to read svg content, instead of renering svg with `img`,
// cause we would like to use CSS variables to support dark and light mode.
const illustration = loadWorkspaceRelativeFile(
'adev/src/assets/images/editor-light-horizontal.svg',
);

// We can assume that all icons are svg files since they are custom.
// We need to read svg content, instead of renering svg with `img`,
// cause we would like to use CSS variables to support dark and light mode.
let icon = '';
if (token.iconImgSrc) {
icon = loadWorkspaceRelativeFile(token.iconImgSrc);
}

return `
<div class="docs-nav-card">
<div class="docs-nav-card-title">
${icon}
<h6>${token.title}</h6>
</div>
<div class="docs-nav-card-content">
<div class="docs-nav-card-links">
${this.parser.parse(token.tokens)}
</div>
<div class="docs-nav-card-svg">
${illustration}
</div>
</div>
</div>
`;
},
};

interface DocsNavLinkToken extends Tokens.Generic {
type: 'docs-nav-link';
title: string;
body: string;
href: string;
iconImgSrc?: string; // Need image since icons are custom
bodyTokens: Token[];
}

// Capture group 1: all attributes on the opening tag
// Capture group 2: all content between the open and close tags
const navLinkRule = /^[^<]*<docs-nav-link\s([^>]*)>((?:.(?!\/docs-nav-link))*)<\/docs-nav-link>/s;

export const docsNavLinkExtension = {
name: 'docs-nav-link',
level: 'block' as const,
start(src: string) {
src.match(/^\s*<docs-nav-link/m)?.index;
},
tokenizer(this: TokenizerThis, src: string): DocsNavLinkToken | undefined {
const match = navLinkRule.exec(src);

if (match) {
const attr = match[1].trim();
const title = titleRule.exec(attr);
const iconImgSrc = iconImgSrcRule.exec(attr);
const href = hrefRule.exec(attr);

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

const token: DocsNavLinkToken = {
type: 'docs-nav-link',
raw: match[0],
title: title ? title[1] : '',
href: href ? href[1] : '',
body: body ?? '',
iconImgSrc: iconImgSrc ? iconImgSrc[1] : undefined,
bodyTokens: [],
};
this.lexer.blockTokens(token.body, token.bodyTokens);
return token;
}
return undefined;
},
renderer(this: RendererThis, token: DocsNavLinkToken) {
// We can assume that all icons are svg files since they are custom.
// We need to read svg content, instead of renering svg with `img`,
// cause we would like to use CSS variables to support dark and light mode.
let icon = '';
if (token.iconImgSrc) {
icon = loadWorkspaceRelativeFile(token.iconImgSrc);
}

return `
<a href="${token.href}" class="docs-card docs-nav-link">
<div class="docs-card-text-content">
<div class="docs-nav-link-title">
${icon}
<h3>${token.title}</h3>
</div>
${this.parser.parse(token.bodyTokens)}
</div>
</a>
`;
},
};
Loading
Loading
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