vaindil
vaindil

Reputation: 7854

Using local Sass variables in mixin

I have a bunch of variables that are defined for use in a light/dark theme (two separate files):

$primary-1: red;
$primary-2: green;

and I don't want to declare them all twice when consuming them. I wrote a mixin that does the assignments for me:

@mixin assign-vars {
  --primary-1: #{$primary-1};
  --primary-2: #{$primary-2};
}

and I would like to use it like this:

@import 'assign-vars';

:root,
:root[data-theme='light'] {
  @import 'light-theme-variables';
  @include assign-vars;
}

:root[data-theme='dark'] {
  @import 'dark-theme-variables';
  @include assign-vars;
}

but this does not work, as I get an error saying that $primary-1 is an undefined variable. How can I accomplish this without having to do all of the declarations twice?

Upvotes: 1

Views: 1568

Answers (1)

vaindil
vaindil

Reputation: 7854

I ended up moving the variables into a map:

$light-vars: (
  $font-name: 'Some Font',
  $primary-1: red
);

$dark-vars: (
  $font-name: 'Some Other Font',
  $primary-1: green
);

and created a helper mixin to assign them to CSS vars of the same name:

@mixin assign-map-properties($map) {
  @each $key, $value in $map {
    @if (type-of($value) == 'string') {
      --#{$key}: '#{$value}';
    }
    @else {
      --#{$key}: #{$value};
    }
  }
}

which allowed me to accomplish what I need:

@import 'assign-map-properties';

:root,
:root[data-theme='light'] {
  @import 'light-vars';
  @include assign-map-properties($light-vars);
}

:root[data-theme='dark'] {
  @import 'dark-vars';
  @include assign-map-properties($dark-vars);
}

Generated CSS:

:root,
:root[data-theme='light'] {
  --font-name: 'Some Font';
  --primary-1: red;
}

:root[data-theme='dark'] {
  --font-name: 'Some Other Font';
  --primary-1: green;
}

Upvotes: 2

Related Questions