@@ -204,6 +204,8 @@ function getTokenExtractionCode(
204204 const stringJoin = '__privateStringJoin' ;
205205 const m3Tokens = '___privateM3Tokens' ;
206206 const palettes = '___privatePalettes' ;
207+ const sassUtils = '__privateSassUtils' ;
208+ const inferTokenType = '__privateInferFromValue' ;
207209 const defineOverrides = '_define-overrides' ;
208210 const corePath = relative ( dirname ( absoluteThemePath ) , join ( srcPath , 'material/core' ) ) || '.' ;
209211
@@ -215,12 +217,12 @@ function getTokenExtractionCode(
215217 @use 'sass:string' as ${ str } ;
216218 @use '${ join ( corePath , 'tokens/m3-tokens' ) } ' as ${ m3Tokens } ;
217219 @use '${ join ( corePath , 'theming/palettes' ) } ' as ${ palettes } ;
218- @use '${ join ( corePath , 'style/sass-utils' ) } ' as __privateSassUtils ;
220+ @use '${ join ( corePath , 'style/sass-utils' ) } ' as ${ sassUtils } ;
219221
220222 // The 'generate-*' functions don't have the ability to enable
221223 // system tokens so we have to do it by setting a variable.
222- __privateSassUtils .$use-system-color-variables: true;
223- __privateSassUtils .$use-system-typography-variables: true;
224+ ${ sassUtils } .$use-system-color-variables: true;
225+ ${ sassUtils } .$use-system-typography-variables: true;
224226 ` ;
225227
226228 const append = `
@@ -241,6 +243,7 @@ function getTokenExtractionCode(
241243 @error 'Expected override to be a list but got ' + $__override-type;
242244 }
243245
246+ // Joins all the strings in a list with a separator.
244247 @function ${ stringJoin } ($value, $separator) {
245248 $result: '';
246249 @each $part in $value {
@@ -249,6 +252,37 @@ function getTokenExtractionCode(
249252 @return $result;
250253 }
251254
255+ // Uses some simple heuristics to determine the type of a token based on its name or value.
256+ @function ${ inferTokenType } ($name, $value) {
257+ @if ($value == null) {
258+ @return null;
259+ }
260+
261+ $type: ${ meta } .type-of($value);
262+ $inferred-type: null;
263+
264+ // Note: Sass' string.index returns a 1-based index or null (if the value can't be found)
265+ // so it's safe to just null check it in the conditions below.
266+ @if ($type == 'color' or ${ str } .index($name, 'shadow') or ${ str } .index($name, 'opacity')) {
267+ $inferred-type: color;
268+ } @else if (
269+ ${ str } .index($name, 'font') or
270+ ${ str } .index($name, 'line-height') or
271+ ${ str } .index($name, 'tracking') or
272+ ${ str } .index($name, 'weight') or
273+ (${ str } .index($name, 'text') and ${ str } .index($name, 'size')) or
274+ (${ str } .index($name, 'text') and ${ str } .index($name, 'transform'))
275+ ) {
276+ $inferred-type: typography;
277+ } @else if (${ str } .index($name, 'width') or ${ str } .index($name, 'height')) {
278+ $inferred-type: density;
279+ } @else if ($type == 'string' or ${ str } .index($name, 'shape')) {
280+ $inferred-type: base;
281+ }
282+
283+ @return $inferred-type;
284+ }
285+
252286 @each $map in $__override-tokens {
253287 $namespace: ${ map } .get($map, namespace);
254288 $tokens: ${ map } .get($map, tokens);
@@ -258,7 +292,7 @@ function getTokenExtractionCode(
258292 $typography: ${ map } .get($__all-typography, $namespace) or ();
259293 $density: ${ map } .get($__all-density, $namespace) or ();
260294
261- @each $name, $_ in $tokens {
295+ @each $name, $resolved-value in $tokens {
262296 $color-value: ${ map } .get($color, $name);
263297 $base-value: ${ map } .get($base, $name);
264298 $typography-value: ${ map } .get($typography, $name);
@@ -281,6 +315,19 @@ function getTokenExtractionCode(
281315 $value: $color-value;
282316 }
283317
318+ // If the token has a value, but could not be found in the token maps, try to infer its type
319+ // from the name and value. This is fairly rare, but can happen for some hardcoded tokens.
320+ @if ($value == null and $resolved-value) {
321+ $fallback-type: ${ inferTokenType } ($name, $resolved-value);
322+
323+ @if ($fallback-type == null) {
324+ @error 'Cannot determine type of token "#{$name}". Token extraction script needs to be updated.';
325+ }
326+
327+ $type: $fallback-type;
328+ $value: $resolved-value;
329+ }
330+
284331 @if ($value) {
285332 $__results: ${ list } .append($__results, (
286333 name: ${ str } .unquote($name),
0 commit comments