Skip to content

Commit 4123bfc

Browse files
committed
add symbol name serialization and inputs to level props
1 parent 993fd9e commit 4123bfc

File tree

8 files changed

+435
-8
lines changed

8 files changed

+435
-8
lines changed

packages/core/src/__tests__/__snapshots__/qwik.test.ts.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10145,7 +10145,7 @@ exports[`qwik > page-with-symbol 1`] = `
1014510145
});
1014610146
};
1014710147
",
10148-
"low.js": "import { Symbol1 } from \\"./med.js\\";
10148+
"low.js": "import { SymbolHeaderSymbol } from \\"./med.js\\";
1014910149

1015010150
import {
1015110151
Fragment,
@@ -10178,7 +10178,7 @@ export const MyComponentOnMount = (p) => {
1017810178
return h(
1017910179
Fragment,
1018010180
null,
10181-
h(Symbol1, {
10181+
h(SymbolHeaderSymbol, {
1018210182
class: \\"c713ty2\\",
1018310183
symbol: {
1018410184
model: \\"page\\",

packages/core/src/__tests__/builder/__snapshots__/builder.test.ts.snap

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4925,3 +4925,117 @@ function MyComponent(props) {
49254925
export default MyComponent;
49264926
"
49274927
`;
4928+
4929+
exports[`Symbol Serialization > Multiple symbols with different names 1`] = `
4930+
"import {
4931+
SymbolPrimaryButton,
4932+
SymbolSecondaryButton,
4933+
SymbolFooterSection,
4934+
} from \\"@components\\";
4935+
4936+
export default function MyComponent(props) {
4937+
return (
4938+
<>
4939+
<SymbolPrimaryButton
4940+
symbol={{
4941+
entry: \\"2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e\\",
4942+
model: \\"symbol\\",
4943+
ownerId: \\"99d964b716f94737a50de4d76134d098\\",
4944+
}}
4945+
text={\\"Get Started\\"}
4946+
variant={\\"primary\\"}
4947+
/>
4948+
<SymbolSecondaryButton
4949+
symbol={{
4950+
entry: \\"3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f\\",
4951+
model: \\"symbol\\",
4952+
ownerId: \\"99d964b716f94737a50de4d76134d098\\",
4953+
}}
4954+
text={\\"Learn More\\"}
4955+
variant={\\"secondary\\"}
4956+
/>
4957+
<SymbolFooterSection
4958+
symbol={{
4959+
entry: \\"4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a\\",
4960+
model: \\"symbol\\",
4961+
ownerId: \\"99d964b716f94737a50de4d76134d098\\",
4962+
}}
4963+
copyrightText={\\"© 2024 Company Name\\"}
4964+
showSocialLinks={true}
4965+
/>
4966+
</>
4967+
);
4968+
}
4969+
"
4970+
`;
4971+
4972+
exports[`Symbol Serialization > Symbol with basic metadata 1`] = `
4973+
"import { SymbolBasicSymbol } from \\"@components\\";
4974+
4975+
export default function MyComponent(props) {
4976+
return (
4977+
<SymbolBasicSymbol
4978+
symbol={{
4979+
entry: \\"5a009380a7274b1388f8f1e500d2e28a\\",
4980+
model: \\"symbol\\",
4981+
ownerId: \\"99d964b716f94737a50de4d76134d098\\",
4982+
}}
4983+
/>
4984+
);
4985+
}
4986+
"
4987+
`;
4988+
4989+
exports[`Symbol Serialization > Symbol with entry name 1`] = `
4990+
"import { SymbolHeaderNavigation } from \\"@components\\";
4991+
4992+
export default function MyComponent(props) {
4993+
return (
4994+
<SymbolHeaderNavigation
4995+
symbol={{
4996+
entry: \\"1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d\\",
4997+
model: \\"symbol\\",
4998+
ownerId: \\"99d964b716f94737a50de4d76134d098\\",
4999+
}}
5000+
logoUrl={\\"/logo.png\\"}
5001+
showSearch={true}
5002+
menuItems={[
5003+
{
5004+
label: \\"Home\\",
5005+
url: \\"/\\",
5006+
},
5007+
{
5008+
label: \\"About\\",
5009+
url: \\"/about\\",
5010+
},
5011+
]}
5012+
/>
5013+
);
5014+
}
5015+
"
5016+
`;
5017+
5018+
exports[`Symbol Serialization > Symbol with inputs as top-level props 1`] = `
5019+
"import { SymbolButtonComponent } from \\"@components\\";
5020+
5021+
export default function MyComponent(props) {
5022+
return (
5023+
<SymbolButtonComponent
5024+
symbol={{
5025+
entry: \\"7b8c9d0e1a2b3c4d5e6f7a8b9c0d1e2f\\",
5026+
model: \\"symbol\\",
5027+
ownerId: \\"99d964b716f94737a50de4d76134d098\\",
5028+
}}
5029+
buttonText={\\"Click me!\\"}
5030+
variant={\\"primary\\"}
5031+
isDisabled={false}
5032+
count={42}
5033+
config={{
5034+
showIcon: true,
5035+
iconPosition: \\"left\\",
5036+
}}
5037+
/>
5038+
);
5039+
}
5040+
"
5041+
`;

packages/core/src/__tests__/builder/builder.test.ts

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ import lazyLoadSection from '../data/builder/lazy-load-section.json?raw';
3434
import localization from '../data/builder/localization.json?raw';
3535
import slotsContent from '../data/builder/slots.json?raw';
3636
import slots2Content from '../data/builder/slots2.json?raw';
37+
import symbolBasic from '../data/builder/symbol-basic.json?raw';
38+
import symbolMultiple from '../data/builder/symbol-multiple.json?raw';
39+
import symbolWithInputs from '../data/builder/symbol-with-inputs.json?raw';
40+
import symbolWithNamedEntry from '../data/builder/symbol-with-named-entry.json?raw';
3741
import tagNameContent from '../data/builder/tag-name.json?raw';
3842
import textBindings from '../data/builder/text-bindings.json?raw';
3943
import advancedFor from '../data/for/advanced-for.raw.tsx?raw';
@@ -2094,3 +2098,81 @@ const bindingJson = {
20942098
],
20952099
},
20962100
};
2101+
2102+
describe('Symbol Serialization', () => {
2103+
test('Symbol with basic metadata', () => {
2104+
const builderContent = JSON.parse(symbolBasic) as BuilderContent;
2105+
const component = builderContentToMitosisComponent(builderContent);
2106+
const mitosis = componentToMitosis(mitosisOptions)({ component });
2107+
2108+
// Verify symbol name is sanitized and prefixed
2109+
expect(component.children[0].name).toBe('SymbolBasicSymbol');
2110+
expect(mitosis).toMatchSnapshot();
2111+
});
2112+
2113+
test('Symbol with entry name', () => {
2114+
const builderContent = JSON.parse(symbolWithNamedEntry) as BuilderContent;
2115+
const component = builderContentToMitosisComponent(builderContent);
2116+
const mitosis = componentToMitosis(mitosisOptions)({ component });
2117+
2118+
// Verify symbol name is sanitized and prefixed
2119+
expect(component.children[0].name).toBe('SymbolHeaderNavigation');
2120+
expect(mitosis).toMatchSnapshot();
2121+
});
2122+
2123+
test('Symbol with inputs as top-level props', () => {
2124+
const builderContent = JSON.parse(symbolWithInputs) as BuilderContent;
2125+
const component = builderContentToMitosisComponent(builderContent);
2126+
const mitosis = componentToMitosis(mitosisOptions)({ component });
2127+
2128+
// Verify inputs are top-level bindings
2129+
const symbolNode = component.children[0];
2130+
expect(symbolNode.name).toBe('SymbolButtonComponent');
2131+
expect(symbolNode.bindings).toHaveProperty('buttonText');
2132+
expect(symbolNode.bindings).toHaveProperty('variant');
2133+
expect(symbolNode.bindings).toHaveProperty('isDisabled');
2134+
expect(symbolNode.bindings).toHaveProperty('count');
2135+
expect(symbolNode.bindings).toHaveProperty('config');
2136+
expect(symbolNode.bindings.symbol).toBeDefined();
2137+
2138+
// Verify symbol binding doesn't contain data anymore
2139+
const symbolBinding = JSON.parse(symbolNode.bindings.symbol.code);
2140+
expect(symbolBinding.data).toBeUndefined();
2141+
2142+
expect(mitosis).toMatchSnapshot();
2143+
});
2144+
2145+
test('Multiple symbols with different names', () => {
2146+
const builderContent = JSON.parse(symbolMultiple) as BuilderContent;
2147+
const component = builderContentToMitosisComponent(builderContent);
2148+
const mitosis = componentToMitosis(mitosisOptions)({ component });
2149+
2150+
// Verify each symbol has unique name
2151+
expect(component.children[0].name).toBe('SymbolPrimaryButton');
2152+
expect(component.children[1].name).toBe('SymbolSecondaryButton');
2153+
expect(component.children[2].name).toBe('SymbolFooterSection');
2154+
2155+
// Verify inputs are extracted for each
2156+
expect(component.children[0].bindings).toHaveProperty('text');
2157+
expect(component.children[0].bindings).toHaveProperty('variant');
2158+
expect(component.children[1].bindings).toHaveProperty('text');
2159+
expect(component.children[1].bindings).toHaveProperty('variant');
2160+
expect(component.children[2].bindings).toHaveProperty('copyrightText');
2161+
expect(component.children[2].bindings).toHaveProperty('showSocialLinks');
2162+
2163+
expect(mitosis).toMatchSnapshot();
2164+
});
2165+
2166+
test('Symbol roundtrip: Builder -> Mitosis -> Builder', () => {
2167+
const original = JSON.parse(symbolWithInputs) as BuilderContent;
2168+
const mitosisComponent = builderContentToMitosisComponent(original);
2169+
const backToBuilder = componentToBuilder()({ component: mitosisComponent });
2170+
2171+
// Verify the symbol structure is preserved
2172+
const originalSymbol = original.data?.blocks?.[0];
2173+
const roundtripSymbol = backToBuilder.data?.blocks?.[0];
2174+
2175+
expect(roundtripSymbol?.component?.name).toBeDefined();
2176+
expect(roundtripSymbol?.component?.options?.symbol).toBeDefined();
2177+
});
2178+
});
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"data": {
3+
"blocks": [
4+
{
5+
"@type": "@builder.io/sdk:Element",
6+
"@version": 2,
7+
"id": "builder-abc123",
8+
"component": {
9+
"name": "Symbol",
10+
"options": {
11+
"symbol": {
12+
"entry": "5a009380a7274b1388f8f1e500d2e28a",
13+
"model": "symbol",
14+
"ownerId": "99d964b716f94737a50de4d76134d098",
15+
"content": {
16+
"name": "Basic Symbol"
17+
}
18+
}
19+
}
20+
}
21+
}
22+
]
23+
}
24+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
{
2+
"data": {
3+
"blocks": [
4+
{
5+
"@type": "@builder.io/sdk:Element",
6+
"@version": 2,
7+
"id": "builder-jkl012",
8+
"component": {
9+
"name": "Symbol",
10+
"options": {
11+
"symbol": {
12+
"entry": "2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e",
13+
"model": "symbol",
14+
"ownerId": "99d964b716f94737a50de4d76134d098",
15+
"content": {
16+
"name": "Primary Button"
17+
},
18+
"data": {
19+
"text": "Get Started",
20+
"variant": "primary"
21+
}
22+
}
23+
}
24+
}
25+
},
26+
{
27+
"@type": "@builder.io/sdk:Element",
28+
"@version": 2,
29+
"id": "builder-mno345",
30+
"component": {
31+
"name": "Symbol",
32+
"options": {
33+
"symbol": {
34+
"entry": "3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f",
35+
"model": "symbol",
36+
"ownerId": "99d964b716f94737a50de4d76134d098",
37+
"content": {
38+
"name": "Secondary Button"
39+
},
40+
"data": {
41+
"text": "Learn More",
42+
"variant": "secondary"
43+
}
44+
}
45+
}
46+
}
47+
},
48+
{
49+
"@type": "@builder.io/sdk:Element",
50+
"@version": 2,
51+
"id": "builder-pqr678",
52+
"component": {
53+
"name": "Symbol",
54+
"options": {
55+
"symbol": {
56+
"entry": "4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a",
57+
"model": "symbol",
58+
"ownerId": "99d964b716f94737a50de4d76134d098",
59+
"content": {
60+
"name": "Footer Section"
61+
},
62+
"data": {
63+
"copyrightText": "© 2024 Company Name",
64+
"showSocialLinks": true
65+
}
66+
}
67+
}
68+
}
69+
}
70+
]
71+
}
72+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"data": {
3+
"blocks": [
4+
{
5+
"@type": "@builder.io/sdk:Element",
6+
"@version": 2,
7+
"id": "builder-def456",
8+
"component": {
9+
"name": "Symbol",
10+
"options": {
11+
"symbol": {
12+
"entry": "7b8c9d0e1a2b3c4d5e6f7a8b9c0d1e2f",
13+
"model": "symbol",
14+
"ownerId": "99d964b716f94737a50de4d76134d098",
15+
"content": {
16+
"name": "Button Component"
17+
},
18+
"data": {
19+
"buttonText": "Click me!",
20+
"variant": "primary",
21+
"isDisabled": false,
22+
"count": 42,
23+
"config": {
24+
"showIcon": true,
25+
"iconPosition": "left"
26+
}
27+
}
28+
}
29+
}
30+
}
31+
}
32+
]
33+
}
34+
}

0 commit comments

Comments
 (0)