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