Skip to content

Commit af43f50

Browse files
authored
Feat complex metadata (#1638)
* feat: improve parseJSX to resolve complex useMetadata * fix: issue with metadata always be flat without correct depth * chore: add changeset * chore: add example for complex useMetadata * chore: run fmt * fix: complex metadata with spread variable * chore: run fmt * chore: update snapshots * chore: moved `isTypescriptFile` from `src/helpers` to `parsers/jsx/helpers` * chore: update snapshots
1 parent 20ad8dc commit af43f50

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+6713
-507
lines changed

.changeset/clean-cobras-know.md

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
---
2+
'@builder.io/mitosis': patch
3+
---
4+
5+
[All] Refactored `useMetadata` hook to enable import resolution instead of simple `JSON5` parsing.
6+
7+
You could use a normal JS `Object` and import it inside your `*.lite.tsx` file like this:
8+
9+
```ts
10+
// data.ts
11+
12+
export const myMetadata: Record<string, string | number> = {
13+
a: 'b',
14+
c: 1,
15+
};
16+
```
17+
18+
```tsx
19+
// my-button.lite.tsx
20+
import { useMetadata } from '@builder.io/mitosis';
21+
import { myMetadata } from './data.ts';
22+
23+
useMetadata({
24+
x: 'y',
25+
my: myMetadata,
26+
});
27+
28+
export default function MyButton() {
29+
return <button></button>;
30+
}
31+
```

examples/metdata/.eslintrc.js

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
module.exports = {
2+
env: {
3+
browser: true,
4+
},
5+
plugins: ["@builder.io/mitosis"],
6+
parser: "@typescript-eslint/parser",
7+
extends: [],
8+
parserOptions: {
9+
ecmaVersion: 2018,
10+
sourceType: "module",
11+
ecmaFeatures: {
12+
jsx: true,
13+
},
14+
},
15+
rules: {
16+
"@builder.io/mitosis/no-conditional-render": "warn",
17+
},
18+
};

examples/metdata/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
output

examples/metdata/README.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Metadata example for Mitosis
2+
3+
This is an example to showcase the ``useMetadata`` hook. You can use this to set predefined configuration parameters for each component. Or you can add additional parameters to use them in a plugin.

examples/metdata/mitosis.config.js

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
const metadataPlugin = () => ({
2+
code: {
3+
pre: (code, json) => {
4+
if (json.meta.useMetadata) {
5+
return `
6+
/**
7+
useMetadata:
8+
${JSON.stringify(json.meta.useMetadata)}
9+
*/
10+
11+
${code}`;
12+
}
13+
14+
return code;
15+
},
16+
},
17+
});
18+
19+
module.exports = {
20+
files: 'src/**',
21+
commonOptions: {
22+
plugins: [metadataPlugin],
23+
},
24+
targets: [
25+
'react',
26+
// still unsupported
27+
// 'qwik',
28+
// 'builder',
29+
'vue',
30+
'html',
31+
// TO-DO: fix error causing svelte output not to work
32+
// 'svelte',
33+
'solid',
34+
'angular',
35+
'webcomponent',
36+
],
37+
};

examples/metdata/package.json

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"name": "@builder.io/metadata-example",
3+
"private": true,
4+
"scripts": {
5+
"build": "mitosis build",
6+
"lint": "eslint"
7+
},
8+
"exports": {
9+
"./react/*": "./dist/react/src/*",
10+
"./qwik/*": "./dist/qwik/src/*",
11+
"./vue/*": "./dist/vue/src/*",
12+
"./svelte/*": "./dist/svelte/src/*",
13+
"./angular/*": "./dist/angular/src/*",
14+
"./html/*": "./dist/html/src/*",
15+
"./solid/*": "./dist/solid/src/*"
16+
},
17+
"dependencies": {
18+
"@builder.io/mitosis": "workspace:*",
19+
"@builder.io/mitosis-cli": "workspace:*",
20+
"eslint": "^7.21.0"
21+
}
22+
}
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { ComponentMetadata } from '@builder.io/mitosis';
2+
import { customMetaData } from '../shared/data';
3+
4+
export const metadata: ComponentMetadata = {
5+
regularKey: 'abc',
6+
'some-key': customMetaData,
7+
react: {
8+
forwardRef: 'xxx',
9+
},
10+
vue: {
11+
customKey: 'yyy',
12+
},
13+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { useMetadata } from '@builder.io/mitosis';
2+
import { metadata } from './data';
3+
4+
useMetadata({ ...metadata });
5+
6+
export default function MetadataExample() {
7+
return <div>Metadata</div>;
8+
}

examples/metdata/src/shared/data.ts

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { CustomMetadata } from './model';
2+
3+
export const customMetaData: CustomMetadata = {
4+
a: 'custom',
5+
b: 1,
6+
c: {
7+
d: 'nested',
8+
},
9+
};
10+
11+

examples/metdata/src/shared/model.ts

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export type CustomMetadata = {
2+
a: string;
3+
b: number;
4+
c: Object;
5+
};

examples/metdata/tsconfig.json

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"compilerOptions": {
3+
"target": "ESNext",
4+
"strict": true,
5+
"jsx": "preserve",
6+
"moduleResolution": "node",
7+
"jsxImportSource": "@builder.io/mitosis"
8+
},
9+
"include": ["src"]
10+
}

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

+100-4
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,10 @@ exports[`Alpine.js > jsx > Javascript Test > Basic Outputs 1`] = `
241241
`;
242242
243243
exports[`Alpine.js > jsx > Javascript Test > Basic Outputs Meta 1`] = `
244-
"<div x-data=\\"myBasicOutputsComponent()\\"></div>
244+
"/** useMetadata: {\\"outputs\\":[\\"onMessage\\",\\"onEvent\\"],\\"baz\\":\\"metadata inside
245+
component\\"} */
246+
247+
<div x-data=\\"myBasicOutputsComponent()\\"></div>
245248
<script>
246249
document.addEventListener(\\"alpine:init\\", () => {
247250
Alpine.data(\\"myBasicOutputsComponent\\", () => ({
@@ -1630,7 +1633,9 @@ exports[`Alpine.js > jsx > Javascript Test > basicForwardRef 1`] = `
16301633
`;
16311634
16321635
exports[`Alpine.js > jsx > Javascript Test > basicForwardRefMetadata 1`] = `
1633-
"<style>
1636+
"/** useMetadata: {\\"forwardRef\\":\\"inputRef\\"} */
1637+
1638+
<style>
16341639
.input {
16351640
color: red;
16361641
}
@@ -1784,6 +1789,20 @@ exports[`Alpine.js > jsx > Javascript Test > classState 1`] = `
17841789
"
17851790
`;
17861791
1792+
exports[`Alpine.js > jsx > Javascript Test > complexMeta 1`] = `
1793+
"/** useMetadata:
1794+
{\\"x\\":\\"y\\",\\"asdf\\":{\\"stringValue\\":\\"d\\",\\"booleanValue\\":true,\\"numberValue\\":1,\\"innerObject\\":{\\"stringValue\\":\\"inner\\",\\"numberValue\\":2,\\"booleanValue\\":false},\\"spreadStringValue\\":\\"f\\"}}
1795+
*/
1796+
1797+
<div x-data=\\"complexMetaRaw()\\"></div>
1798+
<script>
1799+
document.addEventListener(\\"alpine:init\\", () => {
1800+
Alpine.data(\\"complexMetaRaw\\", () => ({}));
1801+
});
1802+
</script>
1803+
"
1804+
`;
1805+
17871806
exports[`Alpine.js > jsx > Javascript Test > componentWithContext 1`] = `
17881807
"<div x-data=\\"componentWithContext()\\">
17891808
<div><span x-html=\\"foo.value\\"></span></div>
@@ -1922,6 +1941,35 @@ exports[`Alpine.js > jsx > Javascript Test > expressionState 1`] = `
19221941
"
19231942
`;
19241943
1944+
exports[`Alpine.js > jsx > Javascript Test > figmaMeta 1`] = `
1945+
"/** useMetadata:
1946+
{\\"figma\\":{\\"name\\":\\"def-button-beta-outlined\\",\\"url\\":\\"https://www.figma.com/xxx\\",\\"props\\":{\\"iconSmall\\":{\\"type\\":\\"instance\\",\\"key\\":\\"📍
1947+
Icon Small\\"},\\"iconMedium\\":{\\"type\\":\\"instance\\",\\"key\\":\\"📍 Icon
1948+
Medium\\"},\\"label\\":{\\"type\\":\\"string\\",\\"key\\":\\"✏️
1949+
Label\\"},\\"icon\\":{\\"type\\":\\"boolean\\",\\"key\\":\\"👁️
1950+
Icon\\",\\"value\\":{\\"false\\":false,\\"true\\":\\"placeholder\\"}},\\"interactiveState\\":{\\"type\\":\\"enum\\",\\"key\\":\\"Interactive
1951+
State\\",\\"value\\":{\\"(Def)
1952+
Enabled\\":false,\\"Hovered\\":false,\\"Pressed\\":false,\\"Focused\\":false,\\"Disabled\\":\\"true\\"}},\\"size\\":{\\"type\\":\\"enum\\",\\"key\\":\\"Size\\",\\"value\\":{\\"(Def)
1953+
Medium\\":false,\\"Small\\":\\"small\\"}},\\"width\\":{\\"type\\":\\"enum\\",\\"key\\":\\"Width\\",\\"value\\":{\\"(Def)
1954+
Auto Width\\":false,\\"Full Width\\":\\"full\\"}}}}} */
1955+
1956+
<button
1957+
x-data=\\"figmaButton()\\"
1958+
x-bind:data-icon=\\"icon\\"
1959+
x-bind:data-disabled=\\"interactiveState\\"
1960+
x-bind:data-width=\\"width\\"
1961+
x-bind:data-size=\\"size\\"
1962+
>
1963+
<span x-html=\\"label\\"></span>
1964+
</button>
1965+
<script>
1966+
document.addEventListener(\\"alpine:init\\", () => {
1967+
Alpine.data(\\"figmaButton\\", () => ({}));
1968+
});
1969+
</script>
1970+
"
1971+
`;
1972+
19251973
exports[`Alpine.js > jsx > Javascript Test > getterState 1`] = `
19261974
"<div x-data=\\"button()\\">
19271975
<p><span x-html=\\"foo2\\"></span></p>
@@ -3319,7 +3367,10 @@ exports[`Alpine.js > jsx > Typescript Test > Basic Outputs 1`] = `
33193367
`;
33203368
33213369
exports[`Alpine.js > jsx > Typescript Test > Basic Outputs Meta 1`] = `
3322-
"<div x-data=\\"myBasicOutputsComponent()\\"></div>
3370+
"/** useMetadata: {\\"outputs\\":[\\"onMessage\\",\\"onEvent\\"],\\"baz\\":\\"metadata inside
3371+
component\\"} */
3372+
3373+
<div x-data=\\"myBasicOutputsComponent()\\"></div>
33233374
<script>
33243375
document.addEventListener(\\"alpine:init\\", () => {
33253376
Alpine.data(\\"myBasicOutputsComponent\\", () => ({
@@ -4697,7 +4748,9 @@ exports[`Alpine.js > jsx > Typescript Test > basicForwardRef 1`] = `
46974748
`;
46984749
46994750
exports[`Alpine.js > jsx > Typescript Test > basicForwardRefMetadata 1`] = `
4700-
"<style>
4751+
"/** useMetadata: {\\"forwardRef\\":\\"inputRef\\"} */
4752+
4753+
<style>
47014754
.input {
47024755
color: red;
47034756
}
@@ -4851,6 +4904,20 @@ exports[`Alpine.js > jsx > Typescript Test > classState 1`] = `
48514904
"
48524905
`;
48534906
4907+
exports[`Alpine.js > jsx > Typescript Test > complexMeta 1`] = `
4908+
"/** useMetadata:
4909+
{\\"x\\":\\"y\\",\\"asdf\\":{\\"stringValue\\":\\"d\\",\\"booleanValue\\":true,\\"numberValue\\":1,\\"innerObject\\":{\\"stringValue\\":\\"inner\\",\\"numberValue\\":2,\\"booleanValue\\":false},\\"spreadStringValue\\":\\"f\\"}}
4910+
*/
4911+
4912+
<div x-data=\\"complexMetaRaw()\\"></div>
4913+
<script>
4914+
document.addEventListener(\\"alpine:init\\", () => {
4915+
Alpine.data(\\"complexMetaRaw\\", () => ({}));
4916+
});
4917+
</script>
4918+
"
4919+
`;
4920+
48544921
exports[`Alpine.js > jsx > Typescript Test > componentWithContext 1`] = `
48554922
"<div x-data=\\"componentWithContext()\\">
48564923
<div><span x-html=\\"foo.value\\"></span></div>
@@ -4989,6 +5056,35 @@ exports[`Alpine.js > jsx > Typescript Test > expressionState 1`] = `
49895056
"
49905057
`;
49915058
5059+
exports[`Alpine.js > jsx > Typescript Test > figmaMeta 1`] = `
5060+
"/** useMetadata:
5061+
{\\"figma\\":{\\"name\\":\\"def-button-beta-outlined\\",\\"url\\":\\"https://www.figma.com/xxx\\",\\"props\\":{\\"iconSmall\\":{\\"type\\":\\"instance\\",\\"key\\":\\"📍
5062+
Icon Small\\"},\\"iconMedium\\":{\\"type\\":\\"instance\\",\\"key\\":\\"📍 Icon
5063+
Medium\\"},\\"label\\":{\\"type\\":\\"string\\",\\"key\\":\\"✏️
5064+
Label\\"},\\"icon\\":{\\"type\\":\\"boolean\\",\\"key\\":\\"👁️
5065+
Icon\\",\\"value\\":{\\"false\\":false,\\"true\\":\\"placeholder\\"}},\\"interactiveState\\":{\\"type\\":\\"enum\\",\\"key\\":\\"Interactive
5066+
State\\",\\"value\\":{\\"(Def)
5067+
Enabled\\":false,\\"Hovered\\":false,\\"Pressed\\":false,\\"Focused\\":false,\\"Disabled\\":\\"true\\"}},\\"size\\":{\\"type\\":\\"enum\\",\\"key\\":\\"Size\\",\\"value\\":{\\"(Def)
5068+
Medium\\":false,\\"Small\\":\\"small\\"}},\\"width\\":{\\"type\\":\\"enum\\",\\"key\\":\\"Width\\",\\"value\\":{\\"(Def)
5069+
Auto Width\\":false,\\"Full Width\\":\\"full\\"}}}}} */
5070+
5071+
<button
5072+
x-data=\\"figmaButton()\\"
5073+
x-bind:data-icon=\\"icon\\"
5074+
x-bind:data-disabled=\\"interactiveState\\"
5075+
x-bind:data-width=\\"width\\"
5076+
x-bind:data-size=\\"size\\"
5077+
>
5078+
<span x-html=\\"label\\"></span>
5079+
</button>
5080+
<script>
5081+
document.addEventListener(\\"alpine:init\\", () => {
5082+
Alpine.data(\\"figmaButton\\", () => ({}));
5083+
});
5084+
</script>
5085+
"
5086+
`;
5087+
49925088
exports[`Alpine.js > jsx > Typescript Test > getterState 1`] = `
49935089
"<div x-data=\\"button()\\">
49945090
<p><span x-html=\\"foo2\\"></span></p>

0 commit comments

Comments
 (0)