Skip to content

Commit 2f66dd2

Browse files
committed
fix(transformer/styled-components): preserve whitespace before interpolations in minification (#12558)
close: #12556 Fixed an issue where spaces before template literal interpolations were incorrectly removed during CSS minification in the styled-components plugin. The fix ensures spaces are preserved (e.g., `padding: 0 ${PADDING}px` stays as `padding:0 ${PADDING}px` instead of becoming `padding:0${PADDING}px`).
1 parent 3cdac4c commit 2f66dd2

File tree

5 files changed

+53
-3
lines changed

5 files changed

+53
-3
lines changed

crates/oxc_transformer/src/plugins/styled_components.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1067,8 +1067,16 @@ fn minify_template_literal<'a>(lit: &mut TemplateLiteral<'a>, ast: AstBuilder<'a
10671067
// but preserve whitespace preceding colon, to avoid joining selectors.
10681068
if output.last().is_some_and(|&last| {
10691069
!matches!(last, b' ' | b':' | b'{' | b'}' | b',' | b';')
1070-
}) && (i < bytes.len() && !matches!(bytes[i], b'{' | b'}' | b',' | b';'))
1070+
}) && (i == bytes.len() || !matches!(bytes[i], b'{' | b'}' | b',' | b';'))
10711071
{
1072+
// `i == bytes.len()` means we're at the end of the quasi that has an
1073+
// interpolation after it. Preserve trailing whitespace to avoid joining
1074+
// with the interpolation.
1075+
//
1076+
// For example:
1077+
// `padding: 0 ${PADDING}px`
1078+
// ^ this space should be preserved to avoid it becomes
1079+
// `padding:0${PADDING}px`
10721080
output.push(b' ');
10731081
}
10741082
continue;

tasks/transform_conformance/snapshots/oxc.snap.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
commit: 1d4546bc
22

3-
Passed: 180/300
3+
Passed: 181/301
44

55
# All Passed:
66
* babel-plugin-transform-class-static-block
@@ -1470,7 +1470,7 @@ after transform: ["Function", "babelHelpers"]
14701470
rebuilt : ["babelHelpers", "dec"]
14711471

14721472

1473-
# plugin-styled-components (20/34)
1473+
# plugin-styled-components (21/35)
14741474
* styled-components/add-identifier-with-top-level-import-paths/input.js
14751475
x Output mismatch
14761476

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import styled from 'styled-components';
2+
3+
const PADDING = 2;
4+
5+
// Test case for whitespace before interpolation
6+
const Button = styled.div`
7+
padding: 0 ${PADDING}px 0 2px;
8+
`;
9+
10+
// Multiple interpolations with spaces before
11+
const Box = styled.div`
12+
margin: ${props => props.margin}px ${props => props.margin}px;
13+
padding: 0 ${PADDING}px;
14+
`;
15+
16+
// Space before interpolation in middle of value
17+
const Container = styled.div`
18+
width: calc(100% - ${PADDING}px);
19+
`;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"presets": [
3+
[
4+
"@babel/preset-env",
5+
{
6+
"modules": false,
7+
"targets": "defaults"
8+
}
9+
]
10+
],
11+
"plugins": [
12+
["styled-components", {
13+
"ssr": false,
14+
"displayName": false,
15+
"transpileTemplateLiterals": false
16+
}]
17+
]
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import styled from 'styled-components';
2+
const PADDING = 2;
3+
const Button = styled.div`padding:0 ${PADDING}px 0 2px;`;
4+
const Box = styled.div`margin:${props => props.margin}px ${props => props.margin}px;padding:0 ${PADDING}px;`;
5+
const Container = styled.div`width:calc(100% - ${PADDING}px);`;

0 commit comments

Comments
 (0)