From ddaa9ae79a754eaa9d3a7ba878e1f407867997d1 Mon Sep 17 00:00:00 2001 From: Elana <19191012+elanals@users.noreply.github.com> Date: Sat, 13 Feb 2021 13:26:01 +0100 Subject: [PATCH] theme schemes using css variables --- src/publish/compile-css.js | 57 +++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/src/publish/compile-css.js b/src/publish/compile-css.js index 72f1b31e..4ce7fe7f 100644 --- a/src/publish/compile-css.js +++ b/src/publish/compile-css.js @@ -3,10 +3,13 @@ const path = require('path'); const less = require('less'); const postcssLess = require('postcss-less'); const pCSS = require('postcss'); +const get = require('lodash/get'); +const uniq = require('lodash/uniq'); /* needed for variable parsing, otherwise postcss logs annoying messages we don't care about */ const { noop } = require('../utils/index.js'); const CSS_ELIMINATION_KEYWORD = '__UNDEFINED__'; +const keyToVariable = key => key.replace(/\./g, '_'); const postcss = pCSS([ /* removes all declarations with value of CSS_ELIMINATION_KEYWORD */ @@ -36,15 +39,32 @@ async function compileCSS({ theme, filePaths }) { theme = JSON.parse(JSON.stringify(theme)); - const lessString = (await Promise.all(filePaths.map(saveReadFile))).join(''); + let lessString = (await Promise.all(filePaths.map(saveReadFile))).join(''); const lessVariables = await findLessVariables(lessString, { paths }); + + const schemes = get(theme.data, 'colors.schemes', {}); + + const schemeKeys = uniq( + Object.keys(schemes).reduce((acc, key) => { + acc.push(...Object.keys(schemes[key])); + return acc; + }, []) + ); + + schemeKeys.forEach(key => { + const keyString = keyToVariable(key); + const re = new RegExp(`@${keyString}`, 'g'); + lessString = lessString.replace(re, `var(--${keyString});`); + }); + let varString = ''; for (const variable of lessVariables) { varString = varString.concat(`${variable}: ${CSS_ELIMINATION_KEYWORD};`); } const inputLess = [ + createCssVariables(theme.data, schemeKeys), varString, createFontEntries(theme.fonts, theme.data), lessString, @@ -78,6 +98,41 @@ async function compileCSS({ theme, filePaths }) { return css; } +function createCssVariables(themeData, keys) { + /* default scheme */ + const schemeVariables = [createDefaultSchemeVariables(themeData, keys)]; + + /* additional schemes */ + const schemes = get(themeData, 'colors.schemes', {}); + Object.keys(schemes).forEach(scheme => { + schemeVariables.push(createSchemeVariables(schemes[scheme], scheme)); + }); + + return schemeVariables.join('\n'); + + function createDefaultSchemeVariables(themeData, variables) { + variables = variables + .map(key => { + return `--${keyToVariable(key)}: ${get(themeData, key)};`; + }) + .join('\n\t'); + return `body { + ${variables} +}`; + } + + function createSchemeVariables(scheme, schemeName) { + const variables = Object.keys(scheme) + .map(key => { + return `--${keyToVariable(key)}: ${scheme[key]};`; + }) + .join('\n\t'); + return `body.scheme-${schemeName} { + ${variables} +}`; + } +} + function createFontEntries(fonts, themeData) { const usedFonts = []; const fontStrings = [];