Skip to content

Commit 028b6eb

Browse files
committed
forbid-component-props: add component whitelist
1 parent a5f259f commit 028b6eb

File tree

2 files changed

+55
-8
lines changed

2 files changed

+55
-8
lines changed

lib/rules/forbid-component-props.js

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,20 +31,40 @@ module.exports = {
3131
forbid: {
3232
type: 'array',
3333
items: {
34-
type: 'string'
34+
oneOf: [{
35+
type: 'string'
36+
}, {
37+
type: 'object',
38+
properties: {
39+
propName: {
40+
type: 'string'
41+
},
42+
allowedFor: {
43+
type: 'array',
44+
items: {
45+
type: 'string'
46+
}
47+
}
48+
}
49+
}]
3550
}
3651
}
37-
},
38-
additionalProperties: true
52+
}
3953
}]
4054
},
4155

4256
create: function(context) {
43-
function isForbidden(prop) {
44-
const configuration = context.options[0] || {};
57+
const configuration = context.options[0] || {};
58+
const forbid = new Map((configuration.forbid || DEFAULTS).map((value) => {
59+
const propName = (typeof value === 'string') ? value : value.propName;
60+
const whitelist = (typeof value === 'string') ? [] : (value.allowedFor || []);
61+
return [propName, whitelist];
62+
}));
4563

46-
const forbid = configuration.forbid || DEFAULTS;
47-
return forbid.indexOf(prop) >= 0;
64+
function isForbidden(prop, tagName) {
65+
const whitelist = forbid.get(prop);
66+
// if the tagName is undefined (`<this.something>`), we assume it's a forbidden element
67+
return typeof whitelist !== 'undefined' && (typeof tagName === 'undefined' || !whitelist.includes(tagName));
4868
}
4969

5070
return {
@@ -57,7 +77,7 @@ module.exports = {
5777

5878
const prop = node.name.name;
5979

60-
if (!isForbidden(prop)) {
80+
if (!isForbidden(prop, tag)) {
6181
return;
6282
}
6383

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

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,11 @@ ruleTester.run('forbid-component-props', rule, {
101101
' <this.Foo {...props} />',
102102
');'
103103
].join('\n')
104+
}, {
105+
code: 'const item = (<ReactModal className="foo" />);',
106+
options: [{
107+
forbid: [{propName: 'className', allowedFor: ['ReactModal']}]
108+
}]
104109
}],
105110

106111
invalid: [{
@@ -165,5 +170,27 @@ ruleTester.run('forbid-component-props', rule, {
165170
column: 17,
166171
type: 'JSXAttribute'
167172
}]
173+
}, {
174+
code: 'const item = (<Foo className="foo" />);',
175+
options: [{
176+
forbid: [{propName: 'className', allowedFor: ['ReactModal']}]
177+
}],
178+
errors: [{
179+
message: CLASSNAME_ERROR_MESSAGE,
180+
line: 1,
181+
column: 20,
182+
type: 'JSXAttribute'
183+
}]
184+
}, {
185+
code: 'const item = (<this.ReactModal className="foo" />);',
186+
options: [{
187+
forbid: [{propName: 'className', allowedFor: ['ReactModal']}]
188+
}],
189+
errors: [{
190+
message: CLASSNAME_ERROR_MESSAGE,
191+
line: 1,
192+
column: 32,
193+
type: 'JSXAttribute'
194+
}]
168195
}]
169196
});

0 commit comments

Comments
 (0)