eslint-plugin-solid
Version:
Solid-specific linting rules for ESLint.
61 lines (56 loc) • 2.05 kB
text/typescript
import { TSESLint, ESLintUtils } from "@typescript-eslint/utils";
import { isDOMElementName, jsxGetProp, jsxHasProp } from "../utils";
const createRule = ESLintUtils.RuleCreator.withoutDocs;
const reactSpecificProps = [
{ from: "className", to: "class" },
{ from: "htmlFor", to: "for" },
];
export default createRule({
meta: {
type: "problem",
docs: {
description:
"Disallow usage of React-specific `className`/`htmlFor` props, which were deprecated in v1.4.0.",
url: "https://github.com/solidjs-community/eslint-plugin-solid/blob/main/packages/eslint-plugin-solid/docs/no-react-specific-props.md",
},
fixable: "code",
schema: [],
messages: {
prefer: "Prefer the `{{ to }}` prop over the deprecated `{{ from }}` prop.",
noUselessKey: "Elements in a <For> or <Index> list do not need a key prop.",
},
},
defaultOptions: [],
create(context) {
return {
JSXOpeningElement(node) {
for (const { from, to } of reactSpecificProps) {
const classNameAttribute = jsxGetProp(node.attributes, from);
if (classNameAttribute) {
// only auto-fix if there is no class prop defined
const fix = !jsxHasProp(node.attributes, to)
? (fixer: TSESLint.RuleFixer) => fixer.replaceText(classNameAttribute.name, to)
: undefined;
context.report({
node: classNameAttribute,
messageId: "prefer",
data: { from, to },
fix,
});
}
}
if (node.name.type === "JSXIdentifier" && isDOMElementName(node.name.name)) {
const keyProp = jsxGetProp(node.attributes, "key");
if (keyProp) {
// no DOM element has a 'key' prop, so we can assert that this is a holdover from React.
context.report({
node: keyProp,
messageId: "noUselessKey",
fix: (fixer) => fixer.remove(keyProp),
});
}
}
},
};
},
});