Skip to content

Instantly share code, notes, and snippets.

@calebdwilliams
Last active May 8, 2022 15:00
Show Gist options
  • Save calebdwilliams/7600d847e724c2f2d2a62c0922c6d1a6 to your computer and use it in GitHub Desktop.
Save calebdwilliams/7600d847e724c2f2d2a62c0922c6d1a6 to your computer and use it in GitHub Desktop.
/** See https://astexplorer.net/#/gist/029b3c40b76e04ceb3dada59d4a4cbab/9e5ee857c583ed6fb1ed05d2bbd934a41eb4156e */
import * as postcss from "postcss";
const rootToRefSelectorMap = new WeakMap();
const exportsString = '._export💲';
function toSassMixin(rule) {
const mixin = rule.clone();
mixin.selector = `@mixin ${rule.selector.replace('$', '')}`;
return mixin;
}
export default postcss.plugin('postcss-references', (options = {}) => {
// Work with options here
return (root) => {
console.log(root)
const ruleMap = new Map();
rootToRefSelectorMap.set(root, ruleMap);
// Transform each rule here
root.walkRules((rule) => {
if (rule.selector.match(/^\$/)) {
const { selector } = rule;
if (rule.parent !== root) {
throw new Error('Reference selector definitions must be a child of root');
}
if (ruleMap.has(selector)) {
throw new Error(`${selector} cannot be defined twice in the same root`);
}
/** TODO: handle , */
ruleMap.set(rule.selector, rule.clone());
if (selector.includes(',')) {
rule.selector = selector.replace('$', exportsString);
} else {
rule.remove();
}
}
});
root.walkAtRules((atRule) => {
const { name, params, parent } = atRule;
if (name === "include") {
const replacementRule = ruleMap.get(params).clone();
if (!replacementRule || parent === root) {
throw new Error('Reference selectors can not be applied to root');
}
replacementRule.walk((decl) => {
parent.insertBefore(atRule, decl);
});
atRule.remove();
}
});
for (const [key, rule] of ruleMap.entries()) {
const { selector } = rule;
if (selector.includes(',')) {
continue;
}
console.log(toSassMixin(rule))
const safeKey = key.replace('$', exportsString);
rule.selector = safeKey;
root.append(rule);
}
};
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment