From aba650419319ce99e1e16cc2ef6bfbe25c39be6f Mon Sep 17 00:00:00 2001 From: Devin Haska Date: Wed, 21 Feb 2024 20:31:00 -0800 Subject: [PATCH] wip: add font-related files to css-utils --- config/design-tokens/fonts.json | 44 +++++++++++++++ src/css-utils/colors.js | 2 +- src/css-utils/font-family.js | 53 +++++++++++++++++++ src/css-utils/font-variables.js | 45 ++++++++++++++++ .../{helperClasses.js => helper-classes.js} | 0 src/css-utils/spacing.js | 2 +- 6 files changed, 144 insertions(+), 2 deletions(-) create mode 100644 config/design-tokens/fonts.json create mode 100644 src/css-utils/font-family.js create mode 100644 src/css-utils/font-variables.js rename src/css-utils/{helperClasses.js => helper-classes.js} (100%) diff --git a/config/design-tokens/fonts.json b/config/design-tokens/fonts.json new file mode 100644 index 0000000..87a129a --- /dev/null +++ b/config/design-tokens/fonts.json @@ -0,0 +1,44 @@ +{ + "display": { + "family": "Anek Latin", + "format": "truetype", + "weights": { + "ExtraBold": { + "path": "/aneklatin/AnekLatin-ExtraBold.ttf", + "font-style": "normal", + "weight": 800 + }, + "Bold": { + "path": "/aneklatin/AnekLatin-Bold.ttf", + "font-style": "normal", + "weight": 700 + } + } + }, + "body": { + "family": "iA Writer Quattro V", + "format": "woff2", + "weights": { + "Regular": { + "path": "/quattro/iAWriterQuattroS-Regular.woff2", + "font-style": "normal", + "weight": 400 + }, + "Italic": { + "path": "/quattro/iAWriterQuattroS-Italic.woff2", + "font-style": "italic", + "weight": 400 + }, + "Bold": { + "path": "/quattro/iAWriterQuattroS-Bold.woff2", + "font-style": "normal", + "weight": 650 + }, + "BoldItalic": { + "path": "/quattro/iAWriterQuattroS-BoldItalic.woff2", + "font-style": "italic", + "weight": 650 + } + } + } +} diff --git a/src/css-utils/colors.js b/src/css-utils/colors.js index ba3d278..dc9e9ed 100644 --- a/src/css-utils/colors.js +++ b/src/css-utils/colors.js @@ -1,5 +1,5 @@ const colorSchemes = require("../../config/design-tokens/colors.json"); -const { helperClassesToCss } = require("./helperClasses"); +const { helperClassesToCss } = require("./helper-classes"); const lightScheme = colorSchemes.light; const darkScheme = colorSchemes.dark; diff --git a/src/css-utils/font-family.js b/src/css-utils/font-family.js new file mode 100644 index 0000000..df1f247 --- /dev/null +++ b/src/css-utils/font-family.js @@ -0,0 +1,53 @@ +const path = require("path").posix; +const fonts = require("../../config/design-tokens/fonts.json"); + +const getFontUrl = (src) => path.join("/assets/fonts", src); + +const fontsToCss = (fonts) => { + return Object.entries(fonts).reduce((css, [, fontProperties]) => { + const family = fontProperties.family; + const format = fontProperties.format; + const weights = fontProperties.weights; + + return ( + css + + Object.entries(weights).reduce((css, [variant, fontFamily]) => { + const url = getFontUrl(fontFamily.path); + const style = fontFamily["font-style"]; + const weight = fontFamily.weight; + const postScriptName = [family, variant].join("-").replaceAll(" ", ""); + + return ( + css + + fontFamilyToCss( + family, + style, + weight, + url, + family, + postScriptName, + format, + ) + ); + }, ``) + ); + }, ``); +}; + +const fontFamilyToCss = ( + family, + style, + weight, + url, + localName, + postScriptName, + format, +) => `@font-face { + font-family: ${family}; + font-style: ${style}; + font-weight: ${weight}; + font-display: swap; + src: local("${localName}"), local("${postScriptName}"), url("${url}") format("${format}") +}\n`; + +module.exports = fontsToCss(fonts); diff --git a/src/css-utils/font-variables.js b/src/css-utils/font-variables.js new file mode 100644 index 0000000..21942a5 --- /dev/null +++ b/src/css-utils/font-variables.js @@ -0,0 +1,45 @@ +const fonts = require("../../config/design-tokens/fonts.json"); + +const fallbacks = [ + "-apple-system", + "BlinkMacSystemFont", + "Segoe UI", + "Roboto", + "Ubuntu", + "Open Sans", + "Helvetica Neue", + "sans-serif", +]; + +const fontsToCss = (fonts) => { + return Object.entries(fonts).reduce((css, [fontType, fontProperties]) => { + const family = fontProperties.family; + const weights = fontProperties.weights; + + const fontTypeCss = fontFamilyToCss(fontType, family); + const fontWeightsCss = fontWeightsToCss(fontType, weights); + + return css + fontTypeCss + fontWeightsCss; + }, ``); +}; + +const validVariants = ["regular", "bold", "extrabold"]; + +const fontWeightsToCss = (type, weights) => + Object.entries(weights) + .filter(([variant]) => validVariants.includes(variant.toLowerCase())) + .reduce((css, [variant, fontFamily]) => { + const weight = fontFamily.weight; + + return css + fontWeightToCss(type, variant.toLowerCase(), weight); + }, ``); + +const fontWeightToCss = (type, variant, value) => + `--font-weight-${type}-${variant}: ${value};`; + +const fontFamilyToCss = (type, value) => + `--font-family-${type}: ${value},${fallbacks.join(",")};`; + +const css = `:root{${fontsToCss(fonts)}}`; + +module.exports = css; diff --git a/src/css-utils/helperClasses.js b/src/css-utils/helper-classes.js similarity index 100% rename from src/css-utils/helperClasses.js rename to src/css-utils/helper-classes.js diff --git a/src/css-utils/spacing.js b/src/css-utils/spacing.js index 1a315d4..6246a8c 100644 --- a/src/css-utils/spacing.js +++ b/src/css-utils/spacing.js @@ -1,5 +1,5 @@ const spacing = require("../../config/design-tokens/spacing.json"); -const { helperClassesToCss } = require("./helperClasses"); +const { helperClassesToCss } = require("./helper-classes"); const spacingToCss = (variant, value) => `--spacing-${variant.replace(".", "\\.")}: ${value}px;`;