From b6edf96cc49b0cd7f32d0ce82f779881afe966ef Mon Sep 17 00:00:00 2001 From: Christopher Chedeau Date: Tue, 11 Apr 2017 09:33:02 -0700 Subject: [PATCH] Improve jsx output for style components (#1144) * Hug template literals inside of JSXExpressionContainer We already hug a bunch of things inside of `{}`. It seems that it's a good idea to do it for template literals as well. I don't think I've seen anyone actually indent them. Fixes #1090 * Inline jsx elements with single template literal expression If there is a single expression and a single template literal, then a lot of people in the jsx-style world inline it. I've also myself used this for markdown and printed it that way. So we probably should print it that way. Note that I'm checking for children.length === 1, this means that if there's any whitespace, this is not going to be true and will not enter this case. So it WON'T reformat ```js ``` into ```js ``` which is great. You have to opt-in to the second style in order to get it. Fixes #1090 --- src/printer.js | 21 ++++++++-- .../__snapshots__/jsfmt.spec.js.snap | 42 +++++++++++++++++++ tests/jsx_template/jsfmt.spec.js | 1 + tests/jsx_template/styled-components.js | 18 ++++++++ 4 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 tests/jsx_template/__snapshots__/jsfmt.spec.js.snap create mode 100644 tests/jsx_template/jsfmt.spec.js create mode 100644 tests/jsx_template/styled-components.js diff --git a/src/printer.js b/src/printer.js index ebc89aaf0..233a92921 100644 --- a/src/printer.js +++ b/src/printer.js @@ -1269,6 +1269,8 @@ function genericPrintNoParens(path, options, print, args) { n.expression.type === "CallExpression" || n.expression.type === "FunctionExpression" || n.expression.type === "JSXEmptyExpression" || + n.expression.type === "TemplateLiteral" || + n.expression.type === "TaggedTemplateExpression" || (parent.type === "JSXElement" && (n.expression.type === "ConditionalExpression" || isBinaryish(n.expression))); @@ -2912,8 +2914,23 @@ function printJSXElement(path, options, print) { delete n.closingElement; } - // If no children, just print the opening element const openingLines = path.call(print, "openingElement"); + const closingLines = path.call(print, "closingElement"); + + if ( + n.children.length === 1 && + n.children[0].type === "JSXExpressionContainer" && + (n.children[0].expression.type === "TemplateLiteral" || + n.children[0].expression.type === "TaggedTemplateExpression") + ) { + return concat([ + openingLines, + concat(path.map(print, "children")), + closingLines + ]); + } + + // If no children, just print the opening element if (n.openingElement.selfClosing) { assert.ok(!n.closingElement); return openingLines; @@ -3000,8 +3017,6 @@ function printJSXElement(path, options, print) { ) ]; - const closingLines = path.call(print, "closingElement"); - const multiLineElem = group( concat([ openingLines, diff --git a/tests/jsx_template/__snapshots__/jsfmt.spec.js.snap b/tests/jsx_template/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 000000000..f25403605 --- /dev/null +++ b/tests/jsx_template/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,42 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`styled-components.js 1`] = ` +"; + +; + +; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +; + +; + +; +" +`; diff --git a/tests/jsx_template/jsfmt.spec.js b/tests/jsx_template/jsfmt.spec.js new file mode 100644 index 000000000..989047bcc --- /dev/null +++ b/tests/jsx_template/jsfmt.spec.js @@ -0,0 +1 @@ +run_spec(__dirname); diff --git a/tests/jsx_template/styled-components.js b/tests/jsx_template/styled-components.js new file mode 100644 index 000000000..3377c4078 --- /dev/null +++ b/tests/jsx_template/styled-components.js @@ -0,0 +1,18 @@ +; + +; + +;