-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
A new rule forbid-dom-props was added. It is based on forbid-component-props but it only forbid property on DOM Node elements. This can be useful to enforce some good practices, as not using 'id' attributes or inline styles.
- Loading branch information
Showing
5 changed files
with
219 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# Forbid certain props on DOM Nodes (react/forbid-dom-props) | ||
|
||
This rule prevents passing of props to elements. This rule only applies to DOM Nodes (e.g. `<div />`) and not Components (e.g. `<Component />`). | ||
The list of forbidden props can be customized with the `forbid` option. | ||
|
||
## Rule Details | ||
|
||
This rule checks all JSX elements and verifies that no forbidden props are used | ||
on DOM Nodes. This rule is off by default. | ||
|
||
The following patterns are considered warnings: | ||
|
||
```jsx | ||
// [1, { "forbid": ["id"] }] | ||
<div id='Joe' /> | ||
``` | ||
|
||
```jsx | ||
// [1, { "forbid": ["style"] }] | ||
<div style={{color: 'red'}} /> | ||
``` | ||
|
||
The following patterns are **not** considered warnings: | ||
|
||
```jsx | ||
// [1, { "forbid": ["id"] }] | ||
<Hello id='foo' /> | ||
``` | ||
|
||
```jsx | ||
// [1, { "forbid": ["id"] }] | ||
<Hello id={{color: 'red'}} /> | ||
``` | ||
|
||
## Rule Options | ||
|
||
```js | ||
... | ||
"react/forbid-dom-props": [<enabled>, { "forbid": [<string>] }] | ||
... | ||
``` | ||
|
||
### `forbid` | ||
|
||
An array of strings, with the names of props that are forbidden. The default value of this option `[]`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
/** | ||
* @fileoverview Forbid certain props on DOM Nodes | ||
* @author David Vázquez | ||
*/ | ||
'use strict'; | ||
|
||
// ------------------------------------------------------------------------------ | ||
// Constants | ||
// ------------------------------------------------------------------------------ | ||
|
||
const DEFAULTS = []; | ||
|
||
// ------------------------------------------------------------------------------ | ||
// Rule Definition | ||
// ------------------------------------------------------------------------------ | ||
|
||
module.exports = { | ||
meta: { | ||
docs: { | ||
description: 'Forbid certain props on DOM Nodes', | ||
category: 'Best Practices', | ||
recommended: false | ||
}, | ||
|
||
schema: [{ | ||
type: 'object', | ||
properties: { | ||
forbid: { | ||
type: 'array', | ||
items: { | ||
type: 'string' | ||
} | ||
} | ||
}, | ||
additionalProperties: true | ||
}] | ||
}, | ||
|
||
create: function(context) { | ||
function isForbidden(prop) { | ||
const configuration = context.options[0] || {}; | ||
|
||
const forbid = configuration.forbid || DEFAULTS; | ||
return forbid.indexOf(prop) >= 0; | ||
} | ||
|
||
return { | ||
JSXAttribute: function(node) { | ||
const tag = node.parent.name.name; | ||
if (!(tag && tag[0] !== tag[0].toUpperCase())) { | ||
// This is a Component, not a DOM node, so exit. | ||
return; | ||
} | ||
|
||
const prop = node.name.name; | ||
|
||
if (!isForbidden(prop)) { | ||
return; | ||
} | ||
|
||
context.report({ | ||
node: node, | ||
message: `Prop \`${prop}\` is forbidden on DOM Nodes` | ||
}); | ||
} | ||
}; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
/** | ||
* @fileoverview Tests for forbid-dom-props | ||
*/ | ||
'use strict'; | ||
|
||
// ----------------------------------------------------------------------------- | ||
// Requirements | ||
// ----------------------------------------------------------------------------- | ||
|
||
const rule = require('../../../lib/rules/forbid-dom-props'); | ||
const RuleTester = require('eslint').RuleTester; | ||
|
||
const parserOptions = { | ||
ecmaVersion: 8, | ||
sourceType: 'module', | ||
ecmaFeatures: { | ||
experimentalObjectRestSpread: true, | ||
jsx: true | ||
} | ||
}; | ||
|
||
require('babel-eslint'); | ||
|
||
// ----------------------------------------------------------------------------- | ||
// Tests | ||
// ----------------------------------------------------------------------------- | ||
|
||
const ID_ERROR_MESSAGE = 'Prop `id` is forbidden on DOM Nodes'; | ||
|
||
const ruleTester = new RuleTester({parserOptions}); | ||
ruleTester.run('forbid-element-props', rule, { | ||
|
||
valid: [{ | ||
code: [ | ||
'var First = createReactClass({', | ||
' render: function() {', | ||
' return <Foo id="foo" />;', | ||
' }', | ||
'});' | ||
].join('\n'), | ||
options: [{forbid: ['id']}] | ||
}, { | ||
code: [ | ||
'var First = createReactClass({', | ||
' propTypes: externalPropTypes,', | ||
' render: function() {', | ||
' return <Foo id="bar" style={{color: "red"}} />;', | ||
' }', | ||
'});' | ||
].join('\n'), | ||
options: [{forbid: ['style', 'id']}] | ||
}, { | ||
code: [ | ||
'var First = createReactClass({', | ||
' propTypes: externalPropTypes,', | ||
' render: function() {', | ||
' return <this.Foo bar="baz" />;', | ||
' }', | ||
'});' | ||
].join('\n'), | ||
options: [{forbid: ['id']}] | ||
}, { | ||
code: [ | ||
'class First extends createReactClass {', | ||
' render() {', | ||
' return <this.foo id="bar" />;', | ||
' }', | ||
'}' | ||
].join('\n'), | ||
options: [{forbid: ['id']}] | ||
}, { | ||
code: [ | ||
'const First = (props) => (', | ||
' <this.Foo {...props} />', | ||
');' | ||
].join('\n'), | ||
options: [{forbid: ['id']}] | ||
}, { | ||
code: [ | ||
'const First = (props) => (', | ||
' <div name="foo" />', | ||
');' | ||
].join('\n'), | ||
options: [{forbid: ['id']}] | ||
}], | ||
|
||
invalid: [{ | ||
code: [ | ||
'var First = createReactClass({', | ||
' propTypes: externalPropTypes,', | ||
' render: function() {', | ||
' return <div id="bar" />;', | ||
' }', | ||
'});' | ||
].join('\n'), | ||
options: [{forbid: ['id']}], | ||
errors: [{ | ||
message: ID_ERROR_MESSAGE, | ||
line: 4, | ||
column: 17, | ||
type: 'JSXAttribute' | ||
}] | ||
}] | ||
}); |