daisyui
Version:
daisyUI - Tailwind CSS Components
88 lines (72 loc) • 1.92 kB
JavaScript
const Tokenizer = require('css-selector-tokenizer');
const {
parseAttrSelector,
attrStringify,
itMatchesOne,
} = require('./utils');
function prefixNode(node, prefix) {
if (['class', 'id'].includes(node.type)) {
return {
...node,
name: `${prefix}${node.name}`,
};
}
if (['attribute'].includes(node.type) && node.content) {
const {
type, operator, head, classes, foot,
} = parseAttrSelector(node);
if (!['class', 'id'].includes(type)) return node;
return {
...node,
content: attrStringify({
type,
operator,
head,
classes: classes.map((cls) => `${prefix}${cls}`),
foot,
}),
}
}
return node;
}
function iterateSelectorNodes(selector, options) {
const { prefix, ignore } = options;
return {
...selector,
nodes: selector.nodes.map((node) => {
if (['selector', 'nested-pseudo-class'].includes(node.type)) {
return iterateSelectorNodes(node, options);
}
if (itMatchesOne(ignore, Tokenizer.stringify(node))) return node;
return prefixNode(node, prefix);
}),
};
}
/**
* @type {import('postcss').PluginCreator}
*/
module.exports = (opts = {}) => {
const { prefix, ignore } = {
prefix: '',
ignore: [],
...opts,
};
if (typeof prefix !== 'string') {
throw new Error('@postcss-prefix: prefix option should be of type string.');
}
if (!Array.isArray(ignore)) {
throw new Error('@postcss-prefix: ignore options should be an Array.');
}
if (!prefix.length) return;
return {
postcssPlugin: 'postcss-prefixer',
Root(root, postcss) {
root.walkRules((rule) => {
const parsed = Tokenizer.parse(rule.selector);
const selector = iterateSelectorNodes(parsed, { prefix, ignore });
rule.selector = Tokenizer.stringify(selector);
});
},
};
}
module.exports.postcss = true