improve Editor UI and add Editor headaer

This commit is contained in:
Yanzhen Yu 2021-10-17 16:51:19 +08:00
parent d210160c21
commit 688b23b058
7 changed files with 153 additions and 30 deletions

View File

@ -1,4 +1,4 @@
import { FormControl, FormLabel, Input } from '@chakra-ui/react';
import { FormControl, FormLabel, Input, Box } from '@chakra-ui/react';
import { Application } from '@meta-ui/core';
import React from 'react';
import { eventBus } from '../../eventBus';
@ -31,10 +31,10 @@ export const ComponentForm: React.FC<Props> = props => {
});
return (
<div>
<Box p={4}>
<div>Component Form</div>
<div>ID: {selectedComponent?.id}</div>
<form>{fields}</form>
</div>
</Box>
);
};

View File

@ -1,4 +1,4 @@
import React, { ReactElement } from 'react';
import React from 'react';
import {
Tabs,
TabList,
@ -21,7 +21,7 @@ export const ComponentList: React.FC = () => {
</TabList>
<TabPanels>
{Array.from(registry.components.keys()).map(version => (
<TabPanel key={version}>
<TabPanel key={version} overflow="auto">
<SimpleGrid columns={4} spacing={1}>
{Array.from(registry.components.get(version)!.values()).map(c => {
const onDragStart = (e: any) => {
@ -38,11 +38,12 @@ export const ComponentList: React.FC = () => {
background="gray.100"
width="60px"
height="60px"
borderRadius="md"
align="center"
justify="center"
transition="ease 0.2s"
_hover={{
transform: 'scale(1.1)',
transform: 'scale(1.05)',
background: 'gray.200',
}}
p={2}

View File

@ -1,9 +1,9 @@
import { useMemo, useState } from 'react';
import { GridCallbacks } from '@meta-ui/runtime';
import { Box } from '@chakra-ui/react';
import { Box, Tabs, TabList, Tab, TabPanels, TabPanel } from '@chakra-ui/react';
import { css } from '@emotion/react';
import { last } from 'lodash';
import { App } from '../metaUI';
import { App, stateStore } from '../metaUI';
import { StructureTree } from './StructureTree';
import {
CreateComponentOperation,
@ -12,28 +12,34 @@ import {
import { eventBus } from '../eventBus';
import { ComponentForm } from './ComponentForm';
import { ComponentList } from './ComponentsList';
import { EditorHeader } from './EditorHeader';
import { PreviewModal } from './PreviewModal';
import { useAppModel } from '../operations/useAppModel';
import { KeyboardEventWrapper } from './KeyboardEventWrapper';
let count = 0;
export const Editor = () => {
const [selectedComponentId, setSelectedComponentId] = useState('');
const [scale, setScale] = useState(100);
const [preview, setPreview] = useState(false);
const { app } = useAppModel();
const Wrapper: React.FC<{ id: string }> = useMemo(() => {
return props => {
const style = css`
height: 100%;
box-shadow: 0 0 ${props.id === selectedComponentId ? 1 : 0}px red;
`;
const onClick = (e: React.MouseEvent<HTMLElement>) => {
e.stopPropagation();
setSelectedComponentId(() => props.id);
};
return (
<div onClick={onClick} css={style}>
<Box
onClick={onClick}
css={style}
boxShadow={props.id === selectedComponentId ? 'outline' : undefined}>
{props.children}
</div>
</Box>
);
};
}, [selectedComponentId]);
@ -72,27 +78,86 @@ export const Editor = () => {
return (
<KeyboardEventWrapper selectedComponentId={selectedComponentId}>
<Box display="flex" height="100vh" width="100vw">
<Box flex="1">
<StructureTree app={app} onSelectComponent={id => setSelectedComponentId(id)} />
</Box>
<Box flex="1">
<strong>Drag Component to canvas!</strong>
<ComponentList />
</Box>
<Box flex="3" borderRight="2px solid black">
<App
options={app}
debugEvent={false}
debugStore={false}
gridCallbacks={gridCallbacks}
componentWrapper={Wrapper}
/>
</Box>
<Box flex="1" borderRight="2px solid black">
<ComponentForm app={app} selectedId={selectedComponentId} />
<Box display="flex" height="100vh" width="100vw" flexDirection="column">
<EditorHeader
scale={scale}
setScale={setScale}
onPreview={() => setPreview(true)}
/>
<Box display="flex" flex="1">
<Box width="280px" borderRightWidth="1px" borderColor="gray.200">
<Tabs
align="center"
height="100%"
display="flex"
flexDirection="column"
textAlign="left">
<TabList background="gray.50">
<Tab>UI Tree</Tab>
<Tab>State</Tab>
</TabList>
<TabPanels flex="1" overflow="auto">
<TabPanel p={0}>
<StructureTree
app={app}
onSelectComponent={id => setSelectedComponentId(id)}
/>
</TabPanel>
<TabPanel p={0}>
<pre>{JSON.stringify(stateStore, null, 2)}</pre>
</TabPanel>
</TabPanels>
</Tabs>
</Box>
<Box flex="1" background="gray.50" p={4}>
<Box
widht="100%"
height="100%"
background="white"
transform={`scale(${scale / 100})`}>
<App
options={app}
debugEvent={false}
debugStore={false}
gridCallbacks={gridCallbacks}
componentWrapper={Wrapper}
/>
</Box>
</Box>
<Box width="320px" borderLeftWidth="1px" borderColor="gray.200">
<Tabs
align="center"
textAlign="left"
height="100%"
display="flex"
flexDirection="column">
<TabList background="gray.50">
<Tab>Inspect</Tab>
<Tab>Insert</Tab>
</TabList>
<TabPanels flex="1" overflow="auto">
<TabPanel p={0}>
<ComponentForm app={app} selectedId={selectedComponentId} />
</TabPanel>
<TabPanel p={0}>
<ComponentList />
</TabPanel>
</TabPanels>
</Tabs>
</Box>
</Box>
</Box>
{preview && (
<PreviewModal onClose={() => setPreview(false)}>
<Box width="100%" height="100%">
<App
options={JSON.parse(JSON.stringify(app))}
debugEvent={false}
debugStore={false}
/>
</Box>
</PreviewModal>
)}
</KeyboardEventWrapper>
);
};

View File

@ -0,0 +1,30 @@
import React from 'react';
import { Flex, Button, Box } from '@chakra-ui/react';
export const EditorHeader: React.FC<{
scale: number;
setScale: (v: number) => void;
onPreview: () => void;
}> = ({ scale, setScale, onPreview }) => {
return (
<Flex p={2} borderBottomWidth="2px" borderColor="gray.200" align="center">
<Flex flex="1" />
<Flex flex="1" align="center" justify="center">
<Button size="sm" disabled={scale <= 50} onClick={() => setScale(scale - 10)}>
-
</Button>
<Box fontSize="sm" mx="2" width={10} textAlign="center">
{scale}%
</Box>
<Button size="sm" disabled={scale >= 100} onClick={() => setScale(scale + 10)}>
+
</Button>
</Flex>
<Flex flex="1" justify="end">
<Button colorScheme="blue" onClick={onPreview}>
preview
</Button>
</Flex>
</Flex>
);
};

View File

@ -0,0 +1 @@
export * from './EditorHeader';

View File

@ -0,0 +1,25 @@
import React from 'react';
import {
Modal,
ModalOverlay,
ModalHeader,
ModalContent,
ModalCloseButton,
ModalBody,
} from '@chakra-ui/react';
export const PreviewModal: React.FC<{ onClose: () => void }> = ({
onClose,
children,
}) => {
return (
<Modal onClose={onClose} size="full" isOpen>
<ModalOverlay />
<ModalContent>
<ModalHeader>Preview App</ModalHeader>
<ModalCloseButton />
<ModalBody>{children}</ModalBody>
</ModalContent>
</Modal>
);
};

View File

@ -0,0 +1 @@
export * from './PreviewModal';