mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-09-30 04:33:11 +00:00
fix(lint): enforce error typography composition
This commit is contained in:
parent
392af77b91
commit
620ac65153
2 changed files with 58 additions and 6 deletions
55
eslint-rules/no-vp-error-outside-text.js
Normal file
55
eslint-rules/no-vp-error-outside-text.js
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
function containsVpErrorToken(node) {
|
||||
if (!node || typeof node !== "object") {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (node.type === "Literal" && typeof node.value === "string") {
|
||||
return node.value.split(/\s+/u).includes("vp-error");
|
||||
}
|
||||
|
||||
if (node.type === "TemplateElement") {
|
||||
return node.value.raw.split(/\s+/u).includes("vp-error");
|
||||
}
|
||||
|
||||
return Object.entries(node).some(([key, value]) => {
|
||||
if (key === "parent") {
|
||||
return false;
|
||||
}
|
||||
if (Array.isArray(value)) {
|
||||
return value.some(containsVpErrorToken);
|
||||
}
|
||||
return containsVpErrorToken(value);
|
||||
});
|
||||
}
|
||||
|
||||
const rule = {
|
||||
meta: {
|
||||
type: "problem",
|
||||
docs: {
|
||||
description: "Require the Text component for legacy vp-error styling",
|
||||
},
|
||||
schema: [],
|
||||
messages: {
|
||||
useText:
|
||||
'Use the Text component for the vp-error class; pair the error message with variant="error" so feedback stays accessible and consistent.',
|
||||
},
|
||||
},
|
||||
create(context) {
|
||||
return {
|
||||
JSXAttribute(node) {
|
||||
if (node.name?.name !== "className" || !containsVpErrorToken(node.value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const elementName = node.parent?.name;
|
||||
if (elementName?.type === "JSXIdentifier" && elementName.name === "Text") {
|
||||
return;
|
||||
}
|
||||
|
||||
context.report({ node, messageId: "useText" });
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
export default rule;
|
||||
|
|
@ -6,10 +6,12 @@ import globals from "globals";
|
|||
import tseslint from "typescript-eslint";
|
||||
|
||||
import noNonBooleanJsxAnd from "./eslint-rules/no-non-boolean-jsx-and.js";
|
||||
import noVpErrorOutsideText from "./eslint-rules/no-vp-error-outside-text.js";
|
||||
|
||||
const localRules = {
|
||||
rules: {
|
||||
"no-non-boolean-jsx-and": noNonBooleanJsxAnd,
|
||||
"no-vp-error-outside-text": noVpErrorOutsideText,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -72,6 +74,7 @@ export default tseslint.config(
|
|||
"@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_" }],
|
||||
"@typescript-eslint/no-explicit-any": "warn",
|
||||
"seahaven/no-non-boolean-jsx-and": "error",
|
||||
"seahaven/no-vp-error-outside-text": "error",
|
||||
"no-restricted-syntax": [
|
||||
"error",
|
||||
{
|
||||
|
|
@ -86,12 +89,6 @@ export default tseslint.config(
|
|||
message:
|
||||
"Use the shared Text component so typography semantics, family, tone, and feedback behavior stay consistent.",
|
||||
},
|
||||
{
|
||||
selector:
|
||||
"JSXOpeningElement:not([name.name='Text']) > JSXAttribute[name.name='className'][value.type='Literal'][value.value=/vp-error/]",
|
||||
message:
|
||||
'Use the Text component for the vp-error class; pair the error message with variant="error" so feedback stays accessible and consistent.',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue