fix formatting of pseudo-elements and pseudo-classes in styled-components (#7842)
This commit is contained in:
1 parent
fac9ce07fe
commit
8ec7bc229a
4 files changed
+120
-10
No files matched your search
@@ -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 {
|
||||
}
|
||||
`;
|
||||
```
|
||||
+38
-10
@@ -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);
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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"]
|
||||
|
||||
@@ -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 {}
|
||||
`
|
||||
Reference in new issue
Block a user