@@ -2,6 +2,7 @@ import {readFileSync, writeFileSync} from 'fs';
22import { pathToFileURL } from 'url' ;
33import { relative , join , dirname } from 'path' ;
44import { compileString } from 'sass' ;
5+ import { highlightCodeBlock } from '../highlight-files/highlight-code-block' ;
56
67/** Information extracted for a single token from the theme. */
78interface 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.
3546if ( 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