add playground to editor

This commit is contained in:
Yanzhen Yu 2021-11-06 15:28:28 +08:00
parent b7207db8b0
commit cdfbc49cd8
6 changed files with 97 additions and 9 deletions

View File

@ -4,6 +4,12 @@
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>meta-ui runtime example: basic grid layout</title>
<style>
#root {
width: 100vw;
height: 100vh;
}
</style>
</head>
<body>
<div id="root"></div>

View File

@ -8,8 +8,9 @@
<body>
<div id="root"></div>
<script type="module">
import renderPlayground from './src/playground.tsx';
import examples from '@example.json';
console.log(examples);
renderPlayground(examples);
</script>
</body>
</html>

View File

@ -90,7 +90,7 @@ export const Editor: React.FC<Props> = ({
return (
<KeyboardEventWrapper selectedComponentId={selectedComponentId}>
<Box display="flex" height="100vh" width="100vw" flexDirection="column">
<Box display="flex" height="100%" width="100%" flexDirection="column">
<EditorHeader
scale={scale}
setScale={setScale}

View File

@ -12,6 +12,9 @@ export const KeyboardEventWrapper: React.FC<Props> = props => {
&:focus {
outline: none;
}
width: 100%;
height: 100%;
`;
const onKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {

View File

@ -64,6 +64,8 @@ export class AppModelManager {
eventBus.on('undo', () => this.undo());
eventBus.on('operation', o => this.apply(o));
this.updateApp(this.app);
}
getApp() {

View File

@ -1,27 +1,103 @@
import { ChakraProvider } from '@chakra-ui/react';
import { Application, Module } from '@meta-ui/core';
import { StrictMode } from 'react';
import { Flex, Box, ChakraProvider, Button } from '@chakra-ui/react';
import { Application } from '@meta-ui/core';
import { initMetaUI } from '@meta-ui/runtime';
import { Registry } from '@meta-ui/runtime/lib/services/registry';
import { StrictMode, useMemo, useState } from 'react';
import ReactDOM from 'react-dom';
import 'react-grid-layout/css/styles.css';
import 'react-resizable/css/styles.css';
import { Editor } from './components/Editor';
import { appModelManager } from './operations/useAppModel';
// import { registry } from './metaUI'
import { AppModelManager } from './operations/AppModelManager';
type Example = {
name: string;
value: {
app: Application;
modules?: Module[];
modules?: Parameters<Registry['registerModule']>[0][];
};
};
const Playground: React.FC<{ examples: Example[] }> = ({ examples }) => {
const [example, setExample] = useState<Example | null>(examples[0]);
const { App, registry, stateStore, appModelManager } = useMemo(() => {
if (!example) {
return {};
}
const metaUI = initMetaUI();
const App = metaUI.App;
const registry = metaUI.registry;
const stateStore = metaUI.stateManager.store;
const { app, modules = [] } = example.value;
modules.forEach(m => {
registry.registerModule(m);
});
localStorage.removeItem('schema');
const appModelManager = new AppModelManager(app, registry);
return {
App,
registry,
stateStore,
appModelManager,
};
}, [example]);
return (
<Flex width="100vw" height="100vh">
<Box shadow="md">
<Box width="200px" height="100%" overflow="auto" pl={2}>
{examples.map(e => (
<Button
variant={example === e ? 'solid' : 'ghost'}
key={e.name}
onClick={() => {
/**
* Currently, the data flow between the useAppModel and
* the AppModelManager is a little wierd.
* When initialize the AppModelManager, it will notify
* the useAppModel hook, which will cause the Editor
* component update.
* React does not like this and throw Error to complain
* the Editor and the Playground components are updating
* together.
* So we set example to null, which unmount the editor
* first. Then we can re-create the editor with new example
* spec.
*/
setExample(null);
setTimeout(() => {
setExample(e);
}, 0);
}}
>
{e.name}
</Button>
))}
</Box>
</Box>
<Box flex="1">
{appModelManager && (
<Editor
key={example!.name}
App={App!}
registry={registry!}
stateStore={stateStore!}
appModelManager={appModelManager}
/>
)}
</Box>
</Flex>
);
};
export default function renderPlayground(examples: Example[]) {
ReactDOM.render(
<StrictMode>
<ChakraProvider>
<Editor />
<Playground examples={examples} />
</ChakraProvider>
</StrictMode>,
document.getElementById('root')