Reputation: 548
I have a color array like this :
$colors: (
'primary': '#aaa',
'secondary': '#bbb',
'color-3': '#ccc',
'color-4': '#ddd',
'color-5': '#eee',
);
and I want to automate class creation in loop like this :
@each $col in map-keys($theme-colors){
&.btn-#{$col} {
background-color: map-get($theme-colors, $col);
&:hover{
background-color: map-get($theme-colors, $col + 1); // <= my problem is here to get my "$col + 1"
}
}
}
My idea is to create a class btn-primary
with primary color background but, on hover, secondary color at background.
A class btn-secondary
secondary color background but, on hover, color-3 color at background, etc.
How can I do this?
Thanks ;)
Upvotes: 1
Views: 1361
Reputation: 5060
Here you can find your solution: https://github.com/elcheio/sass-map-get-next-prev
Using that function (i.e. map-get-next function) you can resolve your problem.
So, first of all copy and paste that function... very very simple (^_^;)
@function map-get-next($map, $key, $fallback: false, $return: value) {
// Check if map is valid
@if type-of($map) == map {
// Check if key exists in map
@if map-has-key($map, $key) {
// Init index counter variable
$i: 0;
// Init key index
$key-index: false;
// Traverse map for key
@each $map-key, $map-value in $map {
// Update index
$i: $i + 1;
// If map key found, set key index
@if $map-key == $key {
$key-index: $i;
}
// If next index return next value or key based on $return
@if $i == $key-index + 1 {
@if $return == key {
@return $map-key;
} @else {
@return $map-value;
}
}
// If last entry return false
@if $i == length($map) {
@return $fallback;
}
}
@warn 'No next map item for key #{$key}';
@return $fallback;
}
@warn 'No valid key #{$key} in map';
@return $fallback;
}
@warn 'No valid map';
@return $fallback;
}
Then you can add your map:
$colors: (
'primary': #aaa,
'secondary': #bbb,
'color-3': #ccc,
'color-4': #ddd,
'color-5': #eee,
);
In the end, you have to create an @each loop to estract every pair name/value of your map:
@each $name, $value in $colors{
.btn-#{$name} {
background-color: $value;
&:hover{
background-color: map-get-next($colors, $name, #ffffff); // <== here you have to write the color for your last item (i.e. 'color-5'; in this example is white)
}
}
}
That's it! Your output will be:
.btn-primary {
background-color: #aaa;
}
.btn-primary:hover {
background-color: #bbb;
}
.btn-secondary {
background-color: #bbb;
}
.btn-secondary:hover {
background-color: #ccc;
}
.btn-color-3 {
background-color: #ccc;
}
.btn-color-3:hover {
background-color: #ddd;
}
.btn-color-4 {
background-color: #ddd;
}
.btn-color-4:hover {
background-color: #eee;
}
.btn-color-5 {
background-color: #eee;
}
.btn-color-5:hover {
background-color: #ffffff;
}
Upvotes: 1