56 lines
1.9 KiB
JavaScript
56 lines
1.9 KiB
JavaScript
|
function cartesian(array) {
|
||
|
function* cartesian(head, ...tail) {
|
||
|
let remainder = tail.length ? cartesian(...tail) : [[]]
|
||
|
for (let r of remainder) for (let h of head) yield [h, ...r]
|
||
|
}
|
||
|
|
||
|
return [...cartesian(...array)]
|
||
|
}
|
||
|
|
||
|
function deepKeys(object, separator = '.', prefix = '') {
|
||
|
return Object.keys(object).reduce((result, key) => {
|
||
|
if (Array.isArray(object[key])) {
|
||
|
return [...result, prefix + key];
|
||
|
} else if (typeof object[key] === 'object' && object[key] !== null) {
|
||
|
return [...result, ...deepKeys(object[key], separator, prefix + key + separator)];
|
||
|
}
|
||
|
|
||
|
return [...result, prefix + key];
|
||
|
}, []);
|
||
|
}
|
||
|
|
||
|
const extractTokens = pattern =>
|
||
|
pattern.split(/(?={[^}]+})|(?<={[^}]+})/)
|
||
|
|
||
|
const expandTokens = theme => tokens => {
|
||
|
return tokens.map(token => {
|
||
|
if(token.startsWith('{')) {
|
||
|
const cleanToken = token.replace(/{|}/g, '')
|
||
|
if(cleanToken.includes('.')) {
|
||
|
const color = cleanToken.split('.')[1]
|
||
|
const colorToken = {
|
||
|
[color]: theme(cleanToken, {})
|
||
|
}
|
||
|
return deepKeys(colorToken, '-')
|
||
|
}
|
||
|
return deepKeys(theme(cleanToken, {}), '-')
|
||
|
} else {
|
||
|
return [token]
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
|
||
|
|
||
|
const mapToClasses = expanded =>
|
||
|
expanded.map(values =>
|
||
|
values.join('').replace('-DEFAULT', ''))
|
||
|
|
||
|
module.exports = theme => patterns => {
|
||
|
return patterns // ["text-{gray}", …]
|
||
|
.map(extractTokens) // [["text", "{gray}"], …]
|
||
|
.map(expandTokens(theme)) // [[["text"], ["gray-100", "gray-200",…]], …]
|
||
|
.map(cartesian) // [[["text", "gray-100"], ["text", "gray-200"], …], …]
|
||
|
.flatMap(mapToClasses) // ["text-gray-100", "text-gray-200",…]
|
||
|
}
|
||
|
|