stylelint-scss
Version:
A collection of SCSS-specific rules for Stylelint
87 lines (71 loc) • 2.17 kB
JavaScript
import valueParser from "postcss-value-parser";
import stylelint from "stylelint";
import declarationValueIndex from "../../utils/declarationValueIndex.js";
import namespace from "../../utils/namespace.js";
import ruleUrl from "../../utils/ruleUrl.js";
const { utils } = stylelint;
const ruleName = namespace("function-color-relative");
const messages = utils.ruleMessages(ruleName, {
expected: "Expected the scale-color function to be used"
});
const meta = {
url: ruleUrl(ruleName)
};
const functionNames = new Set([
"saturate",
"desaturate",
"darken",
"lighten",
"opacify",
"fade-in",
"transparentize",
"fade-out"
]);
function isColorFunction(node) {
return node.type === "function" && functionNames.has(node.value);
}
function rule(primary) {
return (root, result) => {
const validOptions = utils.validateOptions(result, ruleName, {
actual: primary
});
if (!validOptions) {
return;
}
root.walkDecls(decl => {
const declValueIndex = declarationValueIndex(decl);
valueParser(decl.value).walk(node => {
// Verify that we're only looking at functions.
if (node.type !== "function" || node.value === "") {
return;
}
const isFilter = decl.prop === "filter";
const isSassColorFunction = !isFilter && isColorFunction(node);
const isDSFilterColorFunction =
isFilter &&
node.value === "drop-shadow" &&
node.nodes.some(isColorFunction);
if (isSassColorFunction || isDSFilterColorFunction) {
const funcNodes = isDSFilterColorFunction
? node.nodes.filter(isColorFunction)
: [node];
funcNodes.forEach(funcNode => {
const index = declValueIndex + funcNode.sourceIndex;
utils.report({
message: messages.expected,
node: decl,
index,
endIndex: index + funcNode.value.length,
result,
ruleName
});
});
}
});
});
};
}
rule.ruleName = ruleName;
rule.messages = messages;
rule.meta = meta;
export default rule;