Method B-1

by joshuatz

HTML

<p>Generated CSS:</p>
<pre id="generatedCssTarget"></pre>

SCSS

$themes: (
    'dark': (
        'primary': black,
        'secondary': white
    ),
    'light': (
        'primary': white,
        'secondary': black
    )
);

/**
* Mixin to use to generate blocks for each theme
* Automatically takes @content
*/
$scopedTheme: null;
@mixin themeGen($allThemesMap: $themes) {
    @each $themeName, $themeMap in $allThemesMap {
        .theme-#{$themeName} & {
            // Creating a map that contains values specific to theme.
            // Global is necessary since in mixin
            $scopedTheme: () !global;
            @each $variableName, $variableValue in $themeMap {
                // Merge each key-value pair into the theme specific map
                $scopedTheme: map-merge($scopedTheme, ($variableName: $variableValue)) !global;
            }
            // The original content passed
            @content;
            // Unset
            $scopedTheme: null !global;
        }
    }
}
/**
* Function to call within themeGen mixin, to get value from the current theme in the iterator
*/
@function getThemeVal($themeVar){
    @return map-get($scopedTheme,$themeVar);
}

/**
* Actually using theme values to generate CSS
*/
.myComponent {
    @include themeGen() {
        background-color: getThemeVal('primary');
        color: getThemeVal('secondary');
    }
}
.myComponent {
    @include themeGen() {
        background-color: getThemeVal('primary');
        color: getThemeVal('secondary');
    }
}

JavaScript

var generatedCss = /\/\*\*[\r\n]*\*\sActually Using[^~]*$/gim.exec(document.querySelector('#compiled-css').innerText)[0];
document.getElementById('generatedCssTarget').innerText = generatedCss;