Skip to content

Commit

Permalink
[react] Fix scoping issue with sx dynamic value transform (#286)
Browse files Browse the repository at this point in the history
Co-authored-by: Brijesh Bittu <[email protected]>
  • Loading branch information
brijeshb42 and Brijesh Bittu authored Oct 24, 2024
1 parent 7e3e341 commit c925f36
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 8 deletions.
10 changes: 10 additions & 0 deletions packages/pigment-css-react/src/processors/sx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,16 @@ export class SxProcessor extends BaseProcessor {
([variableId, expression, isUnitLess]) => {
switch (expression.type) {
case 'ArrowFunctionExpression': {
const fnBody = expression.body as Expression;
// try to deserialize AST if possible
if (fnBody.type === 'StringLiteral') {
try {
const body = JSON.parse(fnBody.value);
return t.objectProperty(t.stringLiteral(variableId), body);
} catch (ex) {
// proceed as usual
}
}
return t.objectProperty(
t.stringLiteral(variableId),
t.arrayExpression([expression.body as Expression, t.booleanLiteral(isUnitLess)]),
Expand Down
2 changes: 0 additions & 2 deletions packages/pigment-css-react/src/utils/cssFnValueToVariable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ function parseAndWrapExpression(
}

function transformThemeKeysInFn(
styleKey: string,
functionString: string,
options: PluginCustomOptions,
filename?: string,
Expand Down Expand Up @@ -182,7 +181,6 @@ function iterateAndReplaceFunctions(
try {
const fnString = value.toString();
const expression = transformThemeKeysInFn(
key,
fnString,
options,
filename,
Expand Down
27 changes: 21 additions & 6 deletions packages/pigment-css-react/src/utils/sxObjectExtractor.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import type { NodePath } from '@babel/core';
import { arrowFunctionExpression, cloneNode } from '@babel/types';
import {
arrayExpression,
arrowFunctionExpression,
booleanLiteral,
cloneNode,
stringLiteral,
} from '@babel/types';
import type {
ArrowFunctionExpression,
Expression,
Expand All @@ -9,6 +15,7 @@ import type {
} from '@babel/types';
import { findIdentifiers } from '@wyw-in-js/transform';
import { isStaticObjectOrArrayExpression } from './checkStaticObjectOrArray';
import { isUnitLess } from './isUnitLess';

function validateObjectKey(
keyPath: NodePath<PrivateName | Expression>,
Expand Down Expand Up @@ -66,7 +73,8 @@ function traverseObjectExpression(
const properties = nodePath.get('properties');
properties.forEach((property) => {
if (property.isObjectProperty()) {
validateObjectKey(property.get('key'), parentCall);
const key = property.get('key');
validateObjectKey(key, parentCall);

const value = property.get('value');
if (!value.isExpression()) {
Expand All @@ -93,10 +101,17 @@ function traverseObjectExpression(
localIdentifiers.push(id);
});
if (localIdentifiers.length) {
const arrowFn = arrowFunctionExpression(
localIdentifiers.map((i) => i.node),
cloneNode(value.node),
);
let cssKey = '';
if (key.isIdentifier()) {
cssKey = key.node.name;
} else if (key.isStringLiteral()) {
cssKey = key.node.value;
}
const unitLess = isUnitLess(cssKey);
const fnBody = arrayExpression([cloneNode(value.node), booleanLiteral(unitLess)]);
// Serialize the actual AST as a string
// which then gets deserialized in sx.ts
const arrowFn = arrowFunctionExpression([], stringLiteral(JSON.stringify(fnBody)));
value.replaceWith(arrowFn);
}
}
Expand Down

0 comments on commit c925f36

Please sign in to comment.