user9024437
user9024437

Reputation:

Nesting Variables within a Variable

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

Answers (1)

Arkellys
Arkellys

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

Related Questions