From 0362317d208b58ff692c7472a303cbc54f4f22b7 Mon Sep 17 00:00:00 2001 From: madrilene Date: Mon, 8 Apr 2024 14:06:10 +0200 Subject: [PATCH] move to ESM, update tokens --- .vscode/settings.json | 3 - _resources/css-utils/tokens-to-tailwind.js | 20 -- _resources/design-tokens/colors.json | 56 ++-- _resources/design-tokens/fonts.json | 56 +++- _resources/design-tokens/spacing.json | 61 ++-- _resources/design-tokens/textLeading.json | 18 ++ .../{text-sizes.json => textSizes.json} | 40 ++- _resources/design-tokens/textWeights.json | 23 ++ _resources/design-tokens/viewports.json | 5 +- .../{css-utils => utils}/clamp-generator.js | 16 +- _resources/utils/tokens-to-tailwind.js | 24 ++ postcss.config.js | 21 +- tailwind.config.js | 266 +++++++++--------- wpexcellent-config.js | 8 - 14 files changed, 348 insertions(+), 269 deletions(-) delete mode 100644 .vscode/settings.json delete mode 100644 _resources/css-utils/tokens-to-tailwind.js create mode 100644 _resources/design-tokens/textLeading.json rename _resources/design-tokens/{text-sizes.json => textSizes.json} (57%) create mode 100644 _resources/design-tokens/textWeights.json rename _resources/{css-utils => utils}/clamp-generator.js (78%) create mode 100644 _resources/utils/tokens-to-tailwind.js delete mode 100644 wpexcellent-config.js diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 0e0dcd2..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - -} \ No newline at end of file diff --git a/_resources/css-utils/tokens-to-tailwind.js b/_resources/css-utils/tokens-to-tailwind.js deleted file mode 100644 index 5bf1277..0000000 --- a/_resources/css-utils/tokens-to-tailwind.js +++ /dev/null @@ -1,20 +0,0 @@ -const slugify = require('slugify'); - -/** - * Converts human readable tokens into tailwind config friendly ones - * - * @param {array} tokens {name: string, value: any} - * @return {object} {key, value} - */ -const tokensToTailwind = tokens => { - const nameSlug = text => slugify(text, { lower: true }); - let response = {}; - - tokens.forEach(({ name, value }) => { - response[nameSlug(name)] = value; - }); - - return response; -}; - -module.exports = tokensToTailwind; diff --git a/_resources/design-tokens/colors.json b/_resources/design-tokens/colors.json index 8ffe327..6381a91 100644 --- a/_resources/design-tokens/colors.json +++ b/_resources/design-tokens/colors.json @@ -1,34 +1,26 @@ { - "title": "Colors", - "description": "Hex color codes that can be shared, cross-platform. They can be converted at point of usage, such as HSL for web or CMYK for print.", - "items": [ - { - "name": "Dark", - "value": "#000" - }, - { - "name": "Light", - "value": "#F5F5F4" - }, - { - "name": "Light Glare", - "value": "#FFFFFF" - }, - { - "name": "Primary", - "value": "#F6BF2A" - }, - { - "name": "Primary Glare", - "value": "#FBE5AA" - }, - { - "name": "Secondary", - "value": "#ca0057" - }, - { - "name": "Secondary Glare", - "value": "ea99bc" - } - ] + "title": "Colors", + "description": "Hex color codes that can be shared, cross-platform. They can be converted at point of usage, such as HSL for web or CMYK for print.", + "items": [ + { + "name": "Base Dark", + "value": "#343434" + }, + { + "name": "Base Light", + "value": "#FBFBFB" + }, + { + "name": "Primary Highlight", + "value": "#dd4462" + }, + { + "name": "Secondary Highlight", + "value": "#4467dd" + }, + { + "name": "Tertiary Highlight", + "value": "#fbbe25" + } + ] } diff --git a/_resources/design-tokens/fonts.json b/_resources/design-tokens/fonts.json index f4e41a0..37a6425 100644 --- a/_resources/design-tokens/fonts.json +++ b/_resources/design-tokens/fonts.json @@ -1,16 +1,44 @@ { - "title": "Fonts", - "description": "Each array of fonts creates a priority-based order. The first font in the array should be the ideal font, followed by sensible, web-safe fallbacks", - "items": [ - { - "name": "Base", - "description": "System fonts for body copy and globally set text.", - "value": ["Inter", "Segoe UI", "Roboto", "Helvetica Neue", "Arial", "sans-serif"] - }, - { - "name": "Serif", - "description": "Expressive sections, like quotes", - "value": ["Georgia", "sans-serif"] - } - ] + "title": "Fonts", + "description": "Each array of fonts creates a priority-based order. The first font in the array should be the ideal font, followed by sensible, web-safe fallbacks", + "items": [ + { + "name": "Display", + "description": "Display font stack for headings and large text.", + "value": [ + "Inter", + "Segoe UI", + "Roboto", + "Helvetica Neue", + "Arial", + "sans-serif" + ] + }, + { + "name": "Base", + "description": "Base font stack for body text.", + "value": [ + "Inter", + "Segoe UI", + "Roboto", + "Helvetica Neue", + "Arial", + "sans-serif" + ] + }, + { + "name": "Mono", + "description": "Monospace font for code and preformatted text.", + "value": [ + "RobotoMono", + "ui-monospace", + "Cascadia Code", + "Source Code Pro", + "Menlo", + "Consolas", + "DejaVu Sans Mono", + "monospace" + ] + } + ] } diff --git a/_resources/design-tokens/spacing.json b/_resources/design-tokens/spacing.json index 0fd3e7f..7d15fa3 100644 --- a/_resources/design-tokens/spacing.json +++ b/_resources/design-tokens/spacing.json @@ -2,78 +2,79 @@ "title": "Spacing", "description": "Consistent spacing sizes, based on a ratio, with min and max sizes. This allows you to set spacing based on the context size. For example, min for mobile and max for desktop browsers.", "meta": { - "scaleGenerator": "https://utopia.fyi/space/calculator?c=320,16,1.2,1350,20,1.414,8,1,&s=0.75|0.5|0.25,2|3|5|8|13,s-l" + "scaleGenerator": "https://utopia.fyi/space/calculator?c=320,19,1.2,1350,26,1.414,8,2,&s=0.75|0.5|0.25,2|3|5|8|13,s-l&g=s,l,xl,12", + "note": "I'm shifing the the scale so spaces don't get too big. XS is euual to 3XS." }, "items": [ { "name": "XS", - "min": 12, - "max": 15 + "min": 5, + "max": 7 }, { "name": "S", - "min": 16, - "max": 20 + "min": 10, + "max": 14 }, { "name": "M", - "min": 24, - "max": 30 + "min": 14, + "max": 21 }, { "name": "L", - "min": 32, - "max": 40 + "min": 19, + "max": 28 }, { "name": "XL", - "min": 48, - "max": 60 + "min": 38, + "max": 56 }, { "name": "2XL", - "min": 64, - "max": 80 + "min": 57, + "max": 84 }, { "name": "3XL", - "min": 96, - "max": 120 + "min": 95, + "max": 140 }, { "name": "XS - S", - "min": 12, - "max": 20 + "min": 5, + "max": 14 }, { "name": "S - M", - "min": 16, - "max": 30 + "min": 10, + "max": 21 }, { "name": "M - L", - "min": 24, - "max": 40 + "min": 14, + "max": 28 }, { "name": "L - XL", - "min": 32, - "max": 60 + "min": 19, + "max": 56 }, { "name": "L - 2xl", - "min": 32, - "max": 80 + "min": 38, + "max": 84 }, { "name": "XL - 2XL", - "min": 48, - "max": 80 + "min": 57, + "max": 140 }, { - "name": "2XL - 3XL", - "min": 64, - "max": 120 + "name": "2XL - 3xl", + "min": 95, + "max": 224 } ] } diff --git a/_resources/design-tokens/textLeading.json b/_resources/design-tokens/textLeading.json new file mode 100644 index 0000000..c221a97 --- /dev/null +++ b/_resources/design-tokens/textLeading.json @@ -0,0 +1,18 @@ +{ + "title": "Leading", + "description": "Ratio-based leading/line-height values", + "items": [ + { + "name": "Flat", + "value": 1 + }, + { + "name": "Fine", + "value": 1.2 + }, + { + "name": "Standard", + "value": 1.5 + } + ] +} diff --git a/_resources/design-tokens/text-sizes.json b/_resources/design-tokens/textSizes.json similarity index 57% rename from _resources/design-tokens/text-sizes.json rename to _resources/design-tokens/textSizes.json index 3ba2f69..e780d6b 100644 --- a/_resources/design-tokens/text-sizes.json +++ b/_resources/design-tokens/textSizes.json @@ -1,44 +1,54 @@ { "title": "Text Sizes", - "description": "A minimum and maximum text size size allows you to pick the right size from a ratio, depending on the context size. The min and max sizes are in pixels and should be converted to appropiate sizes, per context. For example, for web, the should be converted to REM units (pixelSize / baseSize)", + "description": "A minimum and maximum text size size allows you to pick the right size from a ratio, depending on the context size. The min and max sizes are in pixels and should be converted to appropiate sizes, per context", "meta": { - "scaleGenerator": "https://utopia.fyi/type/calculator/?c=320,16,1.2,1350,20,1.414,8,1,&s=0.75|0.5|0.25,1.5|2|3|4|6,s-l" + "scaleGenerator": "https://utopia.fyi/type/calculator?c=320,19,1.2,1350,28,1.25,6,2,&s=0.75|0.5|0.25,2|3|5|8|13,s-l&g=s,l,xl,12" }, "items": [ { - "name": "Step 0", + "name": "Step min 2", + "min": 13, + "max": 16 + }, + { + "name": "Step min 1", "min": 16, - "max": 20 + "max": 22 }, { - "name": "Step 1", + "name": "Step 0", "min": 19, "max": 28 }, { - "name": "Step 2", + "name": "Step 1", "min": 23, - "max": 40 + "max": 35 + }, + { + "name": "Step 2", + "min": 27, + "max": 44 }, { "name": "Step 3", - "min": 28, - "max": 57 + "min": 33, + "max": 55 }, { "name": "Step 4", - "min": 33, - "max": 80 + "min": 40, + "max": 68 }, { "name": "Step 5", - "min": 40, - "max": 113 + "min": 47, + "max": 86 }, { "name": "Step 6", - "min": 48, - "max": 159 + "min": 56, + "max": 107 } ] } diff --git a/_resources/design-tokens/textWeights.json b/_resources/design-tokens/textWeights.json new file mode 100644 index 0000000..783bf7d --- /dev/null +++ b/_resources/design-tokens/textWeights.json @@ -0,0 +1,23 @@ +{ + "title": "Text Weights", + "description": "Helper classes and custom properties for common font weights", + "meta": {}, + "items": [ + { + "name": "Regular", + "value": 400 + }, + { + "name": "Medium", + "value": 500 + }, + { + "name": "Bold", + "value": 700 + }, + { + "name": "Extra Bold", + "value": 900 + } + ] +} diff --git a/_resources/design-tokens/viewports.json b/_resources/design-tokens/viewports.json index 8f0da5f..f7ee791 100644 --- a/_resources/design-tokens/viewports.json +++ b/_resources/design-tokens/viewports.json @@ -2,5 +2,8 @@ "title": "Viewports", "description": "The min and maximum viewports used to generate fluid type and space scales.", "min": 320, - "max": 1350 + "sm": 640, + "navigation": 730, + "md": 1000, + "max": 1360 } diff --git a/_resources/css-utils/clamp-generator.js b/_resources/utils/clamp-generator.js similarity index 78% rename from _resources/css-utils/clamp-generator.js rename to _resources/utils/clamp-generator.js index 0aa5055..4057a11 100644 --- a/_resources/css-utils/clamp-generator.js +++ b/_resources/utils/clamp-generator.js @@ -1,4 +1,7 @@ -const viewports = require("../design-tokens/viewports.json"); +/** + * Credits: + * - © Andy Bell - https://buildexcellentwebsit.es/ + */ /** * Takes an array of tokens and sends back and array of name @@ -7,10 +10,13 @@ const viewports = require("../design-tokens/viewports.json"); * @param {array} tokens array of {name: string, min: number, max: number} * @returns {array} {name: string, value: string} */ -const clampGenerator = (tokens) => { + +import viewports from '../design-tokens/viewports.json'; + +export const clampGenerator = tokens => { const rootSize = 16; - return tokens.map(({ name, min, max }) => { + return tokens.map(({name, min, max}) => { if (min === max) { return `${min / rootSize}rem`; } @@ -31,9 +37,7 @@ const clampGenerator = (tokens) => { name, value: `clamp(${minSize}rem, ${intersection.toFixed(2)}rem + ${( slope * 100 - ).toFixed(2)}vw, ${maxSize}rem)`, + ).toFixed(2)}vw, ${maxSize}rem)` }; }); }; - -module.exports = clampGenerator; diff --git a/_resources/utils/tokens-to-tailwind.js b/_resources/utils/tokens-to-tailwind.js new file mode 100644 index 0000000..2944744 --- /dev/null +++ b/_resources/utils/tokens-to-tailwind.js @@ -0,0 +1,24 @@ +/** + * Credits: + * - © Andy Bell - https://buildexcellentwebsit.es/ + */ + +/** + * Converts human readable tokens into tailwind config friendly ones + * + * @param {array} tokens {name: string, value: any} + * @return {object} {key, value} + */ + +import slugify from 'slugify'; + +export const tokensToTailwind = tokens => { + const nameSlug = text => slugify(text, {lower: true}); + let response = {}; + + tokens.forEach(({name, value}) => { + response[nameSlug(name)] = value; + }); + + return response; +}; diff --git a/postcss.config.js b/postcss.config.js index ee13bab..0e08a9b 100644 --- a/postcss.config.js +++ b/postcss.config.js @@ -1,8 +1,15 @@ -module.exports = { - plugins: [ - require('postcss-import-ext-glob'), - require('postcss-import'), - require('tailwindcss'), - require('cssnano') - ] +import postcssImport from 'postcss-import'; +import postcssImportExtGlob from 'postcss-import-ext-glob'; +import tailwindcss from 'tailwindcss'; +import autoprefixer from 'autoprefixer'; +import cssnano from 'cssnano'; + +export default { + plugins: [ + postcssImportExtGlob(), + postcssImport(), + tailwindcss(), + autoprefixer(), + cssnano() + ] }; diff --git a/tailwind.config.js b/tailwind.config.js index 598d8ae..d71fb85 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,145 +1,145 @@ -/** - * Tailwind creates utility classes on demand. - * The values for the design system are set in _resources/design-tikens. - * - */ -const plugin = require('tailwindcss/plugin'); -const postcss = require('postcss'); -const postcssJs = require('postcss-js'); +/* © Andy Bell - https://buildexcellentwebsit.es/ */ -const clampGenerator = require('./_resources/css-utils/clamp-generator.js'); -const tokensToTailwind = require('./_resources/css-utils/tokens-to-tailwind.js'); +import plugin from 'tailwindcss/plugin'; +import postcss from 'postcss'; +import postcssJs from 'postcss-js'; + +import {clampGenerator} from './_resources/utils/clamp-generator.js'; +import {tokensToTailwind} from './_resources/utils/tokens-to-tailwind.js'; // Raw design tokens -const colorTokens = require('./_resources/design-tokens/colors.json'); -const fontTokens = require('./_resources/design-tokens/fonts.json'); -const spacingTokens = require('./_resources/design-tokens/spacing.json'); -const textSizeTokens = require('./_resources/design-tokens/text-sizes.json'); +import colorTokens from './_resources/design-tokens/colors.json'; +import fontTokens from './_resources/design-tokens/fonts.json'; +import spacingTokens from './_resources/design-tokens/spacing.json'; +import textSizeTokens from './_resources/design-tokens/textSizes.json'; +import textLeadingTokens from './_resources/design-tokens/textLeading.json'; +import textWeightTokens from './_resources/design-tokens/textWeights.json'; +import viewportTokens from './_resources/design-tokens/viewports.json'; // Process design tokens const colors = tokensToTailwind(colorTokens.items); const fontFamily = tokensToTailwind(fontTokens.items); const fontSize = tokensToTailwind(clampGenerator(textSizeTokens.items)); +const fontWeight = tokensToTailwind(textWeightTokens.items); +const fontLeading = tokensToTailwind(textLeadingTokens.items); const spacing = tokensToTailwind(clampGenerator(spacingTokens.items)); -module.exports = { - content: ['./*.{html,js,php,twig}'], - presets: [], - theme: { - extend: { - screens: { - md: '50em', - lg: '80em', - }, - colors, - spacing, - fontSize, - fontFamily, - fontWeight: { - normal: 400, - bold: 700, - black: 800, - }, - backgroundColor: ({ theme }) => theme('colors'), - textColor: ({ theme }) => theme('colors'), - margin: ({ theme }) => ({ - auto: 'auto', - ...theme('spacing'), - }), - padding: ({ theme }) => theme('spacing'), - }, - }, - variantOrder: [ - 'first', - 'last', - 'odd', - 'even', - 'visited', - 'checked', - 'empty', - 'read-only', - 'group-hover', - 'group-focus', - 'focus-within', - 'hover', - 'focus', - 'focus-visible', - 'active', - 'disabled', - ], - - // Disables Tailwind's reset etc - corePlugins: { - preflight: false, - }, - plugins: [ - // Generates custom property values from tailwind config - plugin(function ({ addComponents, config }) { - let result = ''; - - const currentConfig = config(); - - const groups = [ - { key: 'colors', prefix: 'color' }, - { key: 'spacing', prefix: 'space' }, - { key: 'fontSize', prefix: 'size' }, - { key: 'fontFamily', prefix: 'font' }, - ]; - - groups.forEach(({ key, prefix }) => { - const group = currentConfig.theme[key]; - - if (!group) { - return; - } - - Object.keys(group).forEach(key => { - result += `--${prefix}-${key}: ${group[key]};`; - }); - }); - - addComponents({ - ':root': postcssJs.objectify( - postcss.parse(result) - ), - }); - }), - - // Generates custom utility classes - plugin(function ({ addUtilities, config }) { - const currentConfig = config(); - const customUtilities = [ - { - key: 'spacing', - prefix: 'flow-space', - property: '--flow-space', - }, - { - key: 'colors', - prefix: 'spot-color', - property: '--spot-color', - }, - ]; - - customUtilities.forEach(({ key, prefix, property }) => { - const group = currentConfig.theme[key]; - - if (!group) { - return; - } - - Object.keys(group).forEach(key => { - addUtilities({ - [`.${prefix}-${key}`]: - postcssJs.objectify( - postcss.parse( - `${property}: ${group[key]}` - ) - ), - }); - }); - }); - }), - ], +export default { + content: ['./src/**/*.{html,js,md,njk,liquid,webc}'], + presets: [], + theme: { + screens: { + ltsm: {max: `${viewportTokens.sm}px`}, + sm: `${viewportTokens.sm}px`, + md: `${viewportTokens.md}px`, + navigation: `${viewportTokens.navigation}px` + }, + colors, + spacing, + fontFamily, + fontSize, + fontWeight, + fontLeading, + backgroundColor: ({theme}) => theme('colors'), + textColor: ({theme}) => theme('colors'), + margin: ({theme}) => ({ + auto: 'auto', + ...theme('spacing') + }), + padding: ({theme}) => theme('spacing') + }, + variantOrder: [ + 'first', + 'last', + 'odd', + 'even', + 'visited', + 'checked', + 'empty', + 'read-only', + 'group-hover', + 'group-focus', + 'focus-within', + 'hover', + 'focus', + 'focus-visible', + 'active', + 'disabled' + ], + + // Disables Tailwind's reset etc + corePlugins: { + preflight: false, + textOpacity: false, + backgroundOpacity: false, + borderOpacity: false + }, + + // Prevents Tailwind's core components + blocklist: ['container'], + + // Prevents Tailwind from generating that wall of empty custom properties + experimental: { + optimizeUniversalDefaults: true + }, + + plugins: [ + // Generates custom property values from tailwind config + plugin(function ({addComponents, config}) { + let result = ''; + + const currentConfig = config(); + + const groups = [ + {key: 'colors', prefix: 'color'}, + {key: 'spacing', prefix: 'space'}, + {key: 'fontSize', prefix: 'size'}, + {key: 'fontLeading', prefix: 'leading'}, + {key: 'fontFamily', prefix: 'font'}, + {key: 'fontWeight', prefix: 'font'} + ]; + + groups.forEach(({key, prefix}) => { + const group = currentConfig.theme[key]; + + if (!group) { + return; + } + + Object.keys(group).forEach(key => { + result += `--${prefix}-${key}: ${group[key]};`; + }); + }); + + addComponents({ + ':root': postcssJs.objectify(postcss.parse(result)) + }); + }), + + // Generates custom utility classes + plugin(function ({addUtilities, config}) { + const currentConfig = config(); + const customUtilities = [ + {key: 'spacing', prefix: 'flow-space', property: '--flow-space'}, + {key: 'colors', prefix: 'spot-color', property: '--spot-color'} + ]; + + customUtilities.forEach(({key, prefix, property}) => { + const group = currentConfig.theme[key]; + + if (!group) { + return; + } + + Object.keys(group).forEach(key => { + addUtilities({ + [`.${prefix}-${key}`]: postcssJs.objectify( + postcss.parse(`${property}: ${group[key]}`) + ) + }); + }); + }); + }) + ] }; diff --git a/wpexcellent-config.js b/wpexcellent-config.js deleted file mode 100644 index 686660a..0000000 --- a/wpexcellent-config.js +++ /dev/null @@ -1,8 +0,0 @@ -// config.js -const wpexcellentConfig = { - app: { - localDomain: 'wp-excellent.local', - }, -}; - -module.exports = wpexcellentConfig;