diff --git a/changelog_unreleased/javascript/pr-9136.md b/changelog_unreleased/javascript/pr-9136.md new file mode 100644 index 000000000000..62f8518f49cf --- /dev/null +++ b/changelog_unreleased/javascript/pr-9136.md @@ -0,0 +1,46 @@ +#### Fix line breaks for CSS in JS (#9136 by @sosukesuzuki) + + +```js +// Input +styled.div` + // prettier-ignore + @media (aaaaaaaaaaaaa) { + z-index: ${(props) => (props.isComplete ? '1' : '0')}; + } +`; +styled.div` + ${props => getSize(props.$size.xs)} + ${props => getSize(props.$size.sm, 'sm')} + ${props => getSize(props.$size.md, 'md')} +`; + +// Prettier stable +styled.div` + // prettier-ignore + @media (aaaaaaaaaaaaa) { + z-index: ${(props) => + props.isComplete ? "1" : "0"}; + } +`; +styled.div` + ${(props) => getSize(props.$size.xs)} + ${(props) => getSize(props.$size.sm, "sm")} + ${(props) => + getSize(props.$size.md, "md")} +`; + +// Prettier master +styled.div` + // prettier-ignore + @media (aaaaaaaaaaaaa) { + z-index: ${(props) => (props.isComplete ? "1" : "0")}; + } +`; +styled.div` + ${(props) => getSize(props.$size.xs)} + ${(props) => getSize(props.$size.sm, "sm")} + ${(props) => getSize(props.$size.md, "md")} +`; + +``` diff --git a/src/document/doc-utils.js b/src/document/doc-utils.js index e31adbbca304..d9fe00900f66 100644 --- a/src/document/doc-utils.js +++ b/src/document/doc-utils.js @@ -1,5 +1,7 @@ "use strict"; +const { literalline, concat } = require("./doc-builders"); + // Using a unique object to compare by reference. const traverseDocOnExitStackMarker = {}; @@ -258,6 +260,18 @@ function normalizeDoc(doc) { }); } +function replaceNewlinesWithLiterallines(doc) { + return mapDoc(doc, (currentDoc) => + typeof currentDoc === "string" && currentDoc.includes("\n") + ? concat( + currentDoc + .split(/(\n)/g) + .map((v, i) => (i % 2 === 0 ? v : literalline)) + ) + : currentDoc + ); +} + module.exports = { isEmpty, willBreak, @@ -270,4 +284,5 @@ module.exports = { stripTrailingHardline, normalizeParts, normalizeDoc, + replaceNewlinesWithLiterallines, }; diff --git a/src/language-js/embed.js b/src/language-js/embed.js index 64ce711f4a7a..1bf4ce926249 100644 --- a/src/language-js/embed.js +++ b/src/language-js/embed.js @@ -12,7 +12,7 @@ const { group, dedentToRoot, }, - utils: { mapDoc }, + utils: { mapDoc, replaceNewlinesWithLiterallines }, } = require("../document"); const { isBlockComment, hasLeadingComment } = require("./comments"); @@ -301,7 +301,7 @@ function replacePlaceholders(quasisDoc, expressionDocs) { part.split(/@prettier-placeholder-(\d+)-id/).forEach((component, idx) => { // The placeholder is always at odd indices if (idx % 2 === 0) { - replacedParts.push(component); + replacedParts.push(replaceNewlinesWithLiterallines(component)); return; } diff --git a/src/language-markdown/embed.js b/src/language-markdown/embed.js index c5e7d10ef9f4..199aa23267cf 100644 --- a/src/language-markdown/embed.js +++ b/src/language-markdown/embed.js @@ -2,8 +2,8 @@ const { getParserName, getMaxContinuousCount } = require("../common/util"); const { - builders: { hardline, literalline, concat, markAsRoot }, - utils: { mapDoc }, + builders: { hardline, concat, markAsRoot }, + utils: { replaceNewlinesWithLiterallines }, } = require("../document"); const { print: printFrontMatter } = require("../utils/front-matter"); const { getFencedCodeBlockValue } = require("./utils"); @@ -66,18 +66,6 @@ function embed(path, print, textToDoc, options) { } return null; - - function replaceNewlinesWithLiterallines(doc) { - return mapDoc(doc, (currentDoc) => - typeof currentDoc === "string" && currentDoc.includes("\n") - ? concat( - currentDoc - .split(/(\n)/g) - .map((v, i) => (i % 2 === 0 ? v : literalline)) - ) - : currentDoc - ); - } } module.exports = embed; diff --git a/tests/js/multiparser-css/__snapshots__/jsfmt.spec.js.snap b/tests/js/multiparser-css/__snapshots__/jsfmt.spec.js.snap index f230b09ba17f..b1442f2b0f7b 100644 --- a/tests/js/multiparser-css/__snapshots__/jsfmt.spec.js.snap +++ b/tests/js/multiparser-css/__snapshots__/jsfmt.spec.js.snap @@ -573,6 +573,19 @@ const Foo = styled.p\` } \`; +styled(A)\` + // prettier-ignore + @media (aaaaaaaaaaaaa) { + z-index: \${(props) => (props.isComplete ? '1' : '0')}; + } +\`; + +const StyledDiv = styled.div\` + \${props => getSize(props.$size.xs)} + \${props => getSize(props.$size.sm, 'sm')} + \${props => getSize(props.$size.md, 'md')} +\`; + =====================================output===================================== const ListItem1 = styled.li\`\`; @@ -826,6 +839,19 @@ const Foo = styled.p\` } \`; +styled(A)\` + // prettier-ignore + @media (aaaaaaaaaaaaa) { + z-index: \${(props) => (props.isComplete ? "1" : "0")}; + } +\`; + +const StyledDiv = styled.div\` + \${(props) => getSize(props.$size.xs)} + \${(props) => getSize(props.$size.sm, "sm")} + \${(props) => getSize(props.$size.md, "md")} +\`; + ================================================================================ `; diff --git a/tests/js/multiparser-css/styled-components.js b/tests/js/multiparser-css/styled-components.js index e9d5bc387c3b..ceff8028773c 100644 --- a/tests/js/multiparser-css/styled-components.js +++ b/tests/js/multiparser-css/styled-components.js @@ -246,3 +246,16 @@ const Foo = styled.p` margin-top: 3rem; } `; + +styled(A)` + // prettier-ignore + @media (aaaaaaaaaaaaa) { + z-index: ${(props) => (props.isComplete ? '1' : '0')}; + } +`; + +const StyledDiv = styled.div` + ${props => getSize(props.$size.xs)} + ${props => getSize(props.$size.sm, 'sm')} + ${props => getSize(props.$size.md, 'md')} +`;