81 lines
2.3 KiB
JavaScript
81 lines
2.3 KiB
JavaScript
/**
|
|
* ESLint rule to forbid raw HTML and className in templates
|
|
*
|
|
* Templates must use proper reusable UI components instead of low level html and css.
|
|
* To avoid workarounds using `Box` with tailwind classes, the `className` property is forbidden.
|
|
*/
|
|
|
|
module.exports = {
|
|
meta: {
|
|
type: 'problem',
|
|
docs: {
|
|
description: 'Forbid raw HTML and className in templates',
|
|
category: 'Architecture',
|
|
recommended: true,
|
|
},
|
|
fixable: null,
|
|
schema: [],
|
|
messages: {
|
|
noRawHtml: 'Raw HTML tags are forbidden in templates. Use UI components from ui/ instead.',
|
|
noClassName: 'The className property is forbidden in templates. Use proper component props for styling.',
|
|
noStyle: 'The style property is forbidden in templates. Use proper component props for styling.',
|
|
},
|
|
},
|
|
|
|
create(context) {
|
|
const filename = context.getFilename();
|
|
const isInTemplates = filename.includes('/templates/');
|
|
|
|
if (!isInTemplates) return {};
|
|
|
|
return {
|
|
JSXOpeningElement(node) {
|
|
let tagName = '';
|
|
if (node.name.type === 'JSXIdentifier') {
|
|
tagName = node.name.name;
|
|
} else if (node.name.type === 'JSXMemberExpression') {
|
|
tagName = node.name.property.name;
|
|
}
|
|
|
|
if (!tagName) return;
|
|
|
|
// 1. Forbid raw HTML tags (lowercase)
|
|
if (tagName[0] === tagName[0].toLowerCase()) {
|
|
context.report({
|
|
node,
|
|
messageId: 'noRawHtml',
|
|
});
|
|
}
|
|
|
|
// 2. Forbid className property
|
|
const classNameAttr = node.attributes.find(
|
|
attr => attr.type === 'JSXAttribute' &&
|
|
attr.name.type === 'JSXIdentifier' &&
|
|
attr.name.name === 'className'
|
|
);
|
|
|
|
if (classNameAttr) {
|
|
context.report({
|
|
node: classNameAttr,
|
|
messageId: 'noClassName',
|
|
});
|
|
}
|
|
|
|
// 3. Forbid style property
|
|
const styleAttr = node.attributes.find(
|
|
attr => attr.type === 'JSXAttribute' &&
|
|
attr.name.type === 'JSXIdentifier' &&
|
|
attr.name.name === 'style'
|
|
);
|
|
|
|
if (styleAttr) {
|
|
context.report({
|
|
node: styleAttr,
|
|
messageId: 'noStyle',
|
|
});
|
|
}
|
|
},
|
|
};
|
|
},
|
|
};
|