diff --git a/changelog_unreleased/javascript/17616.md b/changelog_unreleased/javascript/17616.md new file mode 100644 index 000000000..775a9d050 --- /dev/null +++ b/changelog_unreleased/javascript/17616.md @@ -0,0 +1,46 @@ +#### Improve consistency for JSX in optional method call (#17616 by @seiyab) + + +```jsx +// Input + +
+ {Array(20) + .fill() + ?.map((_, i) => ( +

{i + 1}

+ ))} +
+
; + +// Prettier stable (ESTree based parsers like espree and typescript) + +
+ {Array(20) + .fill() + ?.map((_, i) =>

{i + 1}

)} +
+
; + +// Prettier stable (babel and babel-ts parser) + +
+ {Array(20) + .fill() + ?.map((_, i) => ( +

{i + 1}

+ ))} +
+
; + +// Prettier main (parsers of both types) + +
+ {Array(20) + .fill() + ?.map((_, i) => ( +

{i + 1}

+ ))} +
+
; +``` diff --git a/src/language-js/print/jsx.js b/src/language-js/print/jsx.js index a2a705491..20b106a7c 100644 --- a/src/language-js/print/jsx.js +++ b/src/language-js/print/jsx.js @@ -504,13 +504,7 @@ function maybeWrapJsxElementInParens(path, elem, options) { return elem; } - const shouldBreak = path.match( - undefined, - (node) => node.type === "ArrowFunctionExpression", - isCallExpression, - (node) => node.type === "JSXExpressionContainer", - ); - + const shouldBreak = shouldBreakJsxElement(path); const needsParens = pathNeedsParens(path, options); return group( @@ -524,6 +518,31 @@ function maybeWrapJsxElementInParens(path, elem, options) { ); } +function shouldBreakJsxElement(path) { + return ( + path.match( + undefined, + (node) => node.type === "ArrowFunctionExpression", + isCallExpression, + ) && + // Babel + (path.match( + undefined, + undefined, + undefined, + (node) => node.type === "JSXExpressionContainer", + ) || + // Estree + path.match( + undefined, + undefined, + undefined, + (node) => node.type === "ChainExpression", + (node) => node.type === "JSXExpressionContainer", + )) + ); +} + function printJsxAttribute(path, options, print) { const { node } = path; const parts = []; diff --git a/tests/format/jsx/optional-chaining/__snapshots__/format.test.js.snap b/tests/format/jsx/optional-chaining/__snapshots__/format.test.js.snap index 959f68a90..770ab4b71 100644 --- a/tests/format/jsx/optional-chaining/__snapshots__/format.test.js.snap +++ b/tests/format/jsx/optional-chaining/__snapshots__/format.test.js.snap @@ -1,4 +1,4 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing exports[`optional-chaining.jsx format 1`] = ` ====================================options===================================== @@ -18,6 +18,46 @@ function foo() { ) } +function Component( ) { + return ( +
+ {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?.bbbbbbbbbbbbbbbbbbbbbbbbb.map( + (p, i) =>

{p}

+ )} +
+ ); +} + +function Component() { + return ( +
+ {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?.bbbbbbbbbbbbbbbbbbbbbbbbb().map( + (p, i) =>

{p}

+ )} +
+ ); +} + +function Component() { + return ( +
+ {aaa?.aaa()?.aaa()?.map( + (p, i) =>

{p}

+ )} +
+ ); +} + +function Component() { + return ( +
+ {aaa?.aaa?.()?.aaa?.()?.map?.( + (p, i) =>

{p}

+ )} +
+ ); +} + =====================================output===================================== function foo() { // https://github.com/marmelab/react-admin/blob/5ae855aa958ba54438b144bf0907b1437c5a5d77/examples/demo/src/orders/Totals.tsx#L38-L43 @@ -31,5 +71,55 @@ function foo() { ); } +function Component() { + return ( +
+ {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?.bbbbbbbbbbbbbbbbbbbbbbbbb.map( + (p, i) => ( +

{p}

+ ), + )} +
+ ); +} + +function Component() { + return ( +
+ {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + ?.bbbbbbbbbbbbbbbbbbbbbbbbb() + .map((p, i) => ( +

{p}

+ ))} +
+ ); +} + +function Component() { + return ( +
+ {aaa + ?.aaa() + ?.aaa() + ?.map((p, i) => ( +

{p}

+ ))} +
+ ); +} + +function Component() { + return ( +
+ {aaa + ?.aaa?.() + ?.aaa?.() + ?.map?.((p, i) => ( +

{p}

+ ))} +
+ ); +} + ================================================================================ `; diff --git a/tests/format/jsx/optional-chaining/optional-chaining.jsx b/tests/format/jsx/optional-chaining/optional-chaining.jsx index 3d5ffd50a..6b59a8bc1 100644 --- a/tests/format/jsx/optional-chaining/optional-chaining.jsx +++ b/tests/format/jsx/optional-chaining/optional-chaining.jsx @@ -9,3 +9,43 @@ function foo() { ) } + +function Component( ) { + return ( +
+ {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?.bbbbbbbbbbbbbbbbbbbbbbbbb.map( + (p, i) =>

{p}

+ )} +
+ ); +} + +function Component() { + return ( +
+ {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?.bbbbbbbbbbbbbbbbbbbbbbbbb().map( + (p, i) =>

{p}

+ )} +
+ ); +} + +function Component() { + return ( +
+ {aaa?.aaa()?.aaa()?.map( + (p, i) =>

{p}

+ )} +
+ ); +} + +function Component() { + return ( +
+ {aaa?.aaa?.()?.aaa?.()?.map?.( + (p, i) =>

{p}

+ )} +
+ ); +}