3

Im having difficulties in understanding SCSS Variable Argument. as it shown here, it's pretty easy to understand that you can add more than one argument.

But I don't understand how can I do that with Maps.

For example:

I have this map:

$spacing: (
    none: 0px,
    micro: 2px,
    tiny: 4px,
);

And Im writing a function to control the spacing: (Most probably its super wrong)

@function spacing($value...) {
   $chosen-spacing: null;
   @if length($value) == 1 {
        @if map-has-key($spacing, $value) {
            @return map-get($spacing, $value);
        }@else {
            @error "'#{$value}' doesn't exist in 'spacing map'";
            @return null;
        }
    }@else {
        @each $v in $value {
            @if map-has-key($spacing, $value) {
                $chosen-spacing: map-get($spacing, $value);
            }@else {
                @error "'#{$value}' doesn't exist in 'spacing map'";
                @return null;
            }
        }
        @return $chosen-spacing;
    }   
}

What I want is to be able to call the function as:

.blabla {
  padding: spacing(none);
  margin: spacing (micro, tiny);
}

And the output to be:

.blabla {
  padding: 0px; 
  margin: 2px 4px; 
}

Without the Map, it can be done easily, but with Map how can I do it?

Thank you

Community
  • 1
  • 1

2 Answers2

3

You could use append with a single loop.

$spacing: (
    none: 0px,
    micro: 2px,
    tiny: 4px,
);

@function spacing($value...) {
  $chosen-spacing: null;

  @each $v in $value {
      @if map-has-key($spacing, $v) {
          $chosen-spacing: append($chosen-spacing , map-get($spacing, $v));
      }@else {
          @error "'#{$value}' doesn't exist in 'spacing map'";
          @return null;
      }
  }
  @return $chosen-spacing;
}

.blabla {
  padding: spacing(none);
  margin: spacing(micro, tiny);
}

This is the output:

.blabla {
  padding: 0px; 
  margin: 2px 4px; 
}
ReSedano
  • 4,970
  • 2
  • 18
  • 31
1

Here is how you can do it :

@function spacing($value...) {
  $chosen-spacing: null;

  @each $v in $value {
     @if($chosen-spacing) {
        $chosen-spacing: #{$chosen-spacing + ' '}
     };

     @if map-has-key($spacing, $v) {
        $chosen-spacing: #{$chosen-spacing + map-get($spacing, $v)};
     } @else {
        @error "'#{$v}' doesn't exist in 'spacing map'";
        @return null;
     }
  }

  @return $chosen-spacing;
}

You don't need to check for length, a simple loop is enough.

The loop will read each parameters and add the value got from the map to the $chosen-spacing variable. The first @if check if the variable already has a value, if it is the case, it means that we need to add a space before adding the next value (so we dont get 2px4px).

Arkellys
  • 5,562
  • 2
  • 16
  • 40