Skip to content

Commit

Permalink
[core] Add support for sx replacement in transformed jsx calls
Browse files Browse the repository at this point in the history
  • Loading branch information
brijeshb42 committed Apr 19, 2024
1 parent ed19473 commit ad9c475
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 13 deletions.
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@
"@types/lodash": "^4.17.0",
"@types/mocha": "^10.0.6",
"@types/node": "^18.19.30",
"@types/prettier": "^3.0.0",
"@types/react": "^18.2.74",
"@types/yargs": "^17.0.32",
"@typescript-eslint/eslint-plugin": "^7.5.0",
Expand Down
34 changes: 32 additions & 2 deletions packages/pigment-css-react/src/utils/sx-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ function convertJsxMemberExpressionToMemberExpression(
);
}

function wrapWithSxComponent(
function wrapWithJsxElement(
t: typeof Types,
tagNamePath: NodePath<Types.JSXIdentifier | Types.JSXMemberExpression | Types.JSXNamespacedName>,
sxComponentName: string,
Expand Down Expand Up @@ -71,6 +71,34 @@ function wrapWithSxComponent(
jsxElement.replaceWith(newElement);
}

function wrapWithJsxCall(
t: typeof Types,
tagNamePath: NodePath<Types.Identifier | Types.MemberExpression>,
sxComponentName: string,
) {
const sxComponent = addNamed(
tagNamePath,
sxComponentName,
`${process.env.PACKAGE_NAME}/private-runtime`,
);
const jsxCall = tagNamePath.findParent((p) => p.isCallExpression());
if (!jsxCall?.isCallExpression()) {
return;
}
const originalTag = tagNamePath.node;
const callArgs = jsxCall.get('arguments');
callArgs[0].replaceWith(sxComponent);
const props = callArgs[1];
if (props.isObjectExpression()) {
const properties = props.get('properties');
const newProps = t.objectExpression([
t.objectProperty(t.identifier('sxComponent'), originalTag),
...properties.map((p) => p.node),
]);
props.replaceWith(newProps);
}
}

function replaceNodePath(
expressionPath: NodePath<Types.Expression>,
namePath: NodePath<Types.JSXIdentifier | Types.Identifier>,
Expand Down Expand Up @@ -101,7 +129,9 @@ function replaceNodePath(

if (wasSxTransformed) {
if (tagNamePath.isJSXIdentifier() || tagNamePath.isJSXMemberExpression()) {
wrapWithSxComponent(t, tagNamePath, sxComponentName);
wrapWithJsxElement(t, tagNamePath, sxComponentName);
} else if (tagNamePath.isIdentifier() || tagNamePath.isMemberExpression()) {
wrapWithJsxCall(t, tagNamePath, sxComponentName);
}
}
}
Expand Down
9 changes: 9 additions & 0 deletions packages/pigment-css-react/tests/Box/box.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,13 @@ describe('Pigment CSS - Box', () => {
expect(output.js).to.equal(fixture.js);
expect(output.css).to.equal(fixture.css);
});

it('should transform and render sx prop for jsx calls', async () => {
const { output, fixture } = await runTransformation(
path.join(__dirname, 'fixtures/box-jsx.input.js'),
);

expect(output.js).to.equal(fixture.js);
expect(output.css).to.equal(fixture.css);
});
});
18 changes: 18 additions & 0 deletions packages/pigment-css-react/tests/Box/fixtures/box-jsx.input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import Box from '@pigment-css/react/Box';
import { jsx as _jsx } from 'react/jsx-runtime';

export function App() {
return /*#__PURE__*/ _jsx(Box, {
as: 'ul',
sx: {
margin: 0,
marginBlock: '1rem',
padding: 0,
paddingLeft: '1.5rem',
display: 'flex',
flexDirection: 'column',
gap: '0.5rem',
},
children: 'Hello Box',
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.sd5jss7 {
margin: 0;
margin-block: 1rem;
padding: 0;
padding-left: 1.5rem;
display: flex;
flex-direction: column;
gap: 0.5rem;
}
11 changes: 11 additions & 0 deletions packages/pigment-css-react/tests/Box/fixtures/box-jsx.output.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { ForwardSx as _ForwardSx } from '@pigment-css/react/private-runtime';
import Box from '@pigment-css/react/Box';
import { jsx as _jsx } from 'react/jsx-runtime';
export function App() {
return /*#__PURE__*/ _jsx(_ForwardSx, {
sxComponent: Box,
as: 'ul',
sx: 'sd5jss7',
children: 'Hello Box',
});
}
10 changes: 0 additions & 10 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit ad9c475

Please sign in to comment.