Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .changeset/olive-donkeys-shave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
"@swc/plugin-emotion": patch
---

Merge generated `target`/`label` options into non-object-literal `styled` options instead of appending a third argument.

`styled('div', someIdentifier)` and `styled('div', config.opts)` previously emitted
`styled('div', someIdentifier, { target, label })`. `@emotion/styled` only reads two
arguments, so the generated `target` was silently dropped and `${Component}` selectors
against those components broke at runtime with no build-time signal. These now spread the
original expression into the options object, matching the existing handling of call
expressions such as `styled('div', makeOptions())`.
22 changes: 2 additions & 20 deletions packages/emotion/transform/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -643,7 +643,7 @@ impl<C: Comments> Fold for EmotionTransformer<'_, C> {
Expr::Object(ObjectLit { props, .. }) => {
props.extend(args_props);
}
Expr::Call(_) => {
_ => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve spread arguments when wrapping styled options

When the second argument is itself spread, such as styled("div", ...args)(styles), this arm replaces only its expression while retaining ExprOrSpread.spread. The emitted call becomes styled("div", ...{ target, label, ...args }), and attempting to spread that non-iterable object into the call throws at runtime. Check and handle the argument's spread marker before applying this wrapper; the mirrored tagged-template path has the same issue.

Useful? React with 👍 / 👎.

args_props.push(PropOrSpread::Spread(
SpreadElement {
dot3_token: DUMMY_SP,
Expand All @@ -656,15 +656,6 @@ impl<C: Comments> Fold for EmotionTransformer<'_, C> {
props: args_props,
}));
}
_ => {
c.args.push(
Expr::Object(ObjectLit {
span: DUMMY_SP,
props: args_props,
})
.as_arg(),
);
}
}
} else {
c.args.push(
Expand Down Expand Up @@ -819,7 +810,7 @@ impl<C: Comments> Fold for EmotionTransformer<'_, C> {
Expr::Object(ObjectLit { props, .. }) => {
props.extend(object_props);
}
Expr::Call(_) => {
_ => {
object_props.push(PropOrSpread::Spread(
SpreadElement {
dot3_token: DUMMY_SP,
Expand All @@ -832,15 +823,6 @@ impl<C: Comments> Fold for EmotionTransformer<'_, C> {
props: object_props,
}));
}
_ => {
callee.args.push(
Expr::Object(ObjectLit {
span: DUMMY_SP,
props: object_props,
})
.as_arg(),
);
}
}
} else {
callee.args.push(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import styled from "@emotion/styled";

const opts = { shouldForwardProp: (p: string) => !p.startsWith("$") };
const config = { opts };

const IdentTpl = styled("div", opts)`color: red;`;
const IdentCall = styled("div", opts)({ color: "red" });
const MemberTpl = styled("div", config.opts)`color: red;`;
const MemberCall = styled("div", config.opts)({ color: "red" });
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import styled from "@emotion/styled";
const opts = {
shouldForwardProp: (p: string)=>!p.startsWith("$")
};
const config = {
opts
};
const IdentTpl = /*#__PURE__*/ styled("div", {
target: "e18y1z280",
label: "IdentTpl",
...opts
})("color:red;", "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5wdXQudHMiLCJzb3VyY2VzIjpbImlucHV0LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBzdHlsZWQgZnJvbSBcIkBlbW90aW9uL3N0eWxlZFwiO1xuXG5jb25zdCBvcHRzID0geyBzaG91bGRGb3J3YXJkUHJvcDogKHA6IHN0cmluZykgPT4gIXAuc3RhcnRzV2l0aChcIiRcIikgfTtcbmNvbnN0IGNvbmZpZyA9IHsgb3B0cyB9O1xuXG5jb25zdCBJZGVudFRwbCA9IHN0eWxlZChcImRpdlwiLCBvcHRzKWBjb2xvcjogcmVkO2A7XG5jb25zdCBJZGVudENhbGwgPSBzdHlsZWQoXCJkaXZcIiwgb3B0cykoeyBjb2xvcjogXCJyZWRcIiB9KTtcbmNvbnN0IE1lbWJlclRwbCA9IHN0eWxlZChcImRpdlwiLCBjb25maWcub3B0cylgY29sb3I6IHJlZDtgO1xuY29uc3QgTWVtYmVyQ2FsbCA9IHN0eWxlZChcImRpdlwiLCBjb25maWcub3B0cykoeyBjb2xvcjogXCJyZWRcIiB9KTtcbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFLaUIifQ== */");
const IdentCall = /*#__PURE__*/ styled("div", {
target: "e18y1z281",
label: "IdentCall",
...opts
})({
color: "red"
}, "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5wdXQudHMiLCJzb3VyY2VzIjpbImlucHV0LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBzdHlsZWQgZnJvbSBcIkBlbW90aW9uL3N0eWxlZFwiO1xuXG5jb25zdCBvcHRzID0geyBzaG91bGRGb3J3YXJkUHJvcDogKHA6IHN0cmluZykgPT4gIXAuc3RhcnRzV2l0aChcIiRcIikgfTtcbmNvbnN0IGNvbmZpZyA9IHsgb3B0cyB9O1xuXG5jb25zdCBJZGVudFRwbCA9IHN0eWxlZChcImRpdlwiLCBvcHRzKWBjb2xvcjogcmVkO2A7XG5jb25zdCBJZGVudENhbGwgPSBzdHlsZWQoXCJkaXZcIiwgb3B0cykoeyBjb2xvcjogXCJyZWRcIiB9KTtcbmNvbnN0IE1lbWJlclRwbCA9IHN0eWxlZChcImRpdlwiLCBjb25maWcub3B0cylgY29sb3I6IHJlZDtgO1xuY29uc3QgTWVtYmVyQ2FsbCA9IHN0eWxlZChcImRpdlwiLCBjb25maWcub3B0cykoeyBjb2xvcjogXCJyZWRcIiB9KTtcbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFNa0IifQ== */");
const MemberTpl = /*#__PURE__*/ styled("div", {
target: "e18y1z282",
label: "MemberTpl",
...config.opts
})("color:red;", "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5wdXQudHMiLCJzb3VyY2VzIjpbImlucHV0LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBzdHlsZWQgZnJvbSBcIkBlbW90aW9uL3N0eWxlZFwiO1xuXG5jb25zdCBvcHRzID0geyBzaG91bGRGb3J3YXJkUHJvcDogKHA6IHN0cmluZykgPT4gIXAuc3RhcnRzV2l0aChcIiRcIikgfTtcbmNvbnN0IGNvbmZpZyA9IHsgb3B0cyB9O1xuXG5jb25zdCBJZGVudFRwbCA9IHN0eWxlZChcImRpdlwiLCBvcHRzKWBjb2xvcjogcmVkO2A7XG5jb25zdCBJZGVudENhbGwgPSBzdHlsZWQoXCJkaXZcIiwgb3B0cykoeyBjb2xvcjogXCJyZWRcIiB9KTtcbmNvbnN0IE1lbWJlclRwbCA9IHN0eWxlZChcImRpdlwiLCBjb25maWcub3B0cylgY29sb3I6IHJlZDtgO1xuY29uc3QgTWVtYmVyQ2FsbCA9IHN0eWxlZChcImRpdlwiLCBjb25maWcub3B0cykoeyBjb2xvcjogXCJyZWRcIiB9KTtcbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFPa0IifQ== */");
const MemberCall = /*#__PURE__*/ styled("div", {
target: "e18y1z283",
label: "MemberCall",
...config.opts
})({
color: "red"
}, "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5wdXQudHMiLCJzb3VyY2VzIjpbImlucHV0LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBzdHlsZWQgZnJvbSBcIkBlbW90aW9uL3N0eWxlZFwiO1xuXG5jb25zdCBvcHRzID0geyBzaG91bGRGb3J3YXJkUHJvcDogKHA6IHN0cmluZykgPT4gIXAuc3RhcnRzV2l0aChcIiRcIikgfTtcbmNvbnN0IGNvbmZpZyA9IHsgb3B0cyB9O1xuXG5jb25zdCBJZGVudFRwbCA9IHN0eWxlZChcImRpdlwiLCBvcHRzKWBjb2xvcjogcmVkO2A7XG5jb25zdCBJZGVudENhbGwgPSBzdHlsZWQoXCJkaXZcIiwgb3B0cykoeyBjb2xvcjogXCJyZWRcIiB9KTtcbmNvbnN0IE1lbWJlclRwbCA9IHN0eWxlZChcImRpdlwiLCBjb25maWcub3B0cylgY29sb3I6IHJlZDtgO1xuY29uc3QgTWVtYmVyQ2FsbCA9IHN0eWxlZChcImRpdlwiLCBjb25maWcub3B0cykoeyBjb2xvcjogXCJyZWRcIiB9KTtcbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFRbUIifQ== */");
Loading