2020-04-12 14:48:38 +00:00
|
|
|
import removeMeta from './removeMeta'
|
2022-04-13 16:10:47 +00:00
|
|
|
import dlv from 'dlv'
|
2020-04-13 00:44:43 +00:00
|
|
|
import escapeClassName from 'css.escape'
|
2020-10-08 15:20:54 +00:00
|
|
|
import { ensureArray } from './array'
|
2020-12-01 19:05:58 +00:00
|
|
|
import { remToPx } from './remToPx'
|
2021-07-12 14:23:16 +00:00
|
|
|
import stringifyObject from 'stringify-object'
|
|
|
|
import isObject from './isObject'
|
2020-04-12 14:48:38 +00:00
|
|
|
|
2020-04-11 21:20:45 +00:00
|
|
|
export function stringifyConfigValue(x: any): string {
|
2021-07-12 14:23:16 +00:00
|
|
|
if (isObject(x)) return `${Object.keys(x).length} values`
|
|
|
|
if (typeof x === 'function') return 'ƒ'
|
|
|
|
return stringifyObject(x, {
|
|
|
|
inlineCharacterLimit: Infinity,
|
|
|
|
singleQuotes: false,
|
|
|
|
transform: (obj, prop, originalResult) => {
|
|
|
|
if (typeof obj[prop] === 'function') {
|
|
|
|
return 'ƒ'
|
|
|
|
}
|
|
|
|
return originalResult
|
|
|
|
},
|
|
|
|
})
|
2020-04-11 21:20:45 +00:00
|
|
|
}
|
2020-04-12 14:48:38 +00:00
|
|
|
|
2020-11-26 20:07:39 +00:00
|
|
|
export function stringifyCss(
|
|
|
|
className: string,
|
|
|
|
obj: any,
|
2020-12-01 19:05:58 +00:00
|
|
|
{
|
|
|
|
tabSize = 2,
|
2021-02-05 14:49:06 +00:00
|
|
|
showPixelEquivalents = false,
|
|
|
|
rootFontSize = 16,
|
|
|
|
}: Partial<{
|
|
|
|
tabSize: number
|
|
|
|
showPixelEquivalents: boolean
|
|
|
|
rootFontSize: number
|
|
|
|
}> = {}
|
2020-11-26 20:07:39 +00:00
|
|
|
): string {
|
2020-04-13 00:44:43 +00:00
|
|
|
if (obj.__rule !== true && !Array.isArray(obj)) return null
|
|
|
|
|
|
|
|
if (Array.isArray(obj)) {
|
2020-12-01 19:05:58 +00:00
|
|
|
const rules = obj
|
2021-02-05 14:49:06 +00:00
|
|
|
.map((x) =>
|
|
|
|
stringifyCss(className, x, {
|
|
|
|
tabSize,
|
|
|
|
showPixelEquivalents,
|
|
|
|
rootFontSize,
|
|
|
|
})
|
|
|
|
)
|
2020-12-01 19:05:58 +00:00
|
|
|
.filter(Boolean)
|
2020-04-13 00:44:43 +00:00
|
|
|
if (rules.length === 0) return null
|
|
|
|
return rules.join('\n\n')
|
|
|
|
}
|
|
|
|
|
|
|
|
let css = ``
|
2020-11-26 20:07:39 +00:00
|
|
|
const indent = ' '.repeat(tabSize)
|
2020-04-13 00:44:43 +00:00
|
|
|
|
|
|
|
const context = dlv(obj, '__context', [])
|
|
|
|
const props = Object.keys(removeMeta(obj))
|
|
|
|
if (props.length === 0) return null
|
|
|
|
|
|
|
|
for (let i = 0; i < context.length; i++) {
|
2020-11-26 20:07:39 +00:00
|
|
|
css += `${indent.repeat(i)}${context[i]} {\n`
|
2020-04-12 14:48:38 +00:00
|
|
|
}
|
2020-04-13 00:44:43 +00:00
|
|
|
|
2020-11-26 20:07:39 +00:00
|
|
|
const indentStr = indent.repeat(context.length)
|
2020-04-13 00:44:43 +00:00
|
|
|
const decls = props.reduce((acc, curr, i) => {
|
2020-05-02 12:18:30 +00:00
|
|
|
const propStr = ensureArray(obj[curr])
|
2020-12-01 19:05:58 +00:00
|
|
|
.map((val) => {
|
2021-02-05 14:49:06 +00:00
|
|
|
const px = showPixelEquivalents ? remToPx(val, rootFontSize) : undefined
|
2021-02-07 20:58:41 +00:00
|
|
|
return `${indentStr + indent}${curr}: ${val}${px ? `/* ${px} */` : ''};`
|
2020-12-01 19:05:58 +00:00
|
|
|
})
|
2020-05-02 12:18:30 +00:00
|
|
|
.join('\n')
|
|
|
|
return `${acc}${i === 0 ? '' : '\n'}${propStr}`
|
2020-04-12 14:48:38 +00:00
|
|
|
}, '')
|
2021-07-07 11:38:00 +00:00
|
|
|
css += `${indentStr}${augmentClassName(className, obj)} {\n${decls}\n${indentStr}}`
|
2020-04-13 00:44:43 +00:00
|
|
|
|
|
|
|
for (let i = context.length - 1; i >= 0; i--) {
|
2020-11-26 20:07:39 +00:00
|
|
|
css += `${indent.repeat(i)}\n}`
|
2020-04-13 00:44:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return css
|
|
|
|
}
|
|
|
|
|
|
|
|
function augmentClassName(className: string, obj: any): string {
|
2020-06-12 10:26:17 +00:00
|
|
|
const pseudo = obj.__pseudo.join('')
|
2020-04-13 00:44:43 +00:00
|
|
|
const scope = obj.__scope ? `${obj.__scope} ` : ''
|
|
|
|
return `${scope}.${escapeClassName(className)}${pseudo}`
|
2020-04-12 14:48:38 +00:00
|
|
|
}
|