Skip to content

Commit bd75077

Browse files
authored
build: generate styling example during the build (angular#29964)
Currently the example in the styling pages on the docs site is generated at runtime which doesn't allow us to highlight it as code correctly. These changes move the generation of the example into the main repo and add syntax highlighting.
1 parent a8f6341 commit bd75077

File tree

2 files changed

+51
-4
lines changed

2 files changed

+51
-4
lines changed

tools/extract-tokens/BUILD.bazel

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ ts_library(
1010
devmode_module = "commonjs",
1111
tsconfig = ":tsconfig.json",
1212
deps = [
13+
"//tools/highlight-files:sources",
1314
"@npm//@types/node",
1415
"@npm//sass",
1516
],
@@ -19,6 +20,7 @@ nodejs_binary(
1920
name = "extract-tokens",
2021
data = [
2122
":extract_tokens_lib",
23+
"@npm//highlight.js",
2224
"@npm//sass",
2325
],
2426
entry_point = ":extract-tokens.ts",

tools/extract-tokens/extract-tokens.ts

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {readFileSync, writeFileSync} from 'fs';
22
import {pathToFileURL} from 'url';
33
import {relative, join, dirname} from 'path';
44
import {compileString} from 'sass';
5+
import {highlightCodeBlock} from '../highlight-files/highlight-code-block';
56

67
/** Information extracted for a single token from the theme. */
78
interface ExtractedToken {
@@ -31,6 +32,16 @@ interface Token {
3132
derivedFrom?: string;
3233
}
3334

35+
/** Information extracted from a theme file. */
36+
interface ThemeData {
37+
/** Name of the theme file. */
38+
name: string;
39+
/** Name of the `overrides` mixin within the file. */
40+
overridesMixin: string;
41+
/** Tokens that can be used in the `overrides` mixin. */
42+
tokens: Token[];
43+
}
44+
3445
// Script that extracts the tokens from a specific Bazel target.
3546
if (require.main === module) {
3647
const [packagePath, outputPath, ...inputFiles] = process.argv.slice(2);
@@ -52,20 +63,19 @@ if (require.main === module) {
5263
throw new Error(`Could not find theme files in ${packagePath}`);
5364
}
5465

55-
const themes: {name: string; overridesMixin: string; tokens: Token[]}[] = [];
66+
const themes: ThemeData[] = [];
5667

5768
themeFiles.forEach(theme => {
58-
const tokens = extractTokens(theme.filePath);
5969
themes.push({
6070
name: theme.mixinPrefix,
6171
// This can be derived from the `name` already, but we want the source
6272
// of truth to be in this repo, instead of whatever page consumes the data.
6373
overridesMixin: `${theme.mixinPrefix}-overrides`,
64-
tokens,
74+
tokens: extractTokens(theme.filePath),
6575
});
6676
});
6777

68-
writeFileSync(outputPath, JSON.stringify(themes));
78+
writeFileSync(outputPath, JSON.stringify({example: getUsageExample(themes), themes}));
6979
}
7080

7181
/**
@@ -137,6 +147,41 @@ function extractTokens(themePath: string): Token[] {
137147
});
138148
}
139149

150+
/**
151+
* Generates a highlighted code snippet that illustrates how an overrides mixin can be used.
152+
* @param themes Themes that were extracted from a specific entrypoint. One of these themes will
153+
* be used as an example.
154+
*/
155+
function getUsageExample(themes: ThemeData[]): string | null {
156+
const mixin = themes.find(theme => theme.tokens.length > 0);
157+
158+
if (!mixin) {
159+
return null;
160+
}
161+
162+
// Pick out a couple of color tokens to show as examples.
163+
const firstToken = mixin.tokens.find(token => token.type === 'color');
164+
const secondToken = mixin.tokens.find(token => token.type === 'color' && token !== firstToken);
165+
166+
if (!firstToken) {
167+
return null;
168+
}
169+
170+
const lines = [
171+
`@use '@angular/material' as mat;`,
172+
``,
173+
`// Customize the entire app. Change :root to your selector if you want to scope the styles.`,
174+
`:root {`,
175+
` @include mat.${mixin.overridesMixin}((`,
176+
` ${firstToken.overridesName}: orange,`,
177+
...(secondToken ? [` ${secondToken.overridesName}: red,`] : []),
178+
` ));`,
179+
`}`,
180+
];
181+
182+
return highlightCodeBlock(lines.join('\n'), 'scss');
183+
}
184+
140185
/**
141186
* Generates the code that can be added around a theme file in order to extract its tokens.
142187
* @param srcPath Absolute path to the source root.

0 commit comments

Comments
 (0)