diff --git a/config/design-tokens/colors.json b/config/design-tokens/colors.json new file mode 100644 index 0000000..644cfb9 --- /dev/null +++ b/config/design-tokens/colors.json @@ -0,0 +1,22 @@ +{ + "light": { + "primary": "188deg 84% 35%", + "secondary": "8 84% 50%", + "background": "0 0% 98%", + "surface": "188 27% 94%", + "border": "188 48% 80%", + "text": "0 0% 4%", + "fadeText": "188 12% 32%", + "shadow": "188deg 100% 18%" + }, + "dark": { + "primary": "188deg 84% 28%", + "secondary": "8 84% 43%", + "background": "0 0% 4%", + "surface": "202 10% 10%", + "border": "208 27% 15%", + "text": "0 0% 98%", + "fadeText": "188 12% 70%", + "shadow": "188deg 100% 18%" + } +} diff --git a/src/css-utils/colors.js b/src/css-utils/colors.js new file mode 100644 index 0000000..ba3d278 --- /dev/null +++ b/src/css-utils/colors.js @@ -0,0 +1,35 @@ +const colorSchemes = require("../../config/design-tokens/colors.json"); +const { helperClassesToCss } = require("./helperClasses"); + +const lightScheme = colorSchemes.light; +const darkScheme = colorSchemes.dark; + +const colorToCss = (key, value) => + `--${key}: ${value}; --color-${key}: hsl(${value});`; + +const colorSchemeToCss = (scheme) => + Object.entries(scheme).reduce( + (css, [key, value]) => css + colorToCss(key, value), + ``, + ); + +const lightCss = colorSchemeToCss(lightScheme); +const darkCss = colorSchemeToCss(darkScheme); + +const colorSchemeToHelperClassesCss = (scheme, helperClasses) => { + return Object.entries(scheme).reduce((css, [key]) => { + return css + helperClassesToCss(helperClasses, key, `var(--color-${key})`); + }, ``); +}; + +const helperClasses = [ + ["text", ["color"]], + ["bg", ["background-color"]], +]; + +const helperClassesCss = colorSchemeToHelperClassesCss( + lightScheme, + helperClasses, +); + +module.exports = `:root{${lightCss}}${helperClassesCss}@media (prefers-color-scheme: dark) {:root{${darkCss}}}`; diff --git a/src/css-utils/helperClasses.js b/src/css-utils/helperClasses.js new file mode 100644 index 0000000..d454035 --- /dev/null +++ b/src/css-utils/helperClasses.js @@ -0,0 +1,45 @@ +/** + * Given an array of CSS properties, output css properties + * with each property equal to `value` + */ +const cssPropertiesToCss = (cssProperties, value) => { + return cssProperties.reduce((css, cssProp) => { + return css + `${cssProp}:${value};`; + }, ``); +}; + +/** + * Given a helperClass (string) and array of cssProperties, + * will generate a css class named helperClass that has + * all cssProperties mapped to value. + */ +const helperClassToCss = (helperClass, cssProperties, value) => { + const cssProps = cssPropertiesToCss(cssProperties, value); + return `.${helperClass}{${cssProps}}`; +}; + +/** + * Given an array of helperClasses that map to cssProperties, + * output a string of CSS that maps the helperClass (with variant modifier) + * to the array of css properties with each css property equal to + * value + * + * e.g. + * helperClasses = [["text", ["color"]]], + * variant = "primary", + * value = "#000" + * + * Will output the following: + * .text-primary { + * color: #000; + * } + */ +const helperClassesToCss = (helperClasses, variant, value) => { + return helperClasses.reduce((css, [helperClass, cssProperties]) => { + return ( + css + helperClassToCss(`${helperClass}-${variant}`, cssProperties, value) + ); + }, ``); +}; + +module.exports = { cssPropertiesToCss, helperClassToCss, helperClassesToCss };