noamyg
noamyg

Reputation: 3104

Dynamically interpolate class name and pass it as variable

I have the following mixin:

@mixin indication-circle($color-class, $with-background: true) {
  display: inline;
  border-radius: 15px;
  padding: 0rem 0.75rem;

  &::before {
    content: "\A";
    width: 0.4rem;
    height: 0.4rem;
    margin-left: 0.25rem;
    border-radius: 50%;
    display: inline-block;
  }

  @if $color-class=='success' {
      &::before {
        background: #87F437;
        opacity: 1;
      }

    @if $with-background {
      background-color: #87F43733;
    }
  }

  @if $color-class=='info' {
    &::before {
      background: #807C7E;
      opacity: 1;
    }


    @if $with-background {
      background-color: #E9E7EA;
    }
  }

  @if $color-class=='warning' {
    &::before {
      background: #FFBE43;
      opacity: 1;
    }

    @if $with-background {
      background-color: #FFBE4333;
    }
  }

  @if $color-class=='danger' {
    &::before {
      background: #F43E37;
      opacity: 1;
    }


    @if $with-background {
      background-color: #F43E3733;
    }
  }
}

This mixin is used throughout the app and gives you this (with or without background):

enter image description here

How would I avoid being too explicit when @includeing this mixin? (current usage, repeating each option...):

//Selectors...
&.success {
  label {
    @include indication-circle('success', false);
  }
}
//Same for `&.info`, `&.warning`, `&.danger`...

Can I somehow interpolate the class name and send it as a variable? Or is it a better way to handle these kinds of dynamic styles?

Psuedo:

  label {
    @include indication-circle(#{parentNode.class}, false);
  }

Upvotes: 0

Views: 527

Answers (1)

Amirreza Noori
Amirreza Noori

Reputation: 1525

By using @each, maps and list of SASS code became so small.

https://sass-lang.com/documentation/at-rules/control/each

https://sass-lang.com/documentation/values/lists

https://sass-lang.com/documentation/values/maps

In the following code $indication-colors is a map that keeps two colors of each state. Maps value could be accessed by the map-get function. In this code, the map value is list with two color values.

The last part uses @each to generate the class for each key of the $indication-colors map.

$indication-colors: (
    success:    (#87F437, #87F43733),
    info:       (#807C7E, #E9E7EA),
    warning:    (#87F437, #FFBE4333),
    danger:     (#F43E37, #87F43733),
);


@mixin indication-circle($color-class, $with-background: true) {
    display: inline;
    border-radius: 15px;
    padding: 0rem 0.75rem;
    
    $configs: map-get($indication-colors, $color-class);
    
    &::before {
        content: "\A";
        width: 0.4rem;
        height: 0.4rem;
        margin-left: 0.25rem;
        border-radius: 50%;
        display: inline-block;
        background: nth($configs, 1);
        opacity: 1;
    }
    
    
    @if $with-background {
        background-color: nth($configs, 2);
    }
}

@each $states in $indication-colors {
    .parent-class{
        $key: nth($states, 1);
        &.#{$key} {
            label {
                @include indication-circle($key, true);
            }
        }
    }
}

Upvotes: 1

Related Questions