This repository has been archived by the owner on Apr 11, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathremToPx.js
79 lines (66 loc) · 2.08 KB
/
remToPx.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
const getAtPath = require('lodash.get')
// https://stackoverflow.com/a/1175468/283481
function isObjectLiteral(obj) {
if (typeof obj !== 'object' || obj === null)
return false
// get obj's Object constructor's prototype
let ObjProto = obj
while (Object.getPrototypeOf(ObjProto = Object.getPrototypeOf(ObjProto)) !== null) {
}
return Object.getPrototypeOf(obj) === ObjProto
}
class RemToPxConverter {
constructor(twTheme, pxBase) {
this._twTheme = twTheme
this._pxBase = pxBase
}
_convertValue(value, preserveUnknowns = false, propPath = null) {
if (isObjectLiteral(value)) {
return this.convert(value, propPath)
} else if (Array.isArray(value)) {
return value.map((v) => this._convertValue(v, true))
} else if (typeof value === 'string') {
return value.replace(
/(?<=^|\s|[()])([+-]?(?:(?:\.\d+)|(?:\d+(?:\.\d+)?))(?:[eE][+-]?\d+)?)rem(?=\)|\s|$)/g,
(match, remValue) => `${parseFloat(remValue) * this._pxBase}px`,
)
} else if (typeof value === 'function' && propPath) {
return (theme, utils) => ({
...this.convert(getAtPath(this._twTheme, propPath)(theme, utils), propPath),
})
} else if (preserveUnknowns) {
return value
}
return null
}
convert(obj = this._twTheme, path = '') {
const target = {}
for (const propName in obj) {
if (!Object.prototype.hasOwnProperty.call(obj, propName)) {
continue
}
const currentPath = path === '' ? propName : `${path}.${propName}`
const value = obj[propName]
if (isObjectLiteral(value)) {
target[propName] = this.convert(value, currentPath)
} else {
const converted = this._convertValue(value, false, currentPath)
if (converted != null) {
target[propName] = converted
}
}
}
return target
}
}
function remToPx(twTheme, pxBase) {
const converter = new RemToPxConverter(twTheme, pxBase)
return converter.convert()
}
module.exports = (twTheme, pxBase = 16) => ({
config: {
theme: {
...remToPx(twTheme, pxBase),
},
},
})