diff --git a/_config/eleventy-plugin-tokens.js b/_config/eleventy-plugin-tokens.js new file mode 100644 index 0000000..6932dfd --- /dev/null +++ b/_config/eleventy-plugin-tokens.js @@ -0,0 +1,41 @@ +/** + * Inspired by CSS { In Real Life }'s blog post + * https://css-irl.info/creating-css-variables-from-a-js-file/ + */ +import fs from 'fs'; +import { writeFile } from 'fs/promises'; + +let config = {} +export default function (eleventyConfig, pluginOptions) { + config = pluginOptions; + + eleventyConfig.on("eleventy.before", () => { + let theme = fs.readFileSync(`./${config.tokens || 'src/_data/tokens.json'}`, 'utf-8'); + buildTheme(JSON.parse(theme)) + }); +}; + +const mapTheme = ([key, value]) => { + if (typeof value === 'string') { + return `--${key}: ${value}` + } + + return Object.entries(value).flatMap(([nestedKey, nestedValue]) => { + const newKey = nestedKey === 'DEFAULT' ? key : `${key}-${nestedKey}` + + return mapTheme([newKey, nestedValue]) + }) +} + +const buildTheme = async (theme) => { + try { + const result = Object.entries(theme).flatMap(mapTheme) + + let content = result.map((line) => `\t${line};`) + content = [':root {', ...content, '}'].join('\n') + + await writeFile(`./${config.destination || 'src/css/theme.css'}`, content, { encoding: 'utf-8' }) + } catch (e) { + console.error(e) + } +} \ No newline at end of file diff --git a/eleventy.config.js b/eleventy.config.js index ebec170..0089461 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -1,6 +1,7 @@ import { inspect } from "util"; import pluginIcons from 'eleventy-plugin-icons'; import eleventyPDF from "./_config/eleventy-plugin-pdf.js"; +import pluginTokens from "./_config/eleventy-plugin-tokens.js"; export default async function (eleventyConfig) { eleventyConfig.setUseGitIgnore(false); @@ -28,6 +29,7 @@ export default async function (eleventyConfig) { eleventyConfig.addPassthroughCopy('src/favicon.ico') + eleventyConfig.addPlugin(pluginTokens, { tokens: "./src/_data/tokens.json", destination: "./src/css/theme.css" }); eleventyConfig.addPlugin(eleventyPDF); eleventyConfig.addPlugin(pluginIcons, { sources: [