2025-06-13 17:44:21 -04:00

52 lines
1.7 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",…]
}