astro-ghostcms/.pnpm-store/v3/files/2d/2be75ce9427d77d90ff0a9deb63...

140 lines
3.6 KiB
Plaintext

const plugin = require('tailwindcss/plugin')
const merge = require('lodash.merge')
const castArray = require('lodash.castarray')
const styles = require('./styles')
const { commonTrailingPseudos } = require('./utils')
const computed = {
// Reserved for future "magic properties", for example:
// bulletColor: (color) => ({ 'ul > li::before': { backgroundColor: color } }),
}
function inWhere(selector, { className, modifier, prefix }) {
let prefixedNot = prefix(`.not-${className}`).slice(1)
let selectorPrefix = selector.startsWith('>')
? `${modifier === 'DEFAULT' ? `.${className}` : `.${className}-${modifier}`} `
: ''
// Parse the selector, if every component ends in the same pseudo element(s) then move it to the end
let [trailingPseudo, rebuiltSelector] = commonTrailingPseudos(selector)
if (trailingPseudo) {
return `:where(${selectorPrefix}${rebuiltSelector}):not(:where([class~="${prefixedNot}"],[class~="${prefixedNot}"] *))${trailingPseudo}`
}
return `:where(${selectorPrefix}${selector}):not(:where([class~="${prefixedNot}"],[class~="${prefixedNot}"] *))`
}
function isObject(value) {
return typeof value === 'object' && value !== null
}
function configToCss(config = {}, { target, className, modifier, prefix }) {
function updateSelector(k, v) {
if (target === 'legacy') {
return [k, v]
}
if (Array.isArray(v)) {
return [k, v]
}
if (isObject(v)) {
let nested = Object.values(v).some(isObject)
if (nested) {
return [
inWhere(k, { className, modifier, prefix }),
v,
Object.fromEntries(Object.entries(v).map(([k, v]) => updateSelector(k, v))),
]
}
return [inWhere(k, { className, modifier, prefix }), v]
}
return [k, v]
}
return Object.fromEntries(
Object.entries(
merge(
{},
...Object.keys(config)
.filter((key) => computed[key])
.map((key) => computed[key](config[key])),
...castArray(config.css || {})
)
).map(([k, v]) => updateSelector(k, v))
)
}
module.exports = plugin.withOptions(
({ className = 'prose', target = 'modern' } = {}) => {
return function ({ addVariant, addComponents, theme, prefix }) {
let modifiers = theme('typography')
let options = { className, prefix }
for (let [name, ...selectors] of [
['headings', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'th'],
['h1'],
['h2'],
['h3'],
['h4'],
['h5'],
['h6'],
['p'],
['a'],
['blockquote'],
['figure'],
['figcaption'],
['strong'],
['em'],
['code'],
['pre'],
['ol'],
['ul'],
['li'],
['table'],
['thead'],
['tr'],
['th'],
['td'],
['img'],
['video'],
['hr'],
['lead', '[class~="lead"]'],
]) {
selectors = selectors.length === 0 ? [name] : selectors
let selector =
target === 'legacy' ? selectors.map((selector) => `& ${selector}`) : selectors.join(', ')
addVariant(
`${className}-${name}`,
target === 'legacy' ? selector : `& :is(${inWhere(selector, options)})`
)
}
addComponents(
Object.keys(modifiers).map((modifier) => ({
[modifier === 'DEFAULT' ? `.${className}` : `.${className}-${modifier}`]: configToCss(
modifiers[modifier],
{
target,
className,
modifier,
prefix,
}
),
}))
)
}
},
() => {
return {
theme: { typography: styles },
}
}
)