mirror of
https://github.com/smartxworks/sunmao-ui.git
synced 2024-11-21 03:15:49 +08:00
improve Editor UI and add Editor headaer
This commit is contained in:
parent
d210160c21
commit
688b23b058
@ -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>
|
||||
);
|
||||
};
|
||||
|
@ -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}
|
||||
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
30
packages/editor/src/components/EditorHeader/EditorHeader.tsx
Normal file
30
packages/editor/src/components/EditorHeader/EditorHeader.tsx
Normal 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>
|
||||
);
|
||||
};
|
1
packages/editor/src/components/EditorHeader/index.ts
Normal file
1
packages/editor/src/components/EditorHeader/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './EditorHeader';
|
25
packages/editor/src/components/PreviewModal/PreviewModal.tsx
Normal file
25
packages/editor/src/components/PreviewModal/PreviewModal.tsx
Normal 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>
|
||||
);
|
||||
};
|
1
packages/editor/src/components/PreviewModal/index.ts
Normal file
1
packages/editor/src/components/PreviewModal/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './PreviewModal';
|
Loading…
Reference in New Issue
Block a user