Skip to content

Commit fc95cd3

Browse files
committed
Add option to sort shorthand properties on jsx-sort-props
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 ```
1 parent 1bd8c89 commit fc95cd3

File tree

3 files changed

+41
-2
lines changed

3 files changed

+41
-2
lines changed

docs/rules/jsx-sort-props.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ The following patterns are considered okay and do not cause warnings:
2626
...
2727
"jsx-sort-props": [<enabled>, {
2828
"callbacksLast": <boolean>,
29+
"shorthandFirst": <boolean>,
2930
"ignoreCase": <boolean>
3031
}]
3132
...
@@ -49,6 +50,14 @@ When `true`, callbacks must be listed after all other props:
4950
<Hello tel={5555555} onClick={this._handleClick} />
5051
```
5152

53+
### `shorthandFirst`
54+
55+
When `true`, short hand props must be listed before all other props, but still respecting the alphabetical order:
56+
57+
```js
58+
<Hello active validate name="John" tel={5555555} />
59+
```
60+
5261
## When not to use
5362

5463
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.

lib/rules/jsx-sort-props.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ module.exports = function(context) {
1717
var configuration = context.options[0] || {};
1818
var ignoreCase = configuration.ignoreCase || false;
1919
var callbacksLast = configuration.callbacksLast || false;
20+
var shorthandFirst = configuration.shorthandFirst || false;
2021

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

2829
var previousPropName = memo.name.name;
2930
var currentPropName = decl.name.name;
31+
var previousValue = memo.value;
32+
var currentValue = decl.value;
3033
var previousIsCallback = isCallbackPropName(previousPropName);
3134
var currentIsCallback = isCallbackPropName(currentPropName);
3235

@@ -47,6 +50,16 @@ module.exports = function(context) {
4750
}
4851
}
4952

53+
if (shorthandFirst) {
54+
if (currentValue && !previousValue) {
55+
return decl;
56+
}
57+
if (!currentValue && previousValue) {
58+
context.report(memo, 'Shorthand props must be listed before all other props');
59+
return memo;
60+
}
61+
}
62+
5063
if (currentPropName < previousPropName) {
5164
context.report(decl, 'Props should be sorted alphabetically');
5265
return memo;
@@ -66,6 +79,10 @@ module.exports.schema = [{
6679
callbacksLast: {
6780
type: 'boolean'
6881
},
82+
// Whether shorthand properties (without a value) should be listed first
83+
shorthandFirst: {
84+
type: 'boolean'
85+
},
6986
ignoreCase: {
7087
type: 'boolean'
7188
}

tests/lib/rules/jsx-sort-props.js

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,16 @@ var expectedCallbackError = {
2626
message: 'Callbacks must be listed after all other props',
2727
type: 'JSXAttribute'
2828
};
29+
var expectedShorthandError = {
30+
message: 'Shorthand props must be listed before all other props',
31+
type: 'JSXAttribute'
32+
};
2933
var callbacksLastArgs = [{
3034
callbacksLast: true
3135
}];
36+
var shorthandFirstArgs = [{
37+
shorthandFirst: true
38+
}];
3239
var ignoreCaseArgs = [{
3340
ignoreCase: true
3441
}];
@@ -52,7 +59,11 @@ ruleTester.run('jsx-sort-props', rule, {
5259
{code: '<App a B c />;', options: ignoreCaseArgs, ecmaFeatures: features},
5360
{code: '<App A b C />;', options: ignoreCaseArgs, ecmaFeatures: features},
5461
// Sorting callbacks below all other props
55-
{code: '<App a z onBar onFoo />;', options: callbacksLastArgs, ecmaFeatures: features}
62+
{code: '<App a z onBar onFoo />;', options: callbacksLastArgs, ecmaFeatures: features},
63+
// Sorting shorthand props before others
64+
{code: '<App a b="b" />;', options: shorthandFirstArgs, ecmaFeatures: features},
65+
{code: '<App z a="a" />;', options: shorthandFirstArgs, ecmaFeatures: features},
66+
{code: '<App x y z a="a" b="b" />;', options: shorthandFirstArgs, ecmaFeatures: features}
5667
],
5768
invalid: [
5869
{code: '<App b a />;', errors: [expectedError], ecmaFeatures: features},
@@ -70,6 +81,8 @@ ruleTester.run('jsx-sort-props', rule, {
7081
errors: [expectedCallbackError],
7182
options: callbacksLastArgs,
7283
ecmaFeatures: features
73-
}
84+
},
85+
{code: '<App a="a" b />;', errors: [expectedShorthandError], options: shorthandFirstArgs, ecmaFeatures: features},
86+
{code: '<App z x a="a" />;', errors: [expectedError], options: shorthandFirstArgs, ecmaFeatures: features}
7487
]
7588
});

0 commit comments

Comments
 (0)