Skip to content

Commit

Permalink
fix: bound call expression styles are preserved in Builder generator (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
liamdebeasi authored Feb 20, 2025
1 parent 58131c4 commit 0b55dc3
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/shy-bears-invent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@builder.io/mitosis': patch
---

[Builder]: bound call expression styles are preserved in generator
127 changes: 127 additions & 0 deletions packages/core/src/__tests__/builder.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -887,6 +887,133 @@ describe('Builder', () => {
`);
});

test('preserve bound call expressions for styles', () => {
const code = dedent`
import { useStore } from "@builder.io/mitosis";
export default function MyComponent(props) {
const state = useStore({
getStyles() {
return {
color: 'red'
}
}
})
return (
<div style={state.getStyles()} />
);
}
`;

const component = parseJsx(code);

expect(component.children[0]).toMatchInlineSnapshot(`
{
"@type": "@builder.io/mitosis/node",
"bindings": {
"style": {
"bindingType": "expression",
"code": "state.getStyles()",
"type": "single",
},
},
"children": [],
"meta": {},
"name": "div",
"properties": {},
"scope": {},
}
`);

const builderJson = componentToBuilder()({ component });

expect(builderJson.data!.blocks![0]).toMatchInlineSnapshot(`
{
"@type": "@builder.io/sdk:Element",
"actions": {},
"bindings": {
"style": "state.getStyles()",
},
"children": [],
"code": {
"actions": {},
"bindings": {},
},
"properties": {},
"tagName": "div",
}
`);

const backToMitosis = builderContentToMitosisComponent(builderJson);

expect(backToMitosis.children[0]).toMatchInlineSnapshot(`
{
"@type": "@builder.io/mitosis/node",
"bindings": {
"style": {
"bindingType": "expression",
"code": "state.getStyles()",
"type": "single",
},
},
"children": [],
"meta": {},
"name": "div",
"properties": {},
"scope": {},
"slots": {},
}
`);

const mitosis = componentToMitosis(mitosisOptions)({
component: backToMitosis,
});
expect(mitosis).toMatchInlineSnapshot(`
"import { useStore } from \\"@builder.io/mitosis\\";
export default function MyComponent(props) {
const state = useStore({
getStyles() {
return {
color: \\"red\\",
};
},
});
return <div style={state.getStyles()} />;
}
"
`);
});

test('invalid style values are removed', () => {
const code = dedent`
export default function MyComponent(props) {
return (
<div style={false} />
);
}
`;

const component = parseJsx(code);
const builderJson = componentToBuilder()({ component });

expect(builderJson.data!.blocks![0]).toMatchInlineSnapshot(`
{
"@type": "@builder.io/sdk:Element",
"actions": {},
"bindings": {},
"children": [],
"code": {
"actions": {},
"bindings": {},
},
"properties": {},
"tagName": "div",
}
`);
});

test('drop unsupported bound styles to avoid crashes', () => {
const jsx = `export default function MyComponent(props) {
return (
Expand Down
25 changes: 24 additions & 1 deletion packages/core/src/generators/builder/generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,7 @@ const mapBoundStyles = (bindings: { [key: string]: Binding | undefined }) => {
if (!styles) {
return;
}
const { parsed } = parseJSObject(styles.code);
const { parsed, unparsed } = parseJSObject(styles.code);

for (const key in parsed) {
const mediaQueryMatch = key.match(mediaQueryRegex);
Expand Down Expand Up @@ -486,6 +486,29 @@ const mapBoundStyles = (bindings: { [key: string]: Binding | undefined }) => {
}

delete bindings['style'];

// unparsed data could be something else such as a function call
if (unparsed) {
try {
const ast = parseExpression(`(${unparsed})`, {
plugins: ['jsx', 'typescript'],
sourceType: 'module',
});

// style={state.getStyles()}
if (ast.type === 'CallExpression') {
bindings['style'] = {
code: unparsed,
bindingType: 'expression',
type: 'single',
};
} else {
throw 'unsupported style';
}
} catch {
console.warn(`The following bound styles are invalid and have been removed: ${unparsed}`);
}
}
};

function isGlobalStyle(key: string) {
Expand Down

0 comments on commit 0b55dc3

Please sign in to comment.