button support grid

This commit is contained in:
Bowen Tan 2021-09-30 11:38:50 +08:00
parent 2d237e5da7
commit 42449ef130
11 changed files with 174 additions and 149 deletions

View File

@ -21,6 +21,7 @@
"url": "https://github.com/webzard-io/meta-ui/issues"
},
"dependencies": {
"@chakra-ui/icons": "^1.0.15",
"@chakra-ui/react": "^1.6.5",
"@emotion/react": "^11",
"@emotion/styled": "^11",

View File

@ -32,7 +32,8 @@ export const ComponentForm: React.FC<Props> = props => {
return (
<div>
<div>{selectedComponent?.id}</div>
<div>Component Form</div>
<div>ID: {selectedComponent?.id}</div>
<form>{fields}</form>
</div>
);

View File

@ -1,6 +1,6 @@
import { useCallback, useEffect, useMemo, useState } from 'react';
import { Application } from '@meta-ui/core';
import { Box } from '@chakra-ui/react';
import { Box, Button } from '@chakra-ui/react';
import { DefaultAppSchema } from '../constants';
import { App } from '../metaUI';
import { StructureTree } from './StructureTree';
@ -20,21 +20,21 @@ export const Editor = () => {
const [selectedComponentId, setSelectedComponentId] = useState('');
const [app, setApp] = useState<Application>(operationManager.getApp());
const Wrapper: React.FC<{ id: string }> = useMemo(() => {
return props => {
const style =
props.id === selectedComponentId ? { boxShadow: '0 0 1px red' } : undefined;
const onClick = (e: React.MouseEvent<HTMLElement>) => {
e.stopPropagation();
setSelectedComponentId(() => props.id);
};
return (
<div onClick={onClick} style={style}>
{props.children}
</div>
);
};
}, [selectedComponentId]);
// const Wrapper: React.FC<{ id: string }> = useMemo(() => {
// return props => {
// const style =
// props.id === selectedComponentId ? { boxShadow: '0 0 1px red' } : undefined;
// const onClick = (e: React.MouseEvent<HTMLElement>) => {
// e.stopPropagation();
// setSelectedComponentId(() => props.id);
// };
// return (
// <div onClick={onClick} style={style}>
// {props.children}
// </div>
// );
// };
// }, [selectedComponentId]);
useEffect(() => {
const onAppChange = (app: Application) => {
@ -47,24 +47,17 @@ export const Editor = () => {
};
}, []);
const onClickAdd = useCallback(() => {
eventBus.send(
'operation',
new CreateComponentOperation('root', 'container', 'chakra_ui/v1/input')
);
}, [app, setApp]);
const onClickUndo = useCallback(() => {
eventBus.send('undo');
}, [app, setApp]);
const gridCallbacks: GridCallbacks = {
onDragStop(id, layout) {
console.log('dragstop');
eventBus.send(
'operation',
new ModifyComponentPropertyOperation(id, 'layout', layout)
);
console.log('onDragStop', id, layout);
},
onDrop(id, layout, item, e) {
const component = e.dataTransfer?.getData('component') || '';
@ -87,19 +80,17 @@ export const Editor = () => {
'operation',
new ModifyComponentPropertyOperation(id, 'layout', newLayout)
);
console.log('onDragStop', id, layout);
console.log('onDrop', id, layout, item);
},
};
return (
<Box display="flex" height="100vh" width="100vw">
<Box flex="1">
<button onClick={onClickAdd}></button>
<button onClick={onClickUndo}></button>
<StructureTree app={app} onSelectComponent={id => setSelectedComponentId(id)} />
<Button onClick={onClickUndo}></Button>
</Box>
<Box flex="1">
<strong>Drag Component to canvas!</strong>
<ComponentList />
</Box>
<Box flex="3" borderRight="2px solid black">

View File

@ -1,5 +1,7 @@
import React from 'react';
import { Application } from '@meta-ui/core';
import { IconButton } from '@chakra-ui/react';
import { DeleteIcon } from '@chakra-ui/icons';
import { eventBus } from '../../eventBus';
import { RemoveComponentOperation } from '../../operations/Operations';
@ -62,7 +64,7 @@ export const StructureTree: React.FC<Props> = props => {
>
{component.id}
</strong>
<span onClick={onClickRemove}></span>
<IconButton aria-label="remove" icon={<DeleteIcon />} onClick={onClickRemove} />
{slotsEle}
</div>
);

View File

@ -3,110 +3,81 @@ import { Application } from '@meta-ui/core';
export const DefaultAppSchema: Application = {
kind: 'Application',
version: 'example/v1',
metadata: {
name: 'basic_grid_layout',
description: 'basic grid layout example',
},
metadata: { name: 'basic_grid_layout', description: 'basic grid layout example' },
spec: {
components: [
{
id: 'root',
id: 'grid',
type: 'core/v1/grid_layout',
properties: {
layout: [
{
w: 10,
h: 2,
x: 0,
y: 0,
w: 5,
h: 2,
i: 'image',
moved: false,
static: false,
isDraggable: true,
},
{
w: 3,
h: 1,
x: 7,
y: 2,
i: 'button',
moved: false,
static: false,
isDraggable: true,
},
{
w: 3,
h: 1,
x: 0,
y: 2,
i: 'input',
isResizable: false,
},
{
x: 4,
y: 0,
w: 4,
h: 9,
i: 'box1',
},
{
x: 8,
y: 0,
w: 2,
h: 12,
i: 'box2',
moved: false,
static: false,
isDraggable: true,
},
],
},
traits: [],
},
{
id: 'input',
type: 'chakra_ui/v1/input',
id: 'image',
type: 'chakra_ui/v1/image',
properties: {
variant: 'filled',
placeholder: 'This a example',
size: 'lg',
colorScheme: 'pink',
focusBorderColor: 'pink.500',
isDisabled: false,
isRequired: true,
left: {
type: 'addon',
children: 'https://',
},
right: {
type: 'element',
children: '.com',
color: 'red',
fontSize: '16px',
},
src: 'https://www.smartx.com/img/smartx-logo-horizontal.ff708dd4.svg',
objectFit: '',
},
traits: [
{
type: 'core/v1/slot',
properties: {
container: {
id: 'root',
slot: 'container',
},
},
properties: { container: { id: 'grid', slot: 'container' } },
},
],
},
{
id: 'box1',
type: 'chakra_ui/v1/box',
id: 'button',
type: 'chakra_ui/v1/button',
properties: { text: { raw: '确认' } },
traits: [
{
type: 'core/v1/slot',
properties: { container: { id: 'grid', slot: 'container' } },
},
],
},
{
id: 'input',
type: 'chakra_ui/v1/input',
properties: {},
traits: [
{
type: 'core/v1/slot',
properties: {
container: {
id: 'root',
slot: 'container',
},
},
},
],
},
{
id: 'box2',
type: 'chakra_ui/v1/box',
properties: {
bgColor: 'pink',
w: '100%',
h: '100%',
},
traits: [
{
type: 'core/v1/slot',
properties: {
container: {
id: 'root',
slot: 'container',
},
},
properties: { container: { id: 'grid', slot: 'container' } },
},
],
},

View File

@ -103,12 +103,22 @@ export class OperationManager {
case 'modifyComponentProperty':
const mo = o as ModifyComponentPropertyOperation;
newApp = produce(this.app, draft => {
draft.spec.components.forEach(c => {
return draft.spec.components.forEach(c => {
if (c.id === mo.componentId) {
c.properties[mo.propertyKey] = mo.propertyValue;
}
});
});
if (!noEffect) {
const oldValue = this.app.spec.components.find(c => c.id === mo.componentId)
?.properties[mo.propertyKey];
const undoOperation = new ModifyComponentPropertyOperation(
mo.componentId,
mo.propertyKey,
oldValue
);
this.undoStack.push(undoOperation);
}
break;
}
this.updateApp(newApp);

View File

@ -10,73 +10,102 @@
<script type="module">
import renderApp from '../../src/main.tsx';
renderApp({
kind: 'Application',
version: 'example/v1',
metadata: {
name: 'basic_grid_layout',
description: 'basic grid layout example',
},
metadata: { name: 'basic_grid_layout', description: 'basic grid layout example' },
spec: {
components: [
{
id: 'grid_container',
id: 'root',
type: 'chakra_ui/v1/root',
properties: {},
traits: [],
},
{
id: 'grid',
type: 'core/v1/grid_layout',
properties: {
layout: [
{
x: 4,
w: 8,
h: 1,
x: 0,
y: 0,
w: 4,
h: 9,
i: 'box1',
i: 'input',
},
{ w: 4, h: 9, x: 0, y: 2, i: 'box1', moved: false, static: false },
{ w: 2, h: 12, x: 8, y: 0, i: 'box2', moved: false, static: false },
{
x: 8,
y: 0,
w: 2,
h: 12,
i: 'box2',
w: 3,
h: 1,
x: 3,
y: 11,
i: 'component0',
},
],
},
traits: [],
},
{
id: 'box1',
type: 'chakra_ui/v1/box',
properties: {
border: '2px solid blue',
w: '100%',
h: '100%',
},
traits: [
{
type: 'core/v1/slot',
properties: {
container: {
id: 'grid_container',
slot: 'container',
},
},
properties: { container: { id: 'root', slot: 'root' } },
},
],
},
{
id: 'input',
type: 'chakra_ui/v1/input',
properties: {
variant: 'filled',
placeholder: 'This a example',
colorScheme: 'pink',
focusBorderColor: 'pink.500',
isDisabled: false,
isRequired: true,
left: { type: 'addon', children: 'https://' },
right: {
type: 'element',
children: '.com',
color: 'red',
fontSize: '16px',
},
},
traits: [
{
type: 'core/v1/slot',
properties: { container: { id: 'grid', slot: 'container' } },
},
],
},
{
id: 'box1',
type: 'chakra_ui/v1/box',
properties: {},
traits: [
{
type: 'core/v1/slot',
properties: { container: { id: 'grid', slot: 'container' } },
},
],
},
{
id: 'box2',
type: 'chakra_ui/v1/box',
properties: {
bgColor: 'pink',
w: '100%',
h: '100%',
},
properties: { bgColor: 'pink', w: '100%', h: '100%' },
traits: [
{
type: 'core/v1/slot',
properties: {
container: {
id: 'grid_container',
slot: 'container',
},
},
properties: { container: { id: 'grid', slot: 'container' } },
},
],
},
{
id: 'component0',
type: 'chakra_ui/v1/button',
properties: { text: { raw: '提交' } },
traits: [
{
type: 'core/v1/slot',
properties: { container: { id: 'grid', slot: 'container' } },
},
],
},

View File

@ -15,6 +15,7 @@
"module": "lib/index.js",
"types": "lib/index.d.ts",
"dependencies": {
"@chakra-ui/icons": "^1.0.15",
"@chakra-ui/react": "^1.6.5",
"@emotion/react": "^11",
"@emotion/styled": "^11",

View File

@ -27,7 +27,7 @@ const GridLayout: React.FC<{
isResizable={!!onDragStop}
compactType={null}
preventCollision={true}
rowHeight={30}
rowHeight={40}
layout={layout}
onDragStop={onDragStop}
onDrop={onDrop}

View File

@ -1,11 +1,17 @@
import { useEffect, useRef } from 'react';
import { createComponent } from '@meta-ui/core';
import { css } from '@emotion/react';
import { Static, Type } from '@sinclair/typebox';
import { Button as BaseButton } from '@chakra-ui/react';
import Text, { TextPropertySchema } from '../_internal/Text';
import { ComponentImplementation } from '../../modules/registry';
import { ColorSchemePropertySchema } from './Types/ColorScheme';
const style = css`
width: 100%;
height: 100%;
`;
const Button: ComponentImplementation<Static<typeof PropsSchema>> = ({
text,
mergeState,
@ -28,7 +34,12 @@ const Button: ComponentImplementation<Static<typeof PropsSchema>> = ({
}, []);
return (
<BaseButton {...{ colorScheme, isLoading }} ref={ref} onClick={callbacks?.click}>
<BaseButton
css={style}
{...{ colorScheme, isLoading }}
ref={ref}
onClick={callbacks?.click}
>
<Text value={text} />
</BaseButton>
);

View File

@ -1152,6 +1152,14 @@
dependencies:
"@chakra-ui/utils" "1.8.2"
"@chakra-ui/icons@^1.0.15":
version "1.0.15"
resolved "https://registry.yarnpkg.com/@chakra-ui/icons/-/icons-1.0.15.tgz#90b0e3c2c161c5a100d6b83a277941b22945f880"
integrity sha512-MMuPwmeCil9vAXceIN/Fxn6CNHbhkLofFQaKUfs+UaBsviiU2tvS0nqGaxm/9FNzLr5ithPVWpbz3uV7DXc77g==
dependencies:
"@chakra-ui/icon" "1.1.11"
"@types/react" "^17.0.0"
"@chakra-ui/image@1.0.20":
version "1.0.20"
resolved "https://registry.yarnpkg.com/@chakra-ui/image/-/image-1.0.20.tgz#18057ca248f17c813ad60812ac4c7965a1de1fda"