Skip to content

Commit

Permalink
Handle JSX attribute indentation in jsx-indent
Browse files Browse the repository at this point in the history
  • Loading branch information
jomasti committed Dec 13, 2018
1 parent 8ef86c5 commit f302f05
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 3 deletions.
12 changes: 12 additions & 0 deletions lib/rules/jsx-indent.js
Original file line number Diff line number Diff line change
Expand Up @@ -242,11 +242,23 @@ module.exports = {
checkNodesIndent(node, peerElementIndent);
}

function handleAttribute(node) {
if (node.value.type !== 'JSXExpressionContainer') {
return;
}
const nameIndent = getNodeIndent(node.name);
const lastToken = sourceCode.getLastToken(node.value);
const firstInLine = astUtil.getFirstNodeInLine(context, lastToken);
const indent = node.name.loc.start.line === firstInLine.loc.start.line ? 0 : nameIndent;
checkNodesIndent(firstInLine, indent);
}

return {
JSXOpeningElement: handleOpeningElement,
JSXOpeningFragment: handleOpeningElement,
JSXClosingElement: handleClosingElement,
JSXClosingFragment: handleClosingElement,
JSXAttribute: handleAttribute,
JSXExpressionContainer: function(node) {
if (!node.parent) {
return;
Expand Down
18 changes: 15 additions & 3 deletions lib/util/ast.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,14 @@ function getComponentProperties(node) {
}
}


/**
* Checks if the node is the first in its line, excluding whitespace.
* Gets the first node in a line from the initial node, excluding whitespace.
* @param {Object} context The node to check
* @param {ASTNode} node The node to check
* @return {Boolean} true if it's the first node in its line
* @return {ASTNode} the first node in the line
*/
function isNodeFirstInLine(context, node) {
function getFirstNodeInLine(context, node) {
const sourceCode = context.getSourceCode();
let token = node;
let lines;
Expand All @@ -87,7 +88,17 @@ function isNodeFirstInLine(context, node) {
token.type === 'JSXText' &&
/^\s*$/.test(lines[lines.length - 1])
);
return token;
}

/**
* Checks if the node is the first in its line, excluding whitespace.
* @param {Object} context The node to check
* @param {ASTNode} node The node to check
* @return {Boolean} true if it's the first node in its line
*/
function isNodeFirstInLine(context, node) {
const token = getFirstNodeInLine(context, node);
const startLine = node.loc.start.line;
const endLine = token ? token.loc.end.line : -1;
return startLine !== endLine;
Expand Down Expand Up @@ -131,6 +142,7 @@ function isClass(node) {

module.exports = {
findReturnStatement: findReturnStatement,
getFirstNodeInLine: getFirstNodeInLine,
getPropertyName: getPropertyName,
getPropertyNameNode: getPropertyNameNode,
getComponentProperties: getComponentProperties,
Expand Down
58 changes: 58 additions & 0 deletions tests/lib/rules/jsx-indent.js
Original file line number Diff line number Diff line change
Expand Up @@ -1478,5 +1478,63 @@ ruleTester.run('jsx-indent', rule, {
errors: [
{message: 'Expected indentation of 4 space characters but found 2.'}
]
}, {
code: `
const Component = () => (
<View
ListFooterComponent={(
<View
rowSpan={3}
placeholder="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do"
/>
)}
/>
);
`,
output: `
const Component = () => (
<View
ListFooterComponent={(
<View
rowSpan={3}
placeholder="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do"
/>
)}
/>
);
`,
options: [2],
errors: [
{message: 'Expected indentation of 8 space characters but found 4.'}
]
}, {
code: `
const Component = () => (
\t<View
\t\tListFooterComponent={(
\t\t\t<View
\t\t\t\trowSpan={3}
\t\t\t\tplaceholder="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do"
\t\t\t/>
)}
\t/>
);
`,
output: `
const Component = () => (
\t<View
\t\tListFooterComponent={(
\t\t\t<View
\t\t\t\trowSpan={3}
\t\t\t\tplaceholder="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do"
\t\t\t/>
\t\t)}
\t/>
);
`,
options: ['tab'],
errors: [
{message: 'Expected indentation of 2 tab characters but found 0.'}
]
}]
});

0 comments on commit f302f05

Please sign in to comment.