Skip to content

Commit 80c8e3a

Browse files
author
Adam Gruber
committed
Separate transform functionality into separate module
1 parent f525f8a commit 80c8e3a

File tree

1 file changed

+95
-0
lines changed

1 file changed

+95
-0
lines changed

lib/transformVars.js

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
const camelCase = require('camel-case');
2+
3+
/*
4+
* Add escaped quotes around font names other than the generic CSS font families
5+
* While quotes are not required, they are recommended by the spec
6+
* https://www.w3.org/TR/css-fonts-3/#generic-font-families
7+
*
8+
* @param {string} str Font family name
9+
*
10+
* @return {string}
11+
*/
12+
function quoteFontName(str) {
13+
const genericFonts = [
14+
'serif',
15+
'sans-serif',
16+
'cursive',
17+
'fantasy',
18+
'monospace',
19+
];
20+
return genericFonts.includes(str.toLowerCase()) ? str : `'${str}'`;
21+
}
22+
23+
/*
24+
* Get the CSS value from a sass-extract data structure
25+
* https://github.com/jgranstrom/sass-extract#general-variable-value-structure
26+
*
27+
* @param {object} sassVar Abstract data structure for SASS variable
28+
*
29+
* @return {string|int} CSS value
30+
*/
31+
function getSassValue(sassVar) {
32+
const { type, value } = sassVar;
33+
switch (type) {
34+
case 'SassNumber':
35+
return sassVar.unit ? `${value}${sassVar.unit}` : value;
36+
37+
case 'SassColor': {
38+
const { r, g, b, a } = value;
39+
const hasAlpha = a !== 1;
40+
return hasAlpha
41+
? `rgba(${r.toFixed()}, ${g.toFixed()}, ${b.toFixed()}, ${a})`
42+
: `rgb(${r.toFixed()}, ${g.toFixed()}, ${b.toFixed()})`;
43+
}
44+
45+
case 'SassList': {
46+
const isStringList = value.every(item => item.type === 'SassString');
47+
const newList = value.map(getSassValue);
48+
return isStringList
49+
? newList.map(quoteFontName).join(', ')
50+
: newList.join(' ');
51+
}
52+
53+
case 'SassMap':
54+
return transformVars(value);
55+
56+
default:
57+
return value;
58+
}
59+
}
60+
61+
/*
62+
* Transform style object key
63+
* - Strip leading '$'
64+
* - Convert to camelCase if `shouldCamelCase` is true
65+
*
66+
* @param {string} key Style object key
67+
* @param {boolean} shouldCamelCase Convert keys to camelCase
68+
*
69+
* @return {string} Converted key
70+
*/
71+
function transformKey(key, shouldCamelCase) {
72+
const newKey = key.replace('$', '');
73+
return shouldCamelCase ? camelCase(newKey, null, true) : newKey;
74+
}
75+
76+
/*
77+
* Reduce SASS-compiled variables object into theme object
78+
*
79+
* @param {object} varsObj Output from `sass-extract` render
80+
* @param {object} [options] Options object
81+
* @param {boolean} [options.camelCase] Should keys be converted to camelCase (default: true)
82+
*
83+
* @return {object} Transformed variables object
84+
*/
85+
function transformVars(varsObj, options) {
86+
const opts = Object.assign({ camelCase: true }, options);
87+
return Object.keys(varsObj).reduce((acc, key) => {
88+
const newKey = transformKey(key, opts.camelCase);
89+
const newVal = getSassValue(varsObj[key]);
90+
acc[newKey] = newVal;
91+
return acc;
92+
}, {});
93+
}
94+
95+
module.exports = transformVars;

0 commit comments

Comments
 (0)