Reputation:
Is it somehow possible to nest several variables within one variable? The code below doesn't throw an error, but I have no clue how to call the inner "first" or "second"
$themes: (
light: (
text: (
first: black,
second: grey
),
button: blue
),
);
map_get
doesn't seem to work because it's too deep nested.
EDIT: The provided solution by Arkellys is basically working. The Problem I got now is that i want to automate this with the simple call of a function. The function should call a mixin where the theming should style my components.
The mixin looks like that:
@mixin theme($themes) {
@each $theme, $map in $themes {
.theme-#{$theme} & {
$theme-map: () !global;
@each $key, $submap in $map {
$value: map-get(map-get($themes, $theme), '#{$key}');
$theme-map: map-merge($theme-map, ($key: $value)) !global;
}
@content;
$theme-map: null !global;
}
}
}
and the function that calls the mixin looks like that:
@function theme($key) {
@return map-get($theme-map, $key);
}
In my scss I call it like that:
.past {
@include theme($themes) {
color: theme('text-second');
}
}
So how do I detect if i use a simple 1st level nesting or already a 2nd level nesting?
Upvotes: 1
Views: 513
Reputation: 7780
Yes it is possible, and to get a value in your map you can use a @function
such as this one by Hugo Giraudel.
As an example:
@function getDeepMapValue($map, $keys...) {
@each $key in $keys { $map: map-get($map, $key); }
@return $map;
}
$themes: (
light: (
text: (
first: black,
second: grey
)
)
);
.class {
color: getDeepMapValue($themes, light, text, first);
}
Will return:
.class {
color: black;
}
Edit: If I understand your @mixin
correctly, doing something along these lines should work. First, edit your @function theme
to use getDeepMapValue
:
@function theme($keys...) {
@return getDeepMapValue($theme-map, $keys...);
}
And then:
.past {
@include theme($themes) {
color: theme(text, second); // grey
background: theme(button); // blue
}
}
Upvotes: 0