core/stylelint/no-css-magic-number.stylelint.rule.ts
core/stylelint/no-css-magic-number.stylelint.rule.ts is a file in GovLab Quality. 57 lines of code and 11 definitions.
import type { Declaration, Root } from "postcss";
import stylelint, { type PostcssResult, type Rule } from "stylelint";
import { CSS_UNITS } from "#configuration/constants/css.constants";
import type { GovlabStylelintMeta } from "#types/stylelint.types";
import { insideAtRule } from "#core/predicates/css.predicate";
import { valueUnits } from "#core/parsers/css.parser";
import { withRuleId } from "#core/formatters/stylelint.formatter";
const { createPlugin, utils } = stylelint;
const ruleName = "govlab/no-css-magic-number";
const ruleId = "no_css_magic_number";
export const RULE_META: GovlabStylelintMeta = {
meta: {
canonical: ["magic-number", "design-tokens"],
description: "Forbid magic numeric CSS values; reference a token/variable so the value stays consistent",
fixable: false,
},
ruleId,
ruleName,
};
const EXCLUDED_PROPS = new Set(["content", "font-family", "animation-name", "grid-template", "transform"]);
const SKIP_VALUES = new Set(["0", "1"]);
const SKIP_FULL = new Set(["100%"]);
const SKIP_ATRULES = new Set(["media", "container"]);
const messages = utils.ruleMessages(ruleName, {
magic: (value: string): string =>
withRuleId(
`Magic numeric value '${value}' bypasses the token system. Define or reference a CSS variable (var(--…)) so the value stays consistent across the design system — 0, 1, and 100% are exempt.`,
ruleId,
),
});
const rule: Rule = Object.assign(
(primary: unknown) =>
(root: Root, result: PostcssResult): void => {
if (primary !== true) {
return;
}
root.walkDecls((decl: Declaration) => {
if (
EXCLUDED_PROPS.has(decl.prop.toLowerCase()) ||
decl.value.includes("var(--") ||
insideAtRule(decl, SKIP_ATRULES)
) {
return;
}
for (const token of valueUnits(decl.value)) {
if (CSS_UNITS.has(token.unit) && !SKIP_VALUES.has(token.number)) {
const full = `${token.number}${token.unit}`;
if (!SKIP_FULL.has(full)) {
utils.report({ message: messages.magic(full), node: decl, result, ruleName, word: full });
}
}
}
});
},
{ messages, ruleName },
);
export default createPlugin(ruleName, rule);