-
-
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.
Merge pull request #72 from AlexKVal/38_sort_propTypes
Add jsx-sort-prop-types rule (fixes #38)
- Loading branch information
Showing
5 changed files
with
509 additions
and
1 deletion.
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,91 @@ | ||
# Enforce propTypes declarations alphabetical sorting (jsx-sort-prop-types) | ||
|
||
Some developers prefer to sort propsTypes declarations alphabetically to be able to find necessary declaration easier at the later time. Others feel that it adds complexity and becomes burden to maintain. | ||
|
||
## Rule Details | ||
|
||
This rule checks all JSX components and verifies that all propsTypes declarations are sorted alphabetically. | ||
The default configuration of the rule is case-sensitive. | ||
This rule is off by default. | ||
|
||
The following patterns are considered warnings: | ||
|
||
```js | ||
var Component = React.createClass({ | ||
propTypes: { | ||
z: React.PropTypes.number, | ||
a: React.PropTypes.any, | ||
b: React.PropTypes.string | ||
}, | ||
... | ||
}); | ||
|
||
class Component extends React.Component { | ||
... | ||
} | ||
Component.propTypes = { | ||
z: React.PropTypes.number, | ||
a: React.PropTypes.any, | ||
b: React.PropTypes.string | ||
}; | ||
|
||
class Component extends React.Component { | ||
static propTypes = { | ||
z: React.PropTypes.any, | ||
y: React.PropTypes.any, | ||
a: React.PropTypes.any | ||
} | ||
render() { | ||
return <div />; | ||
} | ||
} | ||
``` | ||
|
||
The following patterns are considered okay and do not cause warnings: | ||
|
||
```js | ||
var Component = React.createClass({ | ||
propTypes: { | ||
a: React.PropTypes.number, | ||
b: React.PropTypes.any, | ||
c: React.PropTypes.string | ||
}, | ||
... | ||
}); | ||
|
||
class Component extends React.Component { | ||
... | ||
} | ||
Component.propTypes = { | ||
a: React.PropTypes.string, | ||
b: React.PropTypes.any, | ||
c: React.PropTypes.string | ||
}; | ||
|
||
class Component extends React.Component { | ||
static propTypes = { | ||
a: React.PropTypes.any, | ||
b: React.PropTypes.any, | ||
c: React.PropTypes.any | ||
} | ||
render() { | ||
return <div />; | ||
} | ||
} | ||
``` | ||
|
||
## Rule Options | ||
|
||
```js | ||
... | ||
"jsx-sort-prop-types": [<enabled>, { "ignoreCase": <boolean> }] | ||
... | ||
``` | ||
|
||
### `ignoreCase` | ||
|
||
When `true` the rule ignores the case-sensitivity of the declarations order. | ||
|
||
## When not to use | ||
|
||
This rule is a formatting preference and not following it won't negatively affect the quality of your code. If alphabetizing props declarations isn't a part of your coding standards, then you can leave this rule off. |
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,90 @@ | ||
/** | ||
* @fileoverview Enforce propTypes declarations alphabetical sorting | ||
*/ | ||
'use strict'; | ||
|
||
// ------------------------------------------------------------------------------ | ||
// Rule Definition | ||
// ------------------------------------------------------------------------------ | ||
|
||
module.exports = function(context) { | ||
|
||
var configuration = context.options[0] || {}; | ||
var ignoreCase = configuration.ignoreCase || false; | ||
|
||
/** | ||
* Checks if node is `propTypes` declaration | ||
* @param {ASTNode} node The AST node being checked. | ||
* @returns {Boolean} True if node is `propTypes` declaration, false if not. | ||
*/ | ||
function isPropTypesDeclaration(node) { | ||
|
||
// Special case for class properties | ||
// (babel-eslint does not expose property name so we have to rely on tokens) | ||
if (node.type === 'ClassProperty') { | ||
var tokens = context.getFirstTokens(node, 2); | ||
if (tokens[0].value === 'propTypes' || tokens[1].value === 'propTypes') { | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
return Boolean( | ||
node && | ||
node.name === 'propTypes' | ||
); | ||
} | ||
|
||
/** | ||
* Checks if propTypes declarations are sorted | ||
* @param {Array} declarations The array of AST nodes being checked. | ||
* @returns {void} | ||
*/ | ||
function checkSorted(declarations) { | ||
declarations.reduce(function(prev, curr) { | ||
var prevPropName = prev.key.name; | ||
var currenPropName = curr.key.name; | ||
|
||
if (ignoreCase) { | ||
prevPropName = prevPropName.toLowerCase(); | ||
currenPropName = currenPropName.toLowerCase(); | ||
} | ||
|
||
if (currenPropName < prevPropName) { | ||
context.report(curr, 'Prop types declarations should be sorted alphabetically'); | ||
return prev; | ||
} | ||
|
||
return curr; | ||
}, declarations[0]); | ||
} | ||
|
||
return { | ||
ClassProperty: function(node) { | ||
if (isPropTypesDeclaration(node) && node.value.type === 'ObjectExpression') { | ||
checkSorted(node.value.properties); | ||
} | ||
}, | ||
|
||
MemberExpression: function(node) { | ||
if (isPropTypesDeclaration(node.property)) { | ||
var right = node.parent.right; | ||
if (right && right.type === 'ObjectExpression') { | ||
checkSorted(right.properties); | ||
} | ||
} | ||
}, | ||
|
||
ObjectExpression: function(node) { | ||
node.properties.forEach(function(property) { | ||
if (!isPropTypesDeclaration(property.key)) { | ||
return; | ||
} | ||
if (property.value.type === 'ObjectExpression') { | ||
checkSorted(property.value.properties); | ||
} | ||
}); | ||
} | ||
|
||
}; | ||
}; |
Oops, something went wrong.