Skip to content

Commit

Permalink
feat (style-dictionary): resolved class formater
Browse files Browse the repository at this point in the history
  • Loading branch information
santanche committed Aug 22, 2023
1 parent 4f87aa0 commit 46fa0b6
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 51 deletions.
38 changes: 38 additions & 0 deletions design-system/style-dictionary/build/css/classes-resolved.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
@font-face {
font-family: 'MaterialIcons';
src: url('../assets/fonts/MaterialIcons-Regular.ttf');
}
@font-face {
font-family: 'Open Sans';
src: url('../assets/fonts/OpenSans-Regular.ttf');
}
@font-face {
font-family: 'Roboto';
src: url('../assets/fonts/Roboto-Regular.ttf');
}

.btn {
font-family: Roboto;
font-size: 1rem;
border-radius: .375rem;
padding: 0.5rem 1rem;
}
.btn:hover {
cursor: pointer;
}
.btn-primary {
background-color: #616161;
color: #ffffff;
border: #9e9e9e;
}
.btn-primary:hover {
background-color: #212121;
}
.btn-secondary {
background-color: #e0e0e0;
color: #000000;
border: #e0e0e0;
}
.btn-secondary:hover {
background-color: #bdbdbd;
}
126 changes: 77 additions & 49 deletions design-system/style-dictionary/config-classes.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,46 @@ const StyleDictionary = require('style-dictionary')
const fs = require('fs')
const { transferableAbortController } = require('util')

const jsonStrClasses =
fs.readFileSync('classes/classes.json').toString()

// find the path in the token tree and converts to the value
function getFinalValue(tokenName, dictionary) {
const tokenPath = tokenName.split('.')
let value = dictionary.tokens
let subpath = ''
for (const path of tokenPath) {
subpath += path + '.'
if (!value[path]) {
value = subpath + '..?'
break
} else {
value = value[path]
}
}
return value
}

// convert token fonts into css imports
function cssImportFonts (dictionary) {
let cssFonts = ''
const dic = dictionary.tokens
if (dic.asset && dic.asset.font) {
const fonts = dic.asset.font
for (const f in fonts) {
const ftype =
(fonts[f].ttf) ? fonts[f].ttf :
(fonts[f].woff) ? fonts[f].woff :
(fonts[f].woff2) ? fonts[f].woff2 :
(fonts[f].eot) ? fonts[f].eot : null
if (ftype != null)
cssFonts += `@font-face {\n font-family: '${fonts[f].name.value}';\n src: url('${ftype.value}');\n}\n`
}
cssFonts += '\n'
}
return cssFonts
}

/* Output 1: aggregated tokens */
StyleDictionary.registerFormat({
name: 'jsonAggregatedFormat',
Expand All @@ -15,23 +55,8 @@ StyleDictionary.registerFormat({
StyleDictionary.registerFormat({
name: 'jsonResolvedFormat',
formatter: function({dictionary, platform, options, file}) {
const jsonStrClasses = fs.readFileSync('classes/classes.json')
const jsonResClasses = jsonStrClasses.toString().replace(/{(.*)}/g, (match, tokenName) => {
// find the path in the token tree
const tokenPath = tokenName.split('.')
let value = dictionary.tokens
let subpath = ''
for (const path of tokenPath) {
subpath += path + '.'
if (!value[path]) {
value = subpath + '..?'
break
} else {
value = value[path]
}
}
return value
})
const jsonResClasses = jsonStrClasses
.replace(/{(.*)}/g, (match, tokenName) => getFinalValue(tokenName, dictionary))

return jsonResClasses
}
Expand All @@ -41,45 +66,41 @@ StyleDictionary.registerFormat({
StyleDictionary.registerFormat({
name: 'cssClassFormat',
formatter: function({dictionary, platform, options, file}) {
// import token fonts
let cssFonts = ''
const dic = dictionary.tokens
if (dic.asset && dic.asset.font) {
const fonts = dic.asset.font
for (const f in fonts) {
const ftype =
(fonts[f].ttf) ? fonts[f].ttf :
(fonts[f].woff) ? fonts[f].woff :
(fonts[f].woff2) ? fonts[f].woff2 :
(fonts[f].eot) ? fonts[f].eot : null
if (ftype != null)
cssFonts += `@font-face {\n font-family: '${fonts[f].name.value}';\n src: url('${ftype.value}');\n}\n`
}
cssFonts += '\n'
}
return cssImportFonts(dictionary) + classJSONtoCSS (jsonStrClasses)
}
})

// convert JSON classes to CSS classes
const jsonStrClasses = fs.readFileSync('classes/classes.json')
let cssClasses = ''
const jsonClasses = JSON.parse(jsonStrClasses)
for (const cls in jsonClasses) {
cssClasses += `.${cls} {\n`
for (const prop in jsonClasses[cls]) {
let value = jsonClasses[cls][prop]
// check Array type and transform in a string
if (Array.isArray(value))
value = value.join(' ')
// convert JSON classes to CSS classes
function classJSONtoCSS (jsonStrClasses) {
let cssClasses = ''
const jsonClasses = JSON.parse(jsonStrClasses)
for (const cls in jsonClasses) {
cssClasses += `.${cls} {\n`
for (const prop in jsonClasses[cls]) {
let value = jsonClasses[cls][prop]
// check Array type and transform in a string
if (Array.isArray(value))
value = value.join(' ')
if (value.includes('{'))
value = value
.replace(/\.value/g, '')
.replace(/\./g, '-')
.replace(/{/g, 'var(--')
.replace(/}/g, ')')
cssClasses += ` ${prop}: ${value};\n`
}
cssClasses += '}\n'
cssClasses += ` ${prop}: ${value};\n`
}
cssClasses += '}\n'
}
return cssClasses
}

return cssFonts + cssClasses
/* Output 4: CSS file with final values */
StyleDictionary.registerFormat({
name: 'cssResolvedClassFormat',
formatter: function({dictionary, platform, options, file}) {
const jsonResClasses = jsonStrClasses
.replace(/{(.*)}/g, (match, tokenName) => getFinalValue(tokenName, dictionary))
return cssImportFonts(dictionary) + classJSONtoCSS (jsonResClasses)
}
})

Expand Down Expand Up @@ -118,7 +139,14 @@ module.exports = {
},
{
"format": "cssClassFormat",
"destination": "css/classes.css",
"destination": "css/classes-tokens.css",
"options": {
"showFileHeader": false
}
},
{
"format": "cssResolvedClassFormat",
"destination": "css/classes-resolved.css",
"options": {
"showFileHeader": false
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="../build/css/variables.css" rel="stylesheet">
<link href="../build/css/classes.css" rel="stylesheet">
<link href="../../build/css/classes-resolved.css" rel="stylesheet">
</head>
<body>
<p><button class="btn btn-primary">Primary</button></p>
Expand Down
13 changes: 13 additions & 0 deletions design-system/style-dictionary/src/classes-tokens/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="../../build/css/variables.css" rel="stylesheet">
<link href="../../build/css/classes-tokens.css" rel="stylesheet">
</head>
<body>
<p><button class="btn btn-primary">Primary</button></p>
<p><button class="btn btn-secondary">Secondary</button></p>
</body>
</html>

0 comments on commit 46fa0b6

Please sign in to comment.