Получить имя переменной в виде строки - PullRequest
0 голосов
/ 21 сентября 2018

У меня есть класс с именем .text-black, у меня также есть карта с некоторыми значениями.

$black: #000;

map:
  dark: $black;

Я хочу пройтись по этой карте и создать новый класс с $key изатем расширяем новый класс, используя значение text-black.

У меня 2 проблемы.Первое, что я решил, если я могу получить $value как $black вместо #000. Затем я могу удалить $ с помощью замены строки.

Вторая проблема, однако, это доказатьГоловная боль для меня.Мне нужно получить $black вместо #000.

Вот мой код, показывающий мой подход на данный момент.

// String Replacement to remove '$' from varaible name.
@function str-replace($string, $search, $replace: '') {
  $index: str-index($string, $search);
  @if $index {
    @return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace)
  }
  @return $string;
}


// get color from map
@function text-color($key: "weekly-digest") {
    @return map-get($text-colors, $key);
}

$black: #000000;

// map text-colors
$text-colors: () !default;
$text-colors: map-merge(
  (
    "news":         $black,
  ),
  $text-colors
);

// Extendable classes.
.text-black{
  color: $black;
}


// Loop function
@each $name, $value in $text-colors {
    &--#{$name} {
      background-color: $value;

      @extend .text-#{$value}  // This should return '.text-black' not '.text-#000000'
    }
}

1 Ответ

0 голосов
/ 21 сентября 2018

Я стараюсь дать вам 3 разных решения.Во всех этих решениях я использовал 2 цвета (черный и красный) только для того, чтобы посмотреть, могут ли они работать в комбинации:

1.Используя функцию str-split () (возможно, наиболее сложную, но используйте ваш код)

Я нашел магическую функцию, которая разбивает строку на 2 элемента Какразбить строку на два списка чисел в SASS? .

Так что моя идея состоит в том, чтобы использовать эту функцию ( благодаря @ dayenite : если вам нравится это решение, пожалуйста, подпишите его;)) в строке, используя символ (в моем примере "_"), чтобы разделить ваши карты на 3 различных значения (например, 2 ключа и 1 значение): 1. " news " 2. " black " 3. " # 000"

Ваша карта может выглядеть примерно так:

$text-colors: map-merge(
  (
    "news_black":$black,
    "info_red":  $red
  ),
  $text-colors
);

Это весь код в действии:

@function str-split($string, $separator) {
    // empty array/list
    $split-arr: ();
    // first index of separator in string
    $index : str-index($string, $separator);
    // loop through string
    @while $index != null {
        // get the substring from the first character to the separator
        $item: str-slice($string, 1, $index - 1);
        // push item to array
        $split-arr: append($split-arr, $item);
        // remove item and separator from string
        $string: str-slice($string, $index + 1);
        // find new index of separator
        $index : str-index($string, $separator);
    }
    // add the remaining string to list (the last item)
    $split-arr: append($split-arr, $string);

    @return $split-arr;
}


/* Example with 2 colors */
$black: #000000;
$red: #ff0000;

$text-colors: () !default;
$text-colors: map-merge(
  (
    "news_black":$black,
    "info_red":  $red //my add
  ),
  $text-colors
);

// Extendable classes.

.text-black{
  color: $black;
}

.text-red{
  color: $red;
}

// Loop function

.my-div{
  @each $name, $value in $text-colors {
    $list: (); // Create every time an empty list with my 2 argoments, for example "news" and "black"
    $split-values: str-split($name, "_"); //use the function to split the string

    @each $valore in $split-values {
      $list: append($list, str-split($valore, " "));
    }
    //set here the first part of the string (i.e. news/info)
    &--#{nth($list, 1)} {
      background-color: $value;
      @extend .text-#{nth($list, 2)}  // set here the second part: black/red
    }
  }
}

https://www.sassmeister.com/gist/08f699dba4436d3bae6a4d8b666e815b

2.Используя вложенный список

На этот раз я создал простой вложенный список со значением 3 («новости», «черный», $ черный), результат тот же.

$black: #000000;
$red: #ff0000;

// list text-colors
$text-colors: (
    ( "news", "black",  $black ),
    ( "info", "red",  $red )
);

// Extendable classes.
.text-black{
  color: $black;
}

.text-red{
  color: $red;
}

.mydiv{
// Loop function
  @each $item in $text-colors {
      &--#{nth($item, 1)} {
        background-color: nth($item, 3);

        @extend .text-#{nth($item, 2)}
      }
  }
}

https://www.sassmeister.com/gist/59adf5ee60ea46dd7a24e94d7db91d85

3.Использование вложенной карты

Здесь я использую вложенные карты, но структура отличается от вашей, и я не знаю, подходит ли вам это.

$black: #000000;
$red: #ff0000;

// map text-colors
$text-colors: (
    news:(black: $black),
    info:(red: $red)
);

.text-black{
  color: $black;
}

.text-red{
  color: $red;
}

.mydiv{
// Loop function
  @each $name, $value in $text-colors {

    &--#{$name} {
      @each $name-color, $value-color in $value {
        background-color: $value-color;
        @extend .text-#{$name-color}
      }
    }
  }
}

https://www.sassmeister.com/gist/8ddec08755befc84f6e4846fbc625130

Ну, у меня нет других идей.Я надеюсь, что хотя бы один способ мог помочь вам решить вашу проблему.

Приветствия:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...