sasssass-mapsangular-material-theming

SASS - Passing map through map_merge results in similar looking but not equivalent map


I'm trying to write a function to dynamically apply some transformations to a previously defined map of colours for an angular material theme. The problem is that the result that comes out of the function is wrong, somehow.

I've printed the result via the debug log and it looks exactly like the original map, but fails a comparison by keys, and causes errors if I try to feed it to angular material functions.

Here is a simplified demonstration of the issue - you can see that

What I need to accomplish inside the function is for $eenie to be equivalent to $miney after having gone through map_merge

I suspect that maybe because the key looks a number, it is having some kind of datatype crisis, but I don't know enough about SASS to figure out if that's the case or how to get around it. I've tried using quotes, but that does not seem to be an acceptable input for angular material functions, so I need it to match $eenie exactly.

@function merge-things($base-palette){
  $result: ();
  @each $hue, $color in $base-palette {
      $result: map_merge($result, (#{$hue}: $color));
  }
  @return $result;
}

$eenie: (
  50: green,
  contrast: (
    50: white,
  ),
);
$meenie: (
  50: green,
  contrast: (
    50: white,
  ),
);

$miney: merge-things($eenie);
$mo: merge-things($miney);



@debug $eenie;    // DEBUG: (50: green, contrast: (50: white))
@debug $meenie;   // DEBUG: (50: green, contrast: (50: white))
@debug $miney;    // DEBUG: (50: green, contrast: (50: white))
@debug $mo;       // DEBUG: (50: green, contrast: (50: white))
@debug 'eenie-meenie #{map-keys($eenie) == map-keys($meenie)}';   // DEBUG: eenie-meenie true
@debug 'eenie-miney #{map-keys($eenie) == map-keys($miney)}';     // DEBUG: eenie-miney false
@debug 'miney-mo #{map-keys($miney) == map-keys($mo)}';           // DEBUG: miney-mo true

Solution

  • The merge-things function changes the type of keys when interpolation is performed with the key in the map that is a number.

    @use "sass:map";
    
    $result: map-merge($result, (#{$hue}: $color));
    

    The following exercise shows that interpolating a number type converts it to string type.

    @use "sass:meta";
    
    $k: 1;
    
    @debug meta.type-of(#{$k}); // string
    
    @debug meta.type-of($k); // number
    

    Leave the keys as-is when you build up the new map.

    -      $result: map-merge($result, (#{$hue}: $color));
    +      $result: map-merge($result, ($hue: $color));