mirror of
https://github.com/smartxworks/sunmao-ui.git
synced 2025-04-12 21:50:23 +08:00
add component Form
This commit is contained in:
parent
69955e6f62
commit
688065cb95
@ -0,0 +1,41 @@
|
||||
import { ChakraProvider, FormControl, FormLabel, Input } from '@chakra-ui/react';
|
||||
import { Application } from '@meta-ui/core';
|
||||
import React from 'react';
|
||||
import { eventBus } from '../../eventBus';
|
||||
import { ModifyComponentPropertyOperation } from '../../operations/Operations';
|
||||
|
||||
type Props = { selectedId: string; app: Application };
|
||||
|
||||
export const ComponentForm: React.FC<Props> = props => {
|
||||
const { selectedId, app } = props;
|
||||
|
||||
const selectedComponent = app.spec.components.find(c => c.id === selectedId);
|
||||
|
||||
const properties = selectedComponent?.properties;
|
||||
|
||||
const fields = Object.keys(properties || []).map(key => {
|
||||
const value = properties![key];
|
||||
const ref = React.createRef<HTMLInputElement>();
|
||||
const onBlur = () => {
|
||||
eventBus.send(
|
||||
'operation',
|
||||
new ModifyComponentPropertyOperation(selectedId, key, ref.current?.value)
|
||||
);
|
||||
};
|
||||
return (
|
||||
<FormControl key={key}>
|
||||
<FormLabel>{key}</FormLabel>
|
||||
<Input ref={ref} onBlur={onBlur} defaultValue={value as string} />
|
||||
</FormControl>
|
||||
);
|
||||
});
|
||||
|
||||
return (
|
||||
<ChakraProvider>
|
||||
<div>
|
||||
<div>选中{selectedComponent?.id}</div>
|
||||
<form>{fields}</form>
|
||||
</div>
|
||||
</ChakraProvider>
|
||||
);
|
||||
};
|
1
packages/editor/src/components/ComponentForm/index.ts
Normal file
1
packages/editor/src/components/ComponentForm/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './ComponentForm';
|
@ -7,21 +7,29 @@ import { StructureTree } from './StructureTree';
|
||||
import { OperationManager } from '../operations/OperationManager';
|
||||
import { CreateComponentOperation } from '../operations/Operations';
|
||||
import { eventBus } from '../eventBus';
|
||||
import { ComponentForm } from './ComponentForm';
|
||||
|
||||
const operationManager = new OperationManager(DialogFormSchema);
|
||||
|
||||
export const Editor = () => {
|
||||
const [selectedComponent, setSelectedComponent] = useState('');
|
||||
const [selectedComponentId, setSelectedComponentId] = useState('');
|
||||
const [app, setApp] = useState<Application>(operationManager.getApp());
|
||||
|
||||
const Wrapper: React.FC<{ id: string }> = useMemo(() => {
|
||||
return props => {
|
||||
if (props.id === selectedComponent) {
|
||||
return <div style={{ boxShadow: '0 0 1px red' }}>{props.children}</div>;
|
||||
}
|
||||
return <>{props.children}</>;
|
||||
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>
|
||||
);
|
||||
};
|
||||
}, [selectedComponent]);
|
||||
}, [selectedComponentId]);
|
||||
|
||||
useEffect(() => {
|
||||
const onAppChange = (app: Application) => {
|
||||
@ -47,18 +55,16 @@ export const Editor = () => {
|
||||
|
||||
return (
|
||||
<Box display="flex" height="100vh">
|
||||
<button onClick={onClickAdd}>添加</button>
|
||||
<button onClick={onClickUndo}>撤销</button>
|
||||
<Box flex="1">
|
||||
<StructureTree app={app} onSelectComponent={id => setSelectedComponent(id)} />
|
||||
<button onClick={onClickAdd}>添加</button>
|
||||
<button onClick={onClickUndo}>撤销</button>
|
||||
<StructureTree app={app} onSelectComponent={id => setSelectedComponentId(id)} />
|
||||
</Box>
|
||||
<Box flex="3" borderRight="2px solid black">
|
||||
<App
|
||||
debugStore={false}
|
||||
debugEvent={false}
|
||||
options={app}
|
||||
componentWrapper={Wrapper}
|
||||
/>
|
||||
<App options={app} componentWrapper={Wrapper} />
|
||||
</Box>
|
||||
<Box flex="1" borderRight="2px solid black">
|
||||
<ComponentForm app={app} selectedId={selectedComponentId} />
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { css } from '@emotion/react';
|
||||
import { StrictMode } from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { ComponentList } from './components/ComponentsList';
|
||||
import { Editor } from './components/Editor';
|
||||
export default function renderApp() {
|
||||
ReactDOM.render(
|
||||
@ -12,7 +11,6 @@ export default function renderApp() {
|
||||
`}
|
||||
>
|
||||
<Editor />
|
||||
<ComponentList />
|
||||
</div>
|
||||
</StrictMode>,
|
||||
document.getElementById('root')
|
||||
|
@ -4,6 +4,7 @@ import {
|
||||
Operations,
|
||||
CreateComponentOperation,
|
||||
RemoveComponentOperation,
|
||||
ModifyComponentPropertyOperation,
|
||||
} from './Operations';
|
||||
import { produce } from 'immer';
|
||||
import { registry } from '../metaUI';
|
||||
@ -64,7 +65,6 @@ export class OperationManager {
|
||||
}
|
||||
|
||||
apply(o: Operations, noEffect = false) {
|
||||
console.log('apply');
|
||||
let newApp = this.app;
|
||||
switch (o.kind) {
|
||||
case 'createComponent':
|
||||
@ -89,6 +89,16 @@ export class OperationManager {
|
||||
draft.spec.components.splice(i, 1);
|
||||
});
|
||||
break;
|
||||
case 'modifyComponentProperty':
|
||||
const mo = o as ModifyComponentPropertyOperation;
|
||||
newApp = produce(this.app, draft => {
|
||||
draft.spec.components.forEach(c => {
|
||||
if (c.id === mo.componentId) {
|
||||
c.properties[mo.propertyKey] = mo.propertyValue;
|
||||
}
|
||||
});
|
||||
});
|
||||
break;
|
||||
}
|
||||
this.updateApp(newApp);
|
||||
}
|
||||
|
@ -1,4 +1,7 @@
|
||||
export type Operations = CreateComponentOperation | RemoveComponentOperation;
|
||||
export type Operations =
|
||||
| CreateComponentOperation
|
||||
| RemoveComponentOperation
|
||||
| ModifyComponentPropertyOperation;
|
||||
export class CreateComponentOperation {
|
||||
kind = 'createComponent';
|
||||
|
||||
@ -13,3 +16,12 @@ export class RemoveComponentOperation {
|
||||
kind = 'removeComponent';
|
||||
constructor(public componentId: string) {}
|
||||
}
|
||||
|
||||
export class ModifyComponentPropertyOperation {
|
||||
kind = 'modifyComponentProperty';
|
||||
constructor(
|
||||
public componentId: string,
|
||||
public propertyKey: string,
|
||||
public propertyValue: unknown
|
||||
) {}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user