Skip to content

Commit 94e98f5

Browse files
committed
Add option "disallowedFor" for dom element prop
1 parent bdbd2a4 commit 94e98f5

File tree

4 files changed

+109
-5
lines changed

4 files changed

+109
-5
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
66
## Unreleased
77

88
### Added
9+
* [`forbid-dom-props`]: add `disallowedFor` option ([#3338][] @TildaDares)
910
* [`jsx-newline`]: add `allowMultiline` option when prevent option is true ([#3311][] @TildaDares)
1011

1112
### Fixed
@@ -21,6 +22,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
2122
* [Tests] [`jsx-indent`], [`jsx-one-expression-per-line`]: add passing test cases ([#3314][] @ROSSROSALES)
2223
* [Refactor] `boolean-prop-naming`, `jsx-indent`: avoid assigning to arguments ([#3316][] @caroline223)
2324

25+
[#3338]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3338
2426
[#3331]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3331
2527
[#3328]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3328
2628
[#3327]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3327

docs/rules/forbid-dom-props.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,13 @@ Examples of **correct** code for this rule:
4343
### `forbid`
4444

4545
An array of strings, with the names of props that are forbidden. The default value of this option `[]`.
46-
Each array element can either be a string with the property name or object specifying the property name and an optional
47-
custom message:
46+
Each array element can either be a string with the property name or object specifying the property name, an optional
47+
custom message, and a DOM nodes blacklist(e.g. `<div />`):
4848

4949
```js
5050
{
5151
"propName": "someProp",
52+
"disallowedFor": [DOMNode, AnotherDOMNode],
5253
"message": "Avoid using someProp"
5354
}
5455
```

lib/rules/forbid-dom-props.js

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,13 @@ module.exports = {
4747
propName: {
4848
type: 'string',
4949
},
50+
disallowedFor: {
51+
type: 'array',
52+
uniqueItems: true,
53+
items: {
54+
type: 'string',
55+
},
56+
},
5057
message: {
5158
type: 'string',
5259
},
@@ -66,13 +73,20 @@ module.exports = {
6673
const forbid = new Map((configuration.forbid || DEFAULTS).map((value) => {
6774
const propName = typeof value === 'string' ? value : value.propName;
6875
const options = {
76+
disallowList: typeof value === 'string' ? [] : (value.disallowedFor || []),
6977
message: typeof value === 'string' ? null : value.message,
7078
};
7179
return [propName, options];
7280
}));
7381

74-
function isForbidden(prop) {
75-
return forbid.has(prop);
82+
function isForbidden(prop, tagName) {
83+
const options = forbid.get(prop);
84+
const disallowList = options ? options.disallowList : undefined;
85+
return typeof disallowList !== 'undefined'
86+
&& (typeof tagName === 'undefined'
87+
|| disallowList.length === 0
88+
|| (disallowList.length > 0
89+
&& disallowList.indexOf(tagName) !== -1));
7690
}
7791

7892
return {
@@ -85,7 +99,7 @@ module.exports = {
8599

86100
const prop = node.name.name;
87101

88-
if (!isForbidden(prop)) {
102+
if (!isForbidden(prop, tag)) {
89103
return;
90104
}
91105

tests/lib/rules/forbid-dom-props.js

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,23 @@ ruleTester.run('forbid-dom-props', rule, {
9595
`,
9696
options: [{ forbid: ['id'] }],
9797
},
98+
{
99+
code: `
100+
const First = (props) => (
101+
<div otherProp="bar" />
102+
);
103+
`,
104+
options: [
105+
{
106+
forbid: [
107+
{
108+
propName: 'otherProp',
109+
disallowedFor: ['span'],
110+
},
111+
],
112+
},
113+
],
114+
},
98115
]),
99116

100117
invalid: parsers.all([
@@ -237,5 +254,75 @@ ruleTester.run('forbid-dom-props', rule, {
237254
},
238255
],
239256
},
257+
{
258+
code: `
259+
const First = (props) => (
260+
<form accept='file'>
261+
<input type="file" id="videoFile" accept="video/*" />
262+
<input type="hidden" name="fullname" />
263+
</form>
264+
);
265+
`,
266+
options: [
267+
{
268+
forbid: [{
269+
propName: 'accept',
270+
disallowedFor: ['form'],
271+
message: 'Avoid using the accept attribute on <form>',
272+
}],
273+
},
274+
],
275+
errors: [
276+
{
277+
message: 'Avoid using the accept attribute on <form>',
278+
line: 3,
279+
column: 17,
280+
type: 'JSXAttribute',
281+
},
282+
],
283+
},
284+
{
285+
code: `
286+
const First = (props) => (
287+
<div className="foo">
288+
<input className="boo" />
289+
<span className="foobar">Foobar</span>
290+
<div otherProp="bar" />
291+
</div>
292+
);
293+
`,
294+
options: [
295+
{
296+
forbid: [
297+
{
298+
propName: 'className',
299+
disallowedFor: ['div', 'span'],
300+
message: 'Please use class instead of ClassName',
301+
},
302+
{ propName: 'otherProp', message: 'Avoid using otherProp' },
303+
],
304+
},
305+
],
306+
errors: [
307+
{
308+
message: 'Please use class instead of ClassName',
309+
line: 3,
310+
column: 16,
311+
type: 'JSXAttribute',
312+
},
313+
{
314+
message: 'Please use class instead of ClassName',
315+
line: 5,
316+
column: 19,
317+
type: 'JSXAttribute',
318+
},
319+
{
320+
message: 'Avoid using otherProp',
321+
line: 6,
322+
column: 18,
323+
type: 'JSXAttribute',
324+
},
325+
],
326+
},
240327
]),
241328
});

0 commit comments

Comments
 (0)