Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat complex metadata #1638

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .changeset/clean-cobras-know.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
'@builder.io/mitosis': patch
---

[All] Refactored `useMetadata` hook to enable import resolution instead of simple `JSON5` parsing.

You could use a normal JS `Object` and import it inside your `*.lite.tsx` file like this:

```ts
// data.ts

export const myMetadata: Record<string, string | number> = {
a: 'b',
c: 1,
};
```

```tsx
// my-button.lite.tsx
import { useMetadata } from '@builder.io/mitosis';
import { myMetadata } from './data.ts';

useMetadata({
x: 'y',
my: myMetadata,
});

export default function MyButton() {
return <button></button>;
}
```
18 changes: 18 additions & 0 deletions examples/metdata/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module.exports = {
env: {
browser: true,
},
plugins: ["@builder.io/mitosis"],
parser: "@typescript-eslint/parser",
extends: [],
parserOptions: {
ecmaVersion: 2018,
sourceType: "module",
ecmaFeatures: {
jsx: true,
},
},
rules: {
"@builder.io/mitosis/no-conditional-render": "warn",
},
};
1 change: 1 addition & 0 deletions examples/metdata/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
output
3 changes: 3 additions & 0 deletions examples/metdata/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Metadata example for Mitosis

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.
37 changes: 37 additions & 0 deletions examples/metdata/mitosis.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
const metadataPlugin = () => ({
code: {
pre: (code, json) => {
if (json.meta.useMetadata) {
return `
/**
useMetadata:
${JSON.stringify(json.meta.useMetadata)}
*/

${code}`;
}

return code;
},
},
});

module.exports = {
files: 'src/**',
commonOptions: {
plugins: [metadataPlugin],
},
targets: [
'react',
// still unsupported
// 'qwik',
// 'builder',
'vue',
'html',
// TO-DO: fix error causing svelte output not to work
// 'svelte',
'solid',
'angular',
'webcomponent',
],
};
22 changes: 22 additions & 0 deletions examples/metdata/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "@builder.io/metadata-example",
"private": true,
"scripts": {
"build": "mitosis build",
"lint": "eslint"
},
"exports": {
"./react/*": "./dist/react/src/*",
"./qwik/*": "./dist/qwik/src/*",
"./vue/*": "./dist/vue/src/*",
"./svelte/*": "./dist/svelte/src/*",
"./angular/*": "./dist/angular/src/*",
"./html/*": "./dist/html/src/*",
"./solid/*": "./dist/solid/src/*"
},
"dependencies": {
"@builder.io/mitosis": "workspace:*",
"@builder.io/mitosis-cli": "workspace:*",
"eslint": "^7.21.0"
}
}
13 changes: 13 additions & 0 deletions examples/metdata/src/components/data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { ComponentMetadata } from '@builder.io/mitosis';
import { customMetaData } from '../shared/data';

export const metadata: ComponentMetadata = {
regularKey: 'abc',
'some-key': customMetaData,
react: {
forwardRef: 'xxx',
},
vue: {
customKey: 'yyy',
},
};
8 changes: 8 additions & 0 deletions examples/metdata/src/components/metadata.lite.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { useMetadata } from '@builder.io/mitosis';
import { metadata } from './data';

useMetadata({ ...metadata });

export default function MetadataExample() {
return <div>Metadata</div>;
}
11 changes: 11 additions & 0 deletions examples/metdata/src/shared/data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { CustomMetadata } from './model';

export const customMetaData: CustomMetadata = {
a: 'custom',
b: 1,
c: {
d: 'nested',
},
};


5 changes: 5 additions & 0 deletions examples/metdata/src/shared/model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export type CustomMetadata = {
a: string;
b: number;
c: Object;
};
10 changes: 10 additions & 0 deletions examples/metdata/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"compilerOptions": {
"target": "ESNext",
"strict": true,
"jsx": "preserve",
"moduleResolution": "node",
"jsxImportSource": "@builder.io/mitosis"
},
"include": ["src"]
}
104 changes: 100 additions & 4 deletions packages/core/src/__tests__/__snapshots__/alpine.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,10 @@ exports[`Alpine.js > jsx > Javascript Test > Basic Outputs 1`] = `
`;

exports[`Alpine.js > jsx > Javascript Test > Basic Outputs Meta 1`] = `
"<div x-data=\\"myBasicOutputsComponent()\\"></div>
"/** useMetadata: {\\"outputs\\":[\\"onMessage\\",\\"onEvent\\"],\\"baz\\":\\"metadata inside
component\\"} */

<div x-data=\\"myBasicOutputsComponent()\\"></div>
<script>
document.addEventListener(\\"alpine:init\\", () => {
Alpine.data(\\"myBasicOutputsComponent\\", () => ({
Expand Down Expand Up @@ -1616,7 +1619,9 @@ exports[`Alpine.js > jsx > Javascript Test > basicForwardRef 1`] = `
`;

exports[`Alpine.js > jsx > Javascript Test > basicForwardRefMetadata 1`] = `
"<style>
"/** useMetadata: {\\"forwardRef\\":\\"inputRef\\"} */

<style>
.input {
color: red;
}
Expand Down Expand Up @@ -1770,6 +1775,20 @@ exports[`Alpine.js > jsx > Javascript Test > classState 1`] = `
"
`;

exports[`Alpine.js > jsx > Javascript Test > complexMeta 1`] = `
"/** useMetadata:
{\\"x\\":\\"y\\",\\"asdf\\":{\\"stringValue\\":\\"d\\",\\"booleanValue\\":true,\\"numberValue\\":1,\\"innerObject\\":{\\"stringValue\\":\\"inner\\",\\"numberValue\\":2,\\"booleanValue\\":false}}}
*/

<div x-data=\\"complexMetaRaw()\\"></div>
<script>
document.addEventListener(\\"alpine:init\\", () => {
Alpine.data(\\"complexMetaRaw\\", () => ({}));
});
</script>
"
`;

exports[`Alpine.js > jsx > Javascript Test > componentWithContext 1`] = `
"<div x-data=\\"componentWithContext()\\">
<div><span x-html=\\"foo.value\\"></span></div>
Expand Down Expand Up @@ -1908,6 +1927,35 @@ exports[`Alpine.js > jsx > Javascript Test > expressionState 1`] = `
"
`;

exports[`Alpine.js > jsx > Javascript Test > figmaMeta 1`] = `
"/** useMetadata:
{\\"figma\\":{\\"name\\":\\"def-button-beta-outlined\\",\\"url\\":\\"https://www.figma.com/xxx\\",\\"props\\":{\\"iconSmall\\":{\\"type\\":\\"instance\\",\\"key\\":\\"📍
Icon Small\\"},\\"iconMedium\\":{\\"type\\":\\"instance\\",\\"key\\":\\"📍 Icon
Medium\\"},\\"label\\":{\\"type\\":\\"string\\",\\"key\\":\\"✏️
Label\\"},\\"icon\\":{\\"type\\":\\"boolean\\",\\"key\\":\\"👁️
Icon\\",\\"value\\":{\\"false\\":false,\\"true\\":\\"placeholder\\"}},\\"interactiveState\\":{\\"type\\":\\"enum\\",\\"key\\":\\"Interactive
State\\",\\"value\\":{\\"(Def)
Enabled\\":false,\\"Hovered\\":false,\\"Pressed\\":false,\\"Focused\\":false,\\"Disabled\\":\\"true\\"}},\\"size\\":{\\"type\\":\\"enum\\",\\"key\\":\\"Size\\",\\"value\\":{\\"(Def)
Medium\\":false,\\"Small\\":\\"small\\"}},\\"width\\":{\\"type\\":\\"enum\\",\\"key\\":\\"Width\\",\\"value\\":{\\"(Def)
Auto Width\\":false,\\"Full Width\\":\\"full\\"}}}}} */

<button
x-data=\\"figmaButton()\\"
x-bind:data-icon=\\"icon\\"
x-bind:data-disabled=\\"interactiveState\\"
x-bind:data-width=\\"width\\"
x-bind:data-size=\\"size\\"
>
<span x-html=\\"label\\"></span>
</button>
<script>
document.addEventListener(\\"alpine:init\\", () => {
Alpine.data(\\"figmaButton\\", () => ({}));
});
</script>
"
`;

exports[`Alpine.js > jsx > Javascript Test > getterState 1`] = `
"<div x-data=\\"button()\\">
<p><span x-html=\\"foo2\\"></span></p>
Expand Down Expand Up @@ -3305,7 +3353,10 @@ exports[`Alpine.js > jsx > Typescript Test > Basic Outputs 1`] = `
`;

exports[`Alpine.js > jsx > Typescript Test > Basic Outputs Meta 1`] = `
"<div x-data=\\"myBasicOutputsComponent()\\"></div>
"/** useMetadata: {\\"outputs\\":[\\"onMessage\\",\\"onEvent\\"],\\"baz\\":\\"metadata inside
component\\"} */

<div x-data=\\"myBasicOutputsComponent()\\"></div>
<script>
document.addEventListener(\\"alpine:init\\", () => {
Alpine.data(\\"myBasicOutputsComponent\\", () => ({
Expand Down Expand Up @@ -4669,7 +4720,9 @@ exports[`Alpine.js > jsx > Typescript Test > basicForwardRef 1`] = `
`;

exports[`Alpine.js > jsx > Typescript Test > basicForwardRefMetadata 1`] = `
"<style>
"/** useMetadata: {\\"forwardRef\\":\\"inputRef\\"} */

<style>
.input {
color: red;
}
Expand Down Expand Up @@ -4823,6 +4876,20 @@ exports[`Alpine.js > jsx > Typescript Test > classState 1`] = `
"
`;

exports[`Alpine.js > jsx > Typescript Test > complexMeta 1`] = `
"/** useMetadata:
{\\"x\\":\\"y\\",\\"asdf\\":{\\"stringValue\\":\\"d\\",\\"booleanValue\\":true,\\"numberValue\\":1,\\"innerObject\\":{\\"stringValue\\":\\"inner\\",\\"numberValue\\":2,\\"booleanValue\\":false}}}
*/

<div x-data=\\"complexMetaRaw()\\"></div>
<script>
document.addEventListener(\\"alpine:init\\", () => {
Alpine.data(\\"complexMetaRaw\\", () => ({}));
});
</script>
"
`;

exports[`Alpine.js > jsx > Typescript Test > componentWithContext 1`] = `
"<div x-data=\\"componentWithContext()\\">
<div><span x-html=\\"foo.value\\"></span></div>
Expand Down Expand Up @@ -4961,6 +5028,35 @@ exports[`Alpine.js > jsx > Typescript Test > expressionState 1`] = `
"
`;

exports[`Alpine.js > jsx > Typescript Test > figmaMeta 1`] = `
"/** useMetadata:
{\\"figma\\":{\\"name\\":\\"def-button-beta-outlined\\",\\"url\\":\\"https://www.figma.com/xxx\\",\\"props\\":{\\"iconSmall\\":{\\"type\\":\\"instance\\",\\"key\\":\\"📍
Icon Small\\"},\\"iconMedium\\":{\\"type\\":\\"instance\\",\\"key\\":\\"📍 Icon
Medium\\"},\\"label\\":{\\"type\\":\\"string\\",\\"key\\":\\"✏️
Label\\"},\\"icon\\":{\\"type\\":\\"boolean\\",\\"key\\":\\"👁️
Icon\\",\\"value\\":{\\"false\\":false,\\"true\\":\\"placeholder\\"}},\\"interactiveState\\":{\\"type\\":\\"enum\\",\\"key\\":\\"Interactive
State\\",\\"value\\":{\\"(Def)
Enabled\\":false,\\"Hovered\\":false,\\"Pressed\\":false,\\"Focused\\":false,\\"Disabled\\":\\"true\\"}},\\"size\\":{\\"type\\":\\"enum\\",\\"key\\":\\"Size\\",\\"value\\":{\\"(Def)
Medium\\":false,\\"Small\\":\\"small\\"}},\\"width\\":{\\"type\\":\\"enum\\",\\"key\\":\\"Width\\",\\"value\\":{\\"(Def)
Auto Width\\":false,\\"Full Width\\":\\"full\\"}}}}} */

<button
x-data=\\"figmaButton()\\"
x-bind:data-icon=\\"icon\\"
x-bind:data-disabled=\\"interactiveState\\"
x-bind:data-width=\\"width\\"
x-bind:data-size=\\"size\\"
>
<span x-html=\\"label\\"></span>
</button>
<script>
document.addEventListener(\\"alpine:init\\", () => {
Alpine.data(\\"figmaButton\\", () => ({}));
});
</script>
"
`;

exports[`Alpine.js > jsx > Typescript Test > getterState 1`] = `
"<div x-data=\\"button()\\">
<p><span x-html=\\"foo2\\"></span></p>
Expand Down
Loading