mirror of
https://github.com/smartxworks/sunmao-ui.git
synced 2025-04-12 21:50:23 +08:00
add playground to editor
This commit is contained in:
parent
b7207db8b0
commit
cdfbc49cd8
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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}
|
||||
|
@ -12,6 +12,9 @@ export const KeyboardEventWrapper: React.FC<Props> = props => {
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
`;
|
||||
|
||||
const onKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
|
||||
|
@ -64,6 +64,8 @@ export class AppModelManager {
|
||||
|
||||
eventBus.on('undo', () => this.undo());
|
||||
eventBus.on('operation', o => this.apply(o));
|
||||
|
||||
this.updateApp(this.app);
|
||||
}
|
||||
|
||||
getApp() {
|
||||
|
@ -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')
|
||||
|
Loading…
x
Reference in New Issue
Block a user