@onereach/postcss-scoped-selector
Version:
PostCSS plugin for selector scoping
54 lines (42 loc) • 1.41 kB
JavaScript
/**
* @type {import('postcss').PluginCreator}
*/
const parser = require('postcss-selector-parser');
const isChildCombinator = selector =>
selector.type === 'combinator' && (selector.value === '>' || selector.value === ' ')
function transform(scope) {
const pseudoSelector = parser.pseudo({ value: `:where(${scope})` });
return function (selectors) {
const list = selectors.first.split(isChildCombinator);
const place = list.at(0).at(-1);
if (list.length === 1) {
place.parent.insertAfter(place, pseudoSelector);
} else {
place.parent.insertBefore(place, pseudoSelector);
}
}
}
module.exports = (options = {}) => {
const { selector = '' } = options;
return {
postcssPlugin: 'postcss-scoped-selector',
Once(root) {
if (selector) {
root.walkRules(function (rule) {
if (rule.parent.type === 'atrule' && rule.parent.name === 'keyframes') {
return;
}
let selectors = [];
rule.selectors.forEach(function (currentSelector) {
if (!currentSelector) return;
selectors.push(`:where(${selector}) ${currentSelector}`);
const transformed = parser(transform(selector)).processSync(currentSelector);
selectors.push(transformed);
});
rule.selectors = selectors;
});
}
}
}
}
module.exports.postcss = true