mirror of
https://github.com/smartxworks/sunmao-ui.git
synced 2025-04-06 21:40:23 +08:00
button support grid
This commit is contained in:
parent
2d237e5da7
commit
42449ef130
@ -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",
|
||||
|
@ -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>
|
||||
);
|
||||
|
@ -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">
|
||||
|
@ -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>
|
||||
);
|
||||
|
@ -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' } },
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -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);
|
||||
|
@ -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' } },
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -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",
|
||||
|
@ -27,7 +27,7 @@ const GridLayout: React.FC<{
|
||||
isResizable={!!onDragStop}
|
||||
compactType={null}
|
||||
preventCollision={true}
|
||||
rowHeight={30}
|
||||
rowHeight={40}
|
||||
layout={layout}
|
||||
onDragStop={onDragStop}
|
||||
onDrop={onDrop}
|
||||
|
@ -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>
|
||||
);
|
||||
|
@ -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"
|
||||
|
Loading…
x
Reference in New Issue
Block a user