Skip to content

Commit

Permalink
fix innerHTML property handling in react codegen (#1679)
Browse files Browse the repository at this point in the history
* fix innerHTML property handling in react codegen

* fix merge conflict

* changeset

---------

Co-authored-by: Kyle Fowler <[email protected]>
Co-authored-by: Kyle Fowler <[email protected]>
  • Loading branch information
3 people authored Feb 7, 2025
1 parent 5f7fe53 commit b6a01ab
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 5 deletions.
5 changes: 5 additions & 0 deletions .changeset/brave-beds-act.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@builder.io/mitosis': patch
---

Fix: properly handle innerHTML properties in react codegen
33 changes: 33 additions & 0 deletions packages/core/src/__tests__/__snapshots__/builder.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -3530,6 +3530,39 @@ exports[`Builder > Text with bindings 3`] = `
}
`;
exports[`Builder > Valid Custom Code 1`] = `
"<template>
<div><div innerHTML='<svg width=\\"200\\" height=\\"200\\"></svg>'></div></div>
</template>
<script>
import { defineComponent } from \\"vue\\";
export default defineComponent({
name: \\"my-component\\",
});
</script>"
`;
exports[`Builder > Valid Custom Code 2`] = `
"import * as React from \\"react\\";
function MyComponent(props) {
return (
<div>
<div
dangerouslySetInnerHTML={{
__html: \\"<svg width=&quot;200&quot; height=&quot;200&quot;></svg>\\",
}}
/>
</div>
);
}
export default MyComponent;
"
`;
exports[`Builder > async bindings 1`] = `
{
"data": {
Expand Down
30 changes: 30 additions & 0 deletions packages/core/src/__tests__/builder.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { componentToHtml } from '@/generators/html';
import { componentToMitosis } from '@/generators/mitosis';
import { ToMitosisOptions } from '@/generators/mitosis/types';
import { componentToReact } from '@/generators/react';
import { componentToVue } from '@/generators/vue';
import { dedent } from '@/helpers/dedent';
import {
builderContentToMitosisComponent,
Expand Down Expand Up @@ -322,6 +323,35 @@ describe('Builder', () => {
expect(html).toMatchSnapshot();
});

test('Valid Custom Code', async () => {
const builderJson: BuilderContent = {
data: {
blocks: [
{
'@type': '@builder.io/sdk:Element',
component: {
name: 'CustomCode',
options: {
code: `<svg width="200" height="200"></svg>`,
},
},
},
],
},
} as BuilderContent;
const component = builderContentToMitosisComponent(builderJson);

const vue = componentToVue({
plugins: [compileAwayBuilderComponents()],
})({ component });
expect(vue).toMatchSnapshot();

const react = componentToReact({
plugins: [compileAwayBuilderComponents()],
})({ component });
expect(react).toMatchSnapshot();
});

test('Regenerate custom Hero', () => {
const code = dedent`
import { Hero } from "@components";
Expand Down
19 changes: 15 additions & 4 deletions packages/core/src/generators/react/blocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,12 @@ const ATTTRIBUTE_MAPPERS: { [key: string]: string } = {
const BINDING_MAPPERS: {
[key: string]:
| string
| ((key: string, value: string, options?: ToReactOptions) => [string, string]);
| ((
key: string,
value: string,
options?: ToReactOptions,
isProperty?: boolean,
) => [string, string]);
} = {
ref(ref, value, options) {
if (options?.preact) {
Expand All @@ -161,8 +166,14 @@ const BINDING_MAPPERS: {
}
return [ref, value];
},
innerHTML(_key, value) {
return ['dangerouslySetInnerHTML', `{__html: ${value.replace(/\s+/g, ' ')}}`];
innerHTML(_key, value, _options, isProperty) {
const wrapChar = isProperty ? '"' : '';
let useValue = value.replace(/\s+/g, ' ');

if (isProperty) {
useValue = value.replace(/"/g, '\\"');
}
return ['dangerouslySetInnerHTML', `{__html: ${wrapChar}${useValue}${wrapChar}}`];
},
...ATTTRIBUTE_MAPPERS,
};
Expand Down Expand Up @@ -246,7 +257,7 @@ export const blockToReact = (
} else if (BINDING_MAPPERS[key]) {
const mapper = BINDING_MAPPERS[key];
if (typeof mapper === 'function') {
const [newKey, newValue] = mapper(key, value, options);
const [newKey, newValue] = mapper(key, value, options, true);
str += ` ${newKey}={${newValue}} `;
} else {
str += ` ${BINDING_MAPPERS[key]}="${value}" `;
Expand Down
5 changes: 4 additions & 1 deletion packages/core/src/plugins/compile-away-builder-components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,10 @@ export const components: CompileAwayComponentsMap = {
bindings.innerHTML = node.bindings.code;
}
return wrapOutput(
node,
{
...node,
properties: omit(node.properties, 'code'),
},
createMitosisNode({
name: (node.properties.builderTag as string) || 'div',
properties: {
Expand Down

0 comments on commit b6a01ab

Please sign in to comment.