From 5bbc280f798108f9288dbabe38bb0f584448e684 Mon Sep 17 00:00:00 2001 From: YeonJuan Date: Sat, 9 Aug 2025 23:15:15 +0900 Subject: [PATCH 1/2] feat: [require-attrs] add message options --- docs/rules.md | 1 + docs/rules/require-attrs.md | 87 ++++++++++++++----- .../eslint-plugin/lib/rules/require-attrs.js | 13 ++- .../tests/rules/require-attrs.test.js | 56 ++++++++++++ 4 files changed, 133 insertions(+), 24 deletions(-) diff --git a/docs/rules.md b/docs/rules.md index 068f62d2..faf6c911 100644 --- a/docs/rules.md +++ b/docs/rules.md @@ -14,6 +14,7 @@ | [no-duplicate-class](rules/no-duplicate-class) | Disallow duplicate class names | 🔧 | | [no-duplicate-id](rules/no-duplicate-id) | Disallow duplicate id attributes | ⭐ | | [no-duplicate-in-head](rules/no-duplicate-in-head) | Disallow duplicate tags in `` | | +| [no-ineffective-attrs](rules/no-ineffective-attrs) | Disallow HTML attributes that have no effect in their context | | | [no-inline-styles](rules/no-inline-styles) | Disallow using inline style | | | [no-invalid-entity](rules/no-invalid-entity) | Disallows the use of invalid HTML entities | | | [no-nested-interactive](rules/no-nested-interactive) | Disallows nested interactive elements | | diff --git a/docs/rules/require-attrs.md b/docs/rules/require-attrs.md index bb1bbb4c..b1b43eb2 100644 --- a/docs/rules/require-attrs.md +++ b/docs/rules/require-attrs.md @@ -22,7 +22,7 @@ module.exports = { ### Options -This rule takes an array of objects which has tag name with attribute name. +This rule takes an array of option objects: ```js module.exports = { @@ -31,38 +31,83 @@ module.exports = { "error", { tag: "img", - attr: "alt", // Enforce to use img with alt attribute. + attr: "alt", }, { tag: "svg", - attr: "viewBox" // Enforce to use svg and viewBox attributes with "0 0 100 100" value. - value: "0 0 100 100" + attr: "viewBox", + value: "0 0 100 100", }, ], }, }; ``` -Examples of **incorrect** code for this rule with the option below: - -```json -{ - "tag": "img", - "attr": "alt" -}, -{ - "tag": "svg", - "attr": "viewBox", - "value": "0 0 100 100" -} +#### tag + +- Type: `string` +- **Required** + +The HTML tag name to check for the specified attribute. + +#### attr + +- Type: `string` +- **Required** + +The attribute name that must be present on the specified tag. + +#### value + +- Type: `string` +- _Optional_ + +The expected value for the attribute. If specified, the attribute must have this exact value. + +#### message + +- Type: `string` +- _Optional_ + +Custom error message to display when the rule is violated. If not provided, a default message will be used. + +```js +module.exports = { + rules: { + "@html-eslint/require-attrs": [ + "error", + { + tag: "img", + attr: "alt", + message: "Images must have alternative text for accessibility", + }, + ], + }, +}; ``` -```html,incorrect - +Examples of **incorrect** code for this rule: + +```html + + + + + + + + ``` -Examples of **correct** code for this rule with the option above: +Examples of **correct** code for this rule: + +```html + + + + + -```html,correct - + + ``` diff --git a/packages/eslint-plugin/lib/rules/require-attrs.js b/packages/eslint-plugin/lib/rules/require-attrs.js index 914bc003..405d4003 100644 --- a/packages/eslint-plugin/lib/rules/require-attrs.js +++ b/packages/eslint-plugin/lib/rules/require-attrs.js @@ -6,6 +6,7 @@ * @property {string} tag * @property {string} attr * @property {string} [value] + * @property {string} [message] * */ @@ -17,6 +18,7 @@ const { getRuleUrl } = require("./utils/rule"); const MESSAGE_IDS = { MISSING: "missing", UNEXPECTED: "unexpected", + CUSTOM: "custom", }; /** @@ -41,6 +43,7 @@ module.exports = { tag: { type: "string" }, attr: { type: "string" }, value: { type: "string" }, + message: { type: "string" }, }, required: ["tag", "attr"], additionalProperties: false, @@ -59,7 +62,7 @@ module.exports = { */ const options = context.options || []; /** - * @type {Map} + * @type {Map} */ const tagOptionsMap = new Map(); @@ -90,7 +93,9 @@ module.exports = { ); if (!attr) { context.report({ - messageId: MESSAGE_IDS.MISSING, + ...(option.message + ? { message: option.message } + : { messageId: MESSAGE_IDS.MISSING }), node, data: { attr: attrName, @@ -111,7 +116,9 @@ module.exports = { (!attr.value || attr.value.value !== option.value) ) { context.report({ - messageId: MESSAGE_IDS.UNEXPECTED, + ...(option.message + ? { message: option.message } + : { messageId: MESSAGE_IDS.UNEXPECTED }), node: attr, data: { attr: attrName, diff --git a/packages/eslint-plugin/tests/rules/require-attrs.test.js b/packages/eslint-plugin/tests/rules/require-attrs.test.js index 568bc232..e2e9c406 100644 --- a/packages/eslint-plugin/tests/rules/require-attrs.test.js +++ b/packages/eslint-plugin/tests/rules/require-attrs.test.js @@ -310,6 +310,44 @@ ruleTester.run("require-attrs", rule, { }, ], }, + // Test custom message option + { + code: ``, + options: [ + { + tag: "img", + attr: "alt", + message: "Image must have alt text for accessibility", + }, + ], + errors: [ + { + line: 1, + column: 1, + message: "Image must have alt text for accessibility", + }, + ], + }, + { + code: ``, + options: [ + { + tag: "svg", + attr: "viewBox", + value: "0 0 100 100", + message: "SVG viewBox must be '0 0 100 100'", + }, + ], + output: ``, + errors: [ + { + line: 1, + column: 6, + endColumn: 21, + message: "SVG viewBox must be '0 0 100 100'", + }, + ], + }, ], }); @@ -354,5 +392,23 @@ templateRuleTester.run("[template] require-attrs", rule, { }, ], }, + // Test custom message option in template + { + code: "html`
`", + options: [ + { + tag: "div", + attr: "role", + message: "Div elements should have a role attribute", + }, + ], + errors: [ + { + line: 1, + column: 6, + message: "Div elements should have a role attribute", + }, + ], + }, ], }); From b66705a4f35de9441487029da04c4e4972406baf Mon Sep 17 00:00:00 2001 From: YeonJuan Date: Sat, 9 Aug 2025 23:18:33 +0900 Subject: [PATCH 2/2] Update require-attrs.js --- packages/eslint-plugin/lib/rules/require-attrs.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/eslint-plugin/lib/rules/require-attrs.js b/packages/eslint-plugin/lib/rules/require-attrs.js index 405d4003..cab47fc3 100644 --- a/packages/eslint-plugin/lib/rules/require-attrs.js +++ b/packages/eslint-plugin/lib/rules/require-attrs.js @@ -18,7 +18,6 @@ const { getRuleUrl } = require("./utils/rule"); const MESSAGE_IDS = { MISSING: "missing", UNEXPECTED: "unexpected", - CUSTOM: "custom", }; /**