Автоматически сгенерированные карты sass

Я пытаюсь создать автоматизированную систему для определения цветов в SASS.

У меня есть карта цветов с именем $brand-colors, и я хочу, чтобы цвета этой карты использовались для создания оттенков и теней во второй карте, независимо от того, сколько цветов содержится в $brand-colors.

Вот точка, куда я прибыл:

$brand-colors: (
  brand-color: (
    primary-color:        #0096d6,
    secondary-color:      #1a4760,
  ),
) !default;

@function generate-map($map) {
  @each $item, $colors in $map {
    @each $color-name, $value in $colors {
      @return(
        $color-name: (
          light-30:   mix(white, $value, 30%),
          light-20:   mix(white, $value, 20%),
          light-10:   mix(white, $value, 10%),
          base:       $value,
          dark-10:    mix(black, $value, 10%),
          dark-20:    mix(black, $value, 20%),
          dark-30:    mix(black, $value, 30%),
        ),
      );
    };
  };
};

$brand-palette: (
  brand-palette:(
    generate-map($_new-brand-colors)
  ),
) !default;

С приведенным выше кодом я получаю этот результат от терминала:

brand-palette:(
  primary-color:(
    light-30: #4db6e2,
    light-20: #33abde,
    light-10: #1aa1da,
    base: #0096d6,
    dark-10: #0087c1,
    dark-20: #0078ab,
    dark-30: #006996
  )
)

Короче берется только первая пара ключ-значение, и не могу понять почему. Может ли кто-нибудь дать мне ответ?


person Alessio Ripa    schedule 30.01.2018    source источник


Ответы (1)


Функции и операторы возврата

Оператор @return указывает функции остановить все и вернуть значение.

@function myFunction() {
    @each $item in [a, b, c, d] {
        @return $item;
    }
}

myFunction() вернет только a. Несмотря на то, что у нас есть цикл с четырьмя элементами, он запустится только один раз (в первый раз), потому что он сразу же попадает в оператор @return.


Лучшая практика, чтобы вернуться один раз в конце функции

Один из лучших способов работы с функциями – использовать переменную $result и вызывать @return $result один раз только в конце функции.

@function myFunctionFixed() {
    $result;
    @each $item in [a, b, c, d] {
        $result: $result + a;
    }
    @return $result;
}

myFunctionFixed() вернет abcd, потому что мы позволяем циклу выполняться от начала до конца, не прерывая его с помощью @return, и мы возвращаемся только в конце функции после завершения цикла.


Использование map-merge для постепенного построения карты

Применяя рекомендации, описанные выше, мы можем переместить оператор @return в конец вашей функции и использовать map-merge для постепенного создания переменной $result-map.

@function generate-map($map) {
    $result-map: () !default;
    @each $item, $colors in $map {
        @each $color-name, $value in $colors {
            $result-map: map-merge($result-map, 
                ($color-name: (
                  light-30:   mix(white, $value, 30%),
                  light-20:   mix(white, $value, 20%),
                  light-10:   mix(white, $value, 10%),
                  base:       $value,
                  dark-10:    mix(black, $value, 10%),
                  dark-20:    mix(black, $value, 20%),
                  dark-30:    mix(black, $value, 30%),
                ))
            );
        };
    };
    @return $result-map;
};
person miir    schedule 30.01.2018