Skip to content

Commit bd20a79

Browse files
committed
jsx-max-props-per-line: Fix when prop spans multiple lines
In this patch we now consider props to be on the same "line" if the line of where one prop ends matches the line of where the next prop begins. e.g. ``` <App foo={{ }} bar /> ``` `foo` and `bar` are now considered to be on the same line. Previously, we would only look at the line in which the prop begins.
1 parent 30e0206 commit bd20a79

File tree

3 files changed

+40
-18
lines changed

3 files changed

+40
-18
lines changed

docs/rules/jsx-max-props-per-line.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,16 @@ Limiting the maximum of props on a single line can improve readability.
44

55
## Rule Details
66

7-
This rule checks all JSX elements and verifies that the number of props per line do not exceed the maximum allowed. A spread attribute counts as one prop. This rule is off by default and when on the default maximum of props on one line is `1`.
7+
This rule checks all JSX elements and verifies that the number of props per line do not exceed the maximum allowed. Props are considered to be in a new line if there is a line break between the start of the prop and the end of the previous prop. A spread attribute counts as one prop. This rule is off by default and when on the default maximum of props on one line is `1`.
88

99
The following patterns are considered warnings:
1010

1111
```jsx
1212
<Hello lastName="Smith" firstName="John" />;
13+
14+
<Hello foo={{
15+
bar
16+
}} baz />;
1317
```
1418

1519
The following patterns are not considered warnings:

lib/rules/jsx-max-props-per-line.js

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55

66
'use strict';
77

8-
var has = require('has');
9-
108
// ------------------------------------------------------------------------------
119
// Rule Definition
1210
// ------------------------------------------------------------------------------
@@ -45,30 +43,31 @@ module.exports = {
4543

4644
return {
4745
JSXOpeningElement: function (node) {
48-
var props = {};
46+
if (!node.attributes.length) {
47+
return;
48+
}
49+
50+
var firstProp = node.attributes[0];
51+
var linePartitionedProps = [[firstProp]];
4952

50-
node.attributes.forEach(function(decl) {
51-
var line = decl.loc.start.line;
52-
if (props[line]) {
53-
props[line].push(decl);
53+
node.attributes.reduce(function(last, decl) {
54+
if (last.loc.end.line === decl.loc.start.line) {
55+
linePartitionedProps[linePartitionedProps.length - 1].push(decl);
5456
} else {
55-
props[line] = [decl];
57+
linePartitionedProps.push([decl]);
5658
}
59+
return decl;
5760
});
5861

59-
for (var line in props) {
60-
if (!has(props, line)) {
61-
continue;
62-
}
63-
if (props[line].length > maximum) {
64-
var name = getPropName(props[line][maximum]);
62+
linePartitionedProps.forEach(function(propsInLine) {
63+
if (propsInLine.length > maximum) {
64+
var name = getPropName(propsInLine[maximum]);
6565
context.report({
66-
node: props[line][maximum],
66+
node: propsInLine[maximum],
6767
message: 'Prop `' + name + '` must be placed on a new line'
6868
});
69-
break;
7069
}
71-
}
70+
});
7271
}
7372
};
7473
}

tests/lib/rules/jsx-max-props-per-line.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,5 +89,24 @@ ruleTester.run('jsx-max-props-per-line', rule, {
8989
].join('\n'),
9090
errors: [{message: 'Prop `this.props` must be placed on a new line'}],
9191
parserOptions: parserOptions
92+
}, {
93+
code: [
94+
'<App',
95+
' foo={{',
96+
' }} bar',
97+
'/>'
98+
].join('\n'),
99+
errors: [{message: 'Prop `bar` must be placed on a new line'}],
100+
parserOptions: parserOptions
101+
}, {
102+
code: [
103+
'<App',
104+
' foo={{',
105+
' }} bar baz',
106+
'/>'
107+
].join('\n'),
108+
options: [{maximum: 2}],
109+
errors: [{message: 'Prop `baz` must be placed on a new line'}],
110+
parserOptions: parserOptions
92111
}]
93112
});

0 commit comments

Comments
 (0)