From 2ab345581b4faad16f894f0bbf8c1146a4bb5669 Mon Sep 17 00:00:00 2001 From: Shayan Zamani Date: Mon, 2 Jun 2025 02:06:24 +0330 Subject: [PATCH 1/2] feat(no-restricted-html-elements): support array of elements --- docs/rules/no-restricted-html-elements.md | 18 ++++++------- lib/rules/no-restricted-html-elements.js | 16 ++++++++--- .../lib/rules/no-restricted-html-elements.js | 27 +++++++++++++++++++ 3 files changed, 49 insertions(+), 12 deletions(-) diff --git a/docs/rules/no-restricted-html-elements.md b/docs/rules/no-restricted-html-elements.md index 2a6d6c997..fef08aeb2 100644 --- a/docs/rules/no-restricted-html-elements.md +++ b/docs/rules/no-restricted-html-elements.md @@ -37,16 +37,16 @@ This rule takes a list of strings, where each string is an HTML element name to ```json { - "vue/no-restricted-html-elements": ["error", "button", "marquee"] + "vue/no-restricted-html-elements": ["error", "a", "marquee"] } ``` - + ```vue ``` @@ -60,8 +60,8 @@ Alternatively, the rule also accepts objects. "vue/no-restricted-html-elements": [ "error", { - "element": "button", - "message": "Prefer use of our custom component" + "element": ["a", "RouterLink"], + "message": "Prefer the use of component" }, { "element": "marquee", @@ -73,18 +73,18 @@ Alternatively, the rule also accepts objects. The following properties can be specified for the object. -- `element` ... Specify the html element. +- `element` ... Specify the HTML element or an array of HTML elements. - `message` ... Specify an optional custom message. -### `{ "element": "marquee" }, { "element": "button" }` +### `{ "element": "marquee" }, { "element": "a" }` - + ```vue ``` diff --git a/lib/rules/no-restricted-html-elements.js b/lib/rules/no-restricted-html-elements.js index e906d86f2..8d5f3c300 100644 --- a/lib/rules/no-restricted-html-elements.js +++ b/lib/rules/no-restricted-html-elements.js @@ -23,7 +23,12 @@ module.exports = { { type: 'object', properties: { - element: { type: 'string' }, + element: { + oneOf: [ + { type: 'string' }, + { type: 'array', items: { type: 'string' } } + ] + }, message: { type: 'string', minLength: 1 } }, required: ['element'], @@ -55,9 +60,12 @@ module.exports = { } for (const option of context.options) { - const element = option.element || option + const restrictedItem = option.element || option + const elementsToRestrict = Array.isArray(restrictedItem) + ? restrictedItem + : [restrictedItem] - if (element === node.rawName) { + if (elementsToRestrict.includes(node.rawName)) { context.report({ messageId: option.message ? 'customMessage' : 'forbiddenElement', data: { @@ -66,6 +74,8 @@ module.exports = { }, node: node.startTag }) + + return } } } diff --git a/tests/lib/rules/no-restricted-html-elements.js b/tests/lib/rules/no-restricted-html-elements.js index c3e3e9eeb..6180b046b 100644 --- a/tests/lib/rules/no-restricted-html-elements.js +++ b/tests/lib/rules/no-restricted-html-elements.js @@ -31,6 +31,11 @@ tester.run('no-restricted-html-elements', rule, { filename: 'test.vue', code: '', options: ['button'] + }, + { + filename: 'test.vue', + code: '', + options: [{ element: ['div', 'span'] }] } ], invalid: [ @@ -69,6 +74,28 @@ tester.run('no-restricted-html-elements', rule, { column: 11 } ] + }, + { + filename: 'test.vue', + code: '', + options: [ + { + element: ['a', 'RouterLink'], + message: 'Prefer the use of component' + } + ], + errors: [ + { + message: 'Prefer the use of component', + line: 1, + column: 11 + }, + { + message: 'Prefer the use of component', + line: 1, + column: 18 + } + ] } ] }) From aeb51f668aa8f3e3426da3d835b997fa358ce22a Mon Sep 17 00:00:00 2001 From: Shayan Zamani Date: Mon, 2 Jun 2025 02:26:55 +0330 Subject: [PATCH 2/2] chore: add changeset --- .changeset/crazy-impalas-pick.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/crazy-impalas-pick.md diff --git a/.changeset/crazy-impalas-pick.md b/.changeset/crazy-impalas-pick.md new file mode 100644 index 000000000..834a6ec8f --- /dev/null +++ b/.changeset/crazy-impalas-pick.md @@ -0,0 +1,5 @@ +--- +'eslint-plugin-vue': minor +--- + +[vue/no-restricted-html-elements](https://eslint.vuejs.org/rules/no-restricted-html-elements.html) now accepts multiple elements in each entry.