Skip to content

Commit

Permalink
fix formatting of pseudo-elements and pseudo-classes in styled-compon…
Browse files Browse the repository at this point in the history
…ents
  • Loading branch information
thorn0 committed Mar 23, 2020
1 parent 0d813b7 commit 4de3aa3
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 10 deletions.
21 changes: 21 additions & 0 deletions changelog_unreleased/javascript/pr-7842.md
@@ -0,0 +1,21 @@
#### Fix formatting of pseudo-elements and pseudo-classes in styled-components template literals ([#7842](https://github.com/prettier/prettier/pull/7842) by [@thorn0](https://github.com/thorn0))

<!-- prettier-ignore -->
```jsx
// Input
const Foo = styled.div`
${media.smallDown}::before {}
`;

// Prettier stable
const Foo = styled.div`
${media.smallDown}: : before{
}
`;

// Prettier master
const Foo = styled.div`
${media.smallDown}::before {
}
`;
```
48 changes: 38 additions & 10 deletions src/language-js/embed.js
Expand Up @@ -36,14 +36,35 @@ function embed(path, print, textToDoc, options) {
const rawQuasis = node.quasis.map((q) => q.value.raw);
let placeholderID = 0;
const text = rawQuasis.reduce((prevVal, currVal, idx) => {
return idx === 0
? currVal
: prevVal +
"@prettier-placeholder-" +
placeholderID++ +
"-id" +
currVal;
if (idx === 0) {
return currVal;
}

let specialSuffix = ""; // colons and whitespaces

const trailingColons = currVal.match(/^(\s*)(:+)(\s*)/);
if (trailingColons) {
const whitespaceBeforeColons = !!trailingColons[1];
const numberOfColons = trailingColons[2].length;
const whitespaceAfterColons = !!trailingColons[3];

if (whitespaceAfterColons) {
// do nothing, it's not a pseudo-element or pseudo-class
} else {
if (whitespaceBeforeColons) {
specialSuffix += "-whitespace";
}
specialSuffix += "-colon".repeat(numberOfColons);

currVal = "\uffff" + currVal.slice(trailingColons[0].length);
}
}

const placeholder = `@prettier-placeholder${specialSuffix}-${placeholderID++}-id`;

return prevVal + placeholder + currVal;
}, "");

const doc = textToDoc(text, { parser: "css" });
return transformCssDoc(doc, path, print);
}
Expand Down Expand Up @@ -292,14 +313,21 @@ function replacePlaceholders(quasisDoc, expressionDocs) {
const placeholder = parts[atPlaceholderIndex];
const rest = parts.slice(atPlaceholderIndex + 1);
const placeholderMatch = placeholder.match(
/@prettier-placeholder-(.+)-id([\s\S]*)/
/@prettier-placeholder((?:-whitespace|-colon)*)-(.+)-id([\s\S]*)/
);
const placeholderID = placeholderMatch[1];
const specialSuffix = placeholderMatch[1]; // colons and whitespaces
const placeholderID = placeholderMatch[2];
// When the expression has a suffix appended, like:
// animation: linear ${time}s ease-out;
const suffix = placeholderMatch[2];
let suffix = placeholderMatch[3];
const expression = expressions[placeholderID];

if (specialSuffix) {
suffix =
specialSuffix.replace(/-whitespace/g, " ").replace(/-colon/g, ":") +
suffix.replace(/^\uffff/g, "");
}

replaceCounter++;
parts = parts
.slice(0, atPlaceholderIndex)
Expand Down
45 changes: 45 additions & 0 deletions tests/multiparser_js_css/__snapshots__/jsfmt.spec.js.snap
@@ -1,5 +1,50 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`colons-after-substitutions.js 1`] = `
====================================options=====================================
parsers: ["babel"]
printWidth: 80
| printWidth
=====================================input======================================
const Icon = styled.div\`
flex: none;
transition: fill 0.25s;
width: 48px;
height: 48px;
\${Link}:hover {
fill: rebeccapurple;
}
\${Link} :hover {
fill: yellow;
}
\${media.smallDown}::before {}
\`
=====================================output=====================================
const Icon = styled.div\`
flex: none;
transition: fill 0.25s;
width: 48px;
height: 48px;
\${Link}:hover {
fill: rebeccapurple;
}
\${Link} :hover {
fill: yellow;
}
\${media.smallDown}::before {
}
\`;
================================================================================
`;

exports[`styled-components.js 1`] = `
====================================options=====================================
parsers: ["babel"]
Expand Down
16 changes: 16 additions & 0 deletions tests/multiparser_js_css/colons-after-substitutions.js
@@ -0,0 +1,16 @@
const Icon = styled.div`
flex: none;
transition: fill 0.25s;
width: 48px;
height: 48px;
${Link}:hover {
fill: rebeccapurple;
}
${Link} :hover {
fill: yellow;
}
${media.smallDown}::before {}
`

0 comments on commit 4de3aa3

Please sign in to comment.