implement virtual example plugin

This vite plugin will read from the examples directory and compose
all the example manifests into a JSON.
This commit is contained in:
Yanzhen Yu 2021-11-06 10:08:21 +08:00
parent 6d99180145
commit ace258079e
3 changed files with 177 additions and 1 deletions

117
examples/box/index.json Normal file
View File

@ -0,0 +1,117 @@
{
"app": {
"version": "example/v1",
"metadata": { "name": "box", "description": "box" },
"spec": {
"components": [
{
"id": "test_btn",
"type": "plain/v1/button",
"properties": { "text": { "raw": "Click", "format": "plain" } },
"traits": [
{
"type": "core/v1/state",
"properties": { "key": "count", "initialValue": 0 }
},
{
"type": "core/v1/event",
"properties": {
"handlers": [
{
"type": "onClick",
"componentId": "test_btn",
"method": {
"name": "setValue",
"parameters": {
"key": "count",
"value": "{{ test_btn.count > 0 ? 0 : test_btn.count + 1 }}"
}
},
"wait": {},
"disabled": false
}
]
}
}
]
},
{
"id": "box_container",
"type": "chakra_ui/v1/box",
"properties": {
"my": 8,
"p": 8,
"display": "flex",
"bg": "{{ test_btn.count % 2 ? 'teal' : 'white' }}",
"border": "1px solid",
"borderColor": "{{ test_btn.count % 2 ? 'white' : 'teal' }}",
"borderRadius": 8,
"h": 200
},
"traits": []
},
{
"id": "box_child_1",
"type": "chakra_ui/v1/box",
"properties": {
"mr": 4,
"flex": 1,
"bg": "{{ test_btn.count % 2 ? 'white' : 'teal' }}",
"color": "{{ test_btn.count % 2 ? 'teal' : 'white' }}",
"display": "flex",
"alignItems": "center",
"justifyContent": "center",
"borderRadius": 4
},
"traits": [
{
"type": "core/v1/slot",
"properties": { "container": { "id": "box_container", "slot": "content" } }
}
]
},
{
"id": "text",
"type": "core/v1/text",
"properties": { "value": { "raw": "in box child 1", "format": "plain" } },
"traits": [
{
"type": "core/v1/slot",
"properties": { "container": { "id": "box_child_1", "slot": "content" } }
}
]
},
{
"id": "box_child_2",
"type": "chakra_ui/v1/box",
"properties": {
"flex": 1,
"bg": "{{ test_btn.count % 2 ? 'white' : 'teal' }}",
"color": "{{ test_btn.count % 2 ? 'teal' : 'white' }}",
"display": "flex",
"alignItems": "center",
"justifyContent": "center",
"borderRadius": 4
},
"traits": [
{
"type": "core/v1/slot",
"properties": { "container": { "id": "box_container", "slot": "content" } }
}
]
},
{
"id": "text",
"type": "core/v1/text",
"properties": { "value": { "raw": "in box child 2", "format": "plain" } },
"traits": [
{
"type": "core/v1/slot",
"properties": { "container": { "id": "box_child_2", "slot": "content" } }
}
]
}
]
}
}
}

View File

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="en" style="overflow: hidden">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>meta-ui runtime examples</title>
</head>
<body>
<div id="root"></div>
<script type="module">
import renderApp from './src/main.tsx';
import examples from '@example.json';
console.log(examples);
const example = examples[0];
renderApp(example.value.app);
</script>
</body>
</html>

View File

@ -1,5 +1,43 @@
import { defineConfig } from 'vite';
import { defineConfig, Plugin } from 'vite';
import react from '@vitejs/plugin-react';
import fs from 'fs';
import path from 'path';
function virtualExamplePlugin(): Plugin {
const virtualFileId = '@example.json';
const exampleDir = path.join(__dirname, '../../examples');
const examples = [];
function walk(dirOrFile: string, frags: string[]) {
if (fs.statSync(dirOrFile).isDirectory()) {
for (const subDir of fs.readdirSync(dirOrFile)) {
frags.push(subDir);
walk(path.join(dirOrFile, subDir), frags);
}
} else {
const value = JSON.parse(fs.readFileSync(dirOrFile, 'utf-8'));
const name = frags.filter(frag => frag !== 'index.json').join('_');
examples.push({ name, value });
}
}
walk(exampleDir, []);
return {
name: 'virtual-example-plugin',
resolveId(id) {
if (id === virtualFileId) {
return virtualFileId;
}
},
load(id) {
if (id === virtualFileId) {
return JSON.stringify(examples);
}
},
};
}
// https://vitejs.dev/config/
export default defineConfig({
@ -18,6 +56,7 @@ export default defineConfig({
],
},
}),
virtualExamplePlugin(),
],
define: {
// https://github.com/satya164/react-simple-code-editor/issues/86