Skip to content

Commit d88ee37

Browse files
author
Yannick Croissant
committed
Fix jsx-indent in multi-line conditional expressions (fixes #901, fixes #907)
1 parent dc7767b commit d88ee37

File tree

2 files changed

+83
-2
lines changed

2 files changed

+83
-2
lines changed

lib/rules/jsx-indent.js

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,20 @@ module.exports = {
183183
);
184184
}
185185

186+
/**
187+
* Check if the node is the alternate member of a conditional expression
188+
* @param {ASTNode} node The node to check
189+
* @return {Boolean} true if its the case, false if not
190+
*/
191+
function isAlternateInConditionalExp(node) {
192+
return (
193+
node.parent &&
194+
node.parent.parent &&
195+
node.parent.parent.type === 'ConditionalExpression' &&
196+
node.parent.parent.alternate === node.parent
197+
);
198+
}
199+
186200
/**
187201
* Check indent for nodes list
188202
* @param {ASTNode} node The node to check
@@ -192,7 +206,13 @@ module.exports = {
192206
function checkNodesIndent(node, indent, excludeCommas) {
193207
var nodeIndent = getNodeIndent(node, false, excludeCommas);
194208
var isCorrectRightInLogicalExp = isRightInLogicalExp(node) && (nodeIndent - indent) === indentSize;
195-
if (nodeIndent !== indent && isNodeFirstInLine(node) && !isCorrectRightInLogicalExp) {
209+
var isCorrectAlternateInCondExp = isAlternateInConditionalExp(node) && (nodeIndent - indent) === 0;
210+
if (
211+
nodeIndent !== indent &&
212+
isNodeFirstInLine(node) &&
213+
!isCorrectRightInLogicalExp &&
214+
!isCorrectAlternateInCondExp
215+
) {
196216
report(node, indent, nodeIndent);
197217
}
198218
}
@@ -208,7 +228,11 @@ module.exports = {
208228
prevToken = sourceCode.getNodeByRangeIndex(prevToken.start).parent;
209229
}
210230
var parentElementIndent = getNodeIndent(prevToken);
211-
var indent = prevToken.loc.start.line === node.loc.start.line || isRightInLogicalExp(node) ? 0 : indentSize;
231+
var indent = (
232+
prevToken.loc.start.line === node.loc.start.line ||
233+
isRightInLogicalExp(node) ||
234+
isAlternateInConditionalExp(node)
235+
) ? 0 : indentSize;
212236
checkNodesIndent(node, parentElementIndent + indent);
213237
},
214238
JSXClosingElement: function(node) {

tests/lib/rules/jsx-indent.js

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,23 @@ ruleTester.run('jsx-indent', rule, {
198198
'</div>'
199199
].join('\n'),
200200
parserOptions: parserOptions
201+
}, {
202+
code: [
203+
'this.props.asd.length > 0 ?',
204+
' <Button className="bacon-yay">{this.props.asd.length}</Button> :',
205+
' <span className="bacon-no-trigger">0</span>'
206+
].join('\n'),
207+
parserOptions: parserOptions
208+
}, {
209+
code: [
210+
'<div>',
211+
' {this.props.asd.length > 0 ?',
212+
' <Button className="bacon-yay">{this.props.asd.length}</Button> :',
213+
' <span className="bacon-no-trigger">0</span>',
214+
' }',
215+
'</div>'
216+
].join('\n'),
217+
parserOptions: parserOptions
201218
}],
202219

203220
invalid: [{
@@ -447,5 +464,45 @@ ruleTester.run('jsx-indent', rule, {
447464
errors: [
448465
{message: 'Expected indentation of 2 space characters but found 0.'}
449466
]
467+
}, {
468+
code: [
469+
'this.props.asd.length > 0 ?',
470+
' <Button className="bacon-yay">{this.props.asd.length}</Button> :',
471+
' <span className="bacon-no-trigger">0</span>'
472+
].join('\n'),
473+
output: [
474+
'this.props.asd.length > 0 ?',
475+
' <Button className="bacon-yay">{this.props.asd.length}</Button> :',
476+
' <span className="bacon-no-trigger">0</span>'
477+
].join('\n'),
478+
parserOptions: parserOptions,
479+
errors: [{
480+
message: 'Expected indentation of 4 space characters but found 8.',
481+
line: 3,
482+
column: 9
483+
}]
484+
}, {
485+
code: [
486+
'<div>',
487+
' {this.props.asd.length > 0 ?',
488+
' <Button className="bacon-yay">{this.props.asd.length}</Button> :',
489+
' <span className="bacon-no-trigger">0</span>',
490+
' }',
491+
'</div>'
492+
].join('\n'),
493+
output: [
494+
'<div>',
495+
' {this.props.asd.length > 0 ?',
496+
' <Button className="bacon-yay">{this.props.asd.length}</Button> :',
497+
' <span className="bacon-no-trigger">0</span>',
498+
' }',
499+
'</div>'
500+
].join('\n'),
501+
parserOptions: parserOptions,
502+
errors: [{
503+
message: 'Expected indentation of 8 space characters but found 4.',
504+
line: 4,
505+
column: 5
506+
}]
450507
}]
451508
});

0 commit comments

Comments
 (0)