Skip to content

Commit

Permalink
Add option to sort shorthand properties on jsx-sort-props
Browse files Browse the repository at this point in the history
You can now require that shorthand props should come before
all other props, but still respecting the alphabetical order.

The following are valid situations:
```
<Component a b="b" />
<Component x z a="a" b="b" />
```

And the following are invalid:
```
<Component z x a="a" b="b" /> // should be in alphabetical order
<Component x z b="b" a="a" /> // should be in alphabetical order
<Component a="a" b="b" x z /> // shorthand props should be at the start
```
  • Loading branch information
lucasmotta committed Nov 27, 2015
1 parent 1bd8c89 commit fc95cd3
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 2 deletions.
9 changes: 9 additions & 0 deletions docs/rules/jsx-sort-props.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ The following patterns are considered okay and do not cause warnings:
...
"jsx-sort-props": [<enabled>, {
"callbacksLast": <boolean>,
"shorthandFirst": <boolean>,
"ignoreCase": <boolean>
}]
...
Expand All @@ -49,6 +50,14 @@ When `true`, callbacks must be listed after all other props:
<Hello tel={5555555} onClick={this._handleClick} />
```

### `shorthandFirst`

When `true`, short hand props must be listed before all other props, but still respecting the alphabetical order:

```js
<Hello active validate name="John" tel={5555555} />
```

## 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 isn't a part of your coding standards, then you can leave this rule off.
17 changes: 17 additions & 0 deletions lib/rules/jsx-sort-props.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ module.exports = function(context) {
var configuration = context.options[0] || {};
var ignoreCase = configuration.ignoreCase || false;
var callbacksLast = configuration.callbacksLast || false;
var shorthandFirst = configuration.shorthandFirst || false;

return {
JSXOpeningElement: function(node) {
Expand All @@ -27,6 +28,8 @@ module.exports = function(context) {

var previousPropName = memo.name.name;
var currentPropName = decl.name.name;
var previousValue = memo.value;
var currentValue = decl.value;
var previousIsCallback = isCallbackPropName(previousPropName);
var currentIsCallback = isCallbackPropName(currentPropName);

Expand All @@ -47,6 +50,16 @@ module.exports = function(context) {
}
}

if (shorthandFirst) {
if (currentValue && !previousValue) {
return decl;
}
if (!currentValue && previousValue) {
context.report(memo, 'Shorthand props must be listed before all other props');
return memo;
}
}

if (currentPropName < previousPropName) {
context.report(decl, 'Props should be sorted alphabetically');
return memo;
Expand All @@ -66,6 +79,10 @@ module.exports.schema = [{
callbacksLast: {
type: 'boolean'
},
// Whether shorthand properties (without a value) should be listed first
shorthandFirst: {
type: 'boolean'
},
ignoreCase: {
type: 'boolean'
}
Expand Down
17 changes: 15 additions & 2 deletions tests/lib/rules/jsx-sort-props.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,16 @@ var expectedCallbackError = {
message: 'Callbacks must be listed after all other props',
type: 'JSXAttribute'
};
var expectedShorthandError = {
message: 'Shorthand props must be listed before all other props',
type: 'JSXAttribute'
};
var callbacksLastArgs = [{
callbacksLast: true
}];
var shorthandFirstArgs = [{
shorthandFirst: true
}];
var ignoreCaseArgs = [{
ignoreCase: true
}];
Expand All @@ -52,7 +59,11 @@ ruleTester.run('jsx-sort-props', rule, {
{code: '<App a B c />;', options: ignoreCaseArgs, ecmaFeatures: features},
{code: '<App A b C />;', options: ignoreCaseArgs, ecmaFeatures: features},
// Sorting callbacks below all other props
{code: '<App a z onBar onFoo />;', options: callbacksLastArgs, ecmaFeatures: features}
{code: '<App a z onBar onFoo />;', options: callbacksLastArgs, ecmaFeatures: features},
// Sorting shorthand props before others
{code: '<App a b="b" />;', options: shorthandFirstArgs, ecmaFeatures: features},
{code: '<App z a="a" />;', options: shorthandFirstArgs, ecmaFeatures: features},
{code: '<App x y z a="a" b="b" />;', options: shorthandFirstArgs, ecmaFeatures: features}
],
invalid: [
{code: '<App b a />;', errors: [expectedError], ecmaFeatures: features},
Expand All @@ -70,6 +81,8 @@ ruleTester.run('jsx-sort-props', rule, {
errors: [expectedCallbackError],
options: callbacksLastArgs,
ecmaFeatures: features
}
},
{code: '<App a="a" b />;', errors: [expectedShorthandError], options: shorthandFirstArgs, ecmaFeatures: features},
{code: '<App z x a="a" />;', errors: [expectedError], options: shorthandFirstArgs, ecmaFeatures: features}
]
});

0 comments on commit fc95cd3

Please sign in to comment.